1 /**
2  * Windows API header module
3  *
4  * Translated from MinGW Windows headers
5  *
6  * Authors: Stewart Gordon
7  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source: $(DRUNTIMESRC src/core/sys/windows/_winsvc.d)
9  */
10 module core.sys.windows.winsvc;
version(Windows)11 version (Windows):
12 @system:
13 
14 version (ANSI) {} else version = Unicode;
15 pragma(lib, "advapi32");
16 
17 import core.sys.windows.w32api, core.sys.windows.windef;
18 
19 // FIXME: check Windows version support
20 
21 const TCHAR[]
22     SERVICES_ACTIVE_DATABASE = "ServicesActive",
23     SERVICES_FAILED_DATABASE = "ServicesFailed";
24 
25 const TCHAR SC_GROUP_IDENTIFIER = '+';
26 
27 enum DWORD
28     SC_MANAGER_ALL_ACCESS         = 0xf003f,
29     SC_MANAGER_CONNECT            =  1,
30     SC_MANAGER_CREATE_SERVICE     =  2,
31     SC_MANAGER_ENUMERATE_SERVICE  =  4,
32     SC_MANAGER_LOCK               =  8,
33     SC_MANAGER_QUERY_LOCK_STATUS  = 16,
34     SC_MANAGER_MODIFY_BOOT_CONFIG = 32;
35 
36 enum DWORD SERVICE_NO_CHANGE = 0xffffffff;
37 
38 enum : DWORD {
39     SERVICE_STOPPED = 1,
40     SERVICE_START_PENDING,
41     SERVICE_STOP_PENDING,
42     SERVICE_RUNNING,
43     SERVICE_CONTINUE_PENDING,
44     SERVICE_PAUSE_PENDING,
45     SERVICE_PAUSED // = 7
46 }
47 
48 enum DWORD
49     SERVICE_ACCEPT_STOP                  =   1,
50     SERVICE_ACCEPT_PAUSE_CONTINUE        =   2,
51     SERVICE_ACCEPT_SHUTDOWN              =   4,
52     SERVICE_ACCEPT_PARAMCHANGE           =   8,
53     SERVICE_ACCEPT_NETBINDCHANGE         =  16,
54     SERVICE_ACCEPT_HARDWAREPROFILECHANGE =  32,
55     SERVICE_ACCEPT_POWEREVENT            =  64,
56     SERVICE_ACCEPT_SESSIONCHANGE         = 128;
57 
58 enum : DWORD {
59     SERVICE_CONTROL_STOP = 1,
60     SERVICE_CONTROL_PAUSE,
61     SERVICE_CONTROL_CONTINUE,
62     SERVICE_CONTROL_INTERROGATE,
63     SERVICE_CONTROL_SHUTDOWN,
64     SERVICE_CONTROL_PARAMCHANGE,
65     SERVICE_CONTROL_NETBINDADD,
66     SERVICE_CONTROL_NETBINDREMOVE,
67     SERVICE_CONTROL_NETBINDENABLE,
68     SERVICE_CONTROL_NETBINDDISABLE,
69     SERVICE_CONTROL_DEVICEEVENT,
70     SERVICE_CONTROL_HARDWAREPROFILECHANGE,
71     SERVICE_CONTROL_POWEREVENT,
72     SERVICE_CONTROL_SESSIONCHANGE, // = 14
73 }
74 
75 enum : DWORD {
76     SERVICE_ACTIVE = 1,
77     SERVICE_INACTIVE,
78     SERVICE_STATE_ALL
79 }
80 
81 enum DWORD
82     SERVICE_QUERY_CONFIG         = 0x0001,
83     SERVICE_CHANGE_CONFIG        = 0x0002,
84     SERVICE_QUERY_STATUS         = 0x0004,
85     SERVICE_ENUMERATE_DEPENDENTS = 0x0008,
86     SERVICE_START                = 0x0010,
87     SERVICE_STOP                 = 0x0020,
88     SERVICE_PAUSE_CONTINUE       = 0x0040,
89     SERVICE_INTERROGATE          = 0x0080,
90     SERVICE_USER_DEFINED_CONTROL = 0x0100,
91     SERVICE_ALL_ACCESS           = 0x01FF | STANDARD_RIGHTS_REQUIRED;
92 
93 // This is not documented on the MSDN site
94 enum SERVICE_RUNS_IN_SYSTEM_PROCESS = 1;
95 
96 enum : DWORD {
97     SERVICE_CONFIG_DESCRIPTION         = 1,
98     SERVICE_CONFIG_FAILURE_ACTIONS,
99     SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
100     SERVICE_CONFIG_FAILURE_ACTIONS_FLAG,
101     SERVICE_CONFIG_SERVICE_SID_INFO,
102     SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO,
103     SERVICE_CONFIG_PRESHUTDOWN_INFO // = 7
104 }
105 
106 struct SERVICE_STATUS {
107     DWORD dwServiceType;
108     DWORD dwCurrentState;
109     DWORD dwControlsAccepted;
110     DWORD dwWin32ExitCode;
111     DWORD dwServiceSpecificExitCode;
112     DWORD dwCheckPoint;
113     DWORD dwWaitHint;
114 }
115 alias SERVICE_STATUS* LPSERVICE_STATUS;
116 
117 struct ENUM_SERVICE_STATUSA {
118     LPSTR          lpServiceName;
119     LPSTR          lpDisplayName;
120     SERVICE_STATUS ServiceStatus;
121 }
122 alias ENUM_SERVICE_STATUSA* LPENUM_SERVICE_STATUSA;
123 
124 struct ENUM_SERVICE_STATUSW {
125     LPWSTR         lpServiceName;
126     LPWSTR         lpDisplayName;
127     SERVICE_STATUS ServiceStatus;
128 }
129 alias ENUM_SERVICE_STATUSW* LPENUM_SERVICE_STATUSW;
130 
131 struct QUERY_SERVICE_CONFIGA {
132     DWORD dwServiceType;
133     DWORD dwStartType;
134     DWORD dwErrorControl;
135     LPSTR lpBinaryPathName;
136     LPSTR lpLoadOrderGroup;
137     DWORD dwTagId;
138     LPSTR lpDependencies;
139     LPSTR lpServiceStartName;
140     LPSTR lpDisplayName;
141 }
142 alias QUERY_SERVICE_CONFIGA* LPQUERY_SERVICE_CONFIGA;
143 
144 struct QUERY_SERVICE_CONFIGW {
145     DWORD  dwServiceType;
146     DWORD  dwStartType;
147     DWORD  dwErrorControl;
148     LPWSTR lpBinaryPathName;
149     LPWSTR lpLoadOrderGroup;
150     DWORD  dwTagId;
151     LPWSTR lpDependencies;
152     LPWSTR lpServiceStartName;
153     LPWSTR lpDisplayName;
154 }
155 alias QUERY_SERVICE_CONFIGW* LPQUERY_SERVICE_CONFIGW;
156 
157 struct QUERY_SERVICE_LOCK_STATUSA {
158     DWORD fIsLocked;
159     LPSTR lpLockOwner;
160     DWORD dwLockDuration;
161 }
162 alias QUERY_SERVICE_LOCK_STATUSA* LPQUERY_SERVICE_LOCK_STATUSA;
163 
164 struct QUERY_SERVICE_LOCK_STATUSW {
165     DWORD  fIsLocked;
166     LPWSTR lpLockOwner;
167     DWORD  dwLockDuration;
168 }
169 alias QUERY_SERVICE_LOCK_STATUSW* LPQUERY_SERVICE_LOCK_STATUSW;
170 
171 extern (Windows) {
172     alias void function(DWORD, LPSTR*)  LPSERVICE_MAIN_FUNCTIONA;
173     alias void function(DWORD, LPWSTR*) LPSERVICE_MAIN_FUNCTIONW;
174 }
175 
176 struct SERVICE_TABLE_ENTRYA {
177     LPSTR                    lpServiceName;
178     LPSERVICE_MAIN_FUNCTIONA lpServiceProc;
179 }
180 alias SERVICE_TABLE_ENTRYA* LPSERVICE_TABLE_ENTRYA;
181 
182 struct SERVICE_TABLE_ENTRYW {
183     LPWSTR                   lpServiceName;
184     LPSERVICE_MAIN_FUNCTIONW lpServiceProc;
185 }
186 alias SERVICE_TABLE_ENTRYW* LPSERVICE_TABLE_ENTRYW;
187 
188 mixin DECLARE_HANDLE!("SC_HANDLE");
189 alias SC_HANDLE* LPSC_HANDLE;
190 alias void* SC_LOCK;
191 mixin DECLARE_HANDLE!("SERVICE_STATUS_HANDLE");
192 
193 extern (Windows) {
194     alias void function(DWORD) LPHANDLER_FUNCTION;
195     alias DWORD function(DWORD, DWORD, LPVOID, LPVOID) LPHANDLER_FUNCTION_EX;
196 }
197 
198 static if (_WIN32_WINNT >= 0x500) {
199     struct SERVICE_STATUS_PROCESS {
200         DWORD dwServiceType;
201         DWORD dwCurrentState;
202         DWORD dwControlsAccepted;
203         DWORD dwWin32ExitCode;
204         DWORD dwServiceSpecificExitCode;
205         DWORD dwCheckPoint;
206         DWORD dwWaitHint;
207         DWORD dwProcessId;
208         DWORD dwServiceFlags;
209     }
210     alias SERVICE_STATUS_PROCESS* LPSERVICE_STATUS_PROCESS;
211 
212     enum SC_STATUS_TYPE {
213         SC_STATUS_PROCESS_INFO = 0
214     }
215 
216     enum SC_ENUM_TYPE {
217         SC_ENUM_PROCESS_INFO = 0
218     }
219 
220     struct ENUM_SERVICE_STATUS_PROCESSA {
221         LPSTR                  lpServiceName;
222         LPSTR                  lpDisplayName;
223         SERVICE_STATUS_PROCESS ServiceStatusProcess;
224     }
225     alias ENUM_SERVICE_STATUS_PROCESSA* LPENUM_SERVICE_STATUS_PROCESSA;
226 
227     struct ENUM_SERVICE_STATUS_PROCESSW {
228         LPWSTR                 lpServiceName;
229         LPWSTR                 lpDisplayName;
230         SERVICE_STATUS_PROCESS ServiceStatusProcess;
231     }
232     alias ENUM_SERVICE_STATUS_PROCESSW* LPENUM_SERVICE_STATUS_PROCESSW;
233 
234     struct SERVICE_DESCRIPTIONA {
235         LPSTR lpDescription;
236     }
237     alias SERVICE_DESCRIPTIONA* LPSERVICE_DESCRIPTIONA;
238 
239     struct SERVICE_DESCRIPTIONW {
240         LPWSTR lpDescription;
241     }
242     alias SERVICE_DESCRIPTIONW* LPSERVICE_DESCRIPTIONW;
243 
244     enum SC_ACTION_TYPE {
245         SC_ACTION_NONE,
246         SC_ACTION_RESTART,
247         SC_ACTION_REBOOT,
248         SC_ACTION_RUN_COMMAND
249     }
250 
251     struct SC_ACTION {
252         SC_ACTION_TYPE Type;
253         DWORD          Delay;
254     }
255     alias SC_ACTION* LPSC_ACTION;
256 
257     struct SERVICE_FAILURE_ACTIONSA {
258         DWORD      dwResetPeriod;
259         LPSTR      lpRebootMsg;
260         LPSTR      lpCommand;
261         DWORD      cActions;
262         SC_ACTION* lpsaActions;
263     }
264     alias SERVICE_FAILURE_ACTIONSA* LPSERVICE_FAILURE_ACTIONSA;
265 
266     struct SERVICE_FAILURE_ACTIONSW {
267         DWORD      dwResetPeriod;
268         LPWSTR     lpRebootMsg;
269         LPWSTR     lpCommand;
270         DWORD      cActions;
271         SC_ACTION* lpsaActions;
272     }
273     alias SERVICE_FAILURE_ACTIONSW* LPSERVICE_FAILURE_ACTIONSW;
274 }
275 
276 extern (Windows) {
277     BOOL ChangeServiceConfigA(SC_HANDLE, DWORD, DWORD, DWORD, LPCSTR,
278       LPCSTR, LPDWORD, LPCSTR, LPCSTR, LPCSTR, LPCSTR);
279     BOOL ChangeServiceConfigW(SC_HANDLE, DWORD, DWORD, DWORD, LPCWSTR,
280       LPCWSTR, LPDWORD, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);
281     BOOL CloseServiceHandle(SC_HANDLE);
282     BOOL ControlService(SC_HANDLE, DWORD, LPSERVICE_STATUS);
283     SC_HANDLE CreateServiceA(SC_HANDLE, LPCSTR, LPCSTR, DWORD, DWORD,
284       DWORD, DWORD, LPCSTR, LPCSTR, PDWORD, LPCSTR, LPCSTR, LPCSTR);
285     SC_HANDLE CreateServiceW(SC_HANDLE, LPCWSTR, LPCWSTR, DWORD, DWORD,
286       DWORD, DWORD, LPCWSTR, LPCWSTR, PDWORD, LPCWSTR, LPCWSTR, LPCWSTR);
287     BOOL DeleteService(SC_HANDLE);
288     BOOL EnumDependentServicesA(SC_HANDLE, DWORD, LPENUM_SERVICE_STATUSA,
289       DWORD, PDWORD, PDWORD);
290     BOOL EnumDependentServicesW(SC_HANDLE, DWORD, LPENUM_SERVICE_STATUSW,
291       DWORD, PDWORD, PDWORD);
292     BOOL EnumServicesStatusA(SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSA,
293       DWORD, PDWORD, PDWORD, PDWORD);
294     BOOL EnumServicesStatusW(SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSW,
295       DWORD, PDWORD, PDWORD, PDWORD);
296     BOOL GetServiceDisplayNameA(SC_HANDLE, LPCSTR, LPSTR, PDWORD);
297     BOOL GetServiceDisplayNameW(SC_HANDLE, LPCWSTR, LPWSTR, PDWORD);
298     BOOL GetServiceKeyNameA(SC_HANDLE, LPCSTR, LPSTR, PDWORD);
299     BOOL GetServiceKeyNameW(SC_HANDLE, LPCWSTR, LPWSTR, PDWORD);
300     SC_LOCK LockServiceDatabase(SC_HANDLE);
301     BOOL NotifyBootConfigStatus(BOOL);
302     SC_HANDLE OpenSCManagerA(LPCSTR, LPCSTR, DWORD);
303     SC_HANDLE OpenSCManagerW(LPCWSTR, LPCWSTR, DWORD);
304     SC_HANDLE OpenServiceA(SC_HANDLE, LPCSTR, DWORD);
305     SC_HANDLE OpenServiceW(SC_HANDLE, LPCWSTR, DWORD);
306     BOOL QueryServiceConfigA(SC_HANDLE, LPQUERY_SERVICE_CONFIGA, DWORD,
307       PDWORD);
308     BOOL QueryServiceConfigW(SC_HANDLE, LPQUERY_SERVICE_CONFIGW, DWORD,
309       PDWORD);
310     BOOL QueryServiceLockStatusA(SC_HANDLE, LPQUERY_SERVICE_LOCK_STATUSA,
311       DWORD, PDWORD);
312     BOOL QueryServiceLockStatusW(SC_HANDLE, LPQUERY_SERVICE_LOCK_STATUSW,
313       DWORD, PDWORD);
314     BOOL QueryServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION,
315       PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
316     BOOL QueryServiceStatus(SC_HANDLE, LPSERVICE_STATUS);
317     SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerA(LPCSTR,
318       LPHANDLER_FUNCTION);
319     SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerW(LPCWSTR,
320       LPHANDLER_FUNCTION);
321     BOOL SetServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION,
322       PSECURITY_DESCRIPTOR);
323     BOOL SetServiceStatus(SERVICE_STATUS_HANDLE, LPSERVICE_STATUS);
324     BOOL StartServiceA(SC_HANDLE, DWORD, LPCSTR*);
325     BOOL StartServiceW(SC_HANDLE, DWORD, LPCWSTR*);
326     BOOL StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA);
327     BOOL StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW);
328     BOOL UnlockServiceDatabase(SC_LOCK);
329 
330     static if (_WIN32_WINNT >= 0x500) {
331         BOOL EnumServicesStatusExA(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE,
332           DWORD, LPDWORD, LPDWORD, LPDWORD, LPCSTR);
333         BOOL EnumServicesStatusExW(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE,
334           DWORD, LPDWORD, LPDWORD, LPDWORD, LPCWSTR);
335         BOOL QueryServiceConfig2A(SC_HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
336         BOOL QueryServiceConfig2W(SC_HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
337         BOOL QueryServiceStatusEx(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD,
338           LPDWORD);
339         SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerExA(LPCSTR,
340           LPHANDLER_FUNCTION_EX, LPVOID);
341         SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerExW(LPCWSTR,
342           LPHANDLER_FUNCTION_EX, LPVOID);
343     }
344 
345     static if (_WIN32_WINNT >= 0x501) {
346         BOOL ChangeServiceConfig2A(SC_HANDLE, DWORD, LPVOID);
347         BOOL ChangeServiceConfig2W(SC_HANDLE, DWORD, LPVOID);
348     }
349 }
350 
version(Unicode)351 version (Unicode) {
352     alias ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUS;
353     alias QUERY_SERVICE_CONFIGW QUERY_SERVICE_CONFIG;
354     alias QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUS;
355     alias LPSERVICE_MAIN_FUNCTIONW LPSERVICE_MAIN_FUNCTION;
356     alias SERVICE_TABLE_ENTRYW SERVICE_TABLE_ENTRY;
357     alias ChangeServiceConfigW ChangeServiceConfig;
358     alias CreateServiceW CreateService;
359     alias EnumDependentServicesW EnumDependentServices;
360     alias EnumServicesStatusW EnumServicesStatus;
361     alias GetServiceDisplayNameW GetServiceDisplayName;
362     alias GetServiceKeyNameW GetServiceKeyName;
363     alias OpenSCManagerW OpenSCManager;
364     alias OpenServiceW OpenService;
365     alias QueryServiceConfigW QueryServiceConfig;
366     alias QueryServiceLockStatusW QueryServiceLockStatus;
367     alias RegisterServiceCtrlHandlerW RegisterServiceCtrlHandler;
368     alias StartServiceW StartService;
369     alias StartServiceCtrlDispatcherW StartServiceCtrlDispatcher;
370 
371     static if (_WIN32_WINNT >= 0x500) {
372         alias ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESS;
373         alias SERVICE_DESCRIPTIONW SERVICE_DESCRIPTION;
374         alias SERVICE_FAILURE_ACTIONSW SERVICE_FAILURE_ACTIONS;
375         alias EnumServicesStatusExW EnumServicesStatusEx;
376         alias QueryServiceConfig2W QueryServiceConfig2;
377         alias RegisterServiceCtrlHandlerExW RegisterServiceCtrlHandlerEx;
378     }
379 
380     static if (_WIN32_WINNT >= 0x501) {
381         alias ChangeServiceConfig2W ChangeServiceConfig2;
382     }
383 
384 } else {
385     alias ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUS;
386     alias QUERY_SERVICE_CONFIGA QUERY_SERVICE_CONFIG;
387     alias QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUS;
388     alias LPSERVICE_MAIN_FUNCTIONA LPSERVICE_MAIN_FUNCTION;
389     alias SERVICE_TABLE_ENTRYA SERVICE_TABLE_ENTRY;
390     alias ChangeServiceConfigA ChangeServiceConfig;
391     alias CreateServiceA CreateService;
392     alias EnumDependentServicesA EnumDependentServices;
393     alias EnumServicesStatusA EnumServicesStatus;
394     alias GetServiceDisplayNameA GetServiceDisplayName;
395     alias GetServiceKeyNameA GetServiceKeyName;
396     alias OpenSCManagerA OpenSCManager;
397     alias OpenServiceA OpenService;
398     alias QueryServiceConfigA QueryServiceConfig;
399     alias QueryServiceLockStatusA QueryServiceLockStatus;
400     alias RegisterServiceCtrlHandlerA RegisterServiceCtrlHandler;
401     alias StartServiceA StartService;
402     alias StartServiceCtrlDispatcherA StartServiceCtrlDispatcher;
403 
404     static if (_WIN32_WINNT >= 0x500) {
405         alias ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESS;
406         alias SERVICE_DESCRIPTIONA SERVICE_DESCRIPTION;
407         alias SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONS;
408         alias EnumServicesStatusExA EnumServicesStatusEx;
409         alias QueryServiceConfig2A QueryServiceConfig2;
410         alias RegisterServiceCtrlHandlerExA RegisterServiceCtrlHandlerEx;
411     }
412 
413     static if (_WIN32_WINNT >= 0x501) {
414         alias ChangeServiceConfig2A ChangeServiceConfig2;
415     }
416 
417 }
418 
419 alias ENUM_SERVICE_STATUS* LPENUM_SERVICE_STATUS;
420 alias QUERY_SERVICE_CONFIG* LPQUERY_SERVICE_CONFIG;
421 alias QUERY_SERVICE_LOCK_STATUS* LPQUERY_SERVICE_LOCK_STATUS;
422 alias SERVICE_TABLE_ENTRY* LPSERVICE_TABLE_ENTRY;
423 
424 static if (_WIN32_WINNT >= 0x500) {
425     alias ENUM_SERVICE_STATUS_PROCESS* LPENUM_SERVICE_STATUS_PROCESS;
426     alias SERVICE_DESCRIPTION* LPSERVICE_DESCRIPTION;
427     alias SERVICE_FAILURE_ACTIONS* LPSERVICE_FAILURE_ACTIONS;
428 }
429