diff --git a/Cargo.toml b/Cargo.toml index d969520..a2cbcab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,9 @@ ctrlc = { version = "3.1", features = ["termination"] } log = "0.4" [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["winbase", "winerror", "winuser", "winsvc", "libloaderapi", "errhandlingapi"] } widestring = "0.4.3" +windows-sys = { version = "0.52", features = ["Win32_Foundation", "Win32_System_RemoteDesktop", "Win32_System_LibraryLoader", "Win32_UI_WindowsAndMessaging", + "Win32_Security", "Win32_System_Services", "Win32_System_Diagnostics_Debug"]} [target.'cfg(target_os = "linux")'.dependencies] systemd-rs = { version="^0.1.2", optional = true } diff --git a/cmdlet/Cargo.toml b/cmdlet/Cargo.toml index 3fd9d53..ba0c2d1 100644 --- a/cmdlet/Cargo.toml +++ b/cmdlet/Cargo.toml @@ -11,7 +11,7 @@ build = "build.rs" [dependencies] libc = "0" log = "0.4" -log4rs = "0.8" +log4rs = "1.3" ctrlc = "3.1" cfg-if = "0.1" base64 = "0.12" @@ -20,9 +20,6 @@ serde_json = "1.0" which = { version = "3.0", default-features = false, features = [] } expand_str = "0.1" -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["winbase", "winuser", "winsvc", "libloaderapi", "errhandlingapi", "winerror"] } - [target.'cfg(windows)'.build-dependencies] embed-resource = "1.3" diff --git a/examples/foobar/Cargo.toml b/examples/foobar/Cargo.toml index e9114d5..d531132 100644 --- a/examples/foobar/Cargo.toml +++ b/examples/foobar/Cargo.toml @@ -16,12 +16,9 @@ path = "src/main.rs" [dependencies] libc = "0" log = "0.4" -log4rs = "0.8" +log4rs = "1.3" clap = { version = "2.31", features = ["yaml"] } ctrlc = "3.1" -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["winbase", "winuser", "winsvc", "libloaderapi", "errhandlingapi", "winerror"] } - [dependencies.ceviche] path = "../.." diff --git a/src/controller/windows.rs b/src/controller/windows.rs index 814f311..b591ab1 100644 --- a/src/controller/windows.rs +++ b/src/controller/windows.rs @@ -1,4 +1,4 @@ -use std::ffi::OsStr; +use std::ffi::{c_void, OsStr}; use std::iter::once; use std::os::windows::ffi::OsStrExt; use std::ptr; @@ -6,29 +6,33 @@ use std::sync::mpsc; use std::{thread, time}; use widestring::WideCString; -use winapi::shared::minwindef::*; -use winapi::shared::winerror::*; -use winapi::um::errhandlingapi::*; -use winapi::um::libloaderapi::*; -use winapi::um::winbase::*; -use winapi::um::winnt::*; -use winapi::um::winsvc::*; -use winapi::um::winuser::*; -use winapi::{self, STRUCT}; +use windows_sys::core::PWSTR; +use windows_sys::Win32::{ + Foundation::{MAX_PATH, ERROR_CALL_NOT_IMPLEMENTED, GetLastError}, + Security::SC_HANDLE, + System::{ + Diagnostics::Debug::{FormatMessageW, FORMAT_MESSAGE_FROM_SYSTEM}, + LibraryLoader::GetModuleFileNameW, + RemoteDesktop::WTSSESSION_NOTIFICATION, + Services::*, + }, + UI::WindowsAndMessaging::{ + WTS_CONSOLE_CONNECT, WTS_CONSOLE_DISCONNECT, WTS_REMOTE_CONNECT, WTS_REMOTE_DISCONNECT, + WTS_SESSION_LOGON, WTS_SESSION_LOGOFF, WTS_SESSION_LOCK, WTS_SESSION_UNLOCK + } +}; use crate::controller::{ControllerInterface, ServiceMainFn}; use crate::session; use crate::Error; use crate::ServiceEvent; -static mut SERVICE_CONTROL_HANDLE: SERVICE_STATUS_HANDLE = ptr::null_mut(); +type DWORD = u32; +type LPVOID = *mut c_void; -STRUCT! {#[allow(non_snake_case)] - struct SERVICE_DESCRIPTION_W { - lpDescription: LPWSTR, -}} +static mut SERVICE_CONTROL_HANDLE: SERVICE_STATUS_HANDLE = 0; -type WindowsServiceMainWrapperFn = extern "system" fn(argc: DWORD, argv: *mut LPWSTR); +type WindowsServiceMainWrapperFn = extern "system" fn(argc: DWORD, argv: *mut PWSTR); pub type Session = session::Session_; struct Service { @@ -37,7 +41,7 @@ struct Service { impl Drop for Service { fn drop(&mut self) { - if !self.handle.is_null() { + if !(self.handle == 0) { unsafe { CloseServiceHandle(self.handle) }; } } @@ -51,7 +55,7 @@ impl ServiceControlManager { fn open(desired_access: DWORD) -> Result { let handle = unsafe { OpenSCManagerW(ptr::null_mut(), ptr::null_mut(), desired_access) }; - if handle.is_null() { + if handle == 0 { Err(Error::new(&format!( "OpenSCManager: {}", get_last_error_text() @@ -70,7 +74,7 @@ impl ServiceControlManager { ) }; - if handle.is_null() { + if handle == 0 { Err(Error::new(&format!( "OpenServiceW: {}", get_last_error_text() @@ -83,7 +87,7 @@ impl ServiceControlManager { impl Drop for ServiceControlManager { fn drop(&mut self) { - if !self.handle.is_null() { + if !(self.handle == 0) { unsafe { CloseServiceHandle(self.handle) }; } } @@ -132,7 +136,7 @@ impl ControllerInterface for WindowsController { ptr::null_mut(), ); - if service.is_null() { + if service == 0 { return Err(Error::new(&format!( "CreateService: {}", get_last_error_text() @@ -143,11 +147,11 @@ impl ControllerInterface for WindowsController { let mut description = get_utf16(self.description.as_str()); - let mut sd = SERVICE_DESCRIPTION_W { + let mut sd = SERVICE_DESCRIPTIONW { lpDescription: description.as_mut_ptr(), }; - let p_sd = &mut sd as *mut _ as *mut winapi::ctypes::c_void; + let p_sd = &mut sd as *mut _ as *mut c_void; ChangeServiceConfig2W(service, SERVICE_CONFIG_DESCRIPTION, p_sd); CloseServiceHandle(service); @@ -261,7 +265,7 @@ impl WindowsController { dwCheckPoint: 0, dwWaitHint: 0, }, - status_handle: ptr::null_mut(), + status_handle: 0, controls_accepted: SERVICE_ACCEPT_STOP, } } @@ -272,11 +276,11 @@ impl WindowsController { service_main_wrapper: WindowsServiceMainWrapperFn, ) -> Result<(), Error> { unsafe { - let service_name = get_utf16(self.service_name.as_str()); + let mut service_name = get_utf16(self.service_name.as_str()); let service_table: &[*const SERVICE_TABLE_ENTRYW] = &[ &SERVICE_TABLE_ENTRYW { - lpServiceName: service_name.as_ptr(), + lpServiceName: service_name.as_mut_ptr(), lpServiceProc: Some(service_main_wrapper), }, ptr::null(), @@ -335,8 +339,8 @@ unsafe extern "system" fn service_handler( 0 } SERVICE_CONTROL_SESSIONCHANGE => { - let event = event_type as usize; - let session_notification = event_data as PWTSSESSION_NOTIFICATION; + let event = event_type; + let session_notification = event_data as *const WTSSESSION_NOTIFICATION; let session_id = (*session_notification).dwSessionId; let session = Session::new(session_id); @@ -372,7 +376,7 @@ unsafe extern "system" fn service_handler( } } -fn get_args(argc: DWORD, argv: *mut LPWSTR) -> Vec { +fn get_args(argc: DWORD, argv: *mut PWSTR) -> Vec { let mut args = Vec::new(); for i in 0..argc { unsafe { @@ -390,9 +394,9 @@ pub fn get_utf16(value: &str) -> Vec { pub fn get_filename() -> String { unsafe { - let mut filename = [0u16; MAX_PATH]; + let mut filename = [0u16; MAX_PATH as usize]; let _size = GetModuleFileNameW( - ptr::null_mut(), + 0, filename.as_mut_ptr(), filename.len() as DWORD, ); @@ -420,17 +424,18 @@ pub fn get_last_error_text() -> String { #[macro_export] macro_rules! Service { ($name:expr, $function:ident) => { - use $crate::winapi::shared::minwindef::DWORD; - use $crate::winapi::um::winnt::LPWSTR; + use std::ffi::c_void; + type DWORD = u32; + type PWSTR = *mut u16; - extern "system" fn service_main_wrapper(argc: DWORD, argv: *mut LPWSTR) { + extern "system" fn service_main_wrapper(argc: DWORD, argv: *mut PWSTR) { dispatch($function, $name, argc, argv); } }; } #[doc(hidden)] -pub fn dispatch(service_main: ServiceMainFn, name: &str, argc: DWORD, argv: *mut LPWSTR) { +pub fn dispatch(service_main: ServiceMainFn, name: &str, argc: DWORD, argv: *mut PWSTR) { let args = get_args(argc, argv); let service_name = get_utf16(name); let (mut tx, rx) = mpsc::channel(); diff --git a/src/lib.rs b/src/lib.rs index bf09f90..a871566 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,7 +76,7 @@ pub mod controller; pub mod session; #[cfg(windows)] -pub use winapi; +pub use windows_sys; use self::controller::Session; use std::fmt;