I try to write a windows service using winapi
How to pass “heventlog” of main function to service_main using
In other languages, we can use global variables. How to deal with this situation in Rust?
Code
use std::sync::{Arc, Mutex};
use windows::core::{w, PWSTR};
use windows::Win32::Foundation::HANDLE;
use windows::Win32::System::Services::{
RegisterServiceCtrlHandlerW, SetServiceStatus, StartServiceCtrlDispatcherW,
SERVICE_ACCEPT_STOP, SERVICE_CONTROL_STOP, SERVICE_RUNNING, SERVICE_START_PENDING,
SERVICE_STATUS, SERVICE_STOPPED, SERVICE_TABLE_ENTRYW, SERVICE_WIN32_OWN_PROCESS,
};
unsafe extern "system" fn service_control_handler(dwcontrol: u32) {
match dwcontrol {
SERVICE_CONTROL_STOP => return,
_ => {}
}
}
unsafe extern "system" fn service_main(_dwnumservicesargs: u32, _lpserviceargvectors: *mut PWSTR) {
// How to use heventlog
let mut lpservicestatus = SERVICE_STATUS {
dwServiceType: SERVICE_WIN32_OWN_PROCESS,
dwCurrentState: SERVICE_START_PENDING,
dwControlsAccepted: SERVICE_ACCEPT_STOP,
dwWin32ExitCode: 0,
dwServiceSpecificExitCode: 0,
dwCheckPoint: 0,
dwWaitHint: 0,
};
let lpservicename = w!("Demo Service");
let hservicestatus =
RegisterServiceCtrlHandlerW(lpservicename, Some(service_control_handler)).unwrap();
lpservicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hservicestatus, &mut lpservicestatus).unwrap();
}
fn main() {
use windows::Win32::System::EventLog::RegisterEventSourceW;
let heventlog = unsafe { RegisterEventSourceW(None, w!("Demo Service")) }.unwrap();
let heventlog: Arc<Mutex<HANDLE>> = Arc::new(Mutex::new(heventlog));
// How heventlog is passed to service_main
let mut lp_service_name = "Demo Service".encode_utf16().collect::<Vec<u16>>();
let lp_service_name = PWSTR::from_raw(lp_service_name.as_mut_ptr());
let lpservicestarttable = [
SERVICE_TABLE_ENTRYW {
lpServiceName: lp_service_name,
lpServiceProc: Some(service_main),
},
SERVICE_TABLE_ENTRYW {
lpServiceName: PWSTR::null(),
lpServiceProc: None,
},
]
.as_ptr();
unsafe { StartServiceCtrlDispatcherW(lpservicestarttable) }.unwrap();
}
service_main can use heventlog to record logs