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 DWORD dwRequiredSize
;
1622 LPQUERY_SERVICE_CONFIGW lpConfig
;
1625 DPRINT("ScmrQueryServiceConfigW() called\n");
1628 return ERROR_SHUTDOWN_IN_PROGRESS
;
1630 hSvc
= (PSERVICE_HANDLE
)hService
;
1631 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1633 DPRINT1("Invalid handle tag!\n");
1634 return ERROR_INVALID_HANDLE
;
1637 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1638 SERVICE_QUERY_CONFIG
))
1640 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1641 return ERROR_ACCESS_DENIED
;
1644 lpService
= hSvc
->ServiceEntry
;
1645 if (lpService
== NULL
)
1647 DPRINT1("lpService == NULL!\n");
1648 return ERROR_INVALID_HANDLE
;
1651 /* FIXME: Lock the service database shared */
1653 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
1656 if (dwError
!= ERROR_SUCCESS
)
1659 dwError
= ScmReadString(hServiceKey
,
1662 if (dwError
!= ERROR_SUCCESS
)
1665 dwRequiredSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1667 if (lpImagePath
!= NULL
)
1668 dwRequiredSize
+= ((wcslen(lpImagePath
) + 1) * sizeof(WCHAR
));
1670 if (lpService
->lpGroup
!= NULL
)
1671 dwRequiredSize
+= ((wcslen(lpService
->lpGroup
->lpGroupName
) + 1) * sizeof(WCHAR
));
1673 /* FIXME: Add Dependencies length*/
1675 /* FIXME: Add ServiceStartName length*/
1677 if (lpService
->lpDisplayName
!= NULL
)
1678 dwRequiredSize
+= ((wcslen(lpService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1680 if (lpServiceConfig
== NULL
|| cbBufSize
< dwRequiredSize
)
1682 dwError
= ERROR_INSUFFICIENT_BUFFER
;
1686 lpConfig
= (LPQUERY_SERVICE_CONFIGW
)lpServiceConfig
;
1687 lpConfig
->dwServiceType
= lpService
->Status
.dwServiceType
;
1688 lpConfig
->dwStartType
= lpService
->dwStartType
;
1689 lpConfig
->dwErrorControl
= lpService
->dwErrorControl
;
1690 lpConfig
->dwTagId
= lpService
->dwTag
;
1692 lpStr
= (LPWSTR
)(lpConfig
+ 1);
1694 if (lpImagePath
!= NULL
)
1696 wcscpy(lpStr
, lpImagePath
);
1697 lpConfig
->lpBinaryPathName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1698 lpStr
+= (wcslen(lpImagePath
) + 1);
1702 lpConfig
->lpBinaryPathName
= NULL
;
1705 if (lpService
->lpGroup
!= NULL
)
1707 wcscpy(lpStr
, lpService
->lpGroup
->lpGroupName
);
1708 lpConfig
->lpLoadOrderGroup
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1709 lpStr
+= (wcslen(lpService
->lpGroup
->lpGroupName
) + 1);
1713 lpConfig
->lpLoadOrderGroup
= NULL
;
1716 /* FIXME: Append Dependencies */
1717 lpConfig
->lpDependencies
= NULL
;
1719 /* FIXME: Append ServiceStartName */
1720 lpConfig
->lpServiceStartName
= NULL
;
1722 if (lpService
->lpDisplayName
!= NULL
)
1724 wcscpy(lpStr
, lpService
->lpDisplayName
);
1725 lpConfig
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1729 lpConfig
->lpDisplayName
= NULL
;
1733 if (pcbBytesNeeded
!= NULL
)
1734 *pcbBytesNeeded
= dwRequiredSize
;
1737 if (lpImagePath
!= NULL
)
1738 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1740 if (hServiceKey
!= NULL
)
1741 RegCloseKey(hServiceKey
);
1743 /* FIXME: Unlock the service database */
1745 DPRINT("ScmrQueryServiceConfigW() done\n");
1753 ScmrQueryServiceLockStatusW(handle_t BindingHandle
,
1754 unsigned int hSCManager
,
1755 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
1756 unsigned long cbBufSize
, /* [in] */
1757 unsigned long *pcbBytesNeeded
) /* [out] */
1759 DPRINT1("ScmrQueryServiceLockStatusW() called\n");
1760 return ERROR_CALL_NOT_IMPLEMENTED
;
1766 ScmrStartServiceW(handle_t BindingHandle
,
1767 unsigned int hService
,
1768 unsigned long dwNumServiceArgs
,
1769 unsigned char *lpServiceArgBuffer
,
1770 unsigned long cbBufSize
)
1772 DWORD dwError
= ERROR_SUCCESS
;
1773 PSERVICE_HANDLE hSvc
;
1774 PSERVICE lpService
= NULL
;
1776 DPRINT("ScmrStartServiceW() called\n");
1779 return ERROR_SHUTDOWN_IN_PROGRESS
;
1781 hSvc
= (PSERVICE_HANDLE
)hService
;
1782 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1784 DPRINT1("Invalid handle tag!\n");
1785 return ERROR_INVALID_HANDLE
;
1788 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1791 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1792 return ERROR_ACCESS_DENIED
;
1795 lpService
= hSvc
->ServiceEntry
;
1796 if (lpService
== NULL
)
1798 DPRINT1("lpService == NULL!\n");
1799 return ERROR_INVALID_HANDLE
;
1802 if (lpService
->dwStartType
== SERVICE_DISABLED
)
1803 return ERROR_SERVICE_DISABLED
;
1805 if (lpService
->bDeleted
)
1806 return ERROR_SERVICE_MARKED_FOR_DELETE
;
1808 /* Start the service */
1809 dwError
= ScmStartService(lpService
, (LPWSTR
)lpServiceArgBuffer
);
1817 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1818 unsigned int hSCManager
,
1819 wchar_t *lpServiceName
,
1820 wchar_t *lpDisplayName
, /* [out, unique] */
1821 unsigned long *lpcchBuffer
)
1823 // PMANAGER_HANDLE hManager;
1828 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1829 DPRINT("hSCManager = %x\n", hSCManager
);
1830 DPRINT("lpServiceName: %S\n", lpServiceName
);
1831 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1832 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1834 // hManager = (PMANAGER_HANDLE)hSCManager;
1835 // if (hManager->Handle.Tag != MANAGER_TAG)
1837 // DPRINT1("Invalid manager handle!\n");
1838 // return ERROR_INVALID_HANDLE;
1841 /* Get service database entry */
1842 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1843 if (lpService
== NULL
)
1845 DPRINT1("Could not find a service!\n");
1846 return ERROR_SERVICE_DOES_NOT_EXIST
;
1849 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1851 if (lpDisplayName
!= NULL
&&
1852 *lpcchBuffer
>= dwLength
)
1854 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1857 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1859 *lpcchBuffer
= dwLength
;
1867 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1868 unsigned int hSCManager
,
1869 wchar_t *lpDisplayName
,
1870 wchar_t *lpServiceName
, /* [out, unique] */
1871 unsigned long *lpcchBuffer
)
1873 // PMANAGER_HANDLE hManager;
1878 DPRINT("ScmrGetServiceKeyNameW() called\n");
1879 DPRINT("hSCManager = %x\n", hSCManager
);
1880 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1881 DPRINT("lpServiceName: %p\n", lpServiceName
);
1882 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1884 // hManager = (PMANAGER_HANDLE)hSCManager;
1885 // if (hManager->Handle.Tag != MANAGER_TAG)
1887 // DPRINT1("Invalid manager handle!\n");
1888 // return ERROR_INVALID_HANDLE;
1891 /* Get service database entry */
1892 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1893 if (lpService
== NULL
)
1895 DPRINT1("Could not find a service!\n");
1896 return ERROR_SERVICE_DOES_NOT_EXIST
;
1899 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1901 if (lpServiceName
!= NULL
&&
1902 *lpcchBuffer
>= dwLength
)
1904 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1907 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1909 *lpcchBuffer
= dwLength
;
1917 ScmrSetServiceBitsA(handle_t BindingHandle
,
1918 unsigned long hServiceStatus
,
1919 unsigned long dwServiceBits
,
1920 unsigned long bSetBitsOn
,
1921 unsigned long bUpdateImmediately
,
1924 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1925 return ERROR_CALL_NOT_IMPLEMENTED
;
1931 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1932 unsigned int hService
,
1933 unsigned long dwServiceType
,
1934 unsigned long dwStartType
,
1935 unsigned long dwErrorControl
,
1936 char *lpBinaryPathName
,
1937 char *lpLoadOrderGroup
,
1938 unsigned long *lpdwTagId
,
1939 char *lpDependencies
,
1940 unsigned long dwDependenciesLength
,
1941 char *lpServiceStartName
,
1943 unsigned long dwPasswordLength
,
1944 char *lpDisplayName
)
1946 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1947 return ERROR_CALL_NOT_IMPLEMENTED
;
1953 ScmrCreateServiceA(handle_t BindingHandle
,
1954 unsigned int hSCManager
,
1955 char *lpServiceName
,
1956 char *lpDisplayName
,
1957 unsigned long dwDesiredAccess
,
1958 unsigned long dwServiceType
,
1959 unsigned long dwStartType
,
1960 unsigned long dwErrorControl
,
1961 char *lpBinaryPathName
,
1962 char *lpLoadOrderGroup
,
1963 unsigned long *lpdwTagId
, /* in, out */
1964 char *lpDependencies
,
1965 unsigned long dwDependenciesLength
,
1966 char *lpServiceStartName
,
1968 unsigned long dwPasswordLength
,
1969 unsigned int *hService
) /* out */
1971 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1972 return ERROR_CALL_NOT_IMPLEMENTED
;
1978 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1979 unsigned int hService
,
1980 unsigned long dwServiceState
,
1981 unsigned char *lpServices
,
1982 unsigned long cbBufSize
,
1983 unsigned long *pcbBytesNeeded
,
1984 unsigned long *lpServicesReturned
)
1986 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
1987 *pcbBytesNeeded
= 0;
1988 *lpServicesReturned
= 0;
1989 return ERROR_CALL_NOT_IMPLEMENTED
;
1995 ScmrEnumServicesStatusA(handle_t BindingHandle
,
1996 unsigned int hSCManager
,
1997 unsigned long dwServiceType
,
1998 unsigned long dwServiceState
,
1999 unsigned char *lpServices
,
2000 unsigned long dwBufSize
,
2001 unsigned long *pcbBytesNeeded
,
2002 unsigned long *lpServicesReturned
,
2003 unsigned long *lpResumeHandle
)
2005 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
2006 return ERROR_CALL_NOT_IMPLEMENTED
;
2012 ScmrOpenSCManagerA(handle_t BindingHandle
,
2013 char *lpMachineName
,
2014 char *lpDatabaseName
,
2015 unsigned long dwDesiredAccess
,
2018 UNICODE_STRING MachineName
;
2019 UNICODE_STRING DatabaseName
;
2022 DPRINT("ScmrOpenSCManagerA() called\n");
2025 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
2029 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
2032 dwError
= ScmrOpenSCManagerW(BindingHandle
,
2033 lpMachineName
? MachineName
.Buffer
: NULL
,
2034 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
2039 RtlFreeUnicodeString(&MachineName
);
2042 RtlFreeUnicodeString(&DatabaseName
);
2050 ScmrOpenServiceA(handle_t BindingHandle
,
2051 unsigned int hSCManager
,
2052 char *lpServiceName
,
2053 unsigned long dwDesiredAccess
,
2054 unsigned int *hService
)
2056 UNICODE_STRING ServiceName
;
2059 DPRINT("ScmrOpenServiceA() called\n");
2061 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
2064 dwError
= ScmrOpenServiceW(BindingHandle
,
2070 RtlFreeUnicodeString(&ServiceName
);
2078 ScmrQueryServiceConfigA(handle_t BindingHandle
,
2079 unsigned int hService
,
2080 unsigned char *lpServiceConfig
,
2081 unsigned long cbBufSize
,
2082 unsigned long *pcbBytesNeeded
)
2084 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2085 return ERROR_CALL_NOT_IMPLEMENTED
;
2091 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2092 unsigned int hSCManager
,
2093 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2094 unsigned long cbBufSize
, /* [in] */
2095 unsigned long *pcbBytesNeeded
) /* [out] */
2097 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2098 return ERROR_CALL_NOT_IMPLEMENTED
;
2104 ScmrStartServiceA(handle_t BindingHandle
,
2105 unsigned int hService
,
2106 unsigned long dwNumServiceArgs
,
2107 unsigned char *lpServiceArgBuffer
,
2108 unsigned long cbBufSize
)
2110 DWORD dwError
= ERROR_SUCCESS
;
2111 PSERVICE_HANDLE hSvc
;
2112 PSERVICE lpService
= NULL
;
2114 DPRINT1("ScmrStartServiceA() called\n");
2117 return ERROR_SHUTDOWN_IN_PROGRESS
;
2119 hSvc
= (PSERVICE_HANDLE
)hService
;
2120 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2122 DPRINT1("Invalid handle tag!\n");
2123 return ERROR_INVALID_HANDLE
;
2126 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2129 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2130 return ERROR_ACCESS_DENIED
;
2133 lpService
= hSvc
->ServiceEntry
;
2134 if (lpService
== NULL
)
2136 DPRINT1("lpService == NULL!\n");
2137 return ERROR_INVALID_HANDLE
;
2140 if (lpService
->dwStartType
== SERVICE_DISABLED
)
2141 return ERROR_SERVICE_DISABLED
;
2143 if (lpService
->bDeleted
)
2144 return ERROR_SERVICE_MARKED_FOR_DELETE
;
2146 /* FIXME: Convert argument vector to Unicode */
2148 /* Start the service */
2149 dwError
= ScmStartService(lpService
, NULL
);
2151 /* FIXME: Free argument vector */
2159 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2160 unsigned int hSCManager
,
2161 char *lpServiceName
,
2162 char *lpDisplayName
, /* [out, unique] */
2163 unsigned long *lpcchBuffer
)
2165 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2166 return ERROR_CALL_NOT_IMPLEMENTED
;
2172 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2173 unsigned int hSCManager
,
2174 char *lpDisplayName
,
2175 char *lpServiceName
, /* [out, unique] */
2176 unsigned long *lpcchBuffer
)
2178 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2179 return ERROR_CALL_NOT_IMPLEMENTED
;
2185 ScmrGetCurrentGroupStateW(handle_t BindingHandle
)
2187 DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
2188 return ERROR_CALL_NOT_IMPLEMENTED
;
2194 ScmrEnumServiceGroupW(handle_t BindingHandle
)
2196 DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
2197 return ERROR_CALL_NOT_IMPLEMENTED
;
2203 ScmrChangeServiceConfig2A(handle_t BindingHandle
,
2204 unsigned int hService
,
2205 unsigned long dwInfoLevel
,
2206 unsigned char *lpInfo
,
2207 unsigned long dwInfoSize
)
2209 DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
2210 return ERROR_CALL_NOT_IMPLEMENTED
;
2216 ScmrChangeServiceConfig2W(handle_t BindingHandle
,
2217 unsigned int hService
,
2218 unsigned long dwInfoLevel
,
2219 unsigned char *lpInfo
,
2220 unsigned long dwInfoSize
)
2222 DPRINT1("ScmrChangeServiceConfig2W() is unimplemented\n");
2223 return ERROR_CALL_NOT_IMPLEMENTED
;
2229 ScmrQueryServiceConfig2A(handle_t BindingHandle
,
2230 unsigned int hService
,
2231 unsigned long dwInfoLevel
,
2232 unsigned char *lpBuffer
,
2233 unsigned long cbBufSize
,
2234 unsigned long *pcbBytesNeeded
)
2236 DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
2237 return ERROR_CALL_NOT_IMPLEMENTED
;
2243 ScmrQueryServiceConfig2W(handle_t BindingHandle
,
2244 unsigned int hService
,
2245 unsigned long dwInfoLevel
,
2246 unsigned char *lpBuffer
,
2247 unsigned long cbBufSize
,
2248 unsigned long *pcbBytesNeeded
)
2250 DPRINT1("ScmrQueryServiceConfig2W() is unimplemented\n");
2251 return ERROR_CALL_NOT_IMPLEMENTED
;
2257 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2258 unsigned int hService
,
2259 unsigned long InfoLevel
,
2260 unsigned char *lpBuffer
, /* out */
2261 unsigned long cbBufSize
,
2262 unsigned long *pcbBytesNeeded
) /* out */
2264 LPSERVICE_STATUS_PROCESS lpStatus
;
2265 PSERVICE_HANDLE hSvc
;
2268 DPRINT("ScmrQueryServiceStatusEx() called\n");
2271 return ERROR_SHUTDOWN_IN_PROGRESS
;
2273 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2274 return ERROR_INVALID_LEVEL
;
2276 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2278 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2279 return ERROR_INSUFFICIENT_BUFFER
;
2281 hSvc
= (PSERVICE_HANDLE
)hService
;
2282 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2284 DPRINT1("Invalid handle tag!\n");
2285 return ERROR_INVALID_HANDLE
;
2288 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2289 SERVICE_QUERY_STATUS
))
2291 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2292 return ERROR_ACCESS_DENIED
;
2295 lpService
= hSvc
->ServiceEntry
;
2296 if (lpService
== NULL
)
2298 DPRINT1("lpService == NULL!\n");
2299 return ERROR_INVALID_HANDLE
;
2302 lpStatus
= (LPSERVICE_STATUS_PROCESS
)lpBuffer
;
2304 /* Return service status information */
2305 RtlCopyMemory(lpStatus
,
2307 sizeof(SERVICE_STATUS
));
2309 lpStatus
->dwProcessId
= lpService
->ProcessId
; /* FIXME */
2310 lpStatus
->dwServiceFlags
= 0; /* FIXME */
2312 return ERROR_SUCCESS
;
2318 ScmrEnumServicesStatusExA(handle_t BindingHandle
,
2319 unsigned int hSCManager
,
2320 unsigned long InfoLevel
,
2321 unsigned long dwServiceType
,
2322 unsigned long dwServiceState
,
2323 unsigned char *lpServices
,
2324 unsigned long dwBufSize
,
2325 unsigned long *pcbBytesNeeded
,
2326 unsigned long *lpServicesReturned
,
2327 unsigned long *lpResumeHandle
,
2330 DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
2331 *pcbBytesNeeded
= 0;
2332 *lpServicesReturned
= 0;
2333 return ERROR_CALL_NOT_IMPLEMENTED
;
2339 ScmrEnumServicesStatusExW(handle_t BindingHandle
,
2340 unsigned int hSCManager
,
2341 unsigned long InfoLevel
,
2342 unsigned long dwServiceType
,
2343 unsigned long dwServiceState
,
2344 unsigned char *lpServices
,
2345 unsigned long dwBufSize
,
2346 unsigned long *pcbBytesNeeded
,
2347 unsigned long *lpServicesReturned
,
2348 unsigned long *lpResumeHandle
,
2349 wchar_t *pszGroupName
)
2351 PMANAGER_HANDLE hManager
;
2353 DWORD dwError
= ERROR_SUCCESS
;
2354 PLIST_ENTRY ServiceEntry
;
2355 PSERVICE CurrentService
;
2357 DWORD dwRequiredSize
;
2358 DWORD dwServiceCount
;
2360 DWORD dwLastResumeCount
;
2361 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
2364 DPRINT("ScmrEnumServicesStatusExW() called\n");
2367 return ERROR_SHUTDOWN_IN_PROGRESS
;
2369 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
2370 return ERROR_INVALID_LEVEL
;
2372 hManager
= (PMANAGER_HANDLE
)hSCManager
;
2373 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
2375 DPRINT1("Invalid manager handle!\n");
2376 return ERROR_INVALID_HANDLE
;
2379 /* Check access rights */
2380 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
2381 SC_MANAGER_ENUMERATE_SERVICE
))
2383 DPRINT1("Insufficient access rights! 0x%lx\n",
2384 hManager
->Handle
.DesiredAccess
);
2385 return ERROR_ACCESS_DENIED
;
2388 *pcbBytesNeeded
= 0;
2389 *lpServicesReturned
= 0;
2391 dwLastResumeCount
= *lpResumeHandle
;
2393 /* Lock the service list shared */
2395 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
2396 if (lpService
== NULL
)
2398 dwError
= ERROR_SUCCESS
;
2405 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2406 ServiceEntry
!= &ServiceListHead
;
2407 ServiceEntry
= ServiceEntry
->Flink
)
2409 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2413 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2416 dwState
= SERVICE_ACTIVE
;
2417 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2418 dwState
= SERVICE_INACTIVE
;
2420 if ((dwState
& dwServiceState
) == 0)
2425 if (*pszGroupName
== 0)
2427 if (CurrentService
->lpGroup
!= NULL
)
2432 if ((CurrentService
->lpGroup
== NULL
) ||
2433 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2438 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2439 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2440 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2442 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2444 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
2445 dwRequiredSize
+= dwSize
;
2447 dwLastResumeCount
= CurrentService
->dwResumeCount
;
2451 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
2457 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
2458 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
2461 ServiceEntry
!= &ServiceListHead
;
2462 ServiceEntry
= ServiceEntry
->Flink
)
2464 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2468 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2471 dwState
= SERVICE_ACTIVE
;
2472 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2473 dwState
= SERVICE_INACTIVE
;
2475 if ((dwState
& dwServiceState
) == 0)
2480 if (*pszGroupName
== 0)
2482 if (CurrentService
->lpGroup
!= NULL
)
2487 if ((CurrentService
->lpGroup
== NULL
) ||
2488 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2493 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2494 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2495 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
2497 dwError
= ERROR_MORE_DATA
;
2500 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
2502 *lpResumeHandle
= dwLastResumeCount
;
2503 *lpServicesReturned
= dwServiceCount
;
2504 *pcbBytesNeeded
= dwRequiredSize
;
2506 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
2507 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
2508 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS_PROCESSW
));
2511 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2512 ServiceEntry
!= &ServiceListHead
;
2513 ServiceEntry
= ServiceEntry
->Flink
)
2515 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2519 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2522 dwState
= SERVICE_ACTIVE
;
2523 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2524 dwState
= SERVICE_INACTIVE
;
2526 if ((dwState
& dwServiceState
) == 0)
2531 if (*pszGroupName
== 0)
2533 if (CurrentService
->lpGroup
!= NULL
)
2538 if ((CurrentService
->lpGroup
== NULL
) ||
2539 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2544 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2545 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2546 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2548 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2550 /* Copy the service name */
2552 CurrentService
->lpServiceName
);
2553 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2554 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
2556 /* Copy the display name */
2558 CurrentService
->lpDisplayName
);
2559 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2560 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
2562 /* Copy the status information */
2563 memcpy(&lpStatusPtr
->ServiceStatusProcess
,
2564 &CurrentService
->Status
,
2565 sizeof(SERVICE_STATUS
));
2566 lpStatusPtr
->ServiceStatusProcess
.dwProcessId
= CurrentService
->ProcessId
; /* FIXME */
2567 lpStatusPtr
->ServiceStatusProcess
.dwServiceFlags
= 0; /* FIXME */
2570 dwRequiredSize
+= dwSize
;
2580 /* Unlock the service list */
2582 DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError
);
2589 /* ScmrSendTSMessage */
2592 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2594 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2598 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2600 HeapFree(GetProcessHeap(), 0, ptr
);