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
= 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
= 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(LPWSTR lpServiceGroup
,
227 DPRINT("Assigning new tag in group %S\n", lpServiceGroup
);
229 return ERROR_SUCCESS
;
235 ScmrCloseServiceHandle(handle_t BindingHandle
,
236 unsigned int hScObject
)
238 PMANAGER_HANDLE hManager
;
240 DPRINT("ScmrCloseServiceHandle() called\n");
242 DPRINT("hScObject = %X\n", hScObject
);
245 return ERROR_INVALID_HANDLE
;
247 hManager
= (PMANAGER_HANDLE
)hScObject
;
248 if (hManager
->Handle
.Tag
== MANAGER_TAG
)
250 DPRINT("Found manager handle\n");
252 hManager
->Handle
.RefCount
--;
253 if (hManager
->Handle
.RefCount
== 0)
255 /* FIXME: add cleanup code */
257 HeapFree(GetProcessHeap(), 0, hManager
);
260 DPRINT("ScmrCloseServiceHandle() done\n");
261 return ERROR_SUCCESS
;
263 else if (hManager
->Handle
.Tag
== SERVICE_TAG
)
265 DPRINT("Found service handle\n");
267 hManager
->Handle
.RefCount
--;
268 if (hManager
->Handle
.RefCount
== 0)
270 /* FIXME: add cleanup code */
272 HeapFree(GetProcessHeap(), 0, hManager
);
275 DPRINT("ScmrCloseServiceHandle() done\n");
276 return ERROR_SUCCESS
;
279 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager
->Handle
.Tag
);
281 return ERROR_INVALID_HANDLE
;
287 ScmrControlService(handle_t BindingHandle
,
288 unsigned int hService
,
289 unsigned long dwControl
,
290 LPSERVICE_STATUS lpServiceStatus
)
292 PSERVICE_HANDLE hSvc
;
294 ACCESS_MASK DesiredAccess
;
295 DWORD dwError
= ERROR_SUCCESS
;
297 DPRINT("ScmrControlService() called\n");
300 return ERROR_SHUTDOWN_IN_PROGRESS
;
302 /* Check the service handle */
303 hSvc
= (PSERVICE_HANDLE
)hService
;
304 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
306 DPRINT1("Invalid handle tag!\n");
307 return ERROR_INVALID_HANDLE
;
310 /* Check access rights */
313 case SERVICE_CONTROL_STOP
:
314 DesiredAccess
= SERVICE_STOP
;
317 case SERVICE_CONTROL_PAUSE
:
318 case SERVICE_CONTROL_CONTINUE
:
319 DesiredAccess
= SERVICE_PAUSE_CONTINUE
;
322 case SERVICE_INTERROGATE
:
323 DesiredAccess
= SERVICE_INTERROGATE
;
327 if (dwControl
>= 128 && dwControl
<= 255)
328 DesiredAccess
= SERVICE_USER_DEFINED_CONTROL
;
330 DesiredAccess
= SERVICE_QUERY_CONFIG
|
331 SERVICE_CHANGE_CONFIG
|
332 SERVICE_QUERY_STATUS
|
334 SERVICE_PAUSE_CONTINUE
;
338 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
340 return ERROR_ACCESS_DENIED
;
342 /* Check the service entry point */
343 lpService
= hSvc
->ServiceEntry
;
344 if (lpService
== NULL
)
346 DPRINT1("lpService == NULL!\n");
347 return ERROR_INVALID_HANDLE
;
350 if (lpService
->Status
.dwServiceType
& SERVICE_DRIVER
)
352 /* Send control code to the driver */
353 dwError
= ScmControlDriver(lpService
,
359 /* FIXME: Send control code to the service */
361 dwError
= ScmControlService(lpService
,
365 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
368 /* Return service status information */
369 RtlCopyMemory(lpServiceStatus
,
371 sizeof(SERVICE_STATUS
));
379 ScmrDeleteService(handle_t BindingHandle
,
380 unsigned int hService
)
382 PSERVICE_HANDLE hSvc
;
386 DPRINT("ScmrDeleteService() called\n");
389 return ERROR_SHUTDOWN_IN_PROGRESS
;
391 hSvc
= (PSERVICE_HANDLE
)hService
;
392 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
393 return ERROR_INVALID_HANDLE
;
395 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
396 STANDARD_RIGHTS_REQUIRED
))
397 return ERROR_ACCESS_DENIED
;
399 lpService
= hSvc
->ServiceEntry
;
400 if (lpService
== NULL
)
402 DPRINT1("lpService == NULL!\n");
403 return ERROR_INVALID_HANDLE
;
406 /* FIXME: Acquire service database lock exclusively */
408 if (lpService
->bDeleted
)
410 DPRINT1("The service has already been marked for delete!\n");
411 return ERROR_SERVICE_MARKED_FOR_DELETE
;
414 /* Mark service for delete */
415 lpService
->bDeleted
= TRUE
;
417 dwError
= ScmMarkServiceForDelete(lpService
);
419 /* FIXME: Release service database lock */
421 DPRINT("ScmrDeleteService() done\n");
429 ScmrLockServiceDatabase(handle_t BindingHandle
,
430 unsigned int hSCManager
,
433 PMANAGER_HANDLE hMgr
;
435 DPRINT("ScmrLockServiceDatabase() called\n");
439 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
440 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
441 return ERROR_INVALID_HANDLE
;
443 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
445 return ERROR_ACCESS_DENIED
;
447 // return ScmLockDatabase(0, hMgr->0xC, hLock);
449 /* FIXME: Lock the database */
450 *hLock
= 0x12345678; /* Dummy! */
452 return ERROR_SUCCESS
;
458 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
,
459 unsigned int hService
,
460 unsigned long dwSecurityInformation
,
461 unsigned char *lpSecurityDescriptor
,
462 unsigned long dwSecuityDescriptorSize
,
463 unsigned long *pcbBytesNeeded
)
466 PSERVICE_HANDLE hSvc
;
468 ULONG DesiredAccess
= 0;
473 DPRINT("ScmrQueryServiceObjectSecurity() called\n");
475 hSvc
= (PSERVICE_HANDLE
)hService
;
476 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
478 DPRINT1("Invalid handle tag!\n");
479 return ERROR_INVALID_HANDLE
;
482 if (dwSecurityInformation
& (DACL_SECURITY_INFORMATION
||
483 GROUP_SECURITY_INFORMATION
||
484 OWNER_SECURITY_INFORMATION
))
485 DesiredAccess
|= READ_CONTROL
;
487 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
488 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
490 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
493 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
494 return ERROR_ACCESS_DENIED
;
497 lpService
= hSvc
->ServiceEntry
;
498 if (lpService
== NULL
)
500 DPRINT1("lpService == NULL!\n");
501 return ERROR_INVALID_HANDLE
;
504 /* FIXME: Lock the service list */
506 Status
= RtlQuerySecurityObject(lpService
->lpSecurityDescriptor
,
507 dwSecurityInformation
,
508 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
509 dwSecuityDescriptorSize
,
512 /* FIXME: Unlock the service list */
514 if (NT_SUCCESS(Status
))
516 *pcbBytesNeeded
= dwBytesNeeded
;
517 dwError
= STATUS_SUCCESS
;
519 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
521 *pcbBytesNeeded
= dwBytesNeeded
;
522 dwError
= ERROR_INSUFFICIENT_BUFFER
;
524 else if (Status
== STATUS_BAD_DESCRIPTOR_FORMAT
)
526 dwError
= ERROR_GEN_FAILURE
;
530 dwError
= RtlNtStatusToDosError(Status
);
535 DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
536 return ERROR_CALL_NOT_IMPLEMENTED
;
542 ScmrSetServiceObjectSecurity(handle_t BindingHandle
,
543 unsigned int hService
,
544 unsigned long dwSecurityInformation
,
545 unsigned char *lpSecurityDescriptor
,
546 unsigned long dwSecuityDescriptorSize
)
549 PSERVICE_HANDLE hSvc
;
551 ULONG DesiredAccess
= 0;
552 HANDLE hToken
= NULL
;
557 DPRINT1("ScmrSetServiceObjectSecurity() called\n");
559 hSvc
= (PSERVICE_HANDLE
)hService
;
560 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
562 DPRINT1("Invalid handle tag!\n");
563 return ERROR_INVALID_HANDLE
;
566 if (dwSecurityInformation
== 0 ||
567 dwSecurityInformation
& ~0xF)
570 if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
))
573 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
574 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
576 if (dwSecurityInformation
& DACL_SECURITY_INFORMATION
)
577 DesiredAccess
|= 0x40000;
579 if (dwSecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
580 DesiredAccess
|= 0x80000;
582 if ((dwSecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
583 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Owner
== NULL
))
586 if ((dwSecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
587 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Group
== NULL
))
590 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
593 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
594 return ERROR_ACCESS_DENIED
;
597 lpService
= hSvc
->ServiceEntry
;
598 if (lpService
== NULL
)
600 DPRINT1("lpService == NULL!\n");
601 return ERROR_INVALID_HANDLE
;
604 if (lpService
->bDeleted
)
607 // RpcImpersonateClient(NULL);
609 Status
= NtOpenThreadToken(NtCurrentThread(),
613 if (!NT_SUCCESS(Status
))
614 return RtlNtStatusToDosError(Status
);
616 // RpcRevertToSelf();
618 /* FIXME: Lock service database */
620 Status
= RtlSetSecurityObject(dwSecurityInformation
,
621 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
622 &lpService
->lpSecurityDescriptor
,
625 if (!NT_SUCCESS(Status
))
627 dwError
= RtlNtStatusToDosError(Status
);
631 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
634 if (dwError
!= ERROR_SUCCESS
)
637 // dwError = ScmWriteSecurityDescriptor(hServiceKey,
638 // lpService->lpSecurityDescriptor);
640 RegFlushKey(hServiceKey
);
641 RegCloseKey(hServiceKey
);
648 /* FIXME: Unlock service database */
650 DPRINT1("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError
);
655 DPRINT1("ScmrSetServiceObjectSecurity() is unimplemented\n");
656 return ERROR_CALL_NOT_IMPLEMENTED
;
662 ScmrQueryServiceStatus(handle_t BindingHandle
,
663 unsigned int hService
,
664 LPSERVICE_STATUS lpServiceStatus
)
666 PSERVICE_HANDLE hSvc
;
669 DPRINT("ScmrQueryServiceStatus() called\n");
672 return ERROR_SHUTDOWN_IN_PROGRESS
;
674 hSvc
= (PSERVICE_HANDLE
)hService
;
675 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
677 DPRINT1("Invalid handle tag!\n");
678 return ERROR_INVALID_HANDLE
;
681 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
682 SERVICE_QUERY_STATUS
))
684 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
685 return ERROR_ACCESS_DENIED
;
688 lpService
= hSvc
->ServiceEntry
;
689 if (lpService
== NULL
)
691 DPRINT1("lpService == NULL!\n");
692 return ERROR_INVALID_HANDLE
;
695 /* Return service status information */
696 RtlCopyMemory(lpServiceStatus
,
698 sizeof(SERVICE_STATUS
));
700 return ERROR_SUCCESS
;
706 ScmrSetServiceStatus(handle_t BindingHandle
,
707 unsigned long hServiceStatus
) /* FIXME */
709 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
711 return ERROR_CALL_NOT_IMPLEMENTED
;
717 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
720 DPRINT1("ScmrUnlockServiceDatabase() called\n");
722 return ERROR_SUCCESS
;
728 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
729 unsigned long BootAcceptable
)
731 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
733 return ERROR_CALL_NOT_IMPLEMENTED
;
739 ScmrSetServiceBitsW(handle_t BindingHandle
,
740 unsigned long hServiceStatus
,
741 unsigned long dwServiceBits
,
742 unsigned long bSetBitsOn
,
743 unsigned long bUpdateImmediately
,
746 DPRINT1("ScmrSetServiceBitsW() called\n");
748 return ERROR_CALL_NOT_IMPLEMENTED
;
754 ScmrChangeServiceConfigW(handle_t BiningHandle
,
755 unsigned int hService
,
756 unsigned long dwServiceType
,
757 unsigned long dwStartType
,
758 unsigned long dwErrorControl
,
759 wchar_t *lpBinaryPathName
,
760 wchar_t *lpLoadOrderGroup
,
761 unsigned long *lpdwTagId
, /* in, out, unique */
762 wchar_t *lpDependencies
,
763 unsigned long dwDependenciesLength
,
764 wchar_t *lpServiceStartName
,
766 unsigned long dwPasswordLength
,
767 wchar_t *lpDisplayName
)
769 DWORD dwError
= ERROR_SUCCESS
;
770 PSERVICE_HANDLE hSvc
;
771 PSERVICE lpService
= NULL
;
772 HKEY hServiceKey
= NULL
;
774 DPRINT("ScmrChangeServiceConfigW() called\n");
775 DPRINT("dwServiceType = %lu\n", dwServiceType
);
776 DPRINT("dwStartType = %lu\n", dwStartType
);
777 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
778 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
779 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
780 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
783 return ERROR_SHUTDOWN_IN_PROGRESS
;
785 hSvc
= (PSERVICE_HANDLE
)hService
;
786 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
788 DPRINT1("Invalid handle tag!\n");
789 return ERROR_INVALID_HANDLE
;
792 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
793 SERVICE_CHANGE_CONFIG
))
795 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
796 return ERROR_ACCESS_DENIED
;
799 lpService
= hSvc
->ServiceEntry
;
800 if (lpService
== NULL
)
802 DPRINT1("lpService == NULL!\n");
803 return ERROR_INVALID_HANDLE
;
806 /* FIXME: Lock database exclusively */
808 if (lpService
->bDeleted
)
810 /* FIXME: Unlock database */
811 DPRINT1("The service has already been marked for delete!\n");
812 return ERROR_SERVICE_MARKED_FOR_DELETE
;
815 /* Open the service key */
816 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
819 if (dwError
!= ERROR_SUCCESS
)
822 /* Write service data to the registry */
823 /* Set the display name */
824 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
826 RegSetValueExW(hServiceKey
,
830 (LPBYTE
)lpDisplayName
,
831 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
832 /* FIXME: update lpService->lpDisplayName */
835 if (dwServiceType
!= SERVICE_NO_CHANGE
)
837 /* Set the service type */
838 dwError
= RegSetValueExW(hServiceKey
,
842 (LPBYTE
)&dwServiceType
,
844 if (dwError
!= ERROR_SUCCESS
)
847 lpService
->Status
.dwServiceType
= dwServiceType
;
850 if (dwStartType
!= SERVICE_NO_CHANGE
)
852 /* Set the start value */
853 dwError
= RegSetValueExW(hServiceKey
,
857 (LPBYTE
)&dwStartType
,
859 if (dwError
!= ERROR_SUCCESS
)
862 lpService
->dwStartType
= dwStartType
;
865 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
867 /* Set the error control value */
868 dwError
= RegSetValueExW(hServiceKey
,
872 (LPBYTE
)&dwErrorControl
,
874 if (dwError
!= ERROR_SUCCESS
)
877 lpService
->dwErrorControl
= dwErrorControl
;
881 /* FIXME: set the new ImagePath value */
883 /* Set the image path */
884 if (dwServiceType
& SERVICE_WIN32
)
886 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
888 dwError
= RegSetValueExW(hServiceKey
,
892 (LPBYTE
)lpBinaryPathName
,
893 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
894 if (dwError
!= ERROR_SUCCESS
)
898 else if (dwServiceType
& SERVICE_DRIVER
)
900 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
902 dwError
= RegSetValueExW(hServiceKey
,
907 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
908 if (dwError
!= ERROR_SUCCESS
)
914 /* Set the group name */
915 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
917 dwError
= RegSetValueExW(hServiceKey
,
921 (LPBYTE
)lpLoadOrderGroup
,
922 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
923 if (dwError
!= ERROR_SUCCESS
)
925 /* FIXME: update lpService->lpServiceGroup */
928 if (lpdwTagId
!= NULL
)
930 dwError
= ScmAssignNewTag(lpService
->lpGroup
->lpGroupName
,
932 if (dwError
!= ERROR_SUCCESS
)
934 dwError
= RegSetValueExW(hServiceKey
,
938 (LPBYTE
)&lpService
->dwTag
,
940 if (dwError
!= ERROR_SUCCESS
)
942 *lpdwTagId
= lpService
->dwTag
;
945 /* Write dependencies */
946 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
948 dwError
= ScmWriteDependencies(hServiceKey
,
950 dwDependenciesLength
);
951 if (dwError
!= ERROR_SUCCESS
)
955 if (lpPassword
!= NULL
)
957 /* FIXME: Write password */
960 /* FIXME: Unlock database */
963 if (hServiceKey
!= NULL
)
964 RegCloseKey(hServiceKey
);
966 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
974 ScmrCreateServiceW(handle_t BindingHandle
,
975 unsigned int hSCManager
,
976 wchar_t *lpServiceName
,
977 wchar_t *lpDisplayName
,
978 unsigned long dwDesiredAccess
,
979 unsigned long dwServiceType
,
980 unsigned long dwStartType
,
981 unsigned long dwErrorControl
,
982 wchar_t *lpBinaryPathName
,
983 wchar_t *lpLoadOrderGroup
,
984 unsigned long *lpdwTagId
, /* in, out */
985 wchar_t *lpDependencies
,
986 unsigned long dwDependenciesLength
,
987 wchar_t *lpServiceStartName
,
989 unsigned long dwPasswordLength
,
990 unsigned int *hService
) /* out */
992 PMANAGER_HANDLE hManager
;
993 DWORD dwError
= ERROR_SUCCESS
;
994 PSERVICE lpService
= NULL
;
995 SC_HANDLE hServiceHandle
= NULL
;
996 LPWSTR lpImagePath
= NULL
;
997 HKEY hServiceKey
= NULL
;
999 DPRINT("ScmrCreateServiceW() called\n");
1000 DPRINT("lpServiceName = %S\n", lpServiceName
);
1001 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
1002 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess
);
1003 DPRINT("dwServiceType = %lu\n", dwServiceType
);
1004 DPRINT("dwStartType = %lu\n", dwStartType
);
1005 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
1006 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
1007 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
1010 return ERROR_SHUTDOWN_IN_PROGRESS
;
1012 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1013 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1015 DPRINT1("Invalid manager handle!\n");
1016 return ERROR_INVALID_HANDLE
;
1019 /* Check access rights */
1020 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1021 SC_MANAGER_CREATE_SERVICE
))
1023 DPRINT1("Insufficient access rights! 0x%lx\n",
1024 hManager
->Handle
.DesiredAccess
);
1025 return ERROR_ACCESS_DENIED
;
1028 /* Fail if the service already exists! */
1029 if (ScmGetServiceEntryByName(lpServiceName
) != NULL
)
1030 return ERROR_SERVICE_EXISTS
;
1032 if (dwServiceType
& SERVICE_DRIVER
)
1034 /* FIXME: Adjust the image path
1035 * Following line is VERY BAD, because it assumes that the
1036 * first part of full file name is the OS directory */
1037 if (lpBinaryPathName
[1] == ':') lpBinaryPathName
+= GetWindowsDirectoryW(NULL
, 0);
1039 lpImagePath
= HeapAlloc(GetProcessHeap(),
1041 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1042 if (lpImagePath
== NULL
)
1044 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1047 wcscpy(lpImagePath
, lpBinaryPathName
);
1050 /* Allocate a new service entry */
1051 dwError
= ScmCreateNewServiceRecord(lpServiceName
,
1053 if (dwError
!= ERROR_SUCCESS
)
1056 /* Fill the new service entry */
1057 lpService
->Status
.dwServiceType
= dwServiceType
;
1058 lpService
->dwStartType
= dwStartType
;
1059 lpService
->dwErrorControl
= dwErrorControl
;
1061 /* Fill the display name */
1062 if (lpDisplayName
!= NULL
&&
1063 *lpDisplayName
!= 0 &&
1064 wcsicmp(lpService
->lpDisplayName
, lpDisplayName
) != 0)
1066 lpService
->lpDisplayName
= HeapAlloc(GetProcessHeap(), 0,
1067 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1068 if (lpService
->lpDisplayName
== NULL
)
1070 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1073 wcscpy(lpService
->lpDisplayName
, lpDisplayName
);
1076 /* Write service data to the registry */
1077 /* Create the service key */
1078 dwError
= ScmCreateServiceKey(lpServiceName
,
1081 if (dwError
!= ERROR_SUCCESS
)
1084 /* Set the display name */
1085 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
1087 RegSetValueExW(hServiceKey
,
1091 (LPBYTE
)lpDisplayName
,
1092 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1095 /* Set the service type */
1096 dwError
= RegSetValueExW(hServiceKey
,
1100 (LPBYTE
)&dwServiceType
,
1102 if (dwError
!= ERROR_SUCCESS
)
1105 /* Set the start value */
1106 dwError
= RegSetValueExW(hServiceKey
,
1110 (LPBYTE
)&dwStartType
,
1112 if (dwError
!= ERROR_SUCCESS
)
1115 /* Set the error control value */
1116 dwError
= RegSetValueExW(hServiceKey
,
1120 (LPBYTE
)&dwErrorControl
,
1122 if (dwError
!= ERROR_SUCCESS
)
1125 /* Set the image path */
1126 if (dwServiceType
& SERVICE_WIN32
)
1128 dwError
= RegSetValueExW(hServiceKey
,
1132 (LPBYTE
)lpBinaryPathName
,
1133 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1134 if (dwError
!= ERROR_SUCCESS
)
1137 else if (dwServiceType
& SERVICE_DRIVER
)
1139 dwError
= RegSetValueExW(hServiceKey
,
1143 (LPBYTE
)lpImagePath
,
1144 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
1145 if (dwError
!= ERROR_SUCCESS
)
1149 /* Set the group name */
1150 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1152 dwError
= RegSetValueExW(hServiceKey
,
1156 (LPBYTE
)lpLoadOrderGroup
,
1157 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
1158 if (dwError
!= ERROR_SUCCESS
)
1162 if (lpdwTagId
!= NULL
)
1164 dwError
= ScmAssignNewTag(lpService
->lpGroup
->lpGroupName
,
1166 if (dwError
!= ERROR_SUCCESS
)
1168 dwError
= RegSetValueExW(hServiceKey
,
1172 (LPBYTE
)&lpService
->dwTag
,
1174 if (dwError
!= ERROR_SUCCESS
)
1178 /* Write dependencies */
1179 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
1181 dwError
= ScmWriteDependencies(hServiceKey
,
1183 dwDependenciesLength
);
1184 if (dwError
!= ERROR_SUCCESS
)
1188 if (lpPassword
!= NULL
)
1190 /* FIXME: Write password */
1193 dwError
= ScmCreateServiceHandle(lpService
,
1195 if (dwError
!= ERROR_SUCCESS
)
1198 dwError
= ScmCheckAccess(hServiceHandle
,
1200 if (dwError
!= ERROR_SUCCESS
)
1204 if (hServiceKey
!= NULL
)
1205 RegCloseKey(hServiceKey
);
1207 if (dwError
== ERROR_SUCCESS
)
1209 DPRINT("hService %lx\n", hServiceHandle
);
1210 *hService
= (unsigned int)hServiceHandle
;
1212 if (lpdwTagId
!= NULL
)
1213 *lpdwTagId
= lpService
->dwTag
;
1217 /* Release the display name buffer */
1218 if (lpService
->lpServiceName
!= lpService
->lpDisplayName
)
1219 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
1221 if (hServiceHandle
!= NULL
)
1223 /* Remove the service handle */
1224 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
1227 if (lpService
!= NULL
)
1229 /* FIXME: remove the service entry */
1233 if (lpImagePath
!= NULL
)
1234 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1236 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
1244 ScmrEnumDependentServicesW(handle_t BindingHandle
,
1245 unsigned int hService
,
1246 unsigned long dwServiceState
,
1247 unsigned char *lpServices
,
1248 unsigned long cbBufSize
,
1249 unsigned long *pcbBytesNeeded
,
1250 unsigned long *lpServicesReturned
)
1252 DWORD dwError
= ERROR_SUCCESS
;
1254 DPRINT1("ScmrEnumDependentServicesW() called\n");
1255 *pcbBytesNeeded
= 0;
1256 *lpServicesReturned
= 0;
1258 DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError
);
1266 ScmrEnumServicesStatusW(handle_t BindingHandle
,
1267 unsigned int hSCManager
,
1268 unsigned long dwServiceType
,
1269 unsigned long dwServiceState
,
1270 unsigned char *lpServices
,
1271 unsigned long dwBufSize
,
1272 unsigned long *pcbBytesNeeded
,
1273 unsigned long *lpServicesReturned
,
1274 unsigned long *lpResumeHandle
)
1276 PMANAGER_HANDLE hManager
;
1278 DWORD dwError
= ERROR_SUCCESS
;
1279 PLIST_ENTRY ServiceEntry
;
1280 PSERVICE CurrentService
;
1282 DWORD dwRequiredSize
;
1283 DWORD dwServiceCount
;
1285 DWORD dwLastResumeCount
;
1286 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1289 DPRINT("ScmrEnumServicesStatusW() called\n");
1292 return ERROR_SHUTDOWN_IN_PROGRESS
;
1294 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1295 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1297 DPRINT1("Invalid manager handle!\n");
1298 return ERROR_INVALID_HANDLE
;
1301 /* Check access rights */
1302 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1303 SC_MANAGER_ENUMERATE_SERVICE
))
1305 DPRINT1("Insufficient access rights! 0x%lx\n",
1306 hManager
->Handle
.DesiredAccess
);
1307 return ERROR_ACCESS_DENIED
;
1310 *pcbBytesNeeded
= 0;
1311 *lpServicesReturned
= 0;
1313 dwLastResumeCount
= *lpResumeHandle
;
1315 /* Lock the service list shared */
1317 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
1318 if (lpService
== NULL
)
1320 dwError
= ERROR_SUCCESS
;
1327 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1328 ServiceEntry
!= &ServiceListHead
;
1329 ServiceEntry
= ServiceEntry
->Flink
)
1331 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1335 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1338 dwState
= SERVICE_ACTIVE
;
1339 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1340 dwState
= SERVICE_INACTIVE
;
1342 if ((dwState
& dwServiceState
) == 0)
1345 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1346 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1347 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1349 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1351 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
1352 dwRequiredSize
+= dwSize
;
1354 dwLastResumeCount
= CurrentService
->dwResumeCount
;
1358 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
1364 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
1365 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
1368 ServiceEntry
!= &ServiceListHead
;
1369 ServiceEntry
= ServiceEntry
->Flink
)
1371 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1375 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1378 dwState
= SERVICE_ACTIVE
;
1379 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1380 dwState
= SERVICE_INACTIVE
;
1382 if ((dwState
& dwServiceState
) == 0)
1385 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUSW
) +
1386 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1387 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
1389 dwError
= ERROR_MORE_DATA
;
1392 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
1394 *lpResumeHandle
= dwLastResumeCount
;
1395 *lpServicesReturned
= dwServiceCount
;
1396 *pcbBytesNeeded
= dwRequiredSize
;
1398 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1399 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
1400 dwServiceCount
* sizeof(ENUM_SERVICE_STATUSW
));
1403 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1404 ServiceEntry
!= &ServiceListHead
;
1405 ServiceEntry
= ServiceEntry
->Flink
)
1407 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1411 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1414 dwState
= SERVICE_ACTIVE
;
1415 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1416 dwState
= SERVICE_INACTIVE
;
1418 if ((dwState
& dwServiceState
) == 0)
1421 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1422 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1423 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1425 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1427 /* Copy the service name */
1429 CurrentService
->lpServiceName
);
1430 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1431 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
1433 /* Copy the display name */
1435 CurrentService
->lpDisplayName
);
1436 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1437 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
1439 /* Copy the status information */
1440 memcpy(&lpStatusPtr
->ServiceStatus
,
1441 &CurrentService
->Status
,
1442 sizeof(SERVICE_STATUS
));
1445 dwRequiredSize
+= dwSize
;
1455 /* Unlock the service list */
1457 DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError
);
1465 ScmrOpenSCManagerW(handle_t BindingHandle
,
1466 wchar_t *lpMachineName
,
1467 wchar_t *lpDatabaseName
,
1468 unsigned long dwDesiredAccess
,
1474 DPRINT("ScmrOpenSCManagerW() called\n");
1475 DPRINT("lpMachineName = %p\n", lpMachineName
);
1476 DPRINT("lpMachineName: %S\n", lpMachineName
);
1477 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
1478 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
1479 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1482 return ERROR_SHUTDOWN_IN_PROGRESS
;
1484 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1486 if (dwError
!= ERROR_SUCCESS
)
1488 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1492 /* Check the desired access */
1493 dwError
= ScmCheckAccess(hHandle
,
1494 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1495 if (dwError
!= ERROR_SUCCESS
)
1497 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1498 HeapFree(GetProcessHeap(), 0, hHandle
);
1502 *hScm
= (unsigned int)hHandle
;
1503 DPRINT("*hScm = %x\n", *hScm
);
1505 DPRINT("ScmrOpenSCManagerW() done\n");
1507 return ERROR_SUCCESS
;
1513 ScmrOpenServiceW(handle_t BindingHandle
,
1514 unsigned int hSCManager
,
1515 wchar_t *lpServiceName
,
1516 unsigned long dwDesiredAccess
,
1517 unsigned int *hService
)
1520 PMANAGER_HANDLE hManager
;
1524 DPRINT("ScmrOpenServiceW() called\n");
1525 DPRINT("hSCManager = %x\n", hSCManager
);
1526 DPRINT("lpServiceName = %p\n", lpServiceName
);
1527 DPRINT("lpServiceName: %S\n", lpServiceName
);
1528 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1531 return ERROR_SHUTDOWN_IN_PROGRESS
;
1533 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1534 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1536 DPRINT1("Invalid manager handle!\n");
1537 return ERROR_INVALID_HANDLE
;
1540 /* FIXME: Lock the service list */
1542 /* Get service database entry */
1543 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1544 if (lpService
== NULL
)
1546 DPRINT("Could not find a service!\n");
1547 return ERROR_SERVICE_DOES_NOT_EXIST
;
1550 /* Create a service handle */
1551 dwError
= ScmCreateServiceHandle(lpService
,
1553 if (dwError
!= ERROR_SUCCESS
)
1555 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1559 /* Check the desired access */
1560 dwError
= ScmCheckAccess(hHandle
,
1562 if (dwError
!= ERROR_SUCCESS
)
1564 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1565 HeapFree(GetProcessHeap(), 0, hHandle
);
1569 *hService
= (unsigned int)hHandle
;
1570 DPRINT("*hService = %x\n", *hService
);
1572 DPRINT("ScmrOpenServiceW() done\n");
1574 return ERROR_SUCCESS
;
1580 ScmrQueryServiceConfigW(handle_t BindingHandle
,
1581 unsigned int hService
,
1582 unsigned char *lpServiceConfig
,
1583 unsigned long cbBufSize
,
1584 unsigned long *pcbBytesNeeded
)
1586 DWORD dwError
= ERROR_SUCCESS
;
1587 PSERVICE_HANDLE hSvc
;
1588 PSERVICE lpService
= NULL
;
1589 HKEY hServiceKey
= NULL
;
1590 LPWSTR lpImagePath
= NULL
;
1591 DWORD dwRequiredSize
;
1592 LPQUERY_SERVICE_CONFIGW lpConfig
;
1595 DPRINT1("ScmrQueryServiceConfigW() called\n");
1598 return ERROR_SHUTDOWN_IN_PROGRESS
;
1600 hSvc
= (PSERVICE_HANDLE
)hService
;
1601 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1603 DPRINT1("Invalid handle tag!\n");
1604 return ERROR_INVALID_HANDLE
;
1607 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1608 SERVICE_QUERY_CONFIG
))
1610 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1611 return ERROR_ACCESS_DENIED
;
1614 lpService
= hSvc
->ServiceEntry
;
1615 if (lpService
== NULL
)
1617 DPRINT1("lpService == NULL!\n");
1618 return ERROR_INVALID_HANDLE
;
1621 /* FIXME: Lock the service database shared */
1623 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
1626 if (dwError
!= ERROR_SUCCESS
)
1629 dwError
= ScmReadString(hServiceKey
,
1632 if (dwError
!= ERROR_SUCCESS
)
1635 dwRequiredSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1637 if (lpImagePath
!= NULL
)
1638 dwRequiredSize
+= ((wcslen(lpImagePath
) + 1) * sizeof(WCHAR
));
1640 if (lpService
->lpGroup
!= NULL
)
1641 dwRequiredSize
+= ((wcslen(lpService
->lpGroup
->lpGroupName
) + 1) * sizeof(WCHAR
));
1643 /* FIXME: Add Dependencies length*/
1645 /* FIXME: Add ServiceStartName length*/
1647 if (lpService
->lpDisplayName
!= NULL
)
1648 dwRequiredSize
+= ((wcslen(lpService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1650 if (lpServiceConfig
== NULL
|| cbBufSize
< dwRequiredSize
)
1652 dwError
= ERROR_INSUFFICIENT_BUFFER
;
1656 lpConfig
= (LPQUERY_SERVICE_CONFIGW
)lpServiceConfig
;
1657 lpConfig
->dwServiceType
= lpService
->Status
.dwServiceType
;
1658 lpConfig
->dwStartType
= lpService
->dwStartType
;
1659 lpConfig
->dwErrorControl
= lpService
->dwErrorControl
;
1660 lpConfig
->dwTagId
= lpService
->dwTag
;
1662 lpStr
= (LPWSTR
)(lpConfig
+ 1);
1664 if (lpImagePath
!= NULL
)
1666 wcscpy(lpStr
, lpImagePath
);
1667 lpConfig
->lpBinaryPathName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1668 lpStr
+= (wcslen(lpImagePath
) + 1);
1672 lpConfig
->lpBinaryPathName
= NULL
;
1675 if (lpService
->lpGroup
!= NULL
)
1677 wcscpy(lpStr
, lpService
->lpGroup
->lpGroupName
);
1678 lpConfig
->lpLoadOrderGroup
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1679 lpStr
+= (wcslen(lpService
->lpGroup
->lpGroupName
) + 1);
1683 lpConfig
->lpLoadOrderGroup
= NULL
;
1686 /* FIXME: Append Dependencies */
1687 lpConfig
->lpDependencies
= NULL
;
1689 /* FIXME: Append ServiceStartName */
1690 lpConfig
->lpServiceStartName
= NULL
;
1692 if (lpService
->lpDisplayName
!= NULL
)
1694 wcscpy(lpStr
, lpService
->lpDisplayName
);
1695 lpConfig
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1699 lpConfig
->lpDisplayName
= NULL
;
1703 if (pcbBytesNeeded
!= NULL
)
1704 *pcbBytesNeeded
= dwRequiredSize
;
1707 if (lpImagePath
!= NULL
)
1708 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1710 if (hServiceKey
!= NULL
)
1711 RegCloseKey(hServiceKey
);
1713 /* FIXME: Unlock the service database */
1715 DPRINT1("ScmrQueryServiceConfigW() done\n");
1723 ScmrQueryServiceLockStatusW(handle_t BindingHandle
,
1724 unsigned int hSCManager
,
1725 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
1726 unsigned long cbBufSize
, /* [in] */
1727 unsigned long *pcbBytesNeeded
) /* [out] */
1729 DPRINT1("ScmrQueryServiceLockStatusW() called\n");
1730 return ERROR_CALL_NOT_IMPLEMENTED
;
1736 ScmrStartServiceW(handle_t BindingHandle
,
1737 unsigned int hService
,
1738 unsigned long dwNumServiceArgs
,
1739 unsigned char *lpServiceArgBuffer
,
1740 unsigned long cbBufSize
)
1742 DWORD dwError
= ERROR_SUCCESS
;
1743 PSERVICE_HANDLE hSvc
;
1744 PSERVICE lpService
= NULL
;
1746 DPRINT1("ScmrStartServiceW() called\n");
1749 return ERROR_SHUTDOWN_IN_PROGRESS
;
1751 hSvc
= (PSERVICE_HANDLE
)hService
;
1752 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1754 DPRINT1("Invalid handle tag!\n");
1755 return ERROR_INVALID_HANDLE
;
1758 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1761 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1762 return ERROR_ACCESS_DENIED
;
1765 lpService
= hSvc
->ServiceEntry
;
1766 if (lpService
== NULL
)
1768 DPRINT1("lpService == NULL!\n");
1769 return ERROR_INVALID_HANDLE
;
1772 if (lpService
->dwStartType
== SERVICE_DISABLED
)
1773 return ERROR_SERVICE_DISABLED
;
1775 if (lpService
->bDeleted
)
1776 return ERROR_SERVICE_MARKED_FOR_DELETE
;
1778 /* FIXME: Start the service */
1786 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1787 unsigned int hSCManager
,
1788 wchar_t *lpServiceName
,
1789 wchar_t *lpDisplayName
, /* [out, unique] */
1790 unsigned long *lpcchBuffer
)
1792 // PMANAGER_HANDLE hManager;
1797 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1798 DPRINT("hSCManager = %x\n", hSCManager
);
1799 DPRINT("lpServiceName: %S\n", lpServiceName
);
1800 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1801 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1803 // hManager = (PMANAGER_HANDLE)hSCManager;
1804 // if (hManager->Handle.Tag != MANAGER_TAG)
1806 // DPRINT1("Invalid manager handle!\n");
1807 // return ERROR_INVALID_HANDLE;
1810 /* Get service database entry */
1811 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1812 if (lpService
== NULL
)
1814 DPRINT1("Could not find a service!\n");
1815 return ERROR_SERVICE_DOES_NOT_EXIST
;
1818 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1820 if (lpDisplayName
!= NULL
&&
1821 *lpcchBuffer
>= dwLength
)
1823 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1826 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1828 *lpcchBuffer
= dwLength
;
1836 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1837 unsigned int hSCManager
,
1838 wchar_t *lpDisplayName
,
1839 wchar_t *lpServiceName
, /* [out, unique] */
1840 unsigned long *lpcchBuffer
)
1842 // PMANAGER_HANDLE hManager;
1847 DPRINT("ScmrGetServiceKeyNameW() called\n");
1848 DPRINT("hSCManager = %x\n", hSCManager
);
1849 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1850 DPRINT("lpServiceName: %p\n", lpServiceName
);
1851 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1853 // hManager = (PMANAGER_HANDLE)hSCManager;
1854 // if (hManager->Handle.Tag != MANAGER_TAG)
1856 // DPRINT1("Invalid manager handle!\n");
1857 // return ERROR_INVALID_HANDLE;
1860 /* Get service database entry */
1861 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1862 if (lpService
== NULL
)
1864 DPRINT1("Could not find a service!\n");
1865 return ERROR_SERVICE_DOES_NOT_EXIST
;
1868 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1870 if (lpServiceName
!= NULL
&&
1871 *lpcchBuffer
>= dwLength
)
1873 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1876 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1878 *lpcchBuffer
= dwLength
;
1886 ScmrSetServiceBitsA(handle_t BindingHandle
,
1887 unsigned long hServiceStatus
,
1888 unsigned long dwServiceBits
,
1889 unsigned long bSetBitsOn
,
1890 unsigned long bUpdateImmediately
,
1893 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1894 return ERROR_CALL_NOT_IMPLEMENTED
;
1900 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1901 unsigned int hService
,
1902 unsigned long dwServiceType
,
1903 unsigned long dwStartType
,
1904 unsigned long dwErrorControl
,
1905 char *lpBinaryPathName
,
1906 char *lpLoadOrderGroup
,
1907 unsigned long *lpdwTagId
,
1908 char *lpDependencies
,
1909 unsigned long dwDependenciesLength
,
1910 char *lpServiceStartName
,
1912 unsigned long dwPasswordLength
,
1913 char *lpDisplayName
)
1915 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1916 return ERROR_CALL_NOT_IMPLEMENTED
;
1922 ScmrCreateServiceA(handle_t BindingHandle
,
1923 unsigned int hSCManager
,
1924 char *lpServiceName
,
1925 char *lpDisplayName
,
1926 unsigned long dwDesiredAccess
,
1927 unsigned long dwServiceType
,
1928 unsigned long dwStartType
,
1929 unsigned long dwErrorControl
,
1930 char *lpBinaryPathName
,
1931 char *lpLoadOrderGroup
,
1932 unsigned long *lpdwTagId
, /* in, out */
1933 char *lpDependencies
,
1934 unsigned long dwDependenciesLength
,
1935 char *lpServiceStartName
,
1937 unsigned long dwPasswordLength
,
1938 unsigned int *hService
) /* out */
1940 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1941 return ERROR_CALL_NOT_IMPLEMENTED
;
1947 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1948 unsigned int hService
,
1949 unsigned long dwServiceState
,
1950 unsigned char *lpServices
,
1951 unsigned long cbBufSize
,
1952 unsigned long *pcbBytesNeeded
,
1953 unsigned long *lpServicesReturned
)
1955 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
1956 *pcbBytesNeeded
= 0;
1957 *lpServicesReturned
= 0;
1958 return ERROR_CALL_NOT_IMPLEMENTED
;
1964 ScmrEnumServicesStatusA(handle_t BindingHandle
,
1965 unsigned int hSCManager
,
1966 unsigned long dwServiceType
,
1967 unsigned long dwServiceState
,
1968 unsigned char *lpServices
,
1969 unsigned long dwBufSize
,
1970 unsigned long *pcbBytesNeeded
,
1971 unsigned long *lpServicesReturned
,
1972 unsigned long *lpResumeHandle
)
1974 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
1975 return ERROR_CALL_NOT_IMPLEMENTED
;
1981 ScmrOpenSCManagerA(handle_t BindingHandle
,
1982 char *lpMachineName
,
1983 char *lpDatabaseName
,
1984 unsigned long dwDesiredAccess
,
1987 UNICODE_STRING MachineName
;
1988 UNICODE_STRING DatabaseName
;
1991 DPRINT("ScmrOpenSCManagerA() called\n");
1994 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
1998 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
2001 dwError
= ScmrOpenSCManagerW(BindingHandle
,
2002 lpMachineName
? MachineName
.Buffer
: NULL
,
2003 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
2008 RtlFreeUnicodeString(&MachineName
);
2011 RtlFreeUnicodeString(&DatabaseName
);
2019 ScmrOpenServiceA(handle_t BindingHandle
,
2020 unsigned int hSCManager
,
2021 char *lpServiceName
,
2022 unsigned long dwDesiredAccess
,
2023 unsigned int *hService
)
2025 UNICODE_STRING ServiceName
;
2028 DPRINT("ScmrOpenServiceA() called\n");
2030 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
2033 dwError
= ScmrOpenServiceW(BindingHandle
,
2039 RtlFreeUnicodeString(&ServiceName
);
2047 ScmrQueryServiceConfigA(handle_t BindingHandle
,
2048 unsigned int hService
,
2049 unsigned char *lpServiceConfig
,
2050 unsigned long cbBufSize
,
2051 unsigned long *pcbBytesNeeded
)
2053 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2054 return ERROR_CALL_NOT_IMPLEMENTED
;
2060 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2061 unsigned int hSCManager
,
2062 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2063 unsigned long cbBufSize
, /* [in] */
2064 unsigned long *pcbBytesNeeded
) /* [out] */
2066 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2067 return ERROR_CALL_NOT_IMPLEMENTED
;
2073 ScmrStartServiceA(handle_t BindingHandle
,
2074 unsigned int hService
,
2075 unsigned long dwNumServiceArgs
,
2076 unsigned char *lpServiceArgBuffer
,
2077 unsigned long cbBufSize
)
2079 DPRINT1("ScmrStartServiceA() called\n");
2080 return ERROR_SUCCESS
;
2081 // return ERROR_CALL_NOT_IMPLEMENTED;
2087 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2088 unsigned int hSCManager
,
2089 char *lpServiceName
,
2090 char *lpDisplayName
, /* [out, unique] */
2091 unsigned long *lpcchBuffer
)
2093 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2094 return ERROR_CALL_NOT_IMPLEMENTED
;
2100 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2101 unsigned int hSCManager
,
2102 char *lpDisplayName
,
2103 char *lpServiceName
, /* [out, unique] */
2104 unsigned long *lpcchBuffer
)
2106 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2107 return ERROR_CALL_NOT_IMPLEMENTED
;
2113 ScmrGetCurrentGroupStateW(handle_t BindingHandle
)
2115 DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
2116 return ERROR_CALL_NOT_IMPLEMENTED
;
2122 ScmrEnumServiceGroupW(handle_t BindingHandle
)
2124 DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
2125 return ERROR_CALL_NOT_IMPLEMENTED
;
2131 ScmrChangeServiceConfig2A(handle_t BindingHandle
,
2132 unsigned int hService
,
2133 unsigned long dwInfoLevel
,
2134 unsigned char *lpInfo
,
2135 unsigned long dwInfoSize
)
2137 DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
2138 return ERROR_CALL_NOT_IMPLEMENTED
;
2144 ScmrChangeServiceConfig2W(handle_t BindingHandle
,
2145 unsigned int hService
,
2146 unsigned long dwInfoLevel
,
2147 unsigned char *lpInfo
,
2148 unsigned long dwInfoSize
)
2150 DPRINT1("ScmrChangeServiceConfig2W() is unimplemented\n");
2151 return ERROR_CALL_NOT_IMPLEMENTED
;
2157 ScmrQueryServiceConfig2A(handle_t BindingHandle
,
2158 unsigned int hService
,
2159 unsigned long dwInfoLevel
,
2160 unsigned char *lpBuffer
,
2161 unsigned long cbBufSize
,
2162 unsigned long *pcbBytesNeeded
)
2164 DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
2165 return ERROR_CALL_NOT_IMPLEMENTED
;
2171 ScmrQueryServiceConfig2W(handle_t BindingHandle
,
2172 unsigned int hService
,
2173 unsigned long dwInfoLevel
,
2174 unsigned char *lpBuffer
,
2175 unsigned long cbBufSize
,
2176 unsigned long *pcbBytesNeeded
)
2178 DPRINT1("ScmrQueryServiceConfig2W() is unimplemented\n");
2179 return ERROR_CALL_NOT_IMPLEMENTED
;
2185 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2186 unsigned int hService
,
2187 unsigned long InfoLevel
,
2188 unsigned char *lpBuffer
, /* out */
2189 unsigned long cbBufSize
,
2190 unsigned long *pcbBytesNeeded
) /* out */
2192 LPSERVICE_STATUS_PROCESS lpStatus
;
2193 PSERVICE_HANDLE hSvc
;
2196 DPRINT("ScmrQueryServiceStatusEx() called\n");
2199 return ERROR_SHUTDOWN_IN_PROGRESS
;
2201 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2202 return ERROR_INVALID_LEVEL
;
2204 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2206 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2207 return ERROR_INSUFFICIENT_BUFFER
;
2209 hSvc
= (PSERVICE_HANDLE
)hService
;
2210 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2212 DPRINT1("Invalid handle tag!\n");
2213 return ERROR_INVALID_HANDLE
;
2216 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2217 SERVICE_QUERY_STATUS
))
2219 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2220 return ERROR_ACCESS_DENIED
;
2223 lpService
= hSvc
->ServiceEntry
;
2224 if (lpService
== NULL
)
2226 DPRINT1("lpService == NULL!\n");
2227 return ERROR_INVALID_HANDLE
;
2230 lpStatus
= (LPSERVICE_STATUS_PROCESS
)lpBuffer
;
2232 /* Return service status information */
2233 RtlCopyMemory(lpStatus
,
2235 sizeof(SERVICE_STATUS
));
2237 lpStatus
->dwProcessId
= lpService
->ProcessId
; /* FIXME */
2238 lpStatus
->dwServiceFlags
= 0; /* FIXME */
2240 return ERROR_SUCCESS
;
2246 ScmrEnumServicesStatusExA(handle_t BindingHandle
,
2247 unsigned int hSCManager
,
2248 unsigned long InfoLevel
,
2249 unsigned long dwServiceType
,
2250 unsigned long dwServiceState
,
2251 unsigned char *lpServices
,
2252 unsigned long dwBufSize
,
2253 unsigned long *pcbBytesNeeded
,
2254 unsigned long *lpServicesReturned
,
2255 unsigned long *lpResumeHandle
,
2258 DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
2259 *pcbBytesNeeded
= 0;
2260 *lpServicesReturned
= 0;
2261 return ERROR_CALL_NOT_IMPLEMENTED
;
2267 ScmrEnumServicesStatusExW(handle_t BindingHandle
,
2268 unsigned int hSCManager
,
2269 unsigned long InfoLevel
,
2270 unsigned long dwServiceType
,
2271 unsigned long dwServiceState
,
2272 unsigned char *lpServices
,
2273 unsigned long dwBufSize
,
2274 unsigned long *pcbBytesNeeded
,
2275 unsigned long *lpServicesReturned
,
2276 unsigned long *lpResumeHandle
,
2277 wchar_t *pszGroupName
)
2279 PMANAGER_HANDLE hManager
;
2281 DWORD dwError
= ERROR_SUCCESS
;
2282 PLIST_ENTRY ServiceEntry
;
2283 PSERVICE CurrentService
;
2285 DWORD dwRequiredSize
;
2286 DWORD dwServiceCount
;
2288 DWORD dwLastResumeCount
;
2289 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
2292 DPRINT("ScmrEnumServicesStatusExW() called\n");
2295 return ERROR_SHUTDOWN_IN_PROGRESS
;
2297 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
2298 return ERROR_INVALID_LEVEL
;
2300 hManager
= (PMANAGER_HANDLE
)hSCManager
;
2301 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
2303 DPRINT1("Invalid manager handle!\n");
2304 return ERROR_INVALID_HANDLE
;
2307 /* Check access rights */
2308 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
2309 SC_MANAGER_ENUMERATE_SERVICE
))
2311 DPRINT1("Insufficient access rights! 0x%lx\n",
2312 hManager
->Handle
.DesiredAccess
);
2313 return ERROR_ACCESS_DENIED
;
2316 *pcbBytesNeeded
= 0;
2317 *lpServicesReturned
= 0;
2319 dwLastResumeCount
= *lpResumeHandle
;
2321 /* Lock the service list shared */
2323 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
2324 if (lpService
== NULL
)
2326 dwError
= ERROR_SUCCESS
;
2333 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2334 ServiceEntry
!= &ServiceListHead
;
2335 ServiceEntry
= ServiceEntry
->Flink
)
2337 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2341 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2344 dwState
= SERVICE_ACTIVE
;
2345 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2346 dwState
= SERVICE_INACTIVE
;
2348 if ((dwState
& dwServiceState
) == 0)
2353 if (*pszGroupName
== 0)
2355 if (CurrentService
->lpGroup
!= NULL
)
2360 if ((CurrentService
->lpGroup
== NULL
) ||
2361 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2366 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2367 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2368 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2370 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2372 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
2373 dwRequiredSize
+= dwSize
;
2375 dwLastResumeCount
= CurrentService
->dwResumeCount
;
2379 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
2385 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
2386 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
2389 ServiceEntry
!= &ServiceListHead
;
2390 ServiceEntry
= ServiceEntry
->Flink
)
2392 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2396 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2399 dwState
= SERVICE_ACTIVE
;
2400 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2401 dwState
= SERVICE_INACTIVE
;
2403 if ((dwState
& dwServiceState
) == 0)
2408 if (*pszGroupName
== 0)
2410 if (CurrentService
->lpGroup
!= NULL
)
2415 if ((CurrentService
->lpGroup
== NULL
) ||
2416 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2421 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2422 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2423 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
2425 dwError
= ERROR_MORE_DATA
;
2428 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
2430 *lpResumeHandle
= dwLastResumeCount
;
2431 *lpServicesReturned
= dwServiceCount
;
2432 *pcbBytesNeeded
= dwRequiredSize
;
2434 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
2435 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
2436 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS_PROCESSW
));
2439 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2440 ServiceEntry
!= &ServiceListHead
;
2441 ServiceEntry
= ServiceEntry
->Flink
)
2443 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2447 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2450 dwState
= SERVICE_ACTIVE
;
2451 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2452 dwState
= SERVICE_INACTIVE
;
2454 if ((dwState
& dwServiceState
) == 0)
2459 if (*pszGroupName
== 0)
2461 if (CurrentService
->lpGroup
!= NULL
)
2466 if ((CurrentService
->lpGroup
== NULL
) ||
2467 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2472 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2473 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2474 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2476 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2478 /* Copy the service name */
2480 CurrentService
->lpServiceName
);
2481 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2482 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
2484 /* Copy the display name */
2486 CurrentService
->lpDisplayName
);
2487 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2488 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
2490 /* Copy the status information */
2491 memcpy(&lpStatusPtr
->ServiceStatusProcess
,
2492 &CurrentService
->Status
,
2493 sizeof(SERVICE_STATUS
));
2494 lpStatusPtr
->ServiceStatusProcess
.dwProcessId
= CurrentService
->ProcessId
; /* FIXME */
2495 lpStatusPtr
->ServiceStatusProcess
.dwServiceFlags
= 0; /* FIXME */
2498 dwRequiredSize
+= dwSize
;
2508 /* Unlock the service list */
2510 DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError
);
2517 /* ScmrSendTSMessage */
2520 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2522 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2526 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2528 HeapFree(GetProcessHeap(), 0, ptr
);