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

Last change on this file since 5890 was 5748, checked in by sandervl, 24 years ago

added systemfunctionxx stubs

File size: 66.0 KB
Line 
1/* $Id: service.cpp,v 1.6 2001-05-19 11:13:05 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 SetLastError (ERROR_ACCESS_DENIED);
1187 return (FALSE); /* signal failure */
1188}
1189
1190
1191/*****************************************************************************
1192 * Name : EnumServicesStatusW
1193 * Purpose : The EnumServicesStatus function enumerates services in the specified
1194 * service control manager database. The name and status of each service are provided.
1195 * Parameters: SC_HANDLE hSCManager handle of service control manager database
1196 * DWORD dwServiceType type of services to enumerate
1197 * DWORD dwServiceState state of services to enumerate
1198 * LPENUM_SERVICE_STATUS lpServices address of service status buffer
1199 * DWORD cbBufSize size of service status buffer
1200 * LPDWORD pcbBytesNeeded address of variable for bytes needed
1201 * LPDWORD lpServicesReturned address of variable for number returned
1202 * LPDWORD lpResumeHandle address of variable for next entry
1203 * Variables :
1204 * Result :
1205 * Remark :
1206 * Status : UNTESTED STUB
1207 *
1208 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1209 *****************************************************************************/
1210
1211BOOL WIN32API EnumServicesStatusW(SC_HANDLE hSCManager,
1212 DWORD dwServiceType,
1213 DWORD dwServiceState,
1214 LPENUM_SERVICE_STATUSW lpServices,
1215 DWORD cbBufSize,
1216 LPDWORD pcbBytesNeeded,
1217 LPDWORD lpServicesReturned,
1218 LPDWORD lpResumeHandle)
1219{
1220 dprintf(("ADVAPI32: EnumServicesStatusW(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1221 hSCManager,
1222 dwServiceType,
1223 dwServiceState,
1224 lpServices,
1225 cbBufSize,
1226 pcbBytesNeeded,
1227 lpServicesReturned,
1228 lpResumeHandle));
1229
1230 SetLastError (ERROR_ACCESS_DENIED);
1231 return (FALSE); /* signal failure */
1232}
1233
1234/*****************************************************************************
1235 * Name : GetServiceKeyNameA
1236 * Purpose : The GetServiceKeyName function obtains the service name that is
1237 * associated with a particular service's display name. The service
1238 * name is the same as the service's registry key name.
1239 * Parameters: SC_HANDLE hSCManager handle to a service control manager database
1240 * LPCSTR lpDisplayName the service's display name
1241 * LPTSTR lpServiceName buffer to receive the service name
1242 * LPDWORD lpcchBuffer size of service name buffer and service name
1243 * Variables :
1244 * Result :
1245 * Remark :
1246 * Status : UNTESTED STUB
1247 *
1248 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1249 *****************************************************************************/
1250
1251BOOL WIN32API GetServiceKeyNameA(SC_HANDLE hSCManager,
1252 LPCSTR lpDisplayName,
1253 LPTSTR lpServiceName,
1254 LPDWORD lpcchBuffer)
1255{
1256 dprintf(("ADVAPI32: GetServiceKeyNameA(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1257 hSCManager,
1258 lpDisplayName,
1259 lpServiceName,
1260 lpcchBuffer));
1261
1262 return (FALSE); /* signal failure */
1263}
1264
1265
1266/*****************************************************************************
1267 * Name : GetServiceKeyNameW
1268 * Purpose : The GetServiceKeyName function obtains the service name that is
1269 * associated with a particular service's display name. The service
1270 * name is the same as the service's registry key name.
1271 * Parameters: SC_HANDLE hSCManager handle to a service control manager database
1272 * LPCWSTR lpDisplayName the service's display name
1273 * LPWSTR lpServiceName buffer to receive the service name
1274 * LPDWORD lpcchBuffer size of service name buffer and service name
1275 * Variables :
1276 * Result :
1277 * Remark :
1278 * Status : UNTESTED STUB
1279 *
1280 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1281 *****************************************************************************/
1282
1283BOOL WIN32API GetServiceKeyNameW(SC_HANDLE hSCManager,
1284 LPCWSTR lpDisplayName,
1285 LPWSTR lpServiceName,
1286 LPDWORD lpcchBuffer)
1287{
1288 dprintf(("ADVAPI32: GetServiceKeyNameW(%08xh,%08xh,%08xh,%08xh) not implemented.\n",
1289 hSCManager,
1290 lpDisplayName,
1291 lpServiceName,
1292 lpcchBuffer));
1293
1294 return (FALSE); /* signal failure */
1295}
1296
1297/*****************************************************************************
1298 * Name : LockServiceDatabase
1299 * Purpose : The LockServiceDatabase function locks a specified database.
1300 * Parameters: SC_HANDLE hSCManager handle of service control manager database
1301 * Variables :
1302 * Result :
1303 * Remark :
1304 * Status : UNTESTED STUB
1305 *
1306 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1307 *****************************************************************************/
1308
1309SC_LOCK WIN32API LockServiceDatabase(SC_HANDLE hSCManager)
1310{
1311 dprintf(("ADVAPI32: LockServiceDatabase(%08xh) not implemented.\n",
1312 hSCManager));
1313
1314 return 0; /* signal failure */
1315}
1316
1317/*****************************************************************************
1318 * Name : UnlockServiceDatabase
1319 * Purpose : The UnlockServiceDatabase function unlocks a service control
1320 * manager database by releasing the specified lock.
1321 * Parameters: SC_LOCK sclLock service control manager database lock to be released
1322 * Variables :
1323 * Result :
1324 * Remark :
1325 * Status : UNTESTED STUB
1326 *
1327 * Author : Patrick Haller [Tue, 1998/06/16 23:00]
1328
1329 *****************************************************************************/
1330
1331BOOL WIN32API UnlockServiceDatabase(SC_LOCK sclLock)
1332{
1333 dprintf(("ADVAPI32: UnlockServiceDatabase(%08xh) not implemented.\n",
1334 sclLock));
1335
1336 return (FALSE); /* signal failure */
1337}
1338
1339//******************************************************************************
1340//Helper for StartServiceCtrlDispatcherA/W; counts nr or arguments in cmd line
1341//******************************************************************************
1342ULONG CountNrArgs(char *cmdline)
1343{
1344 char *cmd = cmdline;
1345 ULONG nrargs = 0;
1346
1347 while(*cmd == ' ') cmd++; //skip leading spaces
1348 while(*cmd != 0) {
1349 while(*cmd != ' ' && *cmd != 0) cmd++; //skip non-space chars
1350 while(*cmd == ' ' && *cmd != 0) cmd++; //skip spaces
1351 nrargs++;
1352 }
1353 return nrargs;
1354}
1355
1356/*****************************************************************************
1357 * Name : StartServiceCtrlDispatcherW
1358 * Purpose : The StartServiceCtrlDispatcher function connects the main thread
1359 * of a service process to the service control manager, which causes
1360 * the thread to be the service control dispatcher thread for the calling process.
1361 * Parameters: LPSERVICE_TABLE_ENTRY lpsteServiceTable address of service table
1362 * Variables :
1363 * Result :
1364 * Remark :
1365 * Status :
1366 *
1367 * Author : SvL
1368 *****************************************************************************/
1369
1370BOOL WIN32API StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW lpsteServiceTable)
1371{
1372 ULONG nrArgs = 0;
1373 LPWSTR cmdline;
1374
1375 dprintf(("ADVAPI32: StartServiceCtrlDispatcherW(%x)", lpsteServiceTable));
1376
1377 if(fServiceCtrlDispatcherStarted == TRUE) {
1378 SetLastError(ERROR_SERVICE_ALREADY_RUNNING);
1379 return FALSE;
1380 }
1381 fServiceCtrlDispatcherStarted = TRUE;
1382 if(lpsteServiceTable->lpServiceProc == NULL) {
1383 SetLastError(ERROR_INVALID_DATA); //or invalid parameter?
1384 return FALSE;
1385 }
1386 while(lpsteServiceTable->lpServiceProc) {
1387 cmdline = (LPWSTR)GetCommandLineW();
1388 nrArgs = CountNrArgs((LPSTR)GetCommandLineA());
1389 lpsteServiceTable->lpServiceProc(nrArgs, cmdline);
1390 lpsteServiceTable++; //next service entrypoint
1391 }
1392 SetLastError(0);
1393 return TRUE;
1394}
1395
1396/*****************************************************************************
1397 * Name : StartServiceCtrlDispatcherA
1398 * Purpose : The StartServiceCtrlDispatcher function connects the main thread
1399 * of a service process to the service control manager, which causes
1400 * the thread to be the service control dispatcher thread for the calling process.
1401 * Parameters: LPSERVICE_TABLE_ENTRY lpsteServiceTable address of service table
1402 * Variables :
1403 * Result :
1404 * Remark :
1405 * Status :
1406 *
1407 * Author : SvL
1408 *****************************************************************************/
1409
1410BOOL WIN32API StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA lpsteServiceTable)
1411{
1412 ULONG nrArgs = 0;
1413 LPSTR cmdline;
1414
1415 dprintf(("ADVAPI32: StartServiceCtrlDispatcherA(%08xh)", lpsteServiceTable));
1416
1417 if(fServiceCtrlDispatcherStarted == TRUE) {
1418 SetLastError(ERROR_SERVICE_ALREADY_RUNNING);
1419 return FALSE;
1420 }
1421 fServiceCtrlDispatcherStarted = TRUE;
1422 if(lpsteServiceTable->lpServiceProc == NULL) {
1423 SetLastError(ERROR_INVALID_DATA); //or invalid parameter?
1424 return FALSE;
1425 }
1426 while(lpsteServiceTable->lpServiceProc) {
1427 cmdline = (LPSTR)GetCommandLineA();
1428 nrArgs = CountNrArgs(cmdline);
1429 lpsteServiceTable->lpServiceProc(nrArgs, cmdline);
1430 lpsteServiceTable++; //next service entrypoint
1431 }
1432 SetLastError(0);
1433 return TRUE;
1434}
1435
1436/*****************************************************************************
1437 * Name : RegisterServiceCtrlHandlerA
1438 * Purpose : The RegisterServiceCtrlHandler function registers a function to
1439 * handle service control requests for a service.
1440 * Parameters: LPCSTR lpszServiceName address of name of service
1441 * LPHANDLER_FUNCTION lpHandlerProc address of handler function
1442 * Variables :
1443 * Result :
1444 * Remark :
1445 * Status :
1446 *
1447 * Author : SvL
1448 *****************************************************************************/
1449
1450SERVICE_STATUS_HANDLE WIN32API RegisterServiceCtrlHandlerA(LPCSTR lpszServiceName,
1451 LPHANDLER_FUNCTION lpHandlerProc)
1452{
1453 SC_HANDLE hSCMgr, hService;
1454
1455 dprintf(("ADVAPI32: RegisterServiceCtrlHandlerA(%s,%08xh) not implemented (FAKED)",
1456 lpszServiceName,
1457 lpHandlerProc));
1458
1459 //Doesn't work for services of type
1460 if(lpszServiceName == NULL) {
1461 SetLastError(ERROR_INVALID_NAME);
1462 return 0;
1463 }
1464 hSCMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1465 hService = OpenServiceA(hSCMgr, lpszServiceName, SERVICE_ALL_ACCESS);
1466 if(hService == 0) {
1467 SetLastError(ERROR_INVALID_NAME);
1468 return 0;
1469 }
1470 CloseServiceHandle(hSCMgr);
1471 //TODO: Start thread with ctrl handler
1472 SetLastError(0);
1473 return hService;
1474}
1475
1476
1477/*****************************************************************************
1478 * Name : RegisterServiceCtrlHandlerW
1479 * Purpose : The RegisterServiceCtrlHandler function registers a function to
1480 * handle service control requests for a service.
1481 * Parameters: LPCWSTR lpszServiceName address of name of service
1482 * LPHANDLER_FUNCTION lpHandlerProc address of handler function
1483 * Variables :
1484 * Result :
1485 * Remark :
1486 * Status :
1487 *
1488 * Author : SvL
1489 *****************************************************************************/
1490
1491SERVICE_STATUS_HANDLE WIN32API RegisterServiceCtrlHandlerW(LPCWSTR lpszServiceName,
1492 LPHANDLER_FUNCTION lpHandlerProc)
1493{
1494 SC_HANDLE hSCMgr, hService;
1495
1496 dprintf(("ADVAPI32: RegisterServiceCtrlHandlerW(%s,%08xh) not implemented (FAKED)",
1497 lpszServiceName,
1498 lpHandlerProc));
1499
1500 //Doesn't work for services of type
1501 if(lpszServiceName == NULL) {
1502 SetLastError(ERROR_INVALID_NAME);
1503 return 0;
1504 }
1505 hSCMgr = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1506 hService = OpenServiceW(hSCMgr, lpszServiceName, SERVICE_ALL_ACCESS);
1507 if(hService == 0) {
1508 SetLastError(ERROR_INVALID_NAME);
1509 return 0;
1510 }
1511 CloseServiceHandle(hSCMgr);
1512 //TODO: Start thread with ctrl handler
1513 SetLastError(0);
1514 return hService;
1515}
1516
1517/*****************************************************************************
1518 * Name : SetServiceBits
1519 * Purpose : The SetServiceBits function registers a service's service type
1520 * with the Service Control Manager and the Server service. The
1521 * Server service can then announce the registered service type
1522 * as one it currently supports. The LAN Manager functions
1523 * NetServerGetInfo and NetServerEnum obtain a specified machine's
1524 * supported service types.
1525 * A service type is represented as a set of bit flags; the
1526 * SetServiceBits function sets or clears combinations of those bit flags.
1527 * Parameters: SERVICE_STATUS_HANDLE hServiceStatus service status handle
1528 * DWORD dwServiceBits service type bits to set or clear
1529 * BOOL bSetBitsOn flag to set or clear the service type bits
1530 * BOOL bUpdateImmediately flag to announce server type immediately
1531 * Variables :
1532 * Result :
1533 * Remark :
1534 * Status :
1535 *
1536 * Author : SvL
1537 *****************************************************************************/
1538
1539BOOL WIN32API SetServiceBits(SERVICE_STATUS_HANDLE hServiceStatus,
1540 DWORD dwServiceBits,
1541 BOOL bSetBitsOn,
1542 BOOL bUpdateImmediately)
1543{
1544 ULONG size, keytype, servicebits;
1545
1546 dprintf(("ADVAPI32: SetServiceBits(%08xh,%08xh,%08xh,%08xh) not correctly implemented",
1547 hServiceStatus,
1548 dwServiceBits,
1549 bSetBitsOn,
1550 bUpdateImmediately));
1551
1552 if(CheckServiceHandle(hServiceStatus) == FALSE) {
1553 SetLastError(ERROR_INVALID_PARAMETER);
1554 return FALSE;
1555 }
1556 //According to the Platform SDK these bits are reserved by MS and we should return
1557 //ERROR_INVALID_DATA
1558 if(dwServiceBits & 0xC00F3F7B) {
1559 SetLastError(ERROR_INVALID_DATA);
1560 return FALSE;
1561 }
1562
1563 size = sizeof(DWORD);
1564 keytype = REG_DWORD;
1565 if(RegQueryValueExA((HKEY)hServiceStatus, REG_SERVICE_BITS, 0, &keytype, (LPBYTE)&servicebits, &size)) {
1566 servicebits = 0;
1567 }
1568 if(bSetBitsOn) {
1569 servicebits |= dwServiceBits;
1570 }
1571 else servicebits &= (~dwServiceBits);
1572
1573 if(!RegSetValueExA((HKEY)hServiceStatus, REG_SERVICE_BITS, 0, REG_DWORD, (LPBYTE)&servicebits, sizeof(DWORD))) {
1574 SetLastError(0);
1575 return TRUE;
1576 }
1577 return (FALSE); /* signal failure */
1578}
1579
1580/*****************************************************************************
1581 * Name : SetServiceStatus
1582 * Purpose : The SetServiceStatus function updates the service control
1583 * manager's status information for the calling service.
1584 * Parameters: SERVICE_STATUS_HANDLE sshServiceStatus service status handle
1585 * LPSERVICE_STATUS lpssServiceStatus address of status structure
1586 * Variables :
1587 * Result :
1588 * Remark : Called from ServiceMain function (registered with RegisterServiceCtrlHandler)
1589 * Status :
1590 *
1591 * Author : SvL
1592 *****************************************************************************/
1593
1594BOOL WIN32API SetServiceStatus(SERVICE_STATUS_HANDLE sshServiceStatus,
1595 LPSERVICE_STATUS lpssServiceStatus)
1596{
1597 dprintf(("ADVAPI32: SetServiceStatus(%08xh,%08xh) not implemented correctly.\n",
1598 sshServiceStatus,
1599 lpssServiceStatus));
1600
1601 if(CheckServiceHandle(sshServiceStatus) == FALSE) {
1602 SetLastError(ERROR_INVALID_PARAMETER);
1603 return FALSE;
1604 }
1605
1606 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_TYPE, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwServiceType, sizeof(DWORD));
1607 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_STATUS, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwCurrentState, sizeof(DWORD));
1608 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_CONTROLS_ACCEPTED, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwControlsAccepted, sizeof(DWORD));
1609
1610 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_EXITCODE, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwWin32ExitCode, sizeof(DWORD));
1611 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_SPECIFIC_EXITCODE, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwServiceSpecificExitCode, sizeof(DWORD));
1612
1613 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_CHECKPOINT, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwCheckPoint, sizeof(DWORD));
1614 RegSetValueExA((HKEY)sshServiceStatus, REG_SERVICE_WAITHINT, 0, REG_DWORD, (LPBYTE)&lpssServiceStatus->dwWaitHint, sizeof(DWORD));
1615
1616 SetLastError(0);
1617 return TRUE;
1618}
1619
1620/*****************************************************************************
1621 * Name : QueryServiceStatus
1622 * Purpose : The QueryServiceStatus function retrieves the current status of
1623 * the specified service.
1624 * Parameters: SC_HANDLE schService handle of service
1625 * LPSERVICE_STATUS lpssServiceStatus address of service status structure
1626 * Variables :
1627 * Result :
1628 * Remark :
1629 * Status :
1630 *
1631 * Author : SvL
1632 *****************************************************************************/
1633
1634BOOL WIN32API QueryServiceStatus(SC_HANDLE schService,
1635 LPSERVICE_STATUS lpssServiceStatus)
1636{
1637 DWORD size, keytype;
1638
1639 dprintf(("ADVAPI32: QueryServiceStatus(%08xh,%08xh) not correctly implemented.\n",
1640 schService,
1641 lpssServiceStatus));
1642
1643 if(CheckServiceHandle(schService) == FALSE) {
1644 SetLastError(ERROR_INVALID_PARAMETER);
1645 return FALSE;
1646 }
1647
1648 memset(lpssServiceStatus, 0, sizeof(SERVICE_STATUS));
1649
1650 size = sizeof(DWORD);
1651 keytype = REG_DWORD;
1652 RegQueryValueExA((HKEY)schService, REG_SERVICE_TYPE, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwServiceType, &size);
1653
1654 size = sizeof(DWORD);
1655 keytype = REG_DWORD;
1656 RegQueryValueExA((HKEY)schService, REG_SERVICE_STATUS, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwCurrentState, &size);
1657
1658 size = sizeof(DWORD);
1659 keytype = REG_DWORD;
1660 RegQueryValueExA((HKEY)schService, REG_SERVICE_CONTROLS_ACCEPTED, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwControlsAccepted, &size);
1661
1662 size = sizeof(DWORD);
1663 keytype = REG_DWORD;
1664 RegQueryValueExA((HKEY)schService, REG_SERVICE_EXITCODE, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwWin32ExitCode, &size);
1665
1666 size = sizeof(DWORD);
1667 keytype = REG_DWORD;
1668 RegQueryValueExA((HKEY)schService, REG_SERVICE_SPECIFIC_EXITCODE, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwServiceSpecificExitCode, &size);
1669
1670 size = sizeof(DWORD);
1671 keytype = REG_DWORD;
1672 RegQueryValueExA((HKEY)schService, REG_SERVICE_CHECKPOINT, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwCheckPoint, &size);
1673
1674 size = sizeof(DWORD);
1675 keytype = REG_DWORD;
1676 RegQueryValueExA((HKEY)schService, REG_SERVICE_WAITHINT, 0, &keytype, (LPBYTE)&lpssServiceStatus->dwWaitHint, &size);
1677
1678 SetLastError(0);
1679 return TRUE;
1680}
Note: See TracBrowser for help on using the repository browser.