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(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 /* FIXME: Send control code to the service */
360 dwError
= ScmControlService(lpService
,
364 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
367 /* Return service status information */
368 RtlCopyMemory(lpServiceStatus
,
370 sizeof(SERVICE_STATUS
));
378 ScmrDeleteService(handle_t BindingHandle
,
379 unsigned int hService
)
381 PSERVICE_HANDLE hSvc
;
385 DPRINT("ScmrDeleteService() called\n");
388 return ERROR_SHUTDOWN_IN_PROGRESS
;
390 hSvc
= (PSERVICE_HANDLE
)hService
;
391 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
392 return ERROR_INVALID_HANDLE
;
394 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
395 STANDARD_RIGHTS_REQUIRED
))
396 return ERROR_ACCESS_DENIED
;
398 lpService
= hSvc
->ServiceEntry
;
399 if (lpService
== NULL
)
401 DPRINT1("lpService == NULL!\n");
402 return ERROR_INVALID_HANDLE
;
405 /* FIXME: Acquire service database lock exclusively */
407 if (lpService
->bDeleted
)
409 DPRINT1("The service has already been marked for delete!\n");
410 return ERROR_SERVICE_MARKED_FOR_DELETE
;
413 /* Mark service for delete */
414 lpService
->bDeleted
= TRUE
;
416 dwError
= ScmMarkServiceForDelete(lpService
);
418 /* FIXME: Release service database lock */
420 DPRINT("ScmrDeleteService() done\n");
428 ScmrLockServiceDatabase(handle_t BindingHandle
,
429 unsigned int hSCManager
,
432 PMANAGER_HANDLE hMgr
;
434 DPRINT("ScmrLockServiceDatabase() called\n");
438 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
439 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
440 return ERROR_INVALID_HANDLE
;
442 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
444 return ERROR_ACCESS_DENIED
;
446 // return ScmLockDatabase(0, hMgr->0xC, hLock);
448 /* FIXME: Lock the database */
449 *hLock
= 0x12345678; /* Dummy! */
451 return ERROR_SUCCESS
;
457 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
,
458 unsigned int hService
,
459 unsigned long dwSecurityInformation
,
460 unsigned char *lpSecurityDescriptor
,
461 unsigned long dwSecuityDescriptorSize
,
462 unsigned long *pcbBytesNeeded
)
465 PSERVICE_HANDLE hSvc
;
467 ULONG DesiredAccess
= 0;
472 DPRINT("ScmrQueryServiceObjectSecurity() called\n");
474 hSvc
= (PSERVICE_HANDLE
)hService
;
475 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
477 DPRINT1("Invalid handle tag!\n");
478 return ERROR_INVALID_HANDLE
;
481 if (dwSecurityInformation
& (DACL_SECURITY_INFORMATION
||
482 GROUP_SECURITY_INFORMATION
||
483 OWNER_SECURITY_INFORMATION
))
484 DesiredAccess
|= READ_CONTROL
;
486 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
487 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
489 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
492 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
493 return ERROR_ACCESS_DENIED
;
496 lpService
= hSvc
->ServiceEntry
;
497 if (lpService
== NULL
)
499 DPRINT1("lpService == NULL!\n");
500 return ERROR_INVALID_HANDLE
;
503 /* FIXME: Lock the service list */
505 Status
= RtlQuerySecurityObject(lpService
->lpSecurityDescriptor
,
506 dwSecurityInformation
,
507 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
508 dwSecuityDescriptorSize
,
511 /* FIXME: Unlock the service list */
513 if (NT_SUCCESS(Status
))
515 *pcbBytesNeeded
= dwBytesNeeded
;
516 dwError
= STATUS_SUCCESS
;
518 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
520 *pcbBytesNeeded
= dwBytesNeeded
;
521 dwError
= ERROR_INSUFFICIENT_BUFFER
;
523 else if (Status
== STATUS_BAD_DESCRIPTOR_FORMAT
)
525 dwError
= ERROR_GEN_FAILURE
;
529 dwError
= RtlNtStatusToDosError(Status
);
534 DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
535 return ERROR_CALL_NOT_IMPLEMENTED
;
541 ScmrSetServiceObjectSecurity(handle_t BindingHandle
,
542 unsigned int hService
,
543 unsigned long dwSecurityInformation
,
544 unsigned char *lpSecurityDescriptor
,
545 unsigned long dwSecuityDescriptorSize
)
548 PSERVICE_HANDLE hSvc
;
550 ULONG DesiredAccess
= 0;
551 HANDLE hToken
= NULL
;
556 DPRINT1("ScmrSetServiceObjectSecurity() called\n");
558 hSvc
= (PSERVICE_HANDLE
)hService
;
559 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
561 DPRINT1("Invalid handle tag!\n");
562 return ERROR_INVALID_HANDLE
;
565 if (dwSecurityInformation
== 0 ||
566 dwSecurityInformation
& ~0xF)
569 if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
))
572 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
573 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
575 if (dwSecurityInformation
& DACL_SECURITY_INFORMATION
)
576 DesiredAccess
|= 0x40000;
578 if (dwSecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
579 DesiredAccess
|= 0x80000;
581 if ((dwSecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
582 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Owner
== NULL
))
585 if ((dwSecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
586 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Group
== NULL
))
589 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
592 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
593 return ERROR_ACCESS_DENIED
;
596 lpService
= hSvc
->ServiceEntry
;
597 if (lpService
== NULL
)
599 DPRINT1("lpService == NULL!\n");
600 return ERROR_INVALID_HANDLE
;
603 if (lpService
->bDeleted
)
606 // RpcImpersonateClient(NULL);
608 Status
= NtOpenThreadToken(NtCurrentThread(),
612 if (!NT_SUCCESS(Status
))
613 return RtlNtStatusToDosError(Status
);
615 // RpcRevertToSelf();
617 /* FIXME: Lock service database */
619 Status
= RtlSetSecurityObject(dwSecurityInformation
,
620 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
621 &lpService
->lpSecurityDescriptor
,
624 if (!NT_SUCCESS(Status
))
626 dwError
= RtlNtStatusToDosError(Status
);
630 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
633 if (dwError
!= ERROR_SUCCESS
)
636 // dwError = ScmWriteSecurityDescriptor(hServiceKey,
637 // lpService->lpSecurityDescriptor);
639 RegFlushKey(hServiceKey
);
640 RegCloseKey(hServiceKey
);
647 /* FIXME: Unlock service database */
649 DPRINT1("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError
);
654 DPRINT1("ScmrSetServiceObjectSecurity() is unimplemented\n");
655 return ERROR_CALL_NOT_IMPLEMENTED
;
661 ScmrQueryServiceStatus(handle_t BindingHandle
,
662 unsigned int hService
,
663 LPSERVICE_STATUS lpServiceStatus
)
665 PSERVICE_HANDLE hSvc
;
668 DPRINT("ScmrQueryServiceStatus() called\n");
671 return ERROR_SHUTDOWN_IN_PROGRESS
;
673 hSvc
= (PSERVICE_HANDLE
)hService
;
674 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
676 DPRINT1("Invalid handle tag!\n");
677 return ERROR_INVALID_HANDLE
;
680 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
681 SERVICE_QUERY_STATUS
))
683 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
684 return ERROR_ACCESS_DENIED
;
687 lpService
= hSvc
->ServiceEntry
;
688 if (lpService
== NULL
)
690 DPRINT1("lpService == NULL!\n");
691 return ERROR_INVALID_HANDLE
;
694 /* Return service status information */
695 RtlCopyMemory(lpServiceStatus
,
697 sizeof(SERVICE_STATUS
));
699 return ERROR_SUCCESS
;
705 ScmrSetServiceStatus(handle_t BindingHandle
,
706 unsigned long hServiceStatus
) /* FIXME */
708 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
710 return ERROR_CALL_NOT_IMPLEMENTED
;
716 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
719 DPRINT1("ScmrUnlockServiceDatabase() called\n");
721 return ERROR_SUCCESS
;
727 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
728 unsigned long BootAcceptable
)
730 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
732 return ERROR_CALL_NOT_IMPLEMENTED
;
738 ScmrSetServiceBitsW(handle_t BindingHandle
,
739 unsigned long hServiceStatus
,
740 unsigned long dwServiceBits
,
741 unsigned long bSetBitsOn
,
742 unsigned long bUpdateImmediately
,
745 DPRINT1("ScmrSetServiceBitsW() called\n");
747 return ERROR_CALL_NOT_IMPLEMENTED
;
753 ScmrChangeServiceConfigW(handle_t BiningHandle
,
754 unsigned int hService
,
755 unsigned long dwServiceType
,
756 unsigned long dwStartType
,
757 unsigned long dwErrorControl
,
758 wchar_t *lpBinaryPathName
,
759 wchar_t *lpLoadOrderGroup
,
760 unsigned long *lpdwTagId
, /* in, out, unique */
761 wchar_t *lpDependencies
,
762 unsigned long dwDependenciesLength
,
763 wchar_t *lpServiceStartName
,
765 unsigned long dwPasswordLength
,
766 wchar_t *lpDisplayName
)
768 DWORD dwError
= ERROR_SUCCESS
;
769 PSERVICE_HANDLE hSvc
;
770 PSERVICE lpService
= NULL
;
771 HKEY hServiceKey
= NULL
;
773 DPRINT("ScmrChangeServiceConfigW() called\n");
774 DPRINT("dwServiceType = %lu\n", dwServiceType
);
775 DPRINT("dwStartType = %lu\n", dwStartType
);
776 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
777 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
778 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
779 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
782 return ERROR_SHUTDOWN_IN_PROGRESS
;
784 hSvc
= (PSERVICE_HANDLE
)hService
;
785 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
787 DPRINT1("Invalid handle tag!\n");
788 return ERROR_INVALID_HANDLE
;
791 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
792 SERVICE_CHANGE_CONFIG
))
794 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
795 return ERROR_ACCESS_DENIED
;
798 lpService
= hSvc
->ServiceEntry
;
799 if (lpService
== NULL
)
801 DPRINT1("lpService == NULL!\n");
802 return ERROR_INVALID_HANDLE
;
805 /* FIXME: Lock database exclusively */
807 if (lpService
->bDeleted
)
809 /* FIXME: Unlock database */
810 DPRINT1("The service has already been marked for delete!\n");
811 return ERROR_SERVICE_MARKED_FOR_DELETE
;
814 /* Open the service key */
815 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
818 if (dwError
!= ERROR_SUCCESS
)
821 /* Write service data to the registry */
822 /* Set the display name */
823 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
825 RegSetValueExW(hServiceKey
,
829 (LPBYTE
)lpDisplayName
,
830 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
831 /* FIXME: update lpService->lpDisplayName */
834 if (dwServiceType
!= SERVICE_NO_CHANGE
)
836 /* Set the service type */
837 dwError
= RegSetValueExW(hServiceKey
,
841 (LPBYTE
)&dwServiceType
,
843 if (dwError
!= ERROR_SUCCESS
)
846 lpService
->Status
.dwServiceType
= dwServiceType
;
849 if (dwStartType
!= SERVICE_NO_CHANGE
)
851 /* Set the start value */
852 dwError
= RegSetValueExW(hServiceKey
,
856 (LPBYTE
)&dwStartType
,
858 if (dwError
!= ERROR_SUCCESS
)
861 lpService
->dwStartType
= dwStartType
;
864 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
866 /* Set the error control value */
867 dwError
= RegSetValueExW(hServiceKey
,
871 (LPBYTE
)&dwErrorControl
,
873 if (dwError
!= ERROR_SUCCESS
)
876 lpService
->dwErrorControl
= dwErrorControl
;
880 /* FIXME: set the new ImagePath value */
882 /* Set the image path */
883 if (dwServiceType
& SERVICE_WIN32
)
885 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
887 dwError
= RegSetValueExW(hServiceKey
,
891 (LPBYTE
)lpBinaryPathName
,
892 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
893 if (dwError
!= ERROR_SUCCESS
)
897 else if (dwServiceType
& SERVICE_DRIVER
)
899 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
901 dwError
= RegSetValueExW(hServiceKey
,
906 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
907 if (dwError
!= ERROR_SUCCESS
)
913 /* Set the group name */
914 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
916 dwError
= RegSetValueExW(hServiceKey
,
920 (LPBYTE
)lpLoadOrderGroup
,
921 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
922 if (dwError
!= ERROR_SUCCESS
)
924 /* FIXME: update lpService->lpServiceGroup */
927 if (lpdwTagId
!= NULL
)
929 dwError
= ScmAssignNewTag(lpService
);
930 if (dwError
!= ERROR_SUCCESS
)
933 dwError
= RegSetValueExW(hServiceKey
,
937 (LPBYTE
)&lpService
->dwTag
,
939 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 /* Assign the service to a group */
1077 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1079 dwError
= ScmSetServiceGroup(lpService
,
1081 if (dwError
!= ERROR_SUCCESS
)
1085 /* Assign a new tag */
1086 if (lpdwTagId
!= NULL
)
1088 dwError
= ScmAssignNewTag(lpService
);
1089 if (dwError
!= ERROR_SUCCESS
)
1093 /* Write service data to the registry */
1094 /* Create the service key */
1095 dwError
= ScmCreateServiceKey(lpServiceName
,
1098 if (dwError
!= ERROR_SUCCESS
)
1101 /* Set the display name */
1102 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
1104 RegSetValueExW(hServiceKey
,
1108 (LPBYTE
)lpDisplayName
,
1109 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1112 /* Set the service type */
1113 dwError
= RegSetValueExW(hServiceKey
,
1117 (LPBYTE
)&dwServiceType
,
1119 if (dwError
!= ERROR_SUCCESS
)
1122 /* Set the start value */
1123 dwError
= RegSetValueExW(hServiceKey
,
1127 (LPBYTE
)&dwStartType
,
1129 if (dwError
!= ERROR_SUCCESS
)
1132 /* Set the error control value */
1133 dwError
= RegSetValueExW(hServiceKey
,
1137 (LPBYTE
)&dwErrorControl
,
1139 if (dwError
!= ERROR_SUCCESS
)
1142 /* Set the image path */
1143 if (dwServiceType
& SERVICE_WIN32
)
1145 dwError
= RegSetValueExW(hServiceKey
,
1149 (LPBYTE
)lpBinaryPathName
,
1150 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1151 if (dwError
!= ERROR_SUCCESS
)
1154 else if (dwServiceType
& SERVICE_DRIVER
)
1156 dwError
= RegSetValueExW(hServiceKey
,
1160 (LPBYTE
)lpImagePath
,
1161 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
1162 if (dwError
!= ERROR_SUCCESS
)
1166 /* Set the group name */
1167 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1169 dwError
= RegSetValueExW(hServiceKey
,
1173 (LPBYTE
)lpLoadOrderGroup
,
1174 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
1175 if (dwError
!= ERROR_SUCCESS
)
1179 if (lpdwTagId
!= NULL
)
1181 dwError
= RegSetValueExW(hServiceKey
,
1185 (LPBYTE
)&lpService
->dwTag
,
1187 if (dwError
!= ERROR_SUCCESS
)
1191 /* Write dependencies */
1192 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
1194 dwError
= ScmWriteDependencies(hServiceKey
,
1196 dwDependenciesLength
);
1197 if (dwError
!= ERROR_SUCCESS
)
1201 if (lpPassword
!= NULL
)
1203 /* FIXME: Write password */
1206 dwError
= ScmCreateServiceHandle(lpService
,
1208 if (dwError
!= ERROR_SUCCESS
)
1211 dwError
= ScmCheckAccess(hServiceHandle
,
1213 if (dwError
!= ERROR_SUCCESS
)
1217 if (hServiceKey
!= NULL
)
1218 RegCloseKey(hServiceKey
);
1220 if (dwError
== ERROR_SUCCESS
)
1222 DPRINT("hService %lx\n", hServiceHandle
);
1223 *hService
= (unsigned int)hServiceHandle
;
1225 if (lpdwTagId
!= NULL
)
1226 *lpdwTagId
= lpService
->dwTag
;
1230 /* Release the display name buffer */
1231 if (lpService
->lpServiceName
!= lpService
->lpDisplayName
)
1232 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
1234 if (hServiceHandle
!= NULL
)
1236 /* Remove the service handle */
1237 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
1240 if (lpService
!= NULL
)
1242 /* FIXME: remove the service entry */
1246 if (lpImagePath
!= NULL
)
1247 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1249 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
1257 ScmrEnumDependentServicesW(handle_t BindingHandle
,
1258 unsigned int hService
,
1259 unsigned long dwServiceState
,
1260 unsigned char *lpServices
,
1261 unsigned long cbBufSize
,
1262 unsigned long *pcbBytesNeeded
,
1263 unsigned long *lpServicesReturned
)
1265 DWORD dwError
= ERROR_SUCCESS
;
1267 DPRINT1("ScmrEnumDependentServicesW() called\n");
1268 *pcbBytesNeeded
= 0;
1269 *lpServicesReturned
= 0;
1271 DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError
);
1279 ScmrEnumServicesStatusW(handle_t BindingHandle
,
1280 unsigned int hSCManager
,
1281 unsigned long dwServiceType
,
1282 unsigned long dwServiceState
,
1283 unsigned char *lpServices
,
1284 unsigned long dwBufSize
,
1285 unsigned long *pcbBytesNeeded
,
1286 unsigned long *lpServicesReturned
,
1287 unsigned long *lpResumeHandle
)
1289 PMANAGER_HANDLE hManager
;
1291 DWORD dwError
= ERROR_SUCCESS
;
1292 PLIST_ENTRY ServiceEntry
;
1293 PSERVICE CurrentService
;
1295 DWORD dwRequiredSize
;
1296 DWORD dwServiceCount
;
1298 DWORD dwLastResumeCount
;
1299 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1302 DPRINT("ScmrEnumServicesStatusW() called\n");
1305 return ERROR_SHUTDOWN_IN_PROGRESS
;
1307 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1308 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1310 DPRINT1("Invalid manager handle!\n");
1311 return ERROR_INVALID_HANDLE
;
1314 /* Check access rights */
1315 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1316 SC_MANAGER_ENUMERATE_SERVICE
))
1318 DPRINT1("Insufficient access rights! 0x%lx\n",
1319 hManager
->Handle
.DesiredAccess
);
1320 return ERROR_ACCESS_DENIED
;
1323 *pcbBytesNeeded
= 0;
1324 *lpServicesReturned
= 0;
1326 dwLastResumeCount
= *lpResumeHandle
;
1328 /* Lock the service list shared */
1330 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
1331 if (lpService
== NULL
)
1333 dwError
= ERROR_SUCCESS
;
1340 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1341 ServiceEntry
!= &ServiceListHead
;
1342 ServiceEntry
= ServiceEntry
->Flink
)
1344 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1348 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1351 dwState
= SERVICE_ACTIVE
;
1352 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1353 dwState
= SERVICE_INACTIVE
;
1355 if ((dwState
& dwServiceState
) == 0)
1358 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1359 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1360 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1362 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1364 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
1365 dwRequiredSize
+= dwSize
;
1367 dwLastResumeCount
= CurrentService
->dwResumeCount
;
1371 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
1377 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
1378 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
1381 ServiceEntry
!= &ServiceListHead
;
1382 ServiceEntry
= ServiceEntry
->Flink
)
1384 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1388 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1391 dwState
= SERVICE_ACTIVE
;
1392 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1393 dwState
= SERVICE_INACTIVE
;
1395 if ((dwState
& dwServiceState
) == 0)
1398 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUSW
) +
1399 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1400 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
1402 dwError
= ERROR_MORE_DATA
;
1405 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
1407 *lpResumeHandle
= dwLastResumeCount
;
1408 *lpServicesReturned
= dwServiceCount
;
1409 *pcbBytesNeeded
= dwRequiredSize
;
1411 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1412 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
1413 dwServiceCount
* sizeof(ENUM_SERVICE_STATUSW
));
1416 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1417 ServiceEntry
!= &ServiceListHead
;
1418 ServiceEntry
= ServiceEntry
->Flink
)
1420 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1424 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1427 dwState
= SERVICE_ACTIVE
;
1428 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1429 dwState
= SERVICE_INACTIVE
;
1431 if ((dwState
& dwServiceState
) == 0)
1434 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1435 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1436 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1438 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1440 /* Copy the service name */
1442 CurrentService
->lpServiceName
);
1443 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1444 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
1446 /* Copy the display name */
1448 CurrentService
->lpDisplayName
);
1449 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1450 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
1452 /* Copy the status information */
1453 memcpy(&lpStatusPtr
->ServiceStatus
,
1454 &CurrentService
->Status
,
1455 sizeof(SERVICE_STATUS
));
1458 dwRequiredSize
+= dwSize
;
1468 /* Unlock the service list */
1470 DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError
);
1478 ScmrOpenSCManagerW(handle_t BindingHandle
,
1479 wchar_t *lpMachineName
,
1480 wchar_t *lpDatabaseName
,
1481 unsigned long dwDesiredAccess
,
1487 DPRINT("ScmrOpenSCManagerW() called\n");
1488 DPRINT("lpMachineName = %p\n", lpMachineName
);
1489 DPRINT("lpMachineName: %S\n", lpMachineName
);
1490 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
1491 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
1492 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1495 return ERROR_SHUTDOWN_IN_PROGRESS
;
1497 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1499 if (dwError
!= ERROR_SUCCESS
)
1501 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1505 /* Check the desired access */
1506 dwError
= ScmCheckAccess(hHandle
,
1507 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1508 if (dwError
!= ERROR_SUCCESS
)
1510 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1511 HeapFree(GetProcessHeap(), 0, hHandle
);
1515 *hScm
= (unsigned int)hHandle
;
1516 DPRINT("*hScm = %x\n", *hScm
);
1518 DPRINT("ScmrOpenSCManagerW() done\n");
1520 return ERROR_SUCCESS
;
1526 ScmrOpenServiceW(handle_t BindingHandle
,
1527 unsigned int hSCManager
,
1528 wchar_t *lpServiceName
,
1529 unsigned long dwDesiredAccess
,
1530 unsigned int *hService
)
1533 PMANAGER_HANDLE hManager
;
1537 DPRINT("ScmrOpenServiceW() called\n");
1538 DPRINT("hSCManager = %x\n", hSCManager
);
1539 DPRINT("lpServiceName = %p\n", lpServiceName
);
1540 DPRINT("lpServiceName: %S\n", lpServiceName
);
1541 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1544 return ERROR_SHUTDOWN_IN_PROGRESS
;
1546 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1547 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1549 DPRINT1("Invalid manager handle!\n");
1550 return ERROR_INVALID_HANDLE
;
1553 /* FIXME: Lock the service list */
1555 /* Get service database entry */
1556 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1557 if (lpService
== NULL
)
1559 DPRINT("Could not find a service!\n");
1560 return ERROR_SERVICE_DOES_NOT_EXIST
;
1563 /* Create a service handle */
1564 dwError
= ScmCreateServiceHandle(lpService
,
1566 if (dwError
!= ERROR_SUCCESS
)
1568 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1572 /* Check the desired access */
1573 dwError
= ScmCheckAccess(hHandle
,
1575 if (dwError
!= ERROR_SUCCESS
)
1577 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1578 HeapFree(GetProcessHeap(), 0, hHandle
);
1582 *hService
= (unsigned int)hHandle
;
1583 DPRINT("*hService = %x\n", *hService
);
1585 DPRINT("ScmrOpenServiceW() done\n");
1587 return ERROR_SUCCESS
;
1593 ScmrQueryServiceConfigW(handle_t BindingHandle
,
1594 unsigned int hService
,
1595 unsigned char *lpServiceConfig
,
1596 unsigned long cbBufSize
,
1597 unsigned long *pcbBytesNeeded
)
1599 DWORD dwError
= ERROR_SUCCESS
;
1600 PSERVICE_HANDLE hSvc
;
1601 PSERVICE lpService
= NULL
;
1602 HKEY hServiceKey
= NULL
;
1603 LPWSTR lpImagePath
= NULL
;
1604 DWORD dwRequiredSize
;
1605 LPQUERY_SERVICE_CONFIGW lpConfig
;
1608 DPRINT1("ScmrQueryServiceConfigW() called\n");
1611 return ERROR_SHUTDOWN_IN_PROGRESS
;
1613 hSvc
= (PSERVICE_HANDLE
)hService
;
1614 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1616 DPRINT1("Invalid handle tag!\n");
1617 return ERROR_INVALID_HANDLE
;
1620 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1621 SERVICE_QUERY_CONFIG
))
1623 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1624 return ERROR_ACCESS_DENIED
;
1627 lpService
= hSvc
->ServiceEntry
;
1628 if (lpService
== NULL
)
1630 DPRINT1("lpService == NULL!\n");
1631 return ERROR_INVALID_HANDLE
;
1634 /* FIXME: Lock the service database shared */
1636 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
1639 if (dwError
!= ERROR_SUCCESS
)
1642 dwError
= ScmReadString(hServiceKey
,
1645 if (dwError
!= ERROR_SUCCESS
)
1648 dwRequiredSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1650 if (lpImagePath
!= NULL
)
1651 dwRequiredSize
+= ((wcslen(lpImagePath
) + 1) * sizeof(WCHAR
));
1653 if (lpService
->lpGroup
!= NULL
)
1654 dwRequiredSize
+= ((wcslen(lpService
->lpGroup
->lpGroupName
) + 1) * sizeof(WCHAR
));
1656 /* FIXME: Add Dependencies length*/
1658 /* FIXME: Add ServiceStartName length*/
1660 if (lpService
->lpDisplayName
!= NULL
)
1661 dwRequiredSize
+= ((wcslen(lpService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1663 if (lpServiceConfig
== NULL
|| cbBufSize
< dwRequiredSize
)
1665 dwError
= ERROR_INSUFFICIENT_BUFFER
;
1669 lpConfig
= (LPQUERY_SERVICE_CONFIGW
)lpServiceConfig
;
1670 lpConfig
->dwServiceType
= lpService
->Status
.dwServiceType
;
1671 lpConfig
->dwStartType
= lpService
->dwStartType
;
1672 lpConfig
->dwErrorControl
= lpService
->dwErrorControl
;
1673 lpConfig
->dwTagId
= lpService
->dwTag
;
1675 lpStr
= (LPWSTR
)(lpConfig
+ 1);
1677 if (lpImagePath
!= NULL
)
1679 wcscpy(lpStr
, lpImagePath
);
1680 lpConfig
->lpBinaryPathName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1681 lpStr
+= (wcslen(lpImagePath
) + 1);
1685 lpConfig
->lpBinaryPathName
= NULL
;
1688 if (lpService
->lpGroup
!= NULL
)
1690 wcscpy(lpStr
, lpService
->lpGroup
->lpGroupName
);
1691 lpConfig
->lpLoadOrderGroup
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1692 lpStr
+= (wcslen(lpService
->lpGroup
->lpGroupName
) + 1);
1696 lpConfig
->lpLoadOrderGroup
= NULL
;
1699 /* FIXME: Append Dependencies */
1700 lpConfig
->lpDependencies
= NULL
;
1702 /* FIXME: Append ServiceStartName */
1703 lpConfig
->lpServiceStartName
= NULL
;
1705 if (lpService
->lpDisplayName
!= NULL
)
1707 wcscpy(lpStr
, lpService
->lpDisplayName
);
1708 lpConfig
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1712 lpConfig
->lpDisplayName
= NULL
;
1716 if (pcbBytesNeeded
!= NULL
)
1717 *pcbBytesNeeded
= dwRequiredSize
;
1720 if (lpImagePath
!= NULL
)
1721 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1723 if (hServiceKey
!= NULL
)
1724 RegCloseKey(hServiceKey
);
1726 /* FIXME: Unlock the service database */
1728 DPRINT1("ScmrQueryServiceConfigW() done\n");
1736 ScmrQueryServiceLockStatusW(handle_t BindingHandle
,
1737 unsigned int hSCManager
,
1738 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
1739 unsigned long cbBufSize
, /* [in] */
1740 unsigned long *pcbBytesNeeded
) /* [out] */
1742 DPRINT1("ScmrQueryServiceLockStatusW() called\n");
1743 return ERROR_CALL_NOT_IMPLEMENTED
;
1749 ScmrStartServiceW(handle_t BindingHandle
,
1750 unsigned int hService
,
1751 unsigned long dwNumServiceArgs
,
1752 unsigned char *lpServiceArgBuffer
,
1753 unsigned long cbBufSize
)
1755 DWORD dwError
= ERROR_SUCCESS
;
1756 PSERVICE_HANDLE hSvc
;
1757 PSERVICE lpService
= NULL
;
1759 DPRINT1("ScmrStartServiceW() called\n");
1762 return ERROR_SHUTDOWN_IN_PROGRESS
;
1764 hSvc
= (PSERVICE_HANDLE
)hService
;
1765 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1767 DPRINT1("Invalid handle tag!\n");
1768 return ERROR_INVALID_HANDLE
;
1771 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1774 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1775 return ERROR_ACCESS_DENIED
;
1778 lpService
= hSvc
->ServiceEntry
;
1779 if (lpService
== NULL
)
1781 DPRINT1("lpService == NULL!\n");
1782 return ERROR_INVALID_HANDLE
;
1785 if (lpService
->dwStartType
== SERVICE_DISABLED
)
1786 return ERROR_SERVICE_DISABLED
;
1788 if (lpService
->bDeleted
)
1789 return ERROR_SERVICE_MARKED_FOR_DELETE
;
1791 /* FIXME: Start the service */
1799 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1800 unsigned int hSCManager
,
1801 wchar_t *lpServiceName
,
1802 wchar_t *lpDisplayName
, /* [out, unique] */
1803 unsigned long *lpcchBuffer
)
1805 // PMANAGER_HANDLE hManager;
1810 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1811 DPRINT("hSCManager = %x\n", hSCManager
);
1812 DPRINT("lpServiceName: %S\n", lpServiceName
);
1813 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1814 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1816 // hManager = (PMANAGER_HANDLE)hSCManager;
1817 // if (hManager->Handle.Tag != MANAGER_TAG)
1819 // DPRINT1("Invalid manager handle!\n");
1820 // return ERROR_INVALID_HANDLE;
1823 /* Get service database entry */
1824 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1825 if (lpService
== NULL
)
1827 DPRINT1("Could not find a service!\n");
1828 return ERROR_SERVICE_DOES_NOT_EXIST
;
1831 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1833 if (lpDisplayName
!= NULL
&&
1834 *lpcchBuffer
>= dwLength
)
1836 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1839 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1841 *lpcchBuffer
= dwLength
;
1849 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1850 unsigned int hSCManager
,
1851 wchar_t *lpDisplayName
,
1852 wchar_t *lpServiceName
, /* [out, unique] */
1853 unsigned long *lpcchBuffer
)
1855 // PMANAGER_HANDLE hManager;
1860 DPRINT("ScmrGetServiceKeyNameW() called\n");
1861 DPRINT("hSCManager = %x\n", hSCManager
);
1862 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1863 DPRINT("lpServiceName: %p\n", lpServiceName
);
1864 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1866 // hManager = (PMANAGER_HANDLE)hSCManager;
1867 // if (hManager->Handle.Tag != MANAGER_TAG)
1869 // DPRINT1("Invalid manager handle!\n");
1870 // return ERROR_INVALID_HANDLE;
1873 /* Get service database entry */
1874 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1875 if (lpService
== NULL
)
1877 DPRINT1("Could not find a service!\n");
1878 return ERROR_SERVICE_DOES_NOT_EXIST
;
1881 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1883 if (lpServiceName
!= NULL
&&
1884 *lpcchBuffer
>= dwLength
)
1886 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1889 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1891 *lpcchBuffer
= dwLength
;
1899 ScmrSetServiceBitsA(handle_t BindingHandle
,
1900 unsigned long hServiceStatus
,
1901 unsigned long dwServiceBits
,
1902 unsigned long bSetBitsOn
,
1903 unsigned long bUpdateImmediately
,
1906 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1907 return ERROR_CALL_NOT_IMPLEMENTED
;
1913 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1914 unsigned int hService
,
1915 unsigned long dwServiceType
,
1916 unsigned long dwStartType
,
1917 unsigned long dwErrorControl
,
1918 char *lpBinaryPathName
,
1919 char *lpLoadOrderGroup
,
1920 unsigned long *lpdwTagId
,
1921 char *lpDependencies
,
1922 unsigned long dwDependenciesLength
,
1923 char *lpServiceStartName
,
1925 unsigned long dwPasswordLength
,
1926 char *lpDisplayName
)
1928 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1929 return ERROR_CALL_NOT_IMPLEMENTED
;
1935 ScmrCreateServiceA(handle_t BindingHandle
,
1936 unsigned int hSCManager
,
1937 char *lpServiceName
,
1938 char *lpDisplayName
,
1939 unsigned long dwDesiredAccess
,
1940 unsigned long dwServiceType
,
1941 unsigned long dwStartType
,
1942 unsigned long dwErrorControl
,
1943 char *lpBinaryPathName
,
1944 char *lpLoadOrderGroup
,
1945 unsigned long *lpdwTagId
, /* in, out */
1946 char *lpDependencies
,
1947 unsigned long dwDependenciesLength
,
1948 char *lpServiceStartName
,
1950 unsigned long dwPasswordLength
,
1951 unsigned int *hService
) /* out */
1953 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1954 return ERROR_CALL_NOT_IMPLEMENTED
;
1960 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1961 unsigned int hService
,
1962 unsigned long dwServiceState
,
1963 unsigned char *lpServices
,
1964 unsigned long cbBufSize
,
1965 unsigned long *pcbBytesNeeded
,
1966 unsigned long *lpServicesReturned
)
1968 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
1969 *pcbBytesNeeded
= 0;
1970 *lpServicesReturned
= 0;
1971 return ERROR_CALL_NOT_IMPLEMENTED
;
1977 ScmrEnumServicesStatusA(handle_t BindingHandle
,
1978 unsigned int hSCManager
,
1979 unsigned long dwServiceType
,
1980 unsigned long dwServiceState
,
1981 unsigned char *lpServices
,
1982 unsigned long dwBufSize
,
1983 unsigned long *pcbBytesNeeded
,
1984 unsigned long *lpServicesReturned
,
1985 unsigned long *lpResumeHandle
)
1987 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
1988 return ERROR_CALL_NOT_IMPLEMENTED
;
1994 ScmrOpenSCManagerA(handle_t BindingHandle
,
1995 char *lpMachineName
,
1996 char *lpDatabaseName
,
1997 unsigned long dwDesiredAccess
,
2000 UNICODE_STRING MachineName
;
2001 UNICODE_STRING DatabaseName
;
2004 DPRINT("ScmrOpenSCManagerA() called\n");
2007 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
2011 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
2014 dwError
= ScmrOpenSCManagerW(BindingHandle
,
2015 lpMachineName
? MachineName
.Buffer
: NULL
,
2016 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
2021 RtlFreeUnicodeString(&MachineName
);
2024 RtlFreeUnicodeString(&DatabaseName
);
2032 ScmrOpenServiceA(handle_t BindingHandle
,
2033 unsigned int hSCManager
,
2034 char *lpServiceName
,
2035 unsigned long dwDesiredAccess
,
2036 unsigned int *hService
)
2038 UNICODE_STRING ServiceName
;
2041 DPRINT("ScmrOpenServiceA() called\n");
2043 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
2046 dwError
= ScmrOpenServiceW(BindingHandle
,
2052 RtlFreeUnicodeString(&ServiceName
);
2060 ScmrQueryServiceConfigA(handle_t BindingHandle
,
2061 unsigned int hService
,
2062 unsigned char *lpServiceConfig
,
2063 unsigned long cbBufSize
,
2064 unsigned long *pcbBytesNeeded
)
2066 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2067 return ERROR_CALL_NOT_IMPLEMENTED
;
2073 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2074 unsigned int hSCManager
,
2075 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2076 unsigned long cbBufSize
, /* [in] */
2077 unsigned long *pcbBytesNeeded
) /* [out] */
2079 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2080 return ERROR_CALL_NOT_IMPLEMENTED
;
2086 ScmrStartServiceA(handle_t BindingHandle
,
2087 unsigned int hService
,
2088 unsigned long dwNumServiceArgs
,
2089 unsigned char *lpServiceArgBuffer
,
2090 unsigned long cbBufSize
)
2092 DPRINT1("ScmrStartServiceA() called\n");
2093 return ERROR_SUCCESS
;
2094 // return ERROR_CALL_NOT_IMPLEMENTED;
2100 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2101 unsigned int hSCManager
,
2102 char *lpServiceName
,
2103 char *lpDisplayName
, /* [out, unique] */
2104 unsigned long *lpcchBuffer
)
2106 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2107 return ERROR_CALL_NOT_IMPLEMENTED
;
2113 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2114 unsigned int hSCManager
,
2115 char *lpDisplayName
,
2116 char *lpServiceName
, /* [out, unique] */
2117 unsigned long *lpcchBuffer
)
2119 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2120 return ERROR_CALL_NOT_IMPLEMENTED
;
2126 ScmrGetCurrentGroupStateW(handle_t BindingHandle
)
2128 DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
2129 return ERROR_CALL_NOT_IMPLEMENTED
;
2135 ScmrEnumServiceGroupW(handle_t BindingHandle
)
2137 DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
2138 return ERROR_CALL_NOT_IMPLEMENTED
;
2144 ScmrChangeServiceConfig2A(handle_t BindingHandle
,
2145 unsigned int hService
,
2146 unsigned long dwInfoLevel
,
2147 unsigned char *lpInfo
,
2148 unsigned long dwInfoSize
)
2150 DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
2151 return ERROR_CALL_NOT_IMPLEMENTED
;
2157 ScmrChangeServiceConfig2W(handle_t BindingHandle
,
2158 unsigned int hService
,
2159 unsigned long dwInfoLevel
,
2160 unsigned char *lpInfo
,
2161 unsigned long dwInfoSize
)
2163 DPRINT1("ScmrChangeServiceConfig2W() is unimplemented\n");
2164 return ERROR_CALL_NOT_IMPLEMENTED
;
2170 ScmrQueryServiceConfig2A(handle_t BindingHandle
,
2171 unsigned int hService
,
2172 unsigned long dwInfoLevel
,
2173 unsigned char *lpBuffer
,
2174 unsigned long cbBufSize
,
2175 unsigned long *pcbBytesNeeded
)
2177 DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
2178 return ERROR_CALL_NOT_IMPLEMENTED
;
2184 ScmrQueryServiceConfig2W(handle_t BindingHandle
,
2185 unsigned int hService
,
2186 unsigned long dwInfoLevel
,
2187 unsigned char *lpBuffer
,
2188 unsigned long cbBufSize
,
2189 unsigned long *pcbBytesNeeded
)
2191 DPRINT1("ScmrQueryServiceConfig2W() is unimplemented\n");
2192 return ERROR_CALL_NOT_IMPLEMENTED
;
2198 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2199 unsigned int hService
,
2200 unsigned long InfoLevel
,
2201 unsigned char *lpBuffer
, /* out */
2202 unsigned long cbBufSize
,
2203 unsigned long *pcbBytesNeeded
) /* out */
2205 LPSERVICE_STATUS_PROCESS lpStatus
;
2206 PSERVICE_HANDLE hSvc
;
2209 DPRINT("ScmrQueryServiceStatusEx() called\n");
2212 return ERROR_SHUTDOWN_IN_PROGRESS
;
2214 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2215 return ERROR_INVALID_LEVEL
;
2217 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2219 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2220 return ERROR_INSUFFICIENT_BUFFER
;
2222 hSvc
= (PSERVICE_HANDLE
)hService
;
2223 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2225 DPRINT1("Invalid handle tag!\n");
2226 return ERROR_INVALID_HANDLE
;
2229 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2230 SERVICE_QUERY_STATUS
))
2232 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2233 return ERROR_ACCESS_DENIED
;
2236 lpService
= hSvc
->ServiceEntry
;
2237 if (lpService
== NULL
)
2239 DPRINT1("lpService == NULL!\n");
2240 return ERROR_INVALID_HANDLE
;
2243 lpStatus
= (LPSERVICE_STATUS_PROCESS
)lpBuffer
;
2245 /* Return service status information */
2246 RtlCopyMemory(lpStatus
,
2248 sizeof(SERVICE_STATUS
));
2250 lpStatus
->dwProcessId
= lpService
->ProcessId
; /* FIXME */
2251 lpStatus
->dwServiceFlags
= 0; /* FIXME */
2253 return ERROR_SUCCESS
;
2259 ScmrEnumServicesStatusExA(handle_t BindingHandle
,
2260 unsigned int hSCManager
,
2261 unsigned long InfoLevel
,
2262 unsigned long dwServiceType
,
2263 unsigned long dwServiceState
,
2264 unsigned char *lpServices
,
2265 unsigned long dwBufSize
,
2266 unsigned long *pcbBytesNeeded
,
2267 unsigned long *lpServicesReturned
,
2268 unsigned long *lpResumeHandle
,
2271 DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
2272 *pcbBytesNeeded
= 0;
2273 *lpServicesReturned
= 0;
2274 return ERROR_CALL_NOT_IMPLEMENTED
;
2280 ScmrEnumServicesStatusExW(handle_t BindingHandle
,
2281 unsigned int hSCManager
,
2282 unsigned long InfoLevel
,
2283 unsigned long dwServiceType
,
2284 unsigned long dwServiceState
,
2285 unsigned char *lpServices
,
2286 unsigned long dwBufSize
,
2287 unsigned long *pcbBytesNeeded
,
2288 unsigned long *lpServicesReturned
,
2289 unsigned long *lpResumeHandle
,
2290 wchar_t *pszGroupName
)
2292 PMANAGER_HANDLE hManager
;
2294 DWORD dwError
= ERROR_SUCCESS
;
2295 PLIST_ENTRY ServiceEntry
;
2296 PSERVICE CurrentService
;
2298 DWORD dwRequiredSize
;
2299 DWORD dwServiceCount
;
2301 DWORD dwLastResumeCount
;
2302 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
2305 DPRINT("ScmrEnumServicesStatusExW() called\n");
2308 return ERROR_SHUTDOWN_IN_PROGRESS
;
2310 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
2311 return ERROR_INVALID_LEVEL
;
2313 hManager
= (PMANAGER_HANDLE
)hSCManager
;
2314 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
2316 DPRINT1("Invalid manager handle!\n");
2317 return ERROR_INVALID_HANDLE
;
2320 /* Check access rights */
2321 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
2322 SC_MANAGER_ENUMERATE_SERVICE
))
2324 DPRINT1("Insufficient access rights! 0x%lx\n",
2325 hManager
->Handle
.DesiredAccess
);
2326 return ERROR_ACCESS_DENIED
;
2329 *pcbBytesNeeded
= 0;
2330 *lpServicesReturned
= 0;
2332 dwLastResumeCount
= *lpResumeHandle
;
2334 /* Lock the service list shared */
2336 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
2337 if (lpService
== NULL
)
2339 dwError
= ERROR_SUCCESS
;
2346 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2347 ServiceEntry
!= &ServiceListHead
;
2348 ServiceEntry
= ServiceEntry
->Flink
)
2350 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2354 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2357 dwState
= SERVICE_ACTIVE
;
2358 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2359 dwState
= SERVICE_INACTIVE
;
2361 if ((dwState
& dwServiceState
) == 0)
2366 if (*pszGroupName
== 0)
2368 if (CurrentService
->lpGroup
!= NULL
)
2373 if ((CurrentService
->lpGroup
== NULL
) ||
2374 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2379 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2380 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2381 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2383 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2385 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
2386 dwRequiredSize
+= dwSize
;
2388 dwLastResumeCount
= CurrentService
->dwResumeCount
;
2392 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
2398 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
2399 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
2402 ServiceEntry
!= &ServiceListHead
;
2403 ServiceEntry
= ServiceEntry
->Flink
)
2405 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2409 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2412 dwState
= SERVICE_ACTIVE
;
2413 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2414 dwState
= SERVICE_INACTIVE
;
2416 if ((dwState
& dwServiceState
) == 0)
2421 if (*pszGroupName
== 0)
2423 if (CurrentService
->lpGroup
!= NULL
)
2428 if ((CurrentService
->lpGroup
== NULL
) ||
2429 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2434 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2435 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2436 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
2438 dwError
= ERROR_MORE_DATA
;
2441 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
2443 *lpResumeHandle
= dwLastResumeCount
;
2444 *lpServicesReturned
= dwServiceCount
;
2445 *pcbBytesNeeded
= dwRequiredSize
;
2447 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
2448 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
2449 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS_PROCESSW
));
2452 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2453 ServiceEntry
!= &ServiceListHead
;
2454 ServiceEntry
= ServiceEntry
->Flink
)
2456 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2460 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2463 dwState
= SERVICE_ACTIVE
;
2464 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2465 dwState
= SERVICE_INACTIVE
;
2467 if ((dwState
& dwServiceState
) == 0)
2472 if (*pszGroupName
== 0)
2474 if (CurrentService
->lpGroup
!= NULL
)
2479 if ((CurrentService
->lpGroup
== NULL
) ||
2480 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2485 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2486 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2487 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2489 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2491 /* Copy the service name */
2493 CurrentService
->lpServiceName
);
2494 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2495 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
2497 /* Copy the display name */
2499 CurrentService
->lpDisplayName
);
2500 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2501 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
2503 /* Copy the status information */
2504 memcpy(&lpStatusPtr
->ServiceStatusProcess
,
2505 &CurrentService
->Status
,
2506 sizeof(SERVICE_STATUS
));
2507 lpStatusPtr
->ServiceStatusProcess
.dwProcessId
= CurrentService
->ProcessId
; /* FIXME */
2508 lpStatusPtr
->ServiceStatusProcess
.dwServiceFlags
= 0; /* FIXME */
2511 dwRequiredSize
+= dwSize
;
2521 /* Unlock the service list */
2523 DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError
);
2530 /* ScmrSendTSMessage */
2533 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2535 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2539 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2541 HeapFree(GetProcessHeap(), 0, ptr
);