Skip to main content

windows_erg/service/
types.rs

1use windows::Win32::System::Services::{
2    SC_MANAGER_ALL_ACCESS, SC_MANAGER_CONNECT, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_ALL_ACCESS,
3    SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_INTERROGATE, SERVICE_CONTROL_PAUSE,
4    SERVICE_CONTROL_STOP, SERVICE_PAUSE_CONTINUE, SERVICE_PAUSED, SERVICE_QUERY_STATUS,
5    SERVICE_RUNNING, SERVICE_START, SERVICE_START_PENDING, SERVICE_STATUS_CURRENT_STATE,
6    SERVICE_STOP, SERVICE_STOP_PENDING, SERVICE_STOPPED,
7};
8
9/// Service state as reported by the Windows Service Control Manager.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ServiceState {
12    /// Service is stopped.
13    Stopped,
14    /// Service is starting.
15    StartPending,
16    /// Service is stopping.
17    StopPending,
18    /// Service is running.
19    Running,
20    /// Service is paused.
21    Paused,
22    /// Unknown/unsupported state value.
23    Unknown(u32),
24}
25
26impl ServiceState {
27    pub(crate) fn from_windows(state: SERVICE_STATUS_CURRENT_STATE) -> Self {
28        match state.0 {
29            x if x == SERVICE_STOPPED.0 => ServiceState::Stopped,
30            x if x == SERVICE_START_PENDING.0 => ServiceState::StartPending,
31            x if x == SERVICE_STOP_PENDING.0 => ServiceState::StopPending,
32            x if x == SERVICE_RUNNING.0 => ServiceState::Running,
33            x if x == SERVICE_PAUSED.0 => ServiceState::Paused,
34            other => ServiceState::Unknown(other),
35        }
36    }
37
38    pub(crate) fn as_str(self) -> &'static str {
39        match self {
40            ServiceState::Stopped => "stopped",
41            ServiceState::StartPending => "start_pending",
42            ServiceState::StopPending => "stop_pending",
43            ServiceState::Running => "running",
44            ServiceState::Paused => "paused",
45            ServiceState::Unknown(_) => "unknown",
46        }
47    }
48}
49
50/// Access rights for opening a Service Control Manager handle.
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum ServiceManagerAccess {
53    /// Connect to the SCM database.
54    Connect,
55    /// Enumerate installed services.
56    EnumerateService,
57    /// Full manager access rights.
58    AllAccess,
59    /// Custom SCM rights.
60    Custom(u32),
61}
62
63impl ServiceManagerAccess {
64    pub(crate) fn to_windows(self) -> u32 {
65        match self {
66            ServiceManagerAccess::Connect => SC_MANAGER_CONNECT,
67            ServiceManagerAccess::EnumerateService => SC_MANAGER_ENUMERATE_SERVICE,
68            ServiceManagerAccess::AllAccess => SC_MANAGER_ALL_ACCESS,
69            ServiceManagerAccess::Custom(rights) => rights,
70        }
71    }
72}
73
74/// Access rights for opening an individual Windows service.
75#[derive(Debug, Clone, Copy, PartialEq, Eq)]
76pub enum ServiceAccess {
77    /// Query runtime status.
78    QueryStatus,
79    /// Start the service.
80    Start,
81    /// Stop the service.
82    Stop,
83    /// Pause/continue the service.
84    PauseContinue,
85    /// Full service access rights.
86    AllAccess,
87    /// Custom service access rights.
88    Custom(u32),
89}
90
91impl ServiceAccess {
92    pub(crate) fn to_windows(self) -> u32 {
93        match self {
94            ServiceAccess::QueryStatus => SERVICE_QUERY_STATUS,
95            ServiceAccess::Start => SERVICE_START,
96            ServiceAccess::Stop => SERVICE_STOP,
97            ServiceAccess::PauseContinue => SERVICE_PAUSE_CONTINUE,
98            ServiceAccess::AllAccess => SERVICE_ALL_ACCESS,
99            ServiceAccess::Custom(rights) => rights,
100        }
101    }
102}
103
104/// Service control codes that can be sent to a service.
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
106pub enum ServiceControl {
107    /// Request service stop.
108    Stop,
109    /// Request service pause.
110    Pause,
111    /// Request service continue.
112    Continue,
113    /// Request service status refresh.
114    Interrogate,
115}
116
117impl ServiceControl {
118    pub(crate) fn to_windows(self) -> u32 {
119        match self {
120            ServiceControl::Stop => SERVICE_CONTROL_STOP,
121            ServiceControl::Pause => SERVICE_CONTROL_PAUSE,
122            ServiceControl::Continue => SERVICE_CONTROL_CONTINUE,
123            ServiceControl::Interrogate => SERVICE_CONTROL_INTERROGATE,
124        }
125    }
126
127    pub(crate) fn operation_name(self) -> &'static str {
128        match self {
129            ServiceControl::Stop => "stop",
130            ServiceControl::Pause => "pause",
131            ServiceControl::Continue => "continue",
132            ServiceControl::Interrogate => "interrogate",
133        }
134    }
135}