Finalized watcher
This commit is contained in:
130
src/util.rs
130
src/util.rs
@ -0,0 +1,130 @@
|
||||
use std::{ptr::null_mut, time::Duration};
|
||||
use winapi::{
|
||||
shared::minwindef::DWORD,
|
||||
um::{
|
||||
errhandlingapi::GetLastError,
|
||||
winsvc::{
|
||||
CloseServiceHandle, ControlService, OpenSCManagerW, OpenServiceW, QueryServiceStatus, StartServiceW, SC_HANDLE__, SC_MANAGER_CONNECT, SERVICE_CONTROL_STOP, SERVICE_QUERY_STATUS, SERVICE_START, SERVICE_STOP
|
||||
},
|
||||
},
|
||||
};
|
||||
use widestring::U16CString;
|
||||
|
||||
const SERVICE_STATUS_RUNNING: u32 = 0x00000004;
|
||||
const SERVICE_STATUS_STOPPED: u32 = 0x00000001;
|
||||
|
||||
fn open_sc_manager(desired_access: DWORD) -> Result<*mut SC_HANDLE__, DWORD> {
|
||||
let sc_manager_handle = unsafe { OpenSCManagerW(null_mut(), null_mut(), desired_access) };
|
||||
if sc_manager_handle.is_null() {
|
||||
Err(unsafe { GetLastError() })
|
||||
} else {
|
||||
Ok(sc_manager_handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn open_service(
|
||||
sc_manager_handle: *mut SC_HANDLE__,
|
||||
service_name: &str,
|
||||
desired_access: DWORD,
|
||||
) -> Result<*mut SC_HANDLE__, DWORD> {
|
||||
let service_name_wstr = U16CString::from_str(service_name).unwrap();
|
||||
let service_handle = unsafe {
|
||||
OpenServiceW(
|
||||
sc_manager_handle,
|
||||
service_name_wstr.as_ptr(),
|
||||
desired_access,
|
||||
)
|
||||
};
|
||||
if service_handle.is_null() {
|
||||
Err(unsafe { GetLastError() })
|
||||
} else {
|
||||
Ok(service_handle)
|
||||
}
|
||||
}
|
||||
|
||||
fn start_service(service_handle: *mut SC_HANDLE__) -> Result<(), DWORD> {
|
||||
let result = unsafe { StartServiceW(service_handle, 0, null_mut()) };
|
||||
if result == 0 {
|
||||
Err(unsafe { GetLastError() })
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn stop_service(service_handle: *mut SC_HANDLE__) -> Result<(), DWORD> {
|
||||
let mut service_status = unsafe { std::mem::zeroed() };
|
||||
let result = unsafe {
|
||||
ControlService(
|
||||
service_handle,
|
||||
SERVICE_CONTROL_STOP,
|
||||
&mut service_status,
|
||||
)
|
||||
};
|
||||
if result == 0 {
|
||||
Err(unsafe { GetLastError() })
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn query_service_status(service_handle: *mut SC_HANDLE__) -> Result<DWORD, DWORD> {
|
||||
let mut service_status = unsafe { std::mem::zeroed() };
|
||||
let result = unsafe { QueryServiceStatus(service_handle, &mut service_status) };
|
||||
if result == 0 {
|
||||
Err(unsafe { GetLastError() })
|
||||
} else {
|
||||
Ok(service_status.dwCurrentState)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restart_service(service_name: String) {
|
||||
let sc_manager_handle = open_sc_manager(SC_MANAGER_CONNECT).unwrap();
|
||||
|
||||
let service_handle = open_service(
|
||||
sc_manager_handle,
|
||||
service_name.as_str(),
|
||||
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let service_status_res = query_service_status(service_handle);
|
||||
|
||||
if let Err(e) = service_status_res {
|
||||
error!("Failed to query service status. Error code: {e}");
|
||||
return;
|
||||
}
|
||||
|
||||
let service_status = service_status_res.unwrap();
|
||||
|
||||
if service_status == SERVICE_STATUS_RUNNING {
|
||||
// Stop the service
|
||||
match stop_service(service_handle) {
|
||||
Ok(_) => info!("Service stopped successfully."),
|
||||
Err(error) => info!("Failed to stop service. Error: {}", error),
|
||||
}
|
||||
|
||||
info!("Waiting for service being stopped successfully");
|
||||
std::thread::sleep(Duration::from_secs(10));
|
||||
|
||||
// Start the service
|
||||
match start_service(service_handle) {
|
||||
Ok(_) => info!("Service started successfully."),
|
||||
Err(error) => info!("Failed to start service. Error: {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
if service_status == SERVICE_STATUS_STOPPED {
|
||||
// Start the service
|
||||
match start_service(service_handle) {
|
||||
Ok(_) => info!("Service started successfully."),
|
||||
Err(error) => info!("Failed to start service. Error: {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
// Close the service and SCM handles
|
||||
unsafe {
|
||||
CloseServiceHandle(service_handle);
|
||||
CloseServiceHandle(sc_manager_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user