source: trunk/src/advapi32/service.cpp@ 3830

Last change on this file since 3830 was 2343, checked in by sandervl, 26 years ago

Security api updates

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