windows_erg/service/
status.rs1use windows::Win32::System::Services::{ENUM_SERVICE_STATUS_PROCESSW, SERVICE_STATUS_PROCESS};
2
3use super::types::ServiceState;
4
5#[derive(Debug, Clone)]
7pub struct ServiceStatus {
8 pub name: String,
10 pub display_name: Option<String>,
12 pub state: ServiceState,
14 pub process_id: u32,
16 pub service_type: u32,
18 pub controls_accepted: u32,
20 pub exit_code: u32,
22 pub service_specific_exit_code: u32,
24 pub checkpoint: u32,
26 pub wait_hint_ms: u32,
28 pub service_flags: u32,
30}
31
32impl ServiceStatus {
33 pub(crate) fn from_status_process(
34 name: String,
35 display_name: Option<String>,
36 status: &SERVICE_STATUS_PROCESS,
37 ) -> Self {
38 ServiceStatus {
39 name,
40 display_name,
41 state: ServiceState::from_windows(status.dwCurrentState),
42 process_id: status.dwProcessId,
43 service_type: status.dwServiceType.0,
44 controls_accepted: status.dwControlsAccepted,
45 exit_code: status.dwWin32ExitCode,
46 service_specific_exit_code: status.dwServiceSpecificExitCode,
47 checkpoint: status.dwCheckPoint,
48 wait_hint_ms: status.dwWaitHint,
49 service_flags: status.dwServiceFlags.0,
50 }
51 }
52
53 pub(crate) fn from_enum_status(raw: &ENUM_SERVICE_STATUS_PROCESSW) -> Self {
54 ServiceStatus {
55 name: unsafe { read_pwstr(raw.lpServiceName.0) },
56 display_name: Some(unsafe { read_pwstr(raw.lpDisplayName.0) }),
57 state: ServiceState::from_windows(raw.ServiceStatusProcess.dwCurrentState),
58 process_id: raw.ServiceStatusProcess.dwProcessId,
59 service_type: raw.ServiceStatusProcess.dwServiceType.0,
60 controls_accepted: raw.ServiceStatusProcess.dwControlsAccepted,
61 exit_code: raw.ServiceStatusProcess.dwWin32ExitCode,
62 service_specific_exit_code: raw.ServiceStatusProcess.dwServiceSpecificExitCode,
63 checkpoint: raw.ServiceStatusProcess.dwCheckPoint,
64 wait_hint_ms: raw.ServiceStatusProcess.dwWaitHint,
65 service_flags: raw.ServiceStatusProcess.dwServiceFlags.0,
66 }
67 }
68}
69
70unsafe fn read_pwstr(ptr: *const u16) -> String {
71 if ptr.is_null() {
72 return String::new();
73 }
74
75 let mut len = 0usize;
76 while unsafe { *ptr.add(len) } != 0 {
77 len += 1;
78 }
79
80 let slice = unsafe { std::slice::from_raw_parts(ptr, len) };
81 String::from_utf16_lossy(slice)
82}