5 /* INCLUDES ****************************************************************/
14 /* GLOBALS *****************************************************************/
16 #define MANAGER_TAG 0x72674D68 /* 'hMgr' */
17 #define SERVICE_TAG 0x63765368 /* 'hSvc' */
19 typedef struct _SCMGR_HANDLE
27 typedef struct _MANAGER_HANDLE
31 /* FIXME: Insert more data here */
33 WCHAR DatabaseName
[1];
34 } MANAGER_HANDLE
, *PMANAGER_HANDLE
;
37 typedef struct _SERVICE_HANDLE
42 PSERVICE ServiceEntry
;
44 /* FIXME: Insert more data here */
46 } SERVICE_HANDLE
, *PSERVICE_HANDLE
;
49 #define SC_MANAGER_READ \
50 (STANDARD_RIGHTS_READ | \
51 SC_MANAGER_QUERY_LOCK_STATUS | \
52 SC_MANAGER_ENUMERATE_SERVICE)
54 #define SC_MANAGER_WRITE \
55 (STANDARD_RIGHTS_WRITE | \
56 SC_MANAGER_MODIFY_BOOT_CONFIG | \
57 SC_MANAGER_CREATE_SERVICE)
59 #define SC_MANAGER_EXECUTE \
60 (STANDARD_RIGHTS_EXECUTE | \
62 SC_MANAGER_ENUMERATE_SERVICE | \
63 SC_MANAGER_CONNECT | \
64 SC_MANAGER_CREATE_SERVICE)
67 #define SERVICE_READ \
68 (STANDARD_RIGHTS_READ | \
69 SERVICE_INTERROGATE | \
70 SERVICE_ENUMERATE_DEPENDENTS | \
71 SERVICE_QUERY_STATUS | \
74 #define SERVICE_WRITE \
75 (STANDARD_RIGHTS_WRITE | \
76 SERVICE_CHANGE_CONFIG)
78 #define SERVICE_EXECUTE \
79 (STANDARD_RIGHTS_EXECUTE | \
80 SERVICE_USER_DEFINED_CONTROL | \
81 SERVICE_PAUSE_CONTINUE | \
86 /* VARIABLES ***************************************************************/
88 static GENERIC_MAPPING
89 ScmManagerMapping
= {SC_MANAGER_READ
,
92 SC_MANAGER_ALL_ACCESS
};
94 static GENERIC_MAPPING
95 ScmServiceMapping
= {SERVICE_READ
,
98 SC_MANAGER_ALL_ACCESS
};
101 /* FUNCTIONS ***************************************************************/
104 ScmStartRpcServer(VOID
)
108 DPRINT("ScmStartRpcServer() called");
110 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
114 if (Status
!= RPC_S_OK
)
116 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
120 Status
= RpcServerRegisterIf(svcctl_ServerIfHandle
,
123 if (Status
!= RPC_S_OK
)
125 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
129 Status
= RpcServerListen(1, 20, TRUE
);
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
136 DPRINT("ScmStartRpcServer() done");
141 ScmCreateManagerHandle(LPWSTR lpDatabaseName
,
146 if (lpDatabaseName
== NULL
)
147 lpDatabaseName
= SERVICES_ACTIVE_DATABASEW
;
149 Ptr
= (MANAGER_HANDLE
*) HeapAlloc(GetProcessHeap(),
151 sizeof(MANAGER_HANDLE
) + wcslen(lpDatabaseName
) * sizeof(WCHAR
));
153 return ERROR_NOT_ENOUGH_MEMORY
;
155 Ptr
->Handle
.Tag
= MANAGER_TAG
;
156 Ptr
->Handle
.RefCount
= 1;
158 /* FIXME: initialize more data here */
160 wcscpy(Ptr
->DatabaseName
, lpDatabaseName
);
162 *Handle
= (SC_HANDLE
)Ptr
;
164 return ERROR_SUCCESS
;
169 ScmCreateServiceHandle(PSERVICE lpServiceEntry
,
174 Ptr
= (SERVICE_HANDLE
*) HeapAlloc(GetProcessHeap(),
176 sizeof(SERVICE_HANDLE
));
178 return ERROR_NOT_ENOUGH_MEMORY
;
180 Ptr
->Handle
.Tag
= SERVICE_TAG
;
181 Ptr
->Handle
.RefCount
= 1;
183 /* FIXME: initialize more data here */
184 Ptr
->ServiceEntry
= lpServiceEntry
;
186 *Handle
= (SC_HANDLE
)Ptr
;
188 return ERROR_SUCCESS
;
193 ScmCheckAccess(SC_HANDLE Handle
,
194 DWORD dwDesiredAccess
)
196 PMANAGER_HANDLE hMgr
;
198 hMgr
= (PMANAGER_HANDLE
)Handle
;
199 if (hMgr
->Handle
.Tag
== MANAGER_TAG
)
201 RtlMapGenericMask(&dwDesiredAccess
,
204 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
206 return ERROR_SUCCESS
;
208 else if (hMgr
->Handle
.Tag
== SERVICE_TAG
)
210 RtlMapGenericMask(&dwDesiredAccess
,
213 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
215 return ERROR_SUCCESS
;
218 return ERROR_INVALID_HANDLE
;
223 ScmAssignNewTag(PSERVICE lpService
)
226 DPRINT("Assigning new tag to service %S\n", lpService
->lpServiceName
);
227 lpService
->dwTag
= 0;
228 return ERROR_SUCCESS
;
234 ScmrCloseServiceHandle(handle_t BindingHandle
,
235 unsigned int hScObject
)
237 PMANAGER_HANDLE hManager
;
239 DPRINT("ScmrCloseServiceHandle() called\n");
241 DPRINT("hScObject = %X\n", hScObject
);
244 return ERROR_INVALID_HANDLE
;
246 hManager
= (PMANAGER_HANDLE
)hScObject
;
247 if (hManager
->Handle
.Tag
== MANAGER_TAG
)
249 DPRINT("Found manager handle\n");
251 hManager
->Handle
.RefCount
--;
252 if (hManager
->Handle
.RefCount
== 0)
254 /* FIXME: add cleanup code */
256 HeapFree(GetProcessHeap(), 0, hManager
);
259 DPRINT("ScmrCloseServiceHandle() done\n");
260 return ERROR_SUCCESS
;
262 else if (hManager
->Handle
.Tag
== SERVICE_TAG
)
264 DPRINT("Found service handle\n");
266 hManager
->Handle
.RefCount
--;
267 if (hManager
->Handle
.RefCount
== 0)
269 /* FIXME: add cleanup code */
271 HeapFree(GetProcessHeap(), 0, hManager
);
274 DPRINT("ScmrCloseServiceHandle() done\n");
275 return ERROR_SUCCESS
;
278 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager
->Handle
.Tag
);
280 return ERROR_INVALID_HANDLE
;
286 ScmrControlService(handle_t BindingHandle
,
287 unsigned int hService
,
288 unsigned long dwControl
,
289 LPSERVICE_STATUS lpServiceStatus
)
291 PSERVICE_HANDLE hSvc
;
293 ACCESS_MASK DesiredAccess
;
294 DWORD dwError
= ERROR_SUCCESS
;
296 DPRINT("ScmrControlService() called\n");
299 return ERROR_SHUTDOWN_IN_PROGRESS
;
301 /* Check the service handle */
302 hSvc
= (PSERVICE_HANDLE
)hService
;
303 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
305 DPRINT1("Invalid handle tag!\n");
306 return ERROR_INVALID_HANDLE
;
309 /* Check access rights */
312 case SERVICE_CONTROL_STOP
:
313 DesiredAccess
= SERVICE_STOP
;
316 case SERVICE_CONTROL_PAUSE
:
317 case SERVICE_CONTROL_CONTINUE
:
318 DesiredAccess
= SERVICE_PAUSE_CONTINUE
;
321 case SERVICE_INTERROGATE
:
322 DesiredAccess
= SERVICE_INTERROGATE
;
326 if (dwControl
>= 128 && dwControl
<= 255)
327 DesiredAccess
= SERVICE_USER_DEFINED_CONTROL
;
329 DesiredAccess
= SERVICE_QUERY_CONFIG
|
330 SERVICE_CHANGE_CONFIG
|
331 SERVICE_QUERY_STATUS
|
333 SERVICE_PAUSE_CONTINUE
;
337 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
339 return ERROR_ACCESS_DENIED
;
341 /* Check the service entry point */
342 lpService
= hSvc
->ServiceEntry
;
343 if (lpService
== NULL
)
345 DPRINT1("lpService == NULL!\n");
346 return ERROR_INVALID_HANDLE
;
349 if (lpService
->Status
.dwServiceType
& SERVICE_DRIVER
)
351 /* Send control code to the driver */
352 dwError
= ScmControlDriver(lpService
,
358 /* Send control code to the service */
359 dwError
= ScmControlService(lpService
,
364 /* Return service status information */
365 RtlCopyMemory(lpServiceStatus
,
367 sizeof(SERVICE_STATUS
));
375 ScmrDeleteService(handle_t BindingHandle
,
376 unsigned int hService
)
378 PSERVICE_HANDLE hSvc
;
382 DPRINT("ScmrDeleteService() called\n");
385 return ERROR_SHUTDOWN_IN_PROGRESS
;
387 hSvc
= (PSERVICE_HANDLE
)hService
;
388 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
389 return ERROR_INVALID_HANDLE
;
391 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
392 STANDARD_RIGHTS_REQUIRED
))
393 return ERROR_ACCESS_DENIED
;
395 lpService
= hSvc
->ServiceEntry
;
396 if (lpService
== NULL
)
398 DPRINT1("lpService == NULL!\n");
399 return ERROR_INVALID_HANDLE
;
402 /* FIXME: Acquire service database lock exclusively */
404 if (lpService
->bDeleted
)
406 DPRINT1("The service has already been marked for delete!\n");
407 return ERROR_SERVICE_MARKED_FOR_DELETE
;
410 /* Mark service for delete */
411 lpService
->bDeleted
= TRUE
;
413 dwError
= ScmMarkServiceForDelete(lpService
);
415 /* FIXME: Release service database lock */
417 DPRINT("ScmrDeleteService() done\n");
425 ScmrLockServiceDatabase(handle_t BindingHandle
,
426 unsigned int hSCManager
,
429 PMANAGER_HANDLE hMgr
;
431 DPRINT("ScmrLockServiceDatabase() called\n");
435 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
436 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
437 return ERROR_INVALID_HANDLE
;
439 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
441 return ERROR_ACCESS_DENIED
;
443 // return ScmLockDatabase(0, hMgr->0xC, hLock);
445 /* FIXME: Lock the database */
446 *hLock
= 0x12345678; /* Dummy! */
448 return ERROR_SUCCESS
;
454 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
,
455 unsigned int hService
,
456 unsigned long dwSecurityInformation
,
457 unsigned char *lpSecurityDescriptor
,
458 unsigned long dwSecuityDescriptorSize
,
459 unsigned long *pcbBytesNeeded
)
462 PSERVICE_HANDLE hSvc
;
464 ULONG DesiredAccess
= 0;
469 DPRINT("ScmrQueryServiceObjectSecurity() called\n");
471 hSvc
= (PSERVICE_HANDLE
)hService
;
472 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
474 DPRINT1("Invalid handle tag!\n");
475 return ERROR_INVALID_HANDLE
;
478 if (dwSecurityInformation
& (DACL_SECURITY_INFORMATION
||
479 GROUP_SECURITY_INFORMATION
||
480 OWNER_SECURITY_INFORMATION
))
481 DesiredAccess
|= READ_CONTROL
;
483 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
484 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
486 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
489 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
490 return ERROR_ACCESS_DENIED
;
493 lpService
= hSvc
->ServiceEntry
;
494 if (lpService
== NULL
)
496 DPRINT1("lpService == NULL!\n");
497 return ERROR_INVALID_HANDLE
;
500 /* FIXME: Lock the service list */
502 Status
= RtlQuerySecurityObject(lpService
->lpSecurityDescriptor
,
503 dwSecurityInformation
,
504 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
505 dwSecuityDescriptorSize
,
508 /* FIXME: Unlock the service list */
510 if (NT_SUCCESS(Status
))
512 *pcbBytesNeeded
= dwBytesNeeded
;
513 dwError
= STATUS_SUCCESS
;
515 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
517 *pcbBytesNeeded
= dwBytesNeeded
;
518 dwError
= ERROR_INSUFFICIENT_BUFFER
;
520 else if (Status
== STATUS_BAD_DESCRIPTOR_FORMAT
)
522 dwError
= ERROR_GEN_FAILURE
;
526 dwError
= RtlNtStatusToDosError(Status
);
531 DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
532 return ERROR_CALL_NOT_IMPLEMENTED
;
538 ScmrSetServiceObjectSecurity(handle_t BindingHandle
,
539 unsigned int hService
,
540 unsigned long dwSecurityInformation
,
541 unsigned char *lpSecurityDescriptor
,
542 unsigned long dwSecuityDescriptorSize
)
544 PSERVICE_HANDLE hSvc
;
546 ULONG DesiredAccess
= 0;
547 HANDLE hToken
= NULL
;
552 DPRINT1("ScmrSetServiceObjectSecurity() called\n");
554 hSvc
= (PSERVICE_HANDLE
)hService
;
555 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
557 DPRINT1("Invalid handle tag!\n");
558 return ERROR_INVALID_HANDLE
;
561 if (dwSecurityInformation
== 0 ||
562 dwSecurityInformation
& ~(OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
563 | DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
))
564 return ERROR_INVALID_PARAMETER
;
566 if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
))
567 return ERROR_INVALID_PARAMETER
;
569 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
570 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
572 if (dwSecurityInformation
& DACL_SECURITY_INFORMATION
)
573 DesiredAccess
|= WRITE_DAC
;
575 if (dwSecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
576 DesiredAccess
|= WRITE_OWNER
;
578 if ((dwSecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
579 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Owner
== NULL
))
580 return ERROR_INVALID_PARAMETER
;
582 if ((dwSecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
583 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Group
== NULL
))
584 return ERROR_INVALID_PARAMETER
;
586 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
589 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
590 return ERROR_ACCESS_DENIED
;
593 lpService
= hSvc
->ServiceEntry
;
594 if (lpService
== NULL
)
596 DPRINT1("lpService == NULL!\n");
597 return ERROR_INVALID_HANDLE
;
600 if (lpService
->bDeleted
)
601 return ERROR_SERVICE_MARKED_FOR_DELETE
;
603 RpcImpersonateClient(NULL
);
605 Status
= NtOpenThreadToken(NtCurrentThread(),
609 if (!NT_SUCCESS(Status
))
610 return RtlNtStatusToDosError(Status
);
614 /* FIXME: Lock service database */
617 Status
= RtlSetSecurityObject(dwSecurityInformation
,
618 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
619 &lpService
->lpSecurityDescriptor
,
622 if (!NT_SUCCESS(Status
))
624 dwError
= RtlNtStatusToDosError(Status
);
629 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
630 READ_CONTROL
| KEY_CREATE_SUB_KEY
| KEY_SET_VALUE
,
632 if (dwError
!= ERROR_SUCCESS
)
635 DPRINT1("Stub: ScmrSetServiceObjectSecurity() is unimplemented\n");
636 dwError
= ERROR_SUCCESS
;
637 // dwError = ScmWriteSecurityDescriptor(hServiceKey,
638 // lpService->lpSecurityDescriptor);
640 RegFlushKey(hServiceKey
);
641 RegCloseKey(hServiceKey
);
648 /* FIXME: Unlock service database */
650 DPRINT("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError
);
658 ScmrQueryServiceStatus(handle_t BindingHandle
,
659 unsigned int hService
,
660 LPSERVICE_STATUS lpServiceStatus
)
662 PSERVICE_HANDLE hSvc
;
665 DPRINT("ScmrQueryServiceStatus() called\n");
668 return ERROR_SHUTDOWN_IN_PROGRESS
;
670 hSvc
= (PSERVICE_HANDLE
)hService
;
671 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
673 DPRINT1("Invalid handle tag!\n");
674 return ERROR_INVALID_HANDLE
;
677 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
678 SERVICE_QUERY_STATUS
))
680 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
681 return ERROR_ACCESS_DENIED
;
684 lpService
= hSvc
->ServiceEntry
;
685 if (lpService
== NULL
)
687 DPRINT1("lpService == NULL!\n");
688 return ERROR_INVALID_HANDLE
;
691 /* Return service status information */
692 RtlCopyMemory(lpServiceStatus
,
694 sizeof(SERVICE_STATUS
));
696 return ERROR_SUCCESS
;
702 ScmrSetServiceStatus(handle_t BindingHandle
,
703 unsigned long hServiceStatus
,
704 LPSERVICE_STATUS lpServiceStatus
)
708 DPRINT("ScmrSetServiceStatus() called\n");
711 return ERROR_SHUTDOWN_IN_PROGRESS
;
713 lpService
= ScmGetServiceEntryByThreadId((ULONG
)hServiceStatus
);
714 if (lpService
== NULL
)
716 DPRINT1("lpService == NULL!\n");
717 return ERROR_INVALID_HANDLE
;
720 RtlCopyMemory(&lpService
->Status
,
722 sizeof(SERVICE_STATUS
));
724 DPRINT("Set %S to %lu\n", lpService
->lpDisplayName
, lpService
->Status
.dwCurrentState
);
725 DPRINT("ScmrSetServiceStatus() done\n");
727 return ERROR_SUCCESS
;
733 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
736 DPRINT1("ScmrUnlockServiceDatabase() called\n");
738 return ERROR_SUCCESS
;
744 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
745 unsigned long BootAcceptable
)
747 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
749 return ERROR_CALL_NOT_IMPLEMENTED
;
755 ScmrSetServiceBitsW(handle_t BindingHandle
,
756 unsigned long hServiceStatus
,
757 unsigned long dwServiceBits
,
758 unsigned long bSetBitsOn
,
759 unsigned long bUpdateImmediately
,
762 DPRINT1("ScmrSetServiceBitsW() called\n");
764 return ERROR_CALL_NOT_IMPLEMENTED
;
770 ScmrChangeServiceConfigW(handle_t BiningHandle
,
771 unsigned int hService
,
772 unsigned long dwServiceType
,
773 unsigned long dwStartType
,
774 unsigned long dwErrorControl
,
775 wchar_t *lpBinaryPathName
,
776 wchar_t *lpLoadOrderGroup
,
777 unsigned long *lpdwTagId
, /* in, out, unique */
778 wchar_t *lpDependencies
,
779 unsigned long dwDependenciesLength
,
780 wchar_t *lpServiceStartName
,
782 unsigned long dwPasswordLength
,
783 wchar_t *lpDisplayName
)
785 DWORD dwError
= ERROR_SUCCESS
;
786 PSERVICE_HANDLE hSvc
;
787 PSERVICE lpService
= NULL
;
788 HKEY hServiceKey
= NULL
;
790 DPRINT("ScmrChangeServiceConfigW() called\n");
791 DPRINT("dwServiceType = %lu\n", dwServiceType
);
792 DPRINT("dwStartType = %lu\n", dwStartType
);
793 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
794 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
795 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
796 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
799 return ERROR_SHUTDOWN_IN_PROGRESS
;
801 hSvc
= (PSERVICE_HANDLE
)hService
;
802 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
804 DPRINT1("Invalid handle tag!\n");
805 return ERROR_INVALID_HANDLE
;
808 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
809 SERVICE_CHANGE_CONFIG
))
811 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
812 return ERROR_ACCESS_DENIED
;
815 lpService
= hSvc
->ServiceEntry
;
816 if (lpService
== NULL
)
818 DPRINT1("lpService == NULL!\n");
819 return ERROR_INVALID_HANDLE
;
822 /* FIXME: Lock database exclusively */
824 if (lpService
->bDeleted
)
826 /* FIXME: Unlock database */
827 DPRINT1("The service has already been marked for delete!\n");
828 return ERROR_SERVICE_MARKED_FOR_DELETE
;
831 /* Open the service key */
832 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
835 if (dwError
!= ERROR_SUCCESS
)
838 /* Write service data to the registry */
839 /* Set the display name */
840 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
842 RegSetValueExW(hServiceKey
,
846 (LPBYTE
)lpDisplayName
,
847 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
848 /* FIXME: update lpService->lpDisplayName */
851 if (dwServiceType
!= SERVICE_NO_CHANGE
)
853 /* Set the service type */
854 dwError
= RegSetValueExW(hServiceKey
,
858 (LPBYTE
)&dwServiceType
,
860 if (dwError
!= ERROR_SUCCESS
)
863 lpService
->Status
.dwServiceType
= dwServiceType
;
866 if (dwStartType
!= SERVICE_NO_CHANGE
)
868 /* Set the start value */
869 dwError
= RegSetValueExW(hServiceKey
,
873 (LPBYTE
)&dwStartType
,
875 if (dwError
!= ERROR_SUCCESS
)
878 lpService
->dwStartType
= dwStartType
;
881 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
883 /* Set the error control value */
884 dwError
= RegSetValueExW(hServiceKey
,
888 (LPBYTE
)&dwErrorControl
,
890 if (dwError
!= ERROR_SUCCESS
)
893 lpService
->dwErrorControl
= dwErrorControl
;
897 /* FIXME: set the new ImagePath value */
899 /* Set the image path */
900 if (dwServiceType
& SERVICE_WIN32
)
902 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
904 dwError
= RegSetValueExW(hServiceKey
,
908 (LPBYTE
)lpBinaryPathName
,
909 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
910 if (dwError
!= ERROR_SUCCESS
)
914 else if (dwServiceType
& SERVICE_DRIVER
)
916 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
918 dwError
= RegSetValueExW(hServiceKey
,
923 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
924 if (dwError
!= ERROR_SUCCESS
)
930 /* Set the group name */
931 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
933 dwError
= RegSetValueExW(hServiceKey
,
937 (LPBYTE
)lpLoadOrderGroup
,
938 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
939 if (dwError
!= ERROR_SUCCESS
)
941 /* FIXME: update lpService->lpServiceGroup */
944 if (lpdwTagId
!= NULL
)
946 dwError
= ScmAssignNewTag(lpService
);
947 if (dwError
!= ERROR_SUCCESS
)
950 dwError
= RegSetValueExW(hServiceKey
,
954 (LPBYTE
)&lpService
->dwTag
,
956 if (dwError
!= ERROR_SUCCESS
)
959 *lpdwTagId
= lpService
->dwTag
;
962 /* Write dependencies */
963 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
965 dwError
= ScmWriteDependencies(hServiceKey
,
967 dwDependenciesLength
);
968 if (dwError
!= ERROR_SUCCESS
)
972 if (lpPassword
!= NULL
)
974 /* FIXME: Write password */
977 /* FIXME: Unlock database */
980 if (hServiceKey
!= NULL
)
981 RegCloseKey(hServiceKey
);
983 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
991 ScmrCreateServiceW(handle_t BindingHandle
,
992 unsigned int hSCManager
,
993 wchar_t *lpServiceName
,
994 wchar_t *lpDisplayName
,
995 unsigned long dwDesiredAccess
,
996 unsigned long dwServiceType
,
997 unsigned long dwStartType
,
998 unsigned long dwErrorControl
,
999 wchar_t *lpBinaryPathName
,
1000 wchar_t *lpLoadOrderGroup
,
1001 unsigned long *lpdwTagId
, /* in, out */
1002 wchar_t *lpDependencies
,
1003 unsigned long dwDependenciesLength
,
1004 wchar_t *lpServiceStartName
,
1005 wchar_t *lpPassword
,
1006 unsigned long dwPasswordLength
,
1007 unsigned int *hService
) /* out */
1009 PMANAGER_HANDLE hManager
;
1010 DWORD dwError
= ERROR_SUCCESS
;
1011 PSERVICE lpService
= NULL
;
1012 SC_HANDLE hServiceHandle
= NULL
;
1013 LPWSTR lpImagePath
= NULL
;
1014 HKEY hServiceKey
= NULL
;
1016 DPRINT("ScmrCreateServiceW() called\n");
1017 DPRINT("lpServiceName = %S\n", lpServiceName
);
1018 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
1019 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess
);
1020 DPRINT("dwServiceType = %lu\n", dwServiceType
);
1021 DPRINT("dwStartType = %lu\n", dwStartType
);
1022 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
1023 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
1024 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
1027 return ERROR_SHUTDOWN_IN_PROGRESS
;
1029 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1030 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1032 DPRINT1("Invalid manager handle!\n");
1033 return ERROR_INVALID_HANDLE
;
1036 /* Check access rights */
1037 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1038 SC_MANAGER_CREATE_SERVICE
))
1040 DPRINT1("Insufficient access rights! 0x%lx\n",
1041 hManager
->Handle
.DesiredAccess
);
1042 return ERROR_ACCESS_DENIED
;
1045 /* Fail if the service already exists! */
1046 if (ScmGetServiceEntryByName(lpServiceName
) != NULL
)
1047 return ERROR_SERVICE_EXISTS
;
1049 if (dwServiceType
& SERVICE_DRIVER
)
1051 /* FIXME: Adjust the image path
1052 * Following line is VERY BAD, because it assumes that the
1053 * first part of full file name is the OS directory */
1054 if (lpBinaryPathName
[1] == ':') lpBinaryPathName
+= GetWindowsDirectoryW(NULL
, 0);
1056 lpImagePath
= (WCHAR
*) HeapAlloc(GetProcessHeap(),
1058 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1059 if (lpImagePath
== NULL
)
1061 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1064 wcscpy(lpImagePath
, lpBinaryPathName
);
1067 /* Allocate a new service entry */
1068 dwError
= ScmCreateNewServiceRecord(lpServiceName
,
1070 if (dwError
!= ERROR_SUCCESS
)
1073 /* Fill the new service entry */
1074 lpService
->Status
.dwServiceType
= dwServiceType
;
1075 lpService
->dwStartType
= dwStartType
;
1076 lpService
->dwErrorControl
= dwErrorControl
;
1078 /* Fill the display name */
1079 if (lpDisplayName
!= NULL
&&
1080 *lpDisplayName
!= 0 &&
1081 wcsicmp(lpService
->lpDisplayName
, lpDisplayName
) != 0)
1083 lpService
->lpDisplayName
= (WCHAR
*) HeapAlloc(GetProcessHeap(), 0,
1084 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1085 if (lpService
->lpDisplayName
== NULL
)
1087 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1090 wcscpy(lpService
->lpDisplayName
, lpDisplayName
);
1093 /* Assign the service to a group */
1094 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1096 dwError
= ScmSetServiceGroup(lpService
,
1098 if (dwError
!= ERROR_SUCCESS
)
1102 /* Assign a new tag */
1103 if (lpdwTagId
!= NULL
)
1105 dwError
= ScmAssignNewTag(lpService
);
1106 if (dwError
!= ERROR_SUCCESS
)
1110 /* Write service data to the registry */
1111 /* Create the service key */
1112 dwError
= ScmCreateServiceKey(lpServiceName
,
1115 if (dwError
!= ERROR_SUCCESS
)
1118 /* Set the display name */
1119 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
1121 RegSetValueExW(hServiceKey
,
1125 (LPBYTE
)lpDisplayName
,
1126 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1129 /* Set the service type */
1130 dwError
= RegSetValueExW(hServiceKey
,
1134 (LPBYTE
)&dwServiceType
,
1136 if (dwError
!= ERROR_SUCCESS
)
1139 /* Set the start value */
1140 dwError
= RegSetValueExW(hServiceKey
,
1144 (LPBYTE
)&dwStartType
,
1146 if (dwError
!= ERROR_SUCCESS
)
1149 /* Set the error control value */
1150 dwError
= RegSetValueExW(hServiceKey
,
1154 (LPBYTE
)&dwErrorControl
,
1156 if (dwError
!= ERROR_SUCCESS
)
1159 /* Set the image path */
1160 if (dwServiceType
& SERVICE_WIN32
)
1162 dwError
= RegSetValueExW(hServiceKey
,
1166 (LPBYTE
)lpBinaryPathName
,
1167 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1168 if (dwError
!= ERROR_SUCCESS
)
1171 else if (dwServiceType
& SERVICE_DRIVER
)
1173 dwError
= RegSetValueExW(hServiceKey
,
1177 (LPBYTE
)lpImagePath
,
1178 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
1179 if (dwError
!= ERROR_SUCCESS
)
1183 /* Set the group name */
1184 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1186 dwError
= RegSetValueExW(hServiceKey
,
1190 (LPBYTE
)lpLoadOrderGroup
,
1191 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
1192 if (dwError
!= ERROR_SUCCESS
)
1196 if (lpdwTagId
!= NULL
)
1198 dwError
= RegSetValueExW(hServiceKey
,
1202 (LPBYTE
)&lpService
->dwTag
,
1204 if (dwError
!= ERROR_SUCCESS
)
1208 /* Write dependencies */
1209 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
1211 dwError
= ScmWriteDependencies(hServiceKey
,
1213 dwDependenciesLength
);
1214 if (dwError
!= ERROR_SUCCESS
)
1218 if (lpPassword
!= NULL
)
1220 /* FIXME: Write password */
1223 dwError
= ScmCreateServiceHandle(lpService
,
1225 if (dwError
!= ERROR_SUCCESS
)
1228 dwError
= ScmCheckAccess(hServiceHandle
,
1230 if (dwError
!= ERROR_SUCCESS
)
1234 if (hServiceKey
!= NULL
)
1235 RegCloseKey(hServiceKey
);
1237 if (dwError
== ERROR_SUCCESS
)
1239 DPRINT("hService %lx\n", hServiceHandle
);
1240 *hService
= (unsigned int)hServiceHandle
;
1242 if (lpdwTagId
!= NULL
)
1243 *lpdwTagId
= lpService
->dwTag
;
1247 /* Release the display name buffer */
1248 if (lpService
->lpServiceName
!= NULL
)
1249 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
1251 if (hServiceHandle
!= NULL
)
1253 /* Remove the service handle */
1254 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
1257 if (lpService
!= NULL
)
1259 /* FIXME: remove the service entry */
1263 if (lpImagePath
!= NULL
)
1264 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1266 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
1274 ScmrEnumDependentServicesW(handle_t BindingHandle
,
1275 unsigned int hService
,
1276 unsigned long dwServiceState
,
1277 unsigned char *lpServices
,
1278 unsigned long cbBufSize
,
1279 unsigned long *pcbBytesNeeded
,
1280 unsigned long *lpServicesReturned
)
1282 DWORD dwError
= ERROR_SUCCESS
;
1284 DPRINT1("ScmrEnumDependentServicesW() called\n");
1285 *pcbBytesNeeded
= 0;
1286 *lpServicesReturned
= 0;
1288 DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError
);
1296 ScmrEnumServicesStatusW(handle_t BindingHandle
,
1297 unsigned int hSCManager
,
1298 unsigned long dwServiceType
,
1299 unsigned long dwServiceState
,
1300 unsigned char *lpServices
,
1301 unsigned long dwBufSize
,
1302 unsigned long *pcbBytesNeeded
,
1303 unsigned long *lpServicesReturned
,
1304 unsigned long *lpResumeHandle
)
1306 PMANAGER_HANDLE hManager
;
1308 DWORD dwError
= ERROR_SUCCESS
;
1309 PLIST_ENTRY ServiceEntry
;
1310 PSERVICE CurrentService
;
1312 DWORD dwRequiredSize
;
1313 DWORD dwServiceCount
;
1315 DWORD dwLastResumeCount
;
1316 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1319 DPRINT("ScmrEnumServicesStatusW() called\n");
1322 return ERROR_SHUTDOWN_IN_PROGRESS
;
1324 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1325 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1327 DPRINT1("Invalid manager handle!\n");
1328 return ERROR_INVALID_HANDLE
;
1331 /* Check access rights */
1332 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1333 SC_MANAGER_ENUMERATE_SERVICE
))
1335 DPRINT1("Insufficient access rights! 0x%lx\n",
1336 hManager
->Handle
.DesiredAccess
);
1337 return ERROR_ACCESS_DENIED
;
1340 *pcbBytesNeeded
= 0;
1341 *lpServicesReturned
= 0;
1343 dwLastResumeCount
= *lpResumeHandle
;
1345 /* FIXME: Lock the service list shared */
1347 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
1348 if (lpService
== NULL
)
1350 dwError
= ERROR_SUCCESS
;
1357 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1358 ServiceEntry
!= &ServiceListHead
;
1359 ServiceEntry
= ServiceEntry
->Flink
)
1361 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1365 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1368 dwState
= SERVICE_ACTIVE
;
1369 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1370 dwState
= SERVICE_INACTIVE
;
1372 if ((dwState
& dwServiceState
) == 0)
1375 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1376 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1377 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1379 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1381 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
1382 dwRequiredSize
+= dwSize
;
1384 dwLastResumeCount
= CurrentService
->dwResumeCount
;
1388 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
1394 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
1395 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
1398 ServiceEntry
!= &ServiceListHead
;
1399 ServiceEntry
= ServiceEntry
->Flink
)
1401 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1405 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1408 dwState
= SERVICE_ACTIVE
;
1409 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1410 dwState
= SERVICE_INACTIVE
;
1412 if ((dwState
& dwServiceState
) == 0)
1415 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUSW
) +
1416 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1417 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
1419 dwError
= ERROR_MORE_DATA
;
1422 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
1424 *lpResumeHandle
= dwLastResumeCount
;
1425 *lpServicesReturned
= dwServiceCount
;
1426 *pcbBytesNeeded
= dwRequiredSize
;
1428 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1429 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
1430 dwServiceCount
* sizeof(ENUM_SERVICE_STATUSW
));
1433 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1434 ServiceEntry
!= &ServiceListHead
;
1435 ServiceEntry
= ServiceEntry
->Flink
)
1437 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1441 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1444 dwState
= SERVICE_ACTIVE
;
1445 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1446 dwState
= SERVICE_INACTIVE
;
1448 if ((dwState
& dwServiceState
) == 0)
1451 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1452 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1453 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1455 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1457 /* Copy the service name */
1459 CurrentService
->lpServiceName
);
1460 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1461 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
1463 /* Copy the display name */
1465 CurrentService
->lpDisplayName
);
1466 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1467 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
1469 /* Copy the status information */
1470 memcpy(&lpStatusPtr
->ServiceStatus
,
1471 &CurrentService
->Status
,
1472 sizeof(SERVICE_STATUS
));
1475 dwRequiredSize
+= dwSize
;
1485 /* FIXME: Unlock the service list */
1487 DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError
);
1495 ScmrOpenSCManagerW(handle_t BindingHandle
,
1496 wchar_t *lpMachineName
,
1497 wchar_t *lpDatabaseName
,
1498 unsigned long dwDesiredAccess
,
1504 DPRINT("ScmrOpenSCManagerW() called\n");
1505 DPRINT("lpMachineName = %p\n", lpMachineName
);
1506 DPRINT("lpMachineName: %S\n", lpMachineName
);
1507 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
1508 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
1509 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1512 return ERROR_SHUTDOWN_IN_PROGRESS
;
1514 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1516 if (dwError
!= ERROR_SUCCESS
)
1518 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1522 /* Check the desired access */
1523 dwError
= ScmCheckAccess(hHandle
,
1524 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1525 if (dwError
!= ERROR_SUCCESS
)
1527 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1528 HeapFree(GetProcessHeap(), 0, hHandle
);
1532 *hScm
= (unsigned int)hHandle
;
1533 DPRINT("*hScm = %x\n", *hScm
);
1535 DPRINT("ScmrOpenSCManagerW() done\n");
1537 return ERROR_SUCCESS
;
1543 ScmrOpenServiceW(handle_t BindingHandle
,
1544 unsigned int hSCManager
,
1545 wchar_t *lpServiceName
,
1546 unsigned long dwDesiredAccess
,
1547 unsigned int *hService
)
1550 PMANAGER_HANDLE hManager
;
1554 DPRINT("ScmrOpenServiceW() called\n");
1555 DPRINT("hSCManager = %x\n", hSCManager
);
1556 DPRINT("lpServiceName = %p\n", lpServiceName
);
1557 DPRINT("lpServiceName: %S\n", lpServiceName
);
1558 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1561 return ERROR_SHUTDOWN_IN_PROGRESS
;
1563 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1564 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1566 DPRINT1("Invalid manager handle!\n");
1567 return ERROR_INVALID_HANDLE
;
1570 /* FIXME: Lock the service list */
1572 /* Get service database entry */
1573 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1574 if (lpService
== NULL
)
1576 DPRINT("Could not find a service!\n");
1577 return ERROR_SERVICE_DOES_NOT_EXIST
;
1580 /* Create a service handle */
1581 dwError
= ScmCreateServiceHandle(lpService
,
1583 if (dwError
!= ERROR_SUCCESS
)
1585 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1589 /* Check the desired access */
1590 dwError
= ScmCheckAccess(hHandle
,
1592 if (dwError
!= ERROR_SUCCESS
)
1594 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1595 HeapFree(GetProcessHeap(), 0, hHandle
);
1599 *hService
= (unsigned int)hHandle
;
1600 DPRINT("*hService = %x\n", *hService
);
1602 DPRINT("ScmrOpenServiceW() done\n");
1604 return ERROR_SUCCESS
;
1610 ScmrQueryServiceConfigW(handle_t BindingHandle
,
1611 unsigned int hService
,
1612 unsigned char *lpServiceConfig
,
1613 unsigned long cbBufSize
,
1614 unsigned long *pcbBytesNeeded
)
1616 DWORD dwError
= ERROR_SUCCESS
;
1617 PSERVICE_HANDLE hSvc
;
1618 PSERVICE lpService
= NULL
;
1619 HKEY hServiceKey
= NULL
;
1620 LPWSTR lpImagePath
= NULL
;
1621 LPWSTR lpServiceStartName
= NULL
;
1622 DWORD dwRequiredSize
;
1623 LPQUERY_SERVICE_CONFIGW lpConfig
;
1626 DPRINT("ScmrQueryServiceConfigW() called\n");
1629 return ERROR_SHUTDOWN_IN_PROGRESS
;
1631 hSvc
= (PSERVICE_HANDLE
)hService
;
1632 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1634 DPRINT1("Invalid handle tag!\n");
1635 return ERROR_INVALID_HANDLE
;
1638 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1639 SERVICE_QUERY_CONFIG
))
1641 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1642 return ERROR_ACCESS_DENIED
;
1645 lpService
= hSvc
->ServiceEntry
;
1646 if (lpService
== NULL
)
1648 DPRINT1("lpService == NULL!\n");
1649 return ERROR_INVALID_HANDLE
;
1652 /* FIXME: Lock the service database shared */
1654 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
1657 if (dwError
!= ERROR_SUCCESS
)
1660 dwError
= ScmReadString(hServiceKey
,
1663 if (dwError
!= ERROR_SUCCESS
)
1666 ScmReadString(hServiceKey
,
1668 &lpServiceStartName
);
1670 dwRequiredSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1672 if (lpImagePath
!= NULL
)
1673 dwRequiredSize
+= ((wcslen(lpImagePath
) + 1) * sizeof(WCHAR
));
1675 if (lpService
->lpGroup
!= NULL
)
1676 dwRequiredSize
+= ((wcslen(lpService
->lpGroup
->lpGroupName
) + 1) * sizeof(WCHAR
));
1678 /* FIXME: Add Dependencies length*/
1680 if (lpServiceStartName
!= NULL
)
1681 dwRequiredSize
+= ((wcslen(lpServiceStartName
) + 1) * sizeof(WCHAR
));
1683 if (lpService
->lpDisplayName
!= NULL
)
1684 dwRequiredSize
+= ((wcslen(lpService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1686 if (lpServiceConfig
== NULL
|| cbBufSize
< dwRequiredSize
)
1688 dwError
= ERROR_INSUFFICIENT_BUFFER
;
1692 lpConfig
= (LPQUERY_SERVICE_CONFIGW
)lpServiceConfig
;
1693 lpConfig
->dwServiceType
= lpService
->Status
.dwServiceType
;
1694 lpConfig
->dwStartType
= lpService
->dwStartType
;
1695 lpConfig
->dwErrorControl
= lpService
->dwErrorControl
;
1696 lpConfig
->dwTagId
= lpService
->dwTag
;
1698 lpStr
= (LPWSTR
)(lpConfig
+ 1);
1700 if (lpImagePath
!= NULL
)
1702 wcscpy(lpStr
, lpImagePath
);
1703 lpConfig
->lpBinaryPathName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1704 lpStr
+= (wcslen(lpImagePath
) + 1);
1708 lpConfig
->lpBinaryPathName
= NULL
;
1711 if (lpService
->lpGroup
!= NULL
)
1713 wcscpy(lpStr
, lpService
->lpGroup
->lpGroupName
);
1714 lpConfig
->lpLoadOrderGroup
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1715 lpStr
+= (wcslen(lpService
->lpGroup
->lpGroupName
) + 1);
1719 lpConfig
->lpLoadOrderGroup
= NULL
;
1722 /* FIXME: Append Dependencies */
1723 lpConfig
->lpDependencies
= NULL
;
1725 if (lpServiceStartName
!= NULL
)
1727 wcscpy(lpStr
, lpServiceStartName
);
1728 lpConfig
->lpServiceStartName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1729 lpStr
+= (wcslen(lpServiceStartName
) + 1);
1733 lpConfig
->lpServiceStartName
= NULL
;
1736 if (lpService
->lpDisplayName
!= NULL
)
1738 wcscpy(lpStr
, lpService
->lpDisplayName
);
1739 lpConfig
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1743 lpConfig
->lpDisplayName
= NULL
;
1747 if (pcbBytesNeeded
!= NULL
)
1748 *pcbBytesNeeded
= dwRequiredSize
;
1751 if (lpImagePath
!= NULL
)
1752 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1754 if (lpServiceStartName
!= NULL
)
1755 HeapFree(GetProcessHeap(), 0, lpServiceStartName
);
1757 if (hServiceKey
!= NULL
)
1758 RegCloseKey(hServiceKey
);
1760 /* FIXME: Unlock the service database */
1762 DPRINT("ScmrQueryServiceConfigW() done\n");
1770 ScmrQueryServiceLockStatusW(handle_t BindingHandle
,
1771 unsigned int hSCManager
,
1772 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
1773 unsigned long cbBufSize
, /* [in] */
1774 unsigned long *pcbBytesNeeded
) /* [out] */
1776 DPRINT1("ScmrQueryServiceLockStatusW() called\n");
1777 return ERROR_CALL_NOT_IMPLEMENTED
;
1783 ScmrStartServiceW(handle_t BindingHandle
,
1784 unsigned int hService
,
1785 unsigned long dwNumServiceArgs
,
1786 unsigned char *lpServiceArgBuffer
,
1787 unsigned long cbBufSize
)
1789 DWORD dwError
= ERROR_SUCCESS
;
1790 PSERVICE_HANDLE hSvc
;
1791 PSERVICE lpService
= NULL
;
1793 DPRINT("ScmrStartServiceW() called\n");
1796 return ERROR_SHUTDOWN_IN_PROGRESS
;
1798 hSvc
= (PSERVICE_HANDLE
)hService
;
1799 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1801 DPRINT1("Invalid handle tag!\n");
1802 return ERROR_INVALID_HANDLE
;
1805 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1808 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1809 return ERROR_ACCESS_DENIED
;
1812 lpService
= hSvc
->ServiceEntry
;
1813 if (lpService
== NULL
)
1815 DPRINT1("lpService == NULL!\n");
1816 return ERROR_INVALID_HANDLE
;
1819 if (lpService
->dwStartType
== SERVICE_DISABLED
)
1820 return ERROR_SERVICE_DISABLED
;
1822 if (lpService
->bDeleted
)
1823 return ERROR_SERVICE_MARKED_FOR_DELETE
;
1825 /* Start the service */
1826 dwError
= ScmStartService(lpService
, (LPWSTR
)lpServiceArgBuffer
);
1834 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1835 unsigned int hSCManager
,
1836 wchar_t *lpServiceName
,
1837 wchar_t *lpDisplayName
, /* [out, unique] */
1838 unsigned long *lpcchBuffer
)
1840 // PMANAGER_HANDLE hManager;
1845 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1846 DPRINT("hSCManager = %x\n", hSCManager
);
1847 DPRINT("lpServiceName: %S\n", lpServiceName
);
1848 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1849 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1851 // hManager = (PMANAGER_HANDLE)hSCManager;
1852 // if (hManager->Handle.Tag != MANAGER_TAG)
1854 // DPRINT1("Invalid manager handle!\n");
1855 // return ERROR_INVALID_HANDLE;
1858 /* Get service database entry */
1859 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1860 if (lpService
== NULL
)
1862 DPRINT1("Could not find a service!\n");
1863 return ERROR_SERVICE_DOES_NOT_EXIST
;
1866 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1868 if (lpDisplayName
!= NULL
&&
1869 *lpcchBuffer
>= dwLength
)
1871 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1874 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1876 *lpcchBuffer
= dwLength
;
1884 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1885 unsigned int hSCManager
,
1886 wchar_t *lpDisplayName
,
1887 wchar_t *lpServiceName
, /* [out, unique] */
1888 unsigned long *lpcchBuffer
)
1890 // PMANAGER_HANDLE hManager;
1895 DPRINT("ScmrGetServiceKeyNameW() called\n");
1896 DPRINT("hSCManager = %x\n", hSCManager
);
1897 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1898 DPRINT("lpServiceName: %p\n", lpServiceName
);
1899 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1901 // hManager = (PMANAGER_HANDLE)hSCManager;
1902 // if (hManager->Handle.Tag != MANAGER_TAG)
1904 // DPRINT1("Invalid manager handle!\n");
1905 // return ERROR_INVALID_HANDLE;
1908 /* Get service database entry */
1909 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1910 if (lpService
== NULL
)
1912 DPRINT1("Could not find a service!\n");
1913 return ERROR_SERVICE_DOES_NOT_EXIST
;
1916 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1918 if (lpServiceName
!= NULL
&&
1919 *lpcchBuffer
>= dwLength
)
1921 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1924 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1926 *lpcchBuffer
= dwLength
;
1934 ScmrSetServiceBitsA(handle_t BindingHandle
,
1935 unsigned long hServiceStatus
,
1936 unsigned long dwServiceBits
,
1937 unsigned long bSetBitsOn
,
1938 unsigned long bUpdateImmediately
,
1941 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1942 return ERROR_CALL_NOT_IMPLEMENTED
;
1948 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1949 unsigned int hService
,
1950 unsigned long dwServiceType
,
1951 unsigned long dwStartType
,
1952 unsigned long dwErrorControl
,
1953 char *lpBinaryPathName
,
1954 char *lpLoadOrderGroup
,
1955 unsigned long *lpdwTagId
,
1956 char *lpDependencies
,
1957 unsigned long dwDependenciesLength
,
1958 char *lpServiceStartName
,
1960 unsigned long dwPasswordLength
,
1961 char *lpDisplayName
)
1963 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1964 return ERROR_CALL_NOT_IMPLEMENTED
;
1970 ScmrCreateServiceA(handle_t BindingHandle
,
1971 unsigned int hSCManager
,
1972 char *lpServiceName
,
1973 char *lpDisplayName
,
1974 unsigned long dwDesiredAccess
,
1975 unsigned long dwServiceType
,
1976 unsigned long dwStartType
,
1977 unsigned long dwErrorControl
,
1978 char *lpBinaryPathName
,
1979 char *lpLoadOrderGroup
,
1980 unsigned long *lpdwTagId
, /* in, out */
1981 char *lpDependencies
,
1982 unsigned long dwDependenciesLength
,
1983 char *lpServiceStartName
,
1985 unsigned long dwPasswordLength
,
1986 unsigned int *hService
) /* out */
1988 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1989 return ERROR_CALL_NOT_IMPLEMENTED
;
1995 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1996 unsigned int hService
,
1997 unsigned long dwServiceState
,
1998 unsigned char *lpServices
,
1999 unsigned long cbBufSize
,
2000 unsigned long *pcbBytesNeeded
,
2001 unsigned long *lpServicesReturned
)
2003 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
2004 *pcbBytesNeeded
= 0;
2005 *lpServicesReturned
= 0;
2006 return ERROR_CALL_NOT_IMPLEMENTED
;
2012 ScmrEnumServicesStatusA(handle_t BindingHandle
,
2013 unsigned int hSCManager
,
2014 unsigned long dwServiceType
,
2015 unsigned long dwServiceState
,
2016 unsigned char *lpServices
,
2017 unsigned long dwBufSize
,
2018 unsigned long *pcbBytesNeeded
,
2019 unsigned long *lpServicesReturned
,
2020 unsigned long *lpResumeHandle
)
2022 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
2023 return ERROR_CALL_NOT_IMPLEMENTED
;
2029 ScmrOpenSCManagerA(handle_t BindingHandle
,
2030 char *lpMachineName
,
2031 char *lpDatabaseName
,
2032 unsigned long dwDesiredAccess
,
2035 UNICODE_STRING MachineName
;
2036 UNICODE_STRING DatabaseName
;
2039 DPRINT("ScmrOpenSCManagerA() called\n");
2042 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
2046 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
2049 dwError
= ScmrOpenSCManagerW(BindingHandle
,
2050 lpMachineName
? MachineName
.Buffer
: NULL
,
2051 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
2056 RtlFreeUnicodeString(&MachineName
);
2059 RtlFreeUnicodeString(&DatabaseName
);
2067 ScmrOpenServiceA(handle_t BindingHandle
,
2068 unsigned int hSCManager
,
2069 char *lpServiceName
,
2070 unsigned long dwDesiredAccess
,
2071 unsigned int *hService
)
2073 UNICODE_STRING ServiceName
;
2076 DPRINT("ScmrOpenServiceA() called\n");
2078 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
2081 dwError
= ScmrOpenServiceW(BindingHandle
,
2087 RtlFreeUnicodeString(&ServiceName
);
2095 ScmrQueryServiceConfigA(handle_t BindingHandle
,
2096 unsigned int hService
,
2097 unsigned char *lpServiceConfig
,
2098 unsigned long cbBufSize
,
2099 unsigned long *pcbBytesNeeded
)
2101 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2102 return ERROR_CALL_NOT_IMPLEMENTED
;
2108 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2109 unsigned int hSCManager
,
2110 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2111 unsigned long cbBufSize
, /* [in] */
2112 unsigned long *pcbBytesNeeded
) /* [out] */
2114 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2115 return ERROR_CALL_NOT_IMPLEMENTED
;
2121 ScmrStartServiceA(handle_t BindingHandle
,
2122 unsigned int hService
,
2123 unsigned long dwNumServiceArgs
,
2124 unsigned char *lpServiceArgBuffer
,
2125 unsigned long cbBufSize
)
2127 DWORD dwError
= ERROR_SUCCESS
;
2128 PSERVICE_HANDLE hSvc
;
2129 PSERVICE lpService
= NULL
;
2131 DPRINT1("ScmrStartServiceA() called\n");
2134 return ERROR_SHUTDOWN_IN_PROGRESS
;
2136 hSvc
= (PSERVICE_HANDLE
)hService
;
2137 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2139 DPRINT1("Invalid handle tag!\n");
2140 return ERROR_INVALID_HANDLE
;
2143 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2146 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2147 return ERROR_ACCESS_DENIED
;
2150 lpService
= hSvc
->ServiceEntry
;
2151 if (lpService
== NULL
)
2153 DPRINT1("lpService == NULL!\n");
2154 return ERROR_INVALID_HANDLE
;
2157 if (lpService
->dwStartType
== SERVICE_DISABLED
)
2158 return ERROR_SERVICE_DISABLED
;
2160 if (lpService
->bDeleted
)
2161 return ERROR_SERVICE_MARKED_FOR_DELETE
;
2163 /* FIXME: Convert argument vector to Unicode */
2165 /* Start the service */
2166 dwError
= ScmStartService(lpService
, NULL
);
2168 /* FIXME: Free argument vector */
2176 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2177 unsigned int hSCManager
,
2178 char *lpServiceName
,
2179 char *lpDisplayName
, /* [out, unique] */
2180 unsigned long *lpcchBuffer
)
2182 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2183 return ERROR_CALL_NOT_IMPLEMENTED
;
2189 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2190 unsigned int hSCManager
,
2191 char *lpDisplayName
,
2192 char *lpServiceName
, /* [out, unique] */
2193 unsigned long *lpcchBuffer
)
2195 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2196 return ERROR_CALL_NOT_IMPLEMENTED
;
2202 ScmrGetCurrentGroupStateW(handle_t BindingHandle
)
2204 DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
2205 return ERROR_CALL_NOT_IMPLEMENTED
;
2211 ScmrEnumServiceGroupW(handle_t BindingHandle
)
2213 DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
2214 return ERROR_CALL_NOT_IMPLEMENTED
;
2220 ScmrChangeServiceConfig2A(handle_t BindingHandle
,
2221 unsigned int hService
,
2222 unsigned long dwInfoLevel
,
2223 unsigned char *lpInfo
,
2224 unsigned long dwInfoSize
)
2226 DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
2227 return ERROR_CALL_NOT_IMPLEMENTED
;
2233 ScmrChangeServiceConfig2W(handle_t BindingHandle
,
2234 unsigned int hService
,
2235 unsigned long dwInfoLevel
,
2236 unsigned char *lpInfo
,
2237 unsigned long dwInfoSize
)
2239 DWORD dwError
= ERROR_SUCCESS
;
2240 PSERVICE_HANDLE hSvc
;
2241 PSERVICE lpService
= NULL
;
2242 HKEY hServiceKey
= NULL
;
2244 DPRINT("ScmrChangeServiceConfig2W() called\n");
2245 DPRINT("dwInfoLevel = %lu\n", dwInfoLevel
);
2246 DPRINT("dwInfoSize = %lu\n", dwInfoSize
);
2249 return ERROR_SHUTDOWN_IN_PROGRESS
;
2251 hSvc
= (PSERVICE_HANDLE
)hService
;
2252 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2254 DPRINT1("Invalid handle tag!\n");
2255 return ERROR_INVALID_HANDLE
;
2258 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2259 SERVICE_CHANGE_CONFIG
))
2261 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2262 return ERROR_ACCESS_DENIED
;
2265 lpService
= hSvc
->ServiceEntry
;
2266 if (lpService
== NULL
)
2268 DPRINT1("lpService == NULL!\n");
2269 return ERROR_INVALID_HANDLE
;
2272 /* FIXME: Lock database exclusively */
2274 if (lpService
->bDeleted
)
2276 /* FIXME: Unlock database */
2277 DPRINT1("The service has already been marked for delete!\n");
2278 return ERROR_SERVICE_MARKED_FOR_DELETE
;
2281 /* Open the service key */
2282 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
2285 if (dwError
!= ERROR_SUCCESS
)
2288 if (dwInfoLevel
& SERVICE_CONFIG_DESCRIPTION
)
2290 LPSERVICE_DESCRIPTIONW lpServiceDescription
= (LPSERVICE_DESCRIPTIONW
)lpInfo
;
2292 if (dwInfoSize
!= sizeof(*lpServiceDescription
))
2294 dwError
= ERROR_INVALID_PARAMETER
;
2298 if (lpServiceDescription
!= NULL
&& lpServiceDescription
->lpDescription
!= NULL
)
2300 RegSetValueExW(hServiceKey
,
2304 (LPBYTE
)lpServiceDescription
->lpDescription
,
2305 (wcslen(lpServiceDescription
->lpDescription
) + 1) * sizeof(WCHAR
));
2307 if (dwError
!= ERROR_SUCCESS
)
2311 else if (dwInfoLevel
& SERVICE_CONFIG_FAILURE_ACTIONS
)
2313 DPRINT1("SERVICE_CONFIG_FAILURE_ACTIONS not implemented\n");
2314 dwError
= ERROR_CALL_NOT_IMPLEMENTED
;
2319 /* FIXME: Unlock database */
2320 if (hServiceKey
!= NULL
)
2321 RegCloseKey(hServiceKey
);
2323 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
2331 ScmrQueryServiceConfig2A(handle_t BindingHandle
,
2332 unsigned int hService
,
2333 unsigned long dwInfoLevel
,
2334 unsigned char *lpBuffer
,
2335 unsigned long cbBufSize
,
2336 unsigned long *pcbBytesNeeded
)
2338 DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
2339 return ERROR_CALL_NOT_IMPLEMENTED
;
2345 ScmrQueryServiceConfig2W(handle_t BindingHandle
,
2346 unsigned int hService
,
2347 unsigned long dwInfoLevel
,
2348 unsigned char *lpBuffer
,
2349 unsigned long cbBufSize
,
2350 unsigned long *pcbBytesNeeded
)
2352 DWORD dwError
= ERROR_SUCCESS
;
2353 PSERVICE_HANDLE hSvc
;
2354 PSERVICE lpService
= NULL
;
2355 HKEY hServiceKey
= NULL
;
2356 DWORD dwRequiredSize
;
2357 LPWSTR lpDescription
= NULL
;
2359 DPRINT("ScmrQueryServiceConfig2W() called\n");
2362 return ERROR_SHUTDOWN_IN_PROGRESS
;
2364 hSvc
= (PSERVICE_HANDLE
)hService
;
2365 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2367 DPRINT1("Invalid handle tag!\n");
2368 return ERROR_INVALID_HANDLE
;
2371 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2372 SERVICE_QUERY_CONFIG
))
2374 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2375 return ERROR_ACCESS_DENIED
;
2378 lpService
= hSvc
->ServiceEntry
;
2379 if (lpService
== NULL
)
2381 DPRINT1("lpService == NULL!\n");
2382 return ERROR_INVALID_HANDLE
;
2385 /* FIXME: Lock the service database shared */
2387 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
2390 if (dwError
!= ERROR_SUCCESS
)
2393 if (dwInfoLevel
& SERVICE_CONFIG_DESCRIPTION
)
2395 LPSERVICE_DESCRIPTIONW lpServiceDescription
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2398 dwError
= ScmReadString(hServiceKey
,
2401 if (dwError
!= ERROR_SUCCESS
)
2404 dwRequiredSize
= sizeof(SERVICE_DESCRIPTIONW
) + ((wcslen(lpDescription
) + 1) * sizeof(WCHAR
));
2406 if (cbBufSize
< dwRequiredSize
)
2408 *pcbBytesNeeded
= dwRequiredSize
;
2409 dwError
= ERROR_INSUFFICIENT_BUFFER
;
2414 lpStr
= (LPWSTR
)(lpServiceDescription
+ 1);
2415 wcscpy(lpStr
, lpDescription
);
2416 lpServiceDescription
->lpDescription
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpServiceDescription
);
2419 else if (dwInfoLevel
& SERVICE_CONFIG_FAILURE_ACTIONS
)
2421 DPRINT1("SERVICE_CONFIG_FAILURE_ACTIONS not implemented\n");
2422 dwError
= ERROR_CALL_NOT_IMPLEMENTED
;
2427 if (lpDescription
!= NULL
)
2428 HeapFree(GetProcessHeap(), 0, lpDescription
);
2430 if (hServiceKey
!= NULL
)
2431 RegCloseKey(hServiceKey
);
2433 /* FIXME: Unlock database */
2435 DPRINT("ScmrQueryServiceConfig2W() done (Error %lu)\n", dwError
);
2443 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2444 unsigned int hService
,
2445 unsigned long InfoLevel
,
2446 unsigned char *lpBuffer
, /* out */
2447 unsigned long cbBufSize
,
2448 unsigned long *pcbBytesNeeded
) /* out */
2450 LPSERVICE_STATUS_PROCESS lpStatus
;
2451 PSERVICE_HANDLE hSvc
;
2454 DPRINT("ScmrQueryServiceStatusEx() called\n");
2457 return ERROR_SHUTDOWN_IN_PROGRESS
;
2459 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2460 return ERROR_INVALID_LEVEL
;
2462 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2464 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2465 return ERROR_INSUFFICIENT_BUFFER
;
2467 hSvc
= (PSERVICE_HANDLE
)hService
;
2468 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2470 DPRINT1("Invalid handle tag!\n");
2471 return ERROR_INVALID_HANDLE
;
2474 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2475 SERVICE_QUERY_STATUS
))
2477 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2478 return ERROR_ACCESS_DENIED
;
2481 lpService
= hSvc
->ServiceEntry
;
2482 if (lpService
== NULL
)
2484 DPRINT1("lpService == NULL!\n");
2485 return ERROR_INVALID_HANDLE
;
2488 lpStatus
= (LPSERVICE_STATUS_PROCESS
)lpBuffer
;
2490 /* Return service status information */
2491 RtlCopyMemory(lpStatus
,
2493 sizeof(SERVICE_STATUS
));
2495 lpStatus
->dwProcessId
= lpService
->ProcessId
; /* FIXME */
2496 lpStatus
->dwServiceFlags
= 0; /* FIXME */
2498 return ERROR_SUCCESS
;
2504 ScmrEnumServicesStatusExA(handle_t BindingHandle
,
2505 unsigned int hSCManager
,
2506 unsigned long InfoLevel
,
2507 unsigned long dwServiceType
,
2508 unsigned long dwServiceState
,
2509 unsigned char *lpServices
,
2510 unsigned long dwBufSize
,
2511 unsigned long *pcbBytesNeeded
,
2512 unsigned long *lpServicesReturned
,
2513 unsigned long *lpResumeHandle
,
2516 DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
2517 *pcbBytesNeeded
= 0;
2518 *lpServicesReturned
= 0;
2519 return ERROR_CALL_NOT_IMPLEMENTED
;
2525 ScmrEnumServicesStatusExW(handle_t BindingHandle
,
2526 unsigned int hSCManager
,
2527 unsigned long InfoLevel
,
2528 unsigned long dwServiceType
,
2529 unsigned long dwServiceState
,
2530 unsigned char *lpServices
,
2531 unsigned long dwBufSize
,
2532 unsigned long *pcbBytesNeeded
,
2533 unsigned long *lpServicesReturned
,
2534 unsigned long *lpResumeHandle
,
2535 wchar_t *pszGroupName
)
2537 PMANAGER_HANDLE hManager
;
2539 DWORD dwError
= ERROR_SUCCESS
;
2540 PLIST_ENTRY ServiceEntry
;
2541 PSERVICE CurrentService
;
2543 DWORD dwRequiredSize
;
2544 DWORD dwServiceCount
;
2546 DWORD dwLastResumeCount
;
2547 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
2550 DPRINT("ScmrEnumServicesStatusExW() called\n");
2553 return ERROR_SHUTDOWN_IN_PROGRESS
;
2555 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
2556 return ERROR_INVALID_LEVEL
;
2558 hManager
= (PMANAGER_HANDLE
)hSCManager
;
2559 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
2561 DPRINT1("Invalid manager handle!\n");
2562 return ERROR_INVALID_HANDLE
;
2565 /* Check access rights */
2566 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
2567 SC_MANAGER_ENUMERATE_SERVICE
))
2569 DPRINT1("Insufficient access rights! 0x%lx\n",
2570 hManager
->Handle
.DesiredAccess
);
2571 return ERROR_ACCESS_DENIED
;
2574 *pcbBytesNeeded
= 0;
2575 *lpServicesReturned
= 0;
2577 dwLastResumeCount
= *lpResumeHandle
;
2579 /* Lock the service list shared */
2581 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
2582 if (lpService
== NULL
)
2584 dwError
= ERROR_SUCCESS
;
2591 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2592 ServiceEntry
!= &ServiceListHead
;
2593 ServiceEntry
= ServiceEntry
->Flink
)
2595 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2599 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2602 dwState
= SERVICE_ACTIVE
;
2603 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2604 dwState
= SERVICE_INACTIVE
;
2606 if ((dwState
& dwServiceState
) == 0)
2611 if (*pszGroupName
== 0)
2613 if (CurrentService
->lpGroup
!= NULL
)
2618 if ((CurrentService
->lpGroup
== NULL
) ||
2619 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2624 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2625 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2626 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2628 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2630 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
2631 dwRequiredSize
+= dwSize
;
2633 dwLastResumeCount
= CurrentService
->dwResumeCount
;
2637 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
2643 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
2644 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
2647 ServiceEntry
!= &ServiceListHead
;
2648 ServiceEntry
= ServiceEntry
->Flink
)
2650 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2654 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2657 dwState
= SERVICE_ACTIVE
;
2658 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2659 dwState
= SERVICE_INACTIVE
;
2661 if ((dwState
& dwServiceState
) == 0)
2666 if (*pszGroupName
== 0)
2668 if (CurrentService
->lpGroup
!= NULL
)
2673 if ((CurrentService
->lpGroup
== NULL
) ||
2674 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2679 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2680 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2681 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
2683 dwError
= ERROR_MORE_DATA
;
2686 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
2688 *lpResumeHandle
= dwLastResumeCount
;
2689 *lpServicesReturned
= dwServiceCount
;
2690 *pcbBytesNeeded
= dwRequiredSize
;
2692 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
2693 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
2694 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS_PROCESSW
));
2697 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2698 ServiceEntry
!= &ServiceListHead
;
2699 ServiceEntry
= ServiceEntry
->Flink
)
2701 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2705 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2708 dwState
= SERVICE_ACTIVE
;
2709 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2710 dwState
= SERVICE_INACTIVE
;
2712 if ((dwState
& dwServiceState
) == 0)
2717 if (*pszGroupName
== 0)
2719 if (CurrentService
->lpGroup
!= NULL
)
2724 if ((CurrentService
->lpGroup
== NULL
) ||
2725 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2730 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2731 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2732 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2734 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2736 /* Copy the service name */
2738 CurrentService
->lpServiceName
);
2739 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2740 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
2742 /* Copy the display name */
2744 CurrentService
->lpDisplayName
);
2745 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2746 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
2748 /* Copy the status information */
2749 memcpy(&lpStatusPtr
->ServiceStatusProcess
,
2750 &CurrentService
->Status
,
2751 sizeof(SERVICE_STATUS
));
2752 lpStatusPtr
->ServiceStatusProcess
.dwProcessId
= CurrentService
->ProcessId
; /* FIXME */
2753 lpStatusPtr
->ServiceStatusProcess
.dwServiceFlags
= 0; /* FIXME */
2756 dwRequiredSize
+= dwSize
;
2766 /* Unlock the service list */
2768 DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError
);
2775 /* ScmrSendTSMessage */
2778 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2780 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2784 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2786 HeapFree(GetProcessHeap(), 0, ptr
);