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