source: trunk/src/advapi32/service.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 66.1 KB
Line 
1/* $Id: service.cpp,v 1.7 2001-06-12 18:24:10 sandervl Exp $ */
2
3/*
4 * Win32 advanced API functions for OS/2
5 *
6 * 1998/06/12
7 *
8 * Copyright 1998 Sander van Leeuwen
9 * Copyright 1998 Patrick Haller
10 *
11 *
12 * TODO: Not done; starting services; control handlers and many other things
13 * TODO: Service status handles are the same as service handles
14 *
15 * NOTE: Uses registry key for service as handle
16 *
17 * Project Odin Software License can be found in LICENSE.TXT
18 *
19 */
20
21#include <os2win.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <odinwrap.h>
26#include <misc.h>
27#include <unicode.h>
28#include <win/winreg.h>
29#include <win/winsvc.h>
30#include <heapstring.h>
31#define USE_ODIN_REGISTRY_APIS
32#include "advapi32.h"
33
34ODINDEBUGCHANNEL(ADVAPI32-SERVICE)
35
36#define REG_SERVICE_TYPE "Start"
37#define REG_SERVICE_TYPE_W (LPWSTR)L"Start"
38#define REG_SERVICE_STARTTYPE "Type"
39#define REG_SERVICE_STARTTYPE_W (LPWSTR)L"Type"
40#define REG_SERVICE_ERRORCONTROL "ErrorControl"
41#define REG_SERVICE_ERRORCONTROL_W (LPWSTR)L"ErrorControl"
42#define REG_SERVICE_DISPLAYNAME "DisplayName"
43#define REG_SERVICE_DISPLAYNAME_W (LPWSTR)L"DisplayName"
44#define REG_SERVICE_LOADORDERGROUP "Group" //???
45#define REG_SERVICE_LOADORDERGROUP_W (LPWSTR)L"Group" //???
46#define REG_SERVICE_DEPENDENCIES "DependOnGroup"
47#define REG_SERVICE_DEPENDENCIES_W (LPWSTR)L"DependOnGroup"
48#define REG_SERVICE_IMAGEPATH "ImagePath"
49#define REG_SERVICE_IMAGEPATH_W (LPWSTR)L"ImagePath"
50#define REG_SERVICE_TAG "Tag"
51#define REG_SERVICE_TAG_W (LPWSTR)L"Tag"
52
53//Odin key
54#define REG_SERVICE_BITS "ServiceBits"
55#define REG_SERVICE_CONTROLS_ACCEPTED "ServiceControlsAccepted"
56#define REG_SERVICE_CHECKPOINT "dwCheckPoint"
57#define REG_SERVICE_WAITHINT "dwWaitHint"
58#define REG_SERVICE_EXITCODE "dwWin32ExitCode"
59#define REG_SERVICE_SPECIFIC_EXITCODE "dwServiceSpecificExitCode"
60#define REG_SERVICE_STATUS "ServiceStatus"
61#define REG_SERVICE_STATUS_W (LPWSTR)L"ServiceStatus"
62//This key exists if DeleteService has been called for a specific service
63#define REG_SERVICE_DELETEPENDING "DeletePending"
64//TODO: How can you query the name of a key from the key handle????
65#define REG_SERVICE_NAME "ServiceName"
66
67//Win32 service can call StartServiceCtrlDispatcherA/W only once
68static BOOL fServiceCtrlDispatcherStarted = FALSE;
69
70//*****************************************************************************
71//TODO: Faster way to checking this
72//*****************************************************************************
73BOOL CheckServiceHandle(SC_HANDLE hService)
74{
75 HKEY keyThisService;
76
77 if(RegOpenKeyA((HKEY)hService, NULL, &keyThisService) != 0) {
78 return FALSE;
79 }
80 RegCloseKey(keyThisService);
81 return TRUE;
82}
83/*****************************************************************************
84 * Name : OpenSCManagerA
85 * Purpose : The OpenSCManager function establishes a connection to the
86 * service control manager on the specified computer and opens the
87 * specified database.
88 * Parameters: LPCSTR lpszMachineName address of machine name string
89 * LPCSTR lpszDatabaseName address of database name string
90 * DWORD fdwDesiredAccess type of access
91 * Variables :
92 * Result :
93 * Remark :
94 * Status : UNTESTED STUB
95 *
96 * Author : SvL
97 *****************************************************************************/
98
99SC_HANDLE WIN32API OpenSCManagerA(LPCSTR lpszMachineName,
100 LPCSTR lpszDatabaseName,
101 DWORD fdwDesiredAccess)
102{
103 dprintf(("ADVAPI32: OpenSCManagerA(%s,%s,%x) not correctly implemented.\n",
104 lpszMachineName,
105 lpszDatabaseName,
106 fdwDesiredAccess));
107
108 if(!lpszMachineName && !lpszDatabaseName) {
109 HKEY keyServices;
110 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services", &keyServices) != 0) {
111 SetLastError(ERROR_INTERNAL_ERROR);
112 return 0;
113 }
114 SetLastError(0);
115 return keyServices;
116 }
117 return 0;
118}
119
120
121/*****************************************************************************
122 * Name : OpenSCManagerW
123 * Purpose : The OpenSCManager function establishes a connection to the
124 * service control manager on the specified computer and opens the
125 * specified database.
126 * Parameters: LPCWSTR lpszMachineName address of machine name string
127 * LPCWSTR lpszDatabaseName address of database name string
128 * DWORD fdwDesiredAccess type of access
129 * Variables :
130 * Result :
131 * Remark :
132 * Status : UNTESTED STUB
133 *
134 * Author : SvL
135 *****************************************************************************/
136
137SC_HANDLE WIN32API OpenSCManagerW(LPCWSTR lpszMachineName,
138 LPCWSTR lpszDatabaseName,
139 DWORD fdwDesiredAccess)
140{
141 LPSTR lpszDataBaseNameA = NULL, lpszMachineNameA = NULL;
142 SC_HANDLE hService;
143
144 dprintf(("ADVAPI32: OpenSCManagerW(%x,%x,%x) not correctly implemented.\n",
145 lpszMachineName,
146 lpszDatabaseName,
147 fdwDesiredAccess));
148
149 if(lpszMachineName)
150 lpszMachineNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpszMachineName);
151 if(lpszDatabaseName)
152 lpszDataBaseNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpszDatabaseName);
153
154 hService = OpenSCManagerA(lpszMachineNameA, lpszDataBaseNameA, fdwDesiredAccess);
155
156 if(lpszMachineNameA)
157 HeapFree(GetProcessHeap(), 0, lpszMachineNameA);
158 if(lpszDataBaseNameA)
159 HeapFree(GetProcessHeap(), 0, lpszDataBaseNameA);
160
161 return hService;
162}
163
164
165/*****************************************************************************
166 * Name : OpenServiceA
167 * Purpose : The OpenService function opens a handle to an existing service.
168 * Parameters: SC_HANDLE schSCManager handle of service control manager database
169 * LPCSTR lpszServiceName address of name of service to start
170 * DWORD fdwDesiredAccess type of access to service
171 * Variables :
172 * Result :
173 * Remark :
174 * Status : UNTESTED STUB
175 *
176 * Author : SvL
177 *****************************************************************************/
178
179SC_HANDLE WIN32API OpenServiceA(SC_HANDLE schSCManager,
180 LPCSTR lpszServiceName,
181 DWORD fdwDesiredAccess)
182{
183 dprintf(("ADVAPI32: OpenServiceA(%08xh,%s,%08xh) not correctly implemented.\n",
184 schSCManager,
185 lpszServiceName,
186 fdwDesiredAccess));
187
188 if(CheckServiceHandle(schSCManager) == FALSE) {
189 SetLastError(ERROR_INVALID_PARAMETER);
190 return FALSE;
191 }
192
193 if(lpszServiceName == NULL) {
194 SetLastError(ERROR_INVALID_PARAMETER);
195 return 0;
196 }
197 HKEY keyThisService;
198 if(RegOpenKeyA((HKEY)schSCManager, lpszServiceName, &keyThisService) != 0) {
199 SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
200 return 0;
201 }
202 SetLastError(0);
203 return keyThisService;
204}
205
206
207/*****************************************************************************
208 * Name : OpenServiceW
209 * Purpose : The OpenService function opens a handle to an existing service.
210 * Parameters: SC_HANDLE schSCManager handle of service control manager database
211 * LPCWSTR lpszServiceName address of name of service to start
212 * DWORD fdwDesiredAccess type of access to service
213 * Variables :
214 * Result :
215 * Remark :
216 * Status : UNTESTED STUB
217 *
218 * Author : SvL
219 *****************************************************************************/
220
221SC_HANDLE WIN32API OpenServiceW(SC_HANDLE schSCManager,
222 LPCWSTR lpszServiceName,
223 DWORD fdwDesiredAccess)
224{
225 LPSTR lpszServiceNameA = NULL;
226 SC_HANDLE hService;
227
228 dprintf(("ADVAPI32: OpenServiceW(%08xh,%s,%08xh) not correctly implemented.\n",
229 schSCManager,
230 lpszServiceName,
231 fdwDesiredAccess));
232
233 if(lpszServiceName == NULL) {
234 SetLastError(ERROR_INVALID_PARAMETER);
235 return 0;
236 }
237 lpszServiceNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpszServiceName);
238 hService = OpenServiceA(schSCManager, lpszServiceNameA, fdwDesiredAccess);
239 HeapFree(GetProcessHeap(), 0, lpszServiceNameA);
240 return hService;
241}
242
243/*****************************************************************************
244 * Name : QueryServiceConfigA
245 * Purpose : The QueryServiceConfig function retrieves the configuration
246 * parameters of the specified service.
247 * Parameters: SC_HANDLE schService handle of service
248 * LPQUERY_SERVICE_CONFIG lpqscServConfig address of service config. structure
249 * DWORD cbBufSize size of service configuration buffer
250 * LPDWORD lpcbBytesNeeded address of variable for bytes needed
251 * Variables :
252 * Result :
253 * Remark :
254 * Status : UNTESTED STUB
255 *
256 * Author : SvL
257 *****************************************************************************/
258
259BOOL WIN32API QueryServiceConfigA(SC_HANDLE schService,
260 LPQUERY_SERVICE_CONFIG lpqscServConfig,
261 DWORD cbBufSize,
262 LPDWORD lpcbBytesNeeded)
263{
264 dprintf(("ADVAPI32: QueryServiceConfigA(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
265 schService,
266 lpqscServConfig,
267 cbBufSize,
268 lpcbBytesNeeded));
269
270 return (FALSE); /* signal failure */
271}
272
273
274/*****************************************************************************
275 * Name : QueryServiceConfigW
276 * Purpose : The QueryServiceConfig function retrieves the configuration
277 * parameters of the specified service.
278 * Parameters: SC_HANDLE schService handle of service
279 * LPQUERY_SERVICE_CONFIG lpqscServConfig address of service config. structure
280 * DWORD cbBufSize size of service configuration buffer
281 * LPDWORD lpcbBytesNeeded address of variable for bytes needed
282 * Variables :
283 * Result :
284 * Remark :
285 * Status : UNTESTED STUB
286 *
287 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
288 *****************************************************************************/
289
290BOOL WIN32API QueryServiceConfigW(SC_HANDLE schService,
291 LPQUERY_SERVICE_CONFIG lpqscServConfig,
292 DWORD cbBufSize,
293 LPDWORD lpcbBytesNeeded)
294{
295 dprintf(("ADVAPI32: QueryServiceConfigW(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
296 schService,
297 lpqscServConfig,
298 cbBufSize,
299 lpcbBytesNeeded));
300
301 return (FALSE); /* signal failure */
302}
303
304
305/*****************************************************************************
306 * Name : QueryServiceLockStatusA
307 * Purpose : The QueryServiceLockStatus function retrieves the lock status
308 * of the specified service control manager database.
309 * Parameters: SC_HANDLE schSCManager handle of svc. ctrl. mgr. database
310 * LPQUERY_SERVICE_LOCK_STATUS lpqslsLockStat address of lock status structure
311 * DWORD cbBufSize size of service configuration buffer
312 * LPDWORD lpcbBytesNeeded address of variable for bytes needed
313 * Variables :
314 * Result :
315 * Remark :
316 * Status : UNTESTED STUB
317 *
318 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
319 *****************************************************************************/
320
321BOOL WIN32API QueryServiceLockStatusA(SC_HANDLE schSCManager,
322 LPQUERY_SERVICE_LOCK_STATUSA lpqslsLockStat,
323 DWORD cbBufSize,
324 LPDWORD lpcbBytesNeeded)
325{
326 dprintf(("ADVAPI32: QueryServiceLockStatusA(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
327 schSCManager,
328 lpqslsLockStat,
329 cbBufSize,
330 lpcbBytesNeeded));
331
332 return (FALSE); /* signal failure */
333}
334
335
336/*****************************************************************************
337 * Name : QueryServiceLockStatusW
338 * Purpose : The QueryServiceLockStatus function retrieves the lock status
339 * of the specified service control manager database.
340 * Parameters: SC_HANDLE schSCManager handle of svc. ctrl. mgr. database
341 * LPQUERY_SERVICE_LOCK_STATUS lpqslsLockStat address of lock status structure
342 * DWORD cbBufSize size of service configuration buffer
343 * LPDWORD lpcbBytesNeeded address of variable for bytes needed
344 * Variables :
345 * Result :
346 * Remark :
347 * Status : UNTESTED STUB
348 *
349 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
350 *****************************************************************************/
351
352BOOL WIN32API QueryServiceLockStatusW(SC_HANDLE schSCManager,
353 LPQUERY_SERVICE_LOCK_STATUSW lpqslsLockStat,
354 DWORD cbBufSize,
355 LPDWORD lpcbBytesNeeded)
356{
357 dprintf(("ADVAPI32: QueryServiceLockStatusW(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
358 schSCManager,
359 lpqslsLockStat,
360 cbBufSize,
361 lpcbBytesNeeded));
362
363 return (FALSE); /* signal failure */
364}
365
366/*****************************************************************************
367 * Name : QueryServiceObjectSecurity
368 * Purpose : The QueryServiceObjectSecurity function retrieves a copy of the
369 * security descriptor protecting a service object.
370 * Parameters: SC_HANDLE schService handle of service
371 * SECURITY_INFORMATION fdwSecurityInfo type of security information requested
372 * PSECURITY_DESCRIPTOR psdSecurityDesc address of security descriptor
373 * DWORD cbBufSize size of security descriptor buffer
374 * LPDWORD lpcbBytesNeeded address of variable for bytes needed
375 * Variables :
376 * Result :
377 * Remark :
378 * Status : UNTESTED STUB
379 *
380 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
381 *****************************************************************************/
382
383BOOL WIN32API QueryServiceObjectSecurity(SC_HANDLE schService,
384 SECURITY_INFORMATION fdwSecurityInfo,
385 PSECURITY_DESCRIPTOR psdSecurityDesc,
386 DWORD cbBufSize,
387 LPDWORD lpcbBytesNeeded)
388{
389 dprintf(("ADVAPI32: QueryServiceObjectSecurity(%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
390 schService,
391 fdwSecurityInfo,
392 psdSecurityDesc,
393 cbBufSize,
394 lpcbBytesNeeded));
395
396 return (FALSE); /* signal failure */
397}
398
399/*****************************************************************************
400 * Name : SetServiceObjectSecurity
401 * Purpose : The SetServiceObjectSecurity function sets the security
402 * descriptor of a service object.
403 * Parameters: SC_HANDLE schService handle of service
404 * SECURITY_INFORMATION fdwSecurityInfo type of security information requested
405 * PSECURITY_DESCRIPTOR psdSecurityDesc address of security descriptor
406 * Variables :
407 * Result :
408 * Remark :
409 * Status : UNTESTED STUB
410 *
411 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
412 *****************************************************************************/
413
414BOOL WIN32API SetServiceObjectSecurity(SC_HANDLE schService,
415 SECURITY_INFORMATION fdwSecurityInfo,
416 PSECURITY_DESCRIPTOR psdSecurityDesc)
417{
418 dprintf(("ADVAPI32: SetServiceObjectSecurity(%08xh,%08xh,%08xh) not implemented.\n",
419 schService,
420 fdwSecurityInfo,
421 psdSecurityDesc));
422
423 return (FALSE); /* signal failure */
424}
425
426/*****************************************************************************
427 * Name : ChangeServiceConfigA
428 * Purpose : The ChangeServiceConfig function changes the configuration
429 * parameters of a service.
430 * Parameters: SC_HANDLE hService handle of service
431 * DWORD dwServiceType type of service
432 * DWORD dwStartType when to start service
433 * DWORD dwErrorControl severity if service fails to start
434 * LPCSTR lpBinaryPathName address of service binary file name
435 * LPCSTR lpLoadOrderGroup address of load ordering group name
436 * LPDWORD lpdwTagId address of variable to get tag identifier
437 * LPCSTR lpDependencies address of array of dependency names
438 * LPCSTR lpServiceStartName address of account name of service
439 * LPCSTR lpPassword address of password for service account
440 * LPCSTR lpDisplayName address of display name
441 * Variables :
442 * Result :
443 * Remark :
444 * Status :
445 *
446 * Author : SvL
447 *****************************************************************************/
448
449BOOL WIN32API ChangeServiceConfigA(SC_HANDLE hService,
450 DWORD dwServiceType,
451 DWORD dwStartType,
452 DWORD dwErrorControl,
453 LPCSTR lpBinaryPathName,
454 LPCSTR lpLoadOrderGroup,
455 LPDWORD lpdwTagId,
456 LPCSTR lpDependencies,
457 LPCSTR lpServiceStartName,
458 LPCSTR lpPassword,
459 LPCSTR lpDisplayName)
460{
461 dprintf(("ADVAPI32: ChangeServiceConfigA(%08xh,%08xh,%08xh,%08xh,%s,%s,%08xh,%s,%s,%s,%s) not implemented.\n",
462 hService,
463 dwServiceType,
464 dwStartType,
465 dwErrorControl,
466 lpBinaryPathName,
467 lpLoadOrderGroup,
468 lpdwTagId,
469 lpDependencies,
470 lpServiceStartName,
471 lpPassword,
472 lpDisplayName));
473
474 return (FALSE); /* signal failure */
475}
476
477
478/*****************************************************************************
479 * Name : ChangeServiceConfigW
480 * Purpose : The ChangeServiceConfig function changes the configuration
481 * parameters of a service.
482 * Parameters: SC_HANDLE hService handle of service
483 * DWORD dwServiceType type of service
484 * DWORD dwStartType when to start service
485 * DWORD dwErrorControl severity if service fails to start
486 * LPCWSTR lpBinaryPathName address of service binary file name
487 * LPCWSTR lpLoadOrderGroup address of load ordering group name
488 * LPDWORD lpdwTagId address of variable to get tag identifier
489 * LPCWSTR lpDependencies address of array of dependency names
490 * LPCWSTR lpServiceStartName address of account name of service
491 * LPCWSTR lpPassword address of password for service account
492 * LPCWSTR lpDisplayName address of display name
493 * Variables :
494 * Result :
495 * Remark :
496 * Status :
497 *
498 * Author : SvL
499 *****************************************************************************/
500
501BOOL WIN32API ChangeServiceConfigW(SC_HANDLE hService,
502 DWORD dwServiceType,
503 DWORD dwStartType,
504 DWORD dwErrorControl,
505 LPCWSTR lpBinaryPathName,
506 LPCWSTR lpLoadOrderGroup,
507 LPDWORD lpdwTagId,
508 LPCWSTR lpDependencies,
509 LPCWSTR lpServiceStartName,
510 LPCWSTR lpPassword,
511 LPCWSTR lpDisplayName)
512{
513 LPSTR lpDisplayNameA = NULL, lpBinaryPathNameA = NULL;
514 LPSTR lpDependenciesA = NULL, lpServiceStartNameA = NULL, lpPasswordA = NULL;
515 LPSTR lpLoadOrderGroupA = NULL;
516 BOOL fRc;
517
518 dprintf(("ADVAPI32: ChangeServiceConfigW(%08xh,%08xh,%08xh,%08xh,%s,%s,%08xh,%s,%s,%s,%s) not implemented.\n",
519 hService,
520 dwServiceType,
521 dwStartType,
522 dwErrorControl,
523 lpBinaryPathName,
524 lpLoadOrderGroup,
525 lpdwTagId,
526 lpDependencies,
527 lpServiceStartName,
528 lpPassword,
529 lpDisplayName));
530
531 if(lpDisplayName)
532 lpDisplayNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDisplayName);
533 if(lpBinaryPathName)
534 lpBinaryPathNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpBinaryPathName);
535 if(lpDependencies)
536 lpDependenciesA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDependencies);
537 if(lpServiceStartName)
538 lpServiceStartNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpServiceStartName);
539 if(lpPassword)
540 lpPasswordA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpPassword);
541 if(lpDisplayName)
542 lpDisplayNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDisplayName);
543 if(lpLoadOrderGroup)
544 lpLoadOrderGroupA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpLoadOrderGroup);
545
546 fRc = ChangeServiceConfigA(hService,dwServiceType, dwStartType, dwErrorControl,
547 lpBinaryPathNameA,
548 lpLoadOrderGroupA,
549 lpdwTagId,
550 lpDependenciesA,
551 lpServiceStartNameA,
552 lpPasswordA,
553 lpDisplayNameA);
554
555 if(lpDisplayNameA) HeapFree(GetProcessHeap(), 0, lpDisplayNameA);
556 if(lpBinaryPathNameA) HeapFree(GetProcessHeap(), 0, lpBinaryPathNameA);
557 if(lpDependenciesA) HeapFree(GetProcessHeap(), 0, lpDependenciesA);
558 if(lpServiceStartNameA) HeapFree(GetProcessHeap(), 0, lpServiceStartNameA);
559 if(lpPasswordA) HeapFree(GetProcessHeap(), 0, lpPasswordA);
560 if(lpLoadOrderGroupA) HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupA);
561
562 return fRc;
563}
564
565
566/*****************************************************************************
567 * Name : CloseServiceHandle
568 * Purpose : The CloseServiceHandle function closes a handle to a service
569 * control manager database as returned by the OpenSCManager function,
570 * or it closes a handle to a service object as returned by either
571 * the OpenService or CreateService function.
572 * Parameters: SC_HANDLE hSCObject handle of service or service control manager database
573 * Variables :
574 * Result :
575 * Remark :
576 * Status :
577 *
578 * Author : SvL
579 *****************************************************************************/
580
581BOOL WIN32API CloseServiceHandle(SC_HANDLE hSCObject)
582{
583 dprintf(("ADVAPI32: CloseServiceHandle(%08xh)",
584 hSCObject));
585
586 if(CheckServiceHandle(hSCObject) == FALSE) {
587 SetLastError(ERROR_INVALID_PARAMETER);
588 return FALSE;
589 }
590
591 DWORD deletepending, keytype = REG_DWORD, size = sizeof(DWORD);
592 if(!RegQueryValueExA((HKEY)hSCObject, REG_SERVICE_DELETEPENDING, 0, &keytype, (LPBYTE)&deletepending, &size)) {
593 CHAR szKeyName[256] = "";
594
595 HKEY keyServices;
596 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services", &keyServices) != 0) {
597 SetLastError(ERROR_INTERNAL_ERROR);
598 return FALSE;
599 }
600 keytype = REG_SZ;
601 size = sizeof(szKeyName);
602 RegQueryValueExA(hSCObject, REG_SERVICE_NAME, 0, &keytype, (LPBYTE)szKeyName, &size);
603
604 RegCloseKey((HKEY)hSCObject);
605 RegDeleteKeyA(keyServices, szKeyName);
606 RegCloseKey((HKEY)keyServices);
607 }
608
609 RegCloseKey((HKEY)hSCObject);
610 SetLastError(0);
611 return TRUE;
612}
613
614/*****************************************************************************
615 * Name : ControlService
616 * Purpose : The ControlService function sends a control code to a Win32 service.
617 * Parameters: SC_HANDLE hService handle of service
618 * DWORD dwControl control code
619 * LPSERVICE_STATUS lpServiceStatus address of service status structure
620 * Variables :
621 * Result :
622 * Remark :
623 * Status :
624 *
625 * Author : SvL
626 *****************************************************************************/
627
628BOOL WIN32API ControlService(SC_HANDLE hService,
629 DWORD dwControl,
630 LPSERVICE_STATUS lpServiceStatus)
631{
632 dprintf(("ADVAPI32: ControlService(%08xh,%08xh,%08xh) not correctly implemented.\n",
633 hService,
634 dwControl,
635 lpServiceStatus));
636 HKEY keyThisService;
637
638 if(CheckServiceHandle(hService) == FALSE) {
639 SetLastError(ERROR_INVALID_PARAMETER);
640 return FALSE;
641 }
642 SetLastError(0);
643 return TRUE;
644}
645
646
647/*****************************************************************************
648 * Name : CreateServiceA
649 * Purpose : The CreateService function creates a service object and adds it
650 * to the specified service control manager database.
651 * Parameters: SC_HANDLE hSCManager handle of service control manager database
652 * LPCSTR lpServiceName address of name of service to start
653 * LPCSTR lpDisplayName address of display name
654 * DWORD dwDesiredAccess type of access to service
655 * DWORD dwServiceType type of service
656 * DWORD dwStartType when to start service
657 * DWORD dwErrorControl severity if service fails to start
658 * LPCSTR lpBinaryPathName address of name of binary file
659 * LPCSTR lpLoadOrderGroup address of name of load ordering group
660 * LPDWORD lpdwTagId address of variable to get tag identifier
661 * LPCSTR lpDependencies address of array of dependency names
662 * LPCSTR lpServiceStartName address of account name of service
663 * LPCSTR lpPassword address of password for service account
664 * Variables :
665 * Result :
666 * Remark :
667 * Status :
668 *
669 * Author : SvL
670 *****************************************************************************/
671
672SC_HANDLE WIN32API CreateServiceA(SC_HANDLE hSCManager,
673 LPCSTR lpServiceName,
674 LPCSTR lpDisplayName,
675 DWORD dwDesiredAccess,
676 DWORD dwServiceType,
677 DWORD dwStartType,
678 DWORD dwErrorControl,
679 LPCSTR lpBinaryPathName,
680 LPCSTR lpLoadOrderGroup,
681 LPDWORD lpdwTagId,
682 LPCSTR lpDependencies,
683 LPCSTR lpServiceStartName,
684 LPCSTR lpPassword)
685{
686 HKEY keyServices, keyThisService;
687
688 dprintf(("ADVAPI32: CreateServiceA(%08xh,%s,%s,%08xh,%08xh,%08xh,%08xh,%s,%s,%08xh,%s,%s,%s) not correctly implemented.\n",
689 hSCManager,
690 lpServiceName,
691 lpDisplayName,
692 dwDesiredAccess,
693 dwServiceType,
694 dwStartType,
695 dwErrorControl,
696 lpBinaryPathName,
697 lpLoadOrderGroup,
698 lpdwTagId,
699 lpDependencies,
700 lpServiceStartName,
701 lpPassword));
702
703 //displayname too?
704 if(lpServiceName == NULL || lpBinaryPathName == NULL) {
705 SetLastError(ERROR_INVALID_PARAMETER);
706 return 0;
707 }
708
709 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services", &keyServices) != 0) {
710 SetLastError(ERROR_INTERNAL_ERROR);
711 return 0;
712 }
713 if(RegCreateKeyA(keyServices, lpServiceName, &keyThisService) != 0) {
714 SetLastError(ERROR_INTERNAL_ERROR);
715 return 0;
716 }
717 RegSetValueExA(keyThisService, REG_SERVICE_NAME, 0, REG_SZ, (LPBYTE)lpServiceName, strlen(lpServiceName)+1);
718 RegSetValueExA(keyThisService, REG_SERVICE_TYPE, 0, REG_DWORD, (LPBYTE)&dwServiceType, sizeof(DWORD));
719 RegSetValueExA(keyThisService, REG_SERVICE_STARTTYPE, 0, REG_DWORD, (LPBYTE)&dwStartType, sizeof(DWORD));
720 RegSetValueExA(keyThisService, REG_SERVICE_ERRORCONTROL, 0, REG_DWORD, (LPBYTE)&dwErrorControl, sizeof(DWORD));
721 if(lpDisplayName)
722 RegSetValueExA(keyThisService, REG_SERVICE_DISPLAYNAME, 0, REG_SZ, (LPBYTE)lpDisplayName, strlen(lpDisplayName)+1);
723 if(lpLoadOrderGroup)
724 RegSetValueExA(keyThisService, REG_SERVICE_LOADORDERGROUP, 0, REG_SZ, (LPBYTE)lpDisplayName, strlen(lpLoadOrderGroup)+1);
725 if(lpDependencies) {
726 //seems to need an extra terminating '0'
727 int size = strlen(lpDependencies)+2;
728 char *dependencies = (char *)malloc(size);
729 memset(dependencies, 0, size);
730 strcpy(dependencies, lpDependencies);
731 RegSetValueExA(keyThisService, REG_SERVICE_DEPENDENCIES, 0, REG_BINARY, (LPBYTE)dependencies, size);
732 free(dependencies);
733 }
734 //TODO: %SystemRoot%
735 RegSetValueExA(keyThisService, REG_SERVICE_IMAGEPATH, 0, REG_SZ, (LPBYTE)lpBinaryPathName, strlen(lpBinaryPathName)+1);
736
737 //Pointer to a variable that receives a tag value that is unique in the group specified in the
738 //lpLoadOrderGroup parameter. Specify NULL if you are not changing the existing tag.
739 DWORD tag = 1; //TODO!!
740 RegSetValueExA(keyThisService, REG_SERVICE_TAG, 0, REG_DWORD, (LPBYTE)&tag, sizeof(DWORD));
741 if(lpdwTagId)
742 *lpdwTagId = tag;
743
744 DWORD state = SERVICE_STOPPED;
745 RegSetValueExA(keyThisService, REG_SERVICE_STATUS, 0, REG_DWORD, (LPBYTE)&state, sizeof(DWORD));
746
747 //TODO: What else?
748
749 RegCloseKey(keyServices);
750 SetLastError(0);
751 return keyThisService;
752}
753
754
755/*****************************************************************************
756 * Name : CreateServiceW
757 * Purpose : The CreateService function creates a service object and adds it
758 * to the specified service control manager database.
759 * Parameters: SC_HANDLE hSCManager handle of service control manager database
760 * LPCWSTR lpServiceName address of name of service to start
761 * LPCWSTR lpDisplayName address of display name
762 * DWORD dwDesiredAccess type of access to service
763 * DWORD dwServiceType type of service
764 * DWORD dwStartType when to start service
765 * DWORD dwErrorControl severity if service fails to start
766 * LPCWSTR lpBinaryPathName address of name of binary file
767 * LPCWSTR lpLoadOrderGroup address of name of load ordering group
768 * LPDWORD lpdwTagId address of variable to get tag identifier
769 * LPCWSTR lpDependencies address of array of dependency names
770 * LPCWSTR lpServiceStartName address of account name of service
771 * LPCWSTR lpPassword address of password for service account
772 * Variables :
773 * Result :
774 * Remark :
775 * Status :
776 *
777 * Author : SvL
778 *****************************************************************************/
779
780SC_HANDLE WIN32API CreateServiceW(SC_HANDLE hSCManager,
781 LPCWSTR lpServiceName,
782 LPCWSTR lpDisplayName,
783 DWORD dwDesiredAccess,
784 DWORD dwServiceType,
785 DWORD dwStartType,
786 DWORD dwErrorControl,
787 LPCWSTR lpBinaryPathName,
788 LPCWSTR lpLoadOrderGroup,
789 LPDWORD lpdwTagId,
790 LPCWSTR lpDependencies,
791 LPCWSTR lpServiceStartName,
792 LPCWSTR lpPassword)
793{
794 LPSTR lpServiceNameA = NULL, lpDisplayNameA = NULL, lpBinaryPathNameA = NULL;
795 LPSTR lpDependenciesA = NULL, lpServiceStartNameA = NULL, lpPasswordA = NULL;
796 LPSTR lpLoadOrderGroupA = NULL;
797 SC_HANDLE hService;
798
799 dprintf(("ADVAPI32: CreateServiceW(%08xh,%s,%s,%08xh,%08xh,%08xh,%08xh,%s,%s,%08xh,%s,%s,%s) not correctly implemented.\n",
800 hSCManager,
801 lpServiceName,
802 lpDisplayName,
803 dwDesiredAccess,
804 dwServiceType,
805 dwStartType,
806 dwErrorControl,
807 lpBinaryPathName,
808 lpLoadOrderGroup,
809 lpdwTagId,
810 lpDependencies,
811 lpServiceStartName,
812 lpPassword));
813
814 if(lpServiceName)
815 lpServiceNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpServiceName);
816 if(lpDisplayName)
817 lpDisplayNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDisplayName);
818 if(lpBinaryPathName)
819 lpBinaryPathNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpBinaryPathName);
820 if(lpDependencies)
821 lpDependenciesA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDependencies);
822 if(lpServiceStartName)
823 lpServiceStartNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpServiceStartName);
824 if(lpPassword)
825 lpPasswordA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpPassword);
826 if(lpDisplayName)
827 lpDisplayNameA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDisplayName);
828 if(lpLoadOrderGroup)
829 lpLoadOrderGroupA = HEAP_strdupWtoA(GetProcessHeap(), 0, lpLoadOrderGroup);
830
831 hService = CreateServiceA(hSCManager,lpServiceNameA, lpDisplayNameA,
832 dwDesiredAccess, dwServiceType, dwStartType,
833 dwErrorControl, lpBinaryPathNameA, lpLoadOrderGroupA,
834 lpdwTagId, lpDependenciesA, lpServiceStartNameA,
835 lpPasswordA);
836
837 if(lpServiceNameA) HeapFree(GetProcessHeap(), 0, lpServiceNameA);
838 if(lpDisplayNameA) HeapFree(GetProcessHeap(), 0, lpDisplayNameA);
839 if(lpBinaryPathNameA) HeapFree(GetProcessHeap(), 0, lpBinaryPathNameA);
840 if(lpDependenciesA) HeapFree(GetProcessHeap(), 0, lpDependenciesA);
841 if(lpServiceStartNameA) HeapFree(GetProcessHeap(), 0, lpServiceStartNameA);
842 if(lpPasswordA) HeapFree(GetProcessHeap(), 0, lpPasswordA);
843 if(lpLoadOrderGroupA) HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupA);
844
845 return hService;
846}
847
848/*****************************************************************************
849 * Name : StartServiceA
850 * Purpose : The StartService function starts the execution of a service.
851 * Parameters: SC_HANDLE schService handle of service
852 * DWORD dwNumServiceArgs number of arguments
853 * LPCSTR *lpszServiceArgs address of array of argument string pointers
854 * Variables :
855 * Result :
856 * Remark :
857 * Status :
858 *
859 * Author : SvL
860 *****************************************************************************/
861
862BOOL WIN32API StartServiceA(SC_HANDLE schService,
863 DWORD dwNumServiceArgs,
864 LPCSTR *lpszServiceArgs)
865{
866 dprintf(("ADVAPI32: StartServiceA(%08xh,%08xh,%s) not implemented.\n",
867 schService,
868 dwNumServiceArgs,
869 lpszServiceArgs));
870
871 if(CheckServiceHandle(schService) == FALSE) {
872 SetLastError(ERROR_INVALID_PARAMETER);
873 return FALSE;
874 }
875
876 DWORD state = SERVICE_RUNNING;
877 if(!RegSetValueExA((HKEY)schService, REG_SERVICE_STATUS, 0, REG_DWORD, (LPBYTE)&state, sizeof(DWORD))) {
878 SetLastError(0);
879 return TRUE;
880 }
881
882 //TODO: Really start service
883 return (FALSE); /* signal failure */
884}
885
886/*****************************************************************************
887 * Name : StartServiceW
888 * Purpose : The StartService function starts the execution of a service.
889 * Parameters: SC_HANDLE schService handle of service
890 * DWORD dwNumServiceArgs number of arguments
891 * LPCWSTR *lpszServiceArgs address of array of argument string pointers
892 * Variables :
893 * Result :
894 * Remark :
895 * Status :
896 *
897 * Author : SvL
898 *****************************************************************************/
899
900BOOL WIN32API StartServiceW(SC_HANDLE schService,
901 DWORD dwNumServiceArgs,
902 LPCWSTR *lpszServiceArgs)
903{
904 dprintf(("ADVAPI32: StartServiceW(%08xh,%08xh,%s) not implemented.\n",
905 schService,
906 dwNumServiceArgs,
907 lpszServiceArgs));
908
909 if(CheckServiceHandle(schService) == FALSE) {
910 SetLastError(ERROR_INVALID_PARAMETER);
911 return FALSE;
912 }
913
914 DWORD state = SERVICE_RUNNING;
915 if(!RegSetValueExW((HKEY)schService, REG_SERVICE_STATUS_W, 0, REG_DWORD, (LPBYTE)&state, sizeof(DWORD))) {
916 SetLastError(0);
917 return TRUE;
918 }
919 //TODO: Really start service
920 return (FALSE); /* signal failure */
921}
922
923/*****************************************************************************
924 * Name : DeleteService
925 * Purpose : The DeleteService function marks the specified service for
926 * deletion from the service control manager database.
927 * Parameters: SC_HANDLE hService handle of service
928 * Variables :
929 * Result :
930 * Remark :
931 * Status :
932 *
933 * Author : SvL
934 *****************************************************************************/
935
936BOOL WIN32API DeleteService(SC_HANDLE hService)
937{
938 dprintf(("ADVAPI32: DeleteService(%08xh)", hService));
939
940 if(CheckServiceHandle(hService) == FALSE) {
941 SetLastError(ERROR_INVALID_PARAMETER);
942 return FALSE;
943 }
944 DWORD deletepending = 1;
945 if(!RegSetValueExA((HKEY)hService, REG_SERVICE_DELETEPENDING, 0, REG_DWORD, (LPBYTE)&deletepending, sizeof(DWORD))) {
946 SetLastError(0);
947 return TRUE;
948 }
949 return FALSE;
950}
951
952/*****************************************************************************
953 * Name : GetServiceDisplayNameA
954 * Purpose : The GetServiceDisplayName function obtains the display name that
955 * is associated with a particular service name. The service name
956 * is the same as the service's registry key name.
957 * Parameters: SC_HANDLE hSCManager handle to a service control manager database
958 * LPCSTR lpServiceName the service name
959 * LPTSTR lpDisplayName buffer to receive the service's display name
960 * LPDWORD lpcchBuffer size of display name buffer and display name
961 * Variables :
962 * Result :
963 * Remark :
964 * Status :
965 *
966 * Author : SvL
967 *****************************************************************************/
968
969BOOL WIN32API GetServiceDisplayNameA(SC_HANDLE hSCManager,
970 LPCSTR lpServiceName,
971 LPTSTR lpDisplayName,
972 LPDWORD lpcchBuffer)
973{
974 HKEY keyThisService;
975 DWORD size, type;
976
977 dprintf(("ADVAPI32: GetServiceDisplayNameA(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
978 hSCManager,
979 lpServiceName,
980 lpDisplayName,
981 lpcchBuffer));
982
983 if(!lpServiceName || !lpDisplayName) {
984 SetLastError(ERROR_INVALID_PARAMETER);
985 return FALSE;
986 }
987 if(CheckServiceHandle(hSCManager) == FALSE) {
988 SetLastError(ERROR_INVALID_PARAMETER);
989 return FALSE;
990 }
991
992 if(RegOpenKeyA((HKEY)hSCManager, lpServiceName, &keyThisService) != 0) {
993 SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
994 return FALSE;
995 }
996 size = *lpcchBuffer;
997 type = REG_SZ;
998 if(RegQueryValueExA(keyThisService, REG_SERVICE_DISPLAYNAME, 0, &type, (LPBYTE)lpDisplayName, &size) == ERROR_MORE_DATA)
999 {
1000 SetLastError(ERROR_MORE_DATA);
1001 *lpcchBuffer = size;
1002 return FALSE;
1003 }
1004 *lpcchBuffer = size;
1005 RegCloseKey(keyThisService);
1006 SetLastError(0);
1007 return TRUE;
1008}
1009
1010
1011/*****************************************************************************
1012 * Name : GetServiceDisplayNameW
1013 * Purpose : The GetServiceDisplayName function obtains the display name that
1014 * is associated with a particular service name. The service name
1015 * is the same as the service's registry key name.
1016 * Parameters: SC_HANDLE hSCManager handle to a service control manager database
1017 * LPCWSTR lpServiceName the service name
1018 * LPWSTR lpDisplayName buffer to receive the service's display name
1019 * LPDWORD lpcchBuffer size of display name buffer and display name
1020 * Variables :
1021 * Result :
1022 * Remark :
1023 * Status :
1024 *
1025 * Author : SvL
1026 *****************************************************************************/
1027
1028BOOL WIN32API GetServiceDisplayNameW(SC_HANDLE hSCManager,
1029 LPCWSTR lpServiceName,
1030 LPWSTR lpDisplayName,
1031 LPDWORD lpcchBuffer)
1032{
1033 HKEY keyThisService;
1034 DWORD size, type;
1035
1036 dprintf(("ADVAPI32: GetServiceDisplayNameW(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1037 hSCManager,
1038 lpServiceName,
1039 lpDisplayName,
1040 lpcchBuffer));
1041
1042 if(!lpServiceName || !lpDisplayName) {
1043 SetLastError(ERROR_INVALID_PARAMETER);
1044 return FALSE;
1045 }
1046 if(CheckServiceHandle(hSCManager) == FALSE) {
1047 SetLastError(ERROR_INVALID_PARAMETER);
1048 return FALSE;
1049 }
1050
1051 if(RegOpenKeyW((HKEY)hSCManager, lpServiceName, &keyThisService) != 0) {
1052 SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
1053 return FALSE;
1054 }
1055 size = *lpcchBuffer;
1056 type = REG_SZ;
1057 if(RegQueryValueExW(keyThisService, REG_SERVICE_DISPLAYNAME_W, 0, &type, (LPBYTE)lpDisplayName, &size) == ERROR_MORE_DATA)
1058 {
1059 SetLastError(ERROR_MORE_DATA);
1060 *lpcchBuffer = size;
1061 return FALSE;
1062 }
1063 *lpcchBuffer = size;
1064 RegCloseKey(keyThisService);
1065 SetLastError(0);
1066 return TRUE;
1067}
1068
1069/*****************************************************************************
1070 * Name : EnumDependentServicesA
1071 * Purpose : The EnumDependentServices function enumerates services that
1072 * depend on another specified service; that is, the specified
1073 * service must be running before the enumerated services can run.
1074 * The name and status of each dependent service are provided.
1075 * Parameters: SC_HANDLE hService handle of service
1076 * DWORD dwServiceState state of services to enumerate
1077 * LPENUM_SERVICE_STATUS lpServices address of service status buffer
1078 * DWORD cbBufSize size of service status buffer
1079 * LPDWORD pcbBytesNeeded address of variable for bytes needed
1080 * LPDWORD lpServicesReturned address of variable for number returned
1081 * Variables :
1082 * Result :
1083 * Remark :
1084 * Status : UNTESTED STUB
1085 *
1086 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1087 *****************************************************************************/
1088
1089BOOL WIN32API EnumDependentServicesA(SC_HANDLE hService,
1090 DWORD dwServiceState,
1091 LPENUM_SERVICE_STATUSA lpServices,
1092 DWORD cbBufSize,
1093 LPDWORD pcbBytesNeeded,
1094 LPDWORD lpServicesReturned)
1095{
1096 dprintf(("ADVAPI32: EnumDependentServicesA(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1097 hService,
1098 dwServiceState,
1099 lpServices,
1100 cbBufSize,
1101 pcbBytesNeeded,
1102 lpServicesReturned));
1103
1104 return (FALSE); /* signal failure */
1105}
1106
1107
1108/*****************************************************************************
1109 * Name : EnumDependentServicesW
1110 * Purpose : The EnumDependentServices function enumerates services that
1111 * depend on another specified service; that is, the specified
1112 * service must be running before the enumerated services can run.
1113 * The name and status of each dependent service are provided.
1114 * Parameters: SC_HANDLE hService handle of service
1115 * DWORD dwServiceState state of services to enumerate
1116 * LPENUM_SERVICE_STATUS lpServices address of service status buffer
1117 * DWORD cbBufSize size of service status buffer
1118 * LPDWORD pcbBytesNeeded address of variable for bytes needed
1119 * LPDWORD lpServicesReturned address of variable for number returned
1120 * Variables :
1121 * Result :
1122 * Remark :
1123 * Status : UNTESTED STUB
1124 *
1125 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1126 *****************************************************************************/
1127
1128BOOL WIN32API EnumDependentServicesW(SC_HANDLE hService,
1129 DWORD dwServiceState,
1130 LPENUM_SERVICE_STATUSW lpServices,
1131 DWORD cbBufSize,
1132 LPDWORD pcbBytesNeeded,
1133 LPDWORD lpServicesReturned)
1134{
1135 dprintf(("ADVAPI32: EnumDependentServicesW(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1136 hService,
1137 dwServiceState,
1138 lpServices,
1139 cbBufSize,
1140 pcbBytesNeeded,
1141 lpServicesReturned));
1142
1143 return (FALSE); /* signal failure */
1144}
1145
1146
1147/*****************************************************************************
1148 * Name : EnumServicesStatusA
1149 * Purpose : The EnumServicesStatus function enumerates services in the specified
1150 * service control manager database. The name and status of each service are provided.
1151 * Parameters: SC_HANDLE hSCManager handle of service control manager database
1152 * DWORD dwServiceType type of services to enumerate
1153 * DWORD dwServiceState state of services to enumerate
1154 * LPENUM_SERVICE_STATUS lpServices address of service status buffer
1155 * DWORD cbBufSize size of service status buffer
1156 * LPDWORD pcbBytesNeeded address of variable for bytes needed
1157 * LPDWORD lpServicesReturned address of variable for number returned
1158 * LPDWORD lpResumeHandle address of variable for next entry
1159 * Variables :
1160 * Result :
1161 * Remark :
1162 * Status : UNTESTED STUB
1163 *
1164 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1165 *****************************************************************************/
1166
1167BOOL WIN32API EnumServicesStatusA(SC_HANDLE hSCManager,
1168 DWORD dwServiceType,
1169 DWORD dwServiceState,
1170 LPENUM_SERVICE_STATUSA lpServices,
1171 DWORD cbBufSize,
1172 LPDWORD pcbBytesNeeded,
1173 LPDWORD lpServicesReturned,
1174 LPDWORD lpResumeHandle)
1175{
1176 dprintf(("ADVAPI32: EnumServicesStatusA(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1177 hSCManager,
1178 dwServiceType,
1179 dwServiceState,
1180 lpServices,
1181 cbBufSize,
1182 pcbBytesNeeded,
1183 lpServicesReturned,
1184 lpResumeHandle));
1185
1186 if(lpServicesReturned) {
1187 *lpServicesReturned = 0;
1188 }
1189 if(pcbBytesNeeded) {
1190 *pcbBytesNeeded = sizeof(ENUM_SERVICE_STATUSA);
1191 }
1192 return TRUE; /* signal failure */
1193}
1194
1195
1196/*****************************************************************************
1197 * Name : EnumServicesStatusW
1198 * Purpose : The EnumServicesStatus function enumerates services in the specified
1199 * service control manager database. The name and status of each service are provided.
1200 * Parameters: SC_HANDLE hSCManager handle of service control manager database
1201 * DWORD dwServiceType type of services to enumerate
1202 * DWORD dwServiceState state of services to enumerate
1203 * LPENUM_SERVICE_STATUS lpServices address of service status buffer
1204 * DWORD cbBufSize size of service status buffer
1205 * LPDWORD pcbBytesNeeded address of variable for bytes needed
1206 * LPDWORD lpServicesReturned address of variable for number returned
1207 * LPDWORD lpResumeHandle address of variable for next entry
1208 * Variables :
1209 * Result :
1210 * Remark :
1211 * Status : UNTESTED STUB
1212 *
1213 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1214 *****************************************************************************/
1215
1216BOOL WIN32API EnumServicesStatusW(SC_HANDLE hSCManager,
1217 DWORD dwServiceType,
1218 DWORD dwServiceState,
1219 LPENUM_SERVICE_STATUSW lpServices,
1220 DWORD cbBufSize,
1221 LPDWORD pcbBytesNeeded,
1222 LPDWORD lpServicesReturned,
1223 LPDWORD lpResumeHandle)
1224{
1225 dprintf(("ADVAPI32: EnumServicesStatusW(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1226 hSCManager,
1227 dwServiceType,
1228 dwServiceState,
1229 lpServices,
1230 cbBufSize,
1231 pcbBytesNeeded,
1232 lpServicesReturned,
1233 lpResumeHandle));
1234
1235 if(lpServicesReturned) {
1236 *lpServicesReturned = 0;
1237 }
1238 if(pcbBytesNeeded) {
1239 *pcbBytesNeeded = sizeof(ENUM_SERVICE_STATUSA);
1240 }
1241 return TRUE; /* signal failure */
1242}
1243
1244/*****************************************************************************
1245 * Name : GetServiceKeyNameA
1246 * Purpose : The GetServiceKeyName function obtains the service name that is
1247 * associated with a particular service's display name. The service
1248 * name is the same as the service's registry key name.
1249 * Parameters: SC_HANDLE hSCManager handle to a service control manager database
1250 * LPCSTR lpDisplayName the service's display name
1251 * LPTSTR lpServiceName buffer to receive the service name
1252 * LPDWORD lpcchBuffer size of service name buffer and service name
1253 * Variables :
1254 * Result :
1255 * Remark :
1256 * Status : UNTESTED STUB
1257 *
1258 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1259 *****************************************************************************/
1260
1261BOOL WIN32API GetServiceKeyNameA(SC_HANDLE hSCManager,
1262 LPCSTR lpDisplayName,
1263 LPTSTR lpServiceName,
1264 LPDWORD lpcchBuffer)
1265{
1266 dprintf(("ADVAPI32: GetServiceKeyNameA(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1267 hSCManager,
1268 lpDisplayName,
1269 lpServiceName,
1270 lpcchBuffer));
1271
1272 return (FALSE); /* signal failure */
1273}
1274
1275
1276/*****************************************************************************
1277 * Name : GetServiceKeyNameW
1278 * Purpose : The GetServiceKeyName function obtains the service name that is
1279 * associated with a particular service's display name. The service
1280 * name is the same as the service's registry key name.
1281 * Parameters: SC_HANDLE hSCManager handle to a service control manager database
1282 * LPCWSTR lpDisplayName the service's display name
1283 * LPWSTR lpServiceName buffer to receive the service name
1284 * LPDWORD lpcchBuffer size of service name buffer and service name
1285 * Variables :
1286 * Result :
1287 * Remark :
1288 * Status : UNTESTED STUB
1289 *
1290 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1291 *****************************************************************************/
1292
1293BOOL WIN32API GetServiceKeyNameW(SC_HANDLE hSCManager,
1294 LPCWSTR lpDisplayName,
1295 LPWSTR lpServiceName,
1296 LPDWORD lpcchBuffer)
1297{
1298 dprintf(("ADVAPI32: GetServiceKeyNameW(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1299 hSCManager,
1300 lpDisplayName,
1301 lpServiceName,
1302 lpcchBuffer));
1303
1304 return (FALSE); /* signal failure */
1305}
1306
1307/*****************************************************************************
1308 * Name : LockServiceDatabase
1309 * Purpose : The LockServiceDatabase function locks a specified database.
1310 * Parameters: SC_HANDLE hSCManager handle of service control manager database
1311 * Variables :
1312 * Result :
1313 * Remark :
1314 * Status : UNTESTED STUB
1315 *
1316 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1317 *****************************************************************************/
1318
1319SC_LOCK WIN32API LockServiceDatabase(SC_HANDLE hSCManager)
1320{
1321 dprintf(("ADVAPI32: LockServiceDatabase(%08xh) not implemented.\n",
1322 hSCManager));
1323
1324 return 0; /* signal failure */
1325}
1326
1327/*****************************************************************************
1328 * Name : UnlockServiceDatabase
1329 * Purpose : The UnlockServiceDatabase function unlocks a service control
1330 * manager database by releasing the specified lock.
1331 * Parameters: SC_LOCK sclLock service control manager database lock to be released
1332 * Variables :
1333 * Result :
1334 * Remark :
1335 * Status : UNTESTED STUB
1336 *
1337 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1338
1339 *****************************************************************************/
1340
1341BOOL WIN32API UnlockServiceDatabase(SC_LOCK sclLock)
1342{
1343 dprintf(("ADVAPI32: UnlockServiceDatabase(%08xh) not implemented.\n",
1344 sclLock));
1345
1346 return (FALSE); /* signal failure */
1347}
1348
1349//******************************************************************************
1350//Helper for StartServiceCtrlDispatcherA/W; counts nr or arguments in cmd line
1351//******************************************************************************
1352ULONG CountNrArgs(char *cmdline)
1353{
1354 char *cmd = cmdline;
1355 ULONG nrargs = 0;
1356
1357 while(*cmd == ' ') cmd++; //skip leading spaces
1358 while(*cmd != 0) {
1359 while(*cmd != ' ' && *cmd != 0) cmd++; //skip non-space chars
1360 while(*cmd == ' ' && *cmd != 0) cmd++; //skip spaces
1361 nrargs++;
1362 }
1363 return nrargs;
1364}
1365
1366/*****************************************************************************
1367 * Name : StartServiceCtrlDispatcherW
1368 * Purpose : The StartServiceCtrlDispatcher function connects the main thread
1369 * of a service process to the service control manager, which causes
1370 * the thread to be the service control dispatcher thread for the calling process.
1371 * Parameters: LPSERVICE_TABLE_ENTRY lpsteServiceTable address of service table
1372 * Variables :
1373 * Result :
1374 * Remark :
1375 * Status :
1376 *
1377 * Author : SvL
1378 *****************************************************************************/
1379
1380BOOL WIN32API StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpsteServiceTable)
1381{
1382 ULONG nrArgs = 0;
1383 LPWSTR cmdline;
1384
1385 dprintf(("ADVAPI32: StartServiceCtrlDispatcherW(%x)", lpsteServiceTable));
1386
1387 if(fServiceCtrlDispatcherStarted == TRUE) {
1388 SetLastError(ERROR_SERVICE_ALREADY_RUNNING);
1389 return FALSE;
1390 }
1391 fServiceCtrlDispatcherStarted = TRUE;
1392 if(lpsteServiceTable->lpServiceProc == NULL) {
1393 SetLastError(ERROR_INVALID_DATA); //or invalid parameter?
1394 return FALSE;
1395 }
1396 while(lpsteServiceTable->lpServiceProc) {
1397 cmdline = (LPWSTR)GetCommandLineW();
1398 nrArgs = CountNrArgs((LPSTR)GetCommandLineA());
1399 lpsteServiceTable->lpServiceProc(nrArgs, cmdline);
1400 lpsteServiceTable++; //next service entrypoint
1401 }
1402 SetLastError(0);
1403 return TRUE;
1404}
1405
1406/*****************************************************************************
1407 * Name : StartServiceCtrlDispatcherA
1408 * Purpose : The StartServiceCtrlDispatcher function connects the main thread
1409 * of a service process to the service control manager, which causes
1410 * the thread to be the service control dispatcher thread for the calling process.
1411 * Parameters: LPSERVICE_TABLE_ENTRY lpsteServiceTable address of service table
1412 * Variables :
1413 * Result :
1414 * Remark :
1415 * Status :
1416 *
1417 * Author : SvL
1418 *****************************************************************************/
1419
1420BOOL WIN32API StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpsteServiceTable)
1421{
1422 ULONG nrArgs = 0;
1423 LPSTR cmdline;
1424
1425 dprintf(("ADVAPI32: StartServiceCtrlDispatcherA(%08xh)", lpsteServiceTable));
1426
1427 if(fServiceCtrlDispatcherStarted == TRUE) {
1428 SetLastError(ERROR_SERVICE_ALREADY_RUNNING);
1429 return FALSE;
1430 }
1431 fServiceCtrlDispatcherStarted = TRUE;
1432 if(lpsteServiceTable->lpServiceProc == NULL) {
1433 SetLastError(ERROR_INVALID_DATA); //or invalid parameter?
1434 return FALSE;
1435 }
1436 while(lpsteServiceTable->lpServiceProc) {
1437 cmdline = (LPSTR)GetCommandLineA();
1438 nrArgs = CountNrArgs(cmdline);
1439 lpsteServiceTable->lpServiceProc(nrArgs, cmdline);
1440 lpsteServiceTable++; //next service entrypoint
1441 }
1442 SetLastError(0);
1443 return TRUE;
1444}
1445
1446/*****************************************************************************
1447 * Name : RegisterServiceCtrlHandlerA
1448 * Purpose : The RegisterServiceCtrlHandler function registers a function to
1449 * handle service control requests for a service.
1450 * Parameters: LPCSTR lpszServiceName address of name of service
1451 * LPHANDLER_FUNCTION lpHandlerProc address of handler function
1452 * Variables :
1453 * Result :
1454 * Remark :
1455 * Status :
1456 *
1457 * Author : SvL
1458 *****************************************************************************/
1459
1460SERVICE_STATUS_HANDLE WIN32API RegisterServiceCtrlHandlerA(LPCSTR lpszServiceName,
1461 LPHANDLER_FUNCTION lpHandlerProc)
1462{
1463 SC_HANDLE hSCMgr, hService;
1464
1465 dprintf(("ADVAPI32: RegisterServiceCtrlHandlerA(%s,%08xh) not implemented (FAKED)",
1466 lpszServiceName,
1467 lpHandlerProc));
1468
1469 //Doesn't work for services of type
1470 if(lpszServiceName == NULL) {
1471 SetLastError(ERROR_INVALID_NAME);
1472 return 0;
1473 }
1474 hSCMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1475 hService = OpenServiceA(hSCMgr, lpszServiceName, SERVICE_ALL_ACCESS);
1476 if(hService == 0) {
1477 SetLastError(ERROR_INVALID_NAME);
1478 return 0;
1479 }
1480 CloseServiceHandle(hSCMgr);
1481 //TODO: Start thread with ctrl handler
1482 SetLastError(0);
1483 return hService;
1484}
1485
1486
1487/*****************************************************************************
1488 * Name : RegisterServiceCtrlHandlerW
1489 * Purpose : The RegisterServiceCtrlHandler function registers a function to
1490 * handle service control requests for a service.
1491 * Parameters: LPCWSTR lpszServiceName address of name of service
1492 * LPHANDLER_FUNCTION lpHandlerProc address of handler function
1493 * Variables :
1494 * Result :
1495 * Remark :
1496 * Status :
1497 *
1498 * Author : SvL
1499 *****************************************************************************/
1500
1501SERVICE_STATUS_HANDLE WIN32API RegisterServiceCtrlHandlerW(LPCWSTR lpszServiceName,
1502 LPHANDLER_FUNCTION lpHandlerProc)
1503{
1504 SC_HANDLE hSCMgr, hService;
1505
1506 dprintf(("ADVAPI32: RegisterServiceCtrlHandlerW(%s,%08xh) not implemented (FAKED)",
1507 lpszServiceName,
1508 lpHandlerProc));
1509
1510 //Doesn't work for services of type
1511 if(lpszServiceName == NULL) {
1512 SetLastError(ERROR_INVALID_NAME);
1513 return 0;
1514 }
1515 hSCMgr = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1516 hService = OpenServiceW(hSCMgr, lpszServiceName, SERVICE_ALL_ACCESS);
1517 if(hService == 0) {
1518 SetLastError(ERROR_INVALID_NAME);
1519 return 0;
1520 }
1521 CloseServiceHandle(hSCMgr);
1522 //TODO: Start thread with ctrl handler
1523 SetLastError(0);
1524 return hService;
1525}
1526
1527/*****************************************************************************
1528 * Name : SetServiceBits
1529 * Purpose : The SetServiceBits function registers a service's service type
1530 * with the Service Control Manager and the Server service. The
1531 * Server service can then announce the registered service type
1532 * as one it currently supports. The LAN Manager functions
1533 * NetServerGetInfo and NetServerEnum obtain a specified machine's
1534 * supported service types.
1535 * A service type is represented as a set of bit flags; the
1536 * SetServiceBits function sets or clears combinations of those bit flags.
1537 * Parameters: SERVICE_STATUS_HANDLE hServiceStatus service status handle
1538 * DWORD dwServiceBits service type bits to set or clear
1539 * BOOL bSetBitsOn flag to set or clear the service type bits
1540 * BOOL bUpdateImmediately flag to announce server type immediately
1541 * Variables :
1542 * Result :
1543 * Remark :
1544 * Status :
1545 *
1546 * Author : SvL
1547 *****************************************************************************/
1548
1549BOOL WIN32API SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus,
1550 DWORD dwServiceBits,
1551 BOOL bSetBitsOn,
1552 BOOL bUpdateImmediately)
1553{
1554 ULONG size, keytype, servicebits;
1555
1556 dprintf(("ADVAPI32: SetServiceBits(%08xh,%08xh,%08xh,%08xh) not correctly implemented",
1557 hServiceStatus,
1558 dwServiceBits,
1559 bSetBitsOn,
1560 bUpdateImmediately));
1561
1562 if(CheckServiceHandle(hServiceStatus) == FALSE) {
1563 SetLastError(ERROR_INVALID_PARAMETER);
1564 return FALSE;
1565 }
1566 //According to the Platform SDK these bits are reserved by MS and we should return
1567 //ERROR_INVALID_DATA
1568 if(dwServiceBits & 0xC00F3F7B) {
1569 SetLastError(ERROR_INVALID_DATA);
1570 return FALSE;
1571 }
1572
1573 size = sizeof(DWORD);
1574 keytype = REG_DWORD;
1575 if(RegQueryValueExA((HKEY)hServiceStatus, REG_SERVICE_BITS, 0, &keytype, (LPBYTE)&servicebits, &size)) {
1576 servicebits = 0;
1577 }
1578 if(bSetBitsOn) {
1579 servicebits |= dwServiceBits;
1580 }
1581 else servicebits &= (~dwServiceBits);
1582
1583 if(!RegSetValueExA((HKEY)hServiceStatus, REG_SERVICE_BITS, 0, REG_DWORD, (LPBYTE)&servicebits, sizeof(DWORD))) {
1584 SetLastError(0);
1585 return TRUE;
1586 }
1587 return (FALSE); /* signal failure */
1588}
1589
1590/*****************************************************************************
1591 * Name : SetServiceStatus
1592 * Purpose : The SetServiceStatus function updates the service control
1593 * manager's status information for the calling service.
1594 * Parameters: SERVICE_STATUS_HANDLE sshServiceStatus service status handle
1595 * LPSERVICE_STATUS lpssServiceStatus address of status structure
1596 * Variables :
1597 * Result :
1598 * Remark : Called from ServiceMain function (registered with RegisterServiceCtrlHandler)
1599 * Status :
1600 *
1601 * Author : SvL
1602 *****************************************************************************/
1603
1604BOOL WIN32API SetServiceStatus(SERVICE_STATUS_HANDLE sshServiceStatus,
1605 LPSERVICE_STATUS lpssServiceStatus)
1606{
1607 dprintf(("ADVAPI32: SetServiceStatus(%08xh,%08xh) not implemented correctly.\n",
1608 sshServiceStatus,
1609 lpssServiceStatus));
1610
1611 if(CheckServiceHandle(sshServiceStatus) == FALSE) {
1612 SetLastError(ERROR_INVALID_PARAMETER);
1613 return FALSE;
1614 }
1615
1616 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_TYPE, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwServiceType, sizeof(DWORD));
1617 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_STATUS, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwCurrentState, sizeof(DWORD));
1618 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_CONTROLS_ACCEPTED, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwControlsAccepted, sizeof(DWORD));
1619
1620 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_EXITCODE, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwWin32ExitCode, sizeof(DWORD));
1621 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_SPECIFIC_EXITCODE, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwServiceSpecificExitCode, sizeof(DWORD));
1622
1623 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_CHECKPOINT, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwCheckPoint, sizeof(DWORD));
1624 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_WAITHINT, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwWaitHint, sizeof(DWORD));
1625
1626 SetLastError(0);
1627 return TRUE;
1628}
1629
1630/*****************************************************************************
1631 * Name : QueryServiceStatus
1632 * Purpose : The QueryServiceStatus function retrieves the current status of
1633 * the specified service.
1634 * Parameters: SC_HANDLE schService handle of service
1635 * LPSERVICE_STATUS lpssServiceStatus address of service status structure
1636 * Variables :
1637 * Result :
1638 * Remark :
1639 * Status :
1640 *
1641 * Author : SvL
1642 *****************************************************************************/
1643
1644BOOL WIN32API QueryServiceStatus(SC_HANDLE schService,
1645 LPSERVICE_STATUS lpssServiceStatus)
1646{
1647 DWORD size, keytype;
1648
1649 dprintf(("ADVAPI32: QueryServiceStatus(%08xh,%08xh) not correctly implemented.\n",
1650 schService,
1651 lpssServiceStatus));
1652
1653 if(CheckServiceHandle(schService) == FALSE) {
1654 SetLastError(ERROR_INVALID_PARAMETER);
1655 return FALSE;
1656 }
1657
1658 memset(lpssServiceStatus, 0, sizeof(SERVICE_STATUS));
1659
1660 size = sizeof(DWORD);
1661 keytype = REG_DWORD;
1662 RegQueryValueExA((HKEY)schService, REG_SERVICE_TYPE, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwServiceType, &size);
1663
1664 size = sizeof(DWORD);
1665 keytype = REG_DWORD;
1666 RegQueryValueExA((HKEY)schService, REG_SERVICE_STATUS, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwCurrentState, &size);
1667
1668 size = sizeof(DWORD);
1669 keytype = REG_DWORD;
1670 RegQueryValueExA((HKEY)schService, REG_SERVICE_CONTROLS_ACCEPTED, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwControlsAccepted, &size);
1671
1672 size = sizeof(DWORD);
1673 keytype = REG_DWORD;
1674 RegQueryValueExA((HKEY)schService, REG_SERVICE_EXITCODE, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwWin32ExitCode, &size);
1675
1676 size = sizeof(DWORD);
1677 keytype = REG_DWORD;
1678 RegQueryValueExA((HKEY)schService, REG_SERVICE_SPECIFIC_EXITCODE, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwServiceSpecificExitCode, &size);
1679
1680 size = sizeof(DWORD);
1681 keytype = REG_DWORD;
1682 RegQueryValueExA((HKEY)schService, REG_SERVICE_CHECKPOINT, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwCheckPoint, &size);
1683
1684 size = sizeof(DWORD);
1685 keytype = REG_DWORD;
1686 RegQueryValueExA((HKEY)schService, REG_SERVICE_WAITHINT, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwWaitHint, &size);
1687
1688 SetLastError(0);
1689 return TRUE;
1690}
Note: See TracBrowser for help on using the repository browser.