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
)
547 PSERVICE_HANDLE hSvc
;
549 ULONG DesiredAccess
= 0;
550 HANDLE hToken
= NULL
;
555 DPRINT1("ScmrSetServiceObjectSecurity() called\n");
557 hSvc
= (PSERVICE_HANDLE
)hService
;
558 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
560 DPRINT1("Invalid handle tag!\n");
561 return ERROR_INVALID_HANDLE
;
564 if (dwSecurityInformation
== 0 ||
565 dwSecurityInformation
& ~(OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
566 | DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
))
567 return ERROR_INVALID_PARAMETER
;
569 if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
))
570 return ERROR_INVALID_PARAMETER
;
572 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
573 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
575 if (dwSecurityInformation
& DACL_SECURITY_INFORMATION
)
576 DesiredAccess
|= WRITE_DAC
;
578 if (dwSecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
579 DesiredAccess
|= WRITE_OWNER
;
581 if ((dwSecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
582 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Owner
== NULL
))
583 return ERROR_INVALID_PARAMETER
;
585 if ((dwSecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
586 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Group
== NULL
))
587 return ERROR_INVALID_PARAMETER
;
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
)
604 return ERROR_SERVICE_MARKED_FOR_DELETE
;
606 RpcImpersonateClient(NULL
);
608 Status
= NtOpenThreadToken(NtCurrentThread(),
612 if (!NT_SUCCESS(Status
))
613 return RtlNtStatusToDosError(Status
);
617 /* FIXME: Lock service database */
620 Status
= RtlSetSecurityObject(dwSecurityInformation
,
621 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
622 &lpService
->lpSecurityDescriptor
,
625 if (!NT_SUCCESS(Status
))
627 dwError
= RtlNtStatusToDosError(Status
);
632 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
633 READ_CONTROL
| KEY_CREATE_SUB_KEY
| KEY_SET_VALUE
,
635 if (dwError
!= ERROR_SUCCESS
)
638 DPRINT1("Stub: ScmrSetServiceObjectSecurity() is unimplemented\n");
639 dwError
= ERROR_SUCCESS
;
640 // dwError = ScmWriteSecurityDescriptor(hServiceKey,
641 // lpService->lpSecurityDescriptor);
643 RegFlushKey(hServiceKey
);
644 RegCloseKey(hServiceKey
);
651 /* FIXME: Unlock service database */
653 DPRINT("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError
);
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 DPRINT("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 DPRINT("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 /* Start the service */
1792 dwError
= ScmStartService(lpService
, (LPWSTR
)lpServiceArgBuffer
);
1800 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1801 unsigned int hSCManager
,
1802 wchar_t *lpServiceName
,
1803 wchar_t *lpDisplayName
, /* [out, unique] */
1804 unsigned long *lpcchBuffer
)
1806 // PMANAGER_HANDLE hManager;
1811 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1812 DPRINT("hSCManager = %x\n", hSCManager
);
1813 DPRINT("lpServiceName: %S\n", lpServiceName
);
1814 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1815 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1817 // hManager = (PMANAGER_HANDLE)hSCManager;
1818 // if (hManager->Handle.Tag != MANAGER_TAG)
1820 // DPRINT1("Invalid manager handle!\n");
1821 // return ERROR_INVALID_HANDLE;
1824 /* Get service database entry */
1825 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1826 if (lpService
== NULL
)
1828 DPRINT1("Could not find a service!\n");
1829 return ERROR_SERVICE_DOES_NOT_EXIST
;
1832 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1834 if (lpDisplayName
!= NULL
&&
1835 *lpcchBuffer
>= dwLength
)
1837 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1840 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1842 *lpcchBuffer
= dwLength
;
1850 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1851 unsigned int hSCManager
,
1852 wchar_t *lpDisplayName
,
1853 wchar_t *lpServiceName
, /* [out, unique] */
1854 unsigned long *lpcchBuffer
)
1856 // PMANAGER_HANDLE hManager;
1861 DPRINT("ScmrGetServiceKeyNameW() called\n");
1862 DPRINT("hSCManager = %x\n", hSCManager
);
1863 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1864 DPRINT("lpServiceName: %p\n", lpServiceName
);
1865 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1867 // hManager = (PMANAGER_HANDLE)hSCManager;
1868 // if (hManager->Handle.Tag != MANAGER_TAG)
1870 // DPRINT1("Invalid manager handle!\n");
1871 // return ERROR_INVALID_HANDLE;
1874 /* Get service database entry */
1875 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1876 if (lpService
== NULL
)
1878 DPRINT1("Could not find a service!\n");
1879 return ERROR_SERVICE_DOES_NOT_EXIST
;
1882 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1884 if (lpServiceName
!= NULL
&&
1885 *lpcchBuffer
>= dwLength
)
1887 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1890 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1892 *lpcchBuffer
= dwLength
;
1900 ScmrSetServiceBitsA(handle_t BindingHandle
,
1901 unsigned long hServiceStatus
,
1902 unsigned long dwServiceBits
,
1903 unsigned long bSetBitsOn
,
1904 unsigned long bUpdateImmediately
,
1907 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1908 return ERROR_CALL_NOT_IMPLEMENTED
;
1914 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1915 unsigned int hService
,
1916 unsigned long dwServiceType
,
1917 unsigned long dwStartType
,
1918 unsigned long dwErrorControl
,
1919 char *lpBinaryPathName
,
1920 char *lpLoadOrderGroup
,
1921 unsigned long *lpdwTagId
,
1922 char *lpDependencies
,
1923 unsigned long dwDependenciesLength
,
1924 char *lpServiceStartName
,
1926 unsigned long dwPasswordLength
,
1927 char *lpDisplayName
)
1929 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1930 return ERROR_CALL_NOT_IMPLEMENTED
;
1936 ScmrCreateServiceA(handle_t BindingHandle
,
1937 unsigned int hSCManager
,
1938 char *lpServiceName
,
1939 char *lpDisplayName
,
1940 unsigned long dwDesiredAccess
,
1941 unsigned long dwServiceType
,
1942 unsigned long dwStartType
,
1943 unsigned long dwErrorControl
,
1944 char *lpBinaryPathName
,
1945 char *lpLoadOrderGroup
,
1946 unsigned long *lpdwTagId
, /* in, out */
1947 char *lpDependencies
,
1948 unsigned long dwDependenciesLength
,
1949 char *lpServiceStartName
,
1951 unsigned long dwPasswordLength
,
1952 unsigned int *hService
) /* out */
1954 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1955 return ERROR_CALL_NOT_IMPLEMENTED
;
1961 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1962 unsigned int hService
,
1963 unsigned long dwServiceState
,
1964 unsigned char *lpServices
,
1965 unsigned long cbBufSize
,
1966 unsigned long *pcbBytesNeeded
,
1967 unsigned long *lpServicesReturned
)
1969 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
1970 *pcbBytesNeeded
= 0;
1971 *lpServicesReturned
= 0;
1972 return ERROR_CALL_NOT_IMPLEMENTED
;
1978 ScmrEnumServicesStatusA(handle_t BindingHandle
,
1979 unsigned int hSCManager
,
1980 unsigned long dwServiceType
,
1981 unsigned long dwServiceState
,
1982 unsigned char *lpServices
,
1983 unsigned long dwBufSize
,
1984 unsigned long *pcbBytesNeeded
,
1985 unsigned long *lpServicesReturned
,
1986 unsigned long *lpResumeHandle
)
1988 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
1989 return ERROR_CALL_NOT_IMPLEMENTED
;
1995 ScmrOpenSCManagerA(handle_t BindingHandle
,
1996 char *lpMachineName
,
1997 char *lpDatabaseName
,
1998 unsigned long dwDesiredAccess
,
2001 UNICODE_STRING MachineName
;
2002 UNICODE_STRING DatabaseName
;
2005 DPRINT("ScmrOpenSCManagerA() called\n");
2008 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
2012 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
2015 dwError
= ScmrOpenSCManagerW(BindingHandle
,
2016 lpMachineName
? MachineName
.Buffer
: NULL
,
2017 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
2022 RtlFreeUnicodeString(&MachineName
);
2025 RtlFreeUnicodeString(&DatabaseName
);
2033 ScmrOpenServiceA(handle_t BindingHandle
,
2034 unsigned int hSCManager
,
2035 char *lpServiceName
,
2036 unsigned long dwDesiredAccess
,
2037 unsigned int *hService
)
2039 UNICODE_STRING ServiceName
;
2042 DPRINT("ScmrOpenServiceA() called\n");
2044 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
2047 dwError
= ScmrOpenServiceW(BindingHandle
,
2053 RtlFreeUnicodeString(&ServiceName
);
2061 ScmrQueryServiceConfigA(handle_t BindingHandle
,
2062 unsigned int hService
,
2063 unsigned char *lpServiceConfig
,
2064 unsigned long cbBufSize
,
2065 unsigned long *pcbBytesNeeded
)
2067 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2068 return ERROR_CALL_NOT_IMPLEMENTED
;
2074 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2075 unsigned int hSCManager
,
2076 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2077 unsigned long cbBufSize
, /* [in] */
2078 unsigned long *pcbBytesNeeded
) /* [out] */
2080 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2081 return ERROR_CALL_NOT_IMPLEMENTED
;
2087 ScmrStartServiceA(handle_t BindingHandle
,
2088 unsigned int hService
,
2089 unsigned long dwNumServiceArgs
,
2090 unsigned char *lpServiceArgBuffer
,
2091 unsigned long cbBufSize
)
2093 DWORD dwError
= ERROR_SUCCESS
;
2094 PSERVICE_HANDLE hSvc
;
2095 PSERVICE lpService
= NULL
;
2097 DPRINT1("ScmrStartServiceA() called\n");
2100 return ERROR_SHUTDOWN_IN_PROGRESS
;
2102 hSvc
= (PSERVICE_HANDLE
)hService
;
2103 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2105 DPRINT1("Invalid handle tag!\n");
2106 return ERROR_INVALID_HANDLE
;
2109 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2112 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2113 return ERROR_ACCESS_DENIED
;
2116 lpService
= hSvc
->ServiceEntry
;
2117 if (lpService
== NULL
)
2119 DPRINT1("lpService == NULL!\n");
2120 return ERROR_INVALID_HANDLE
;
2123 if (lpService
->dwStartType
== SERVICE_DISABLED
)
2124 return ERROR_SERVICE_DISABLED
;
2126 if (lpService
->bDeleted
)
2127 return ERROR_SERVICE_MARKED_FOR_DELETE
;
2129 /* FIXME: Convert argument vector to Unicode */
2131 /* Start the service */
2132 dwError
= ScmStartService(lpService
, NULL
);
2134 /* FIXME: Free argument vector */
2142 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2143 unsigned int hSCManager
,
2144 char *lpServiceName
,
2145 char *lpDisplayName
, /* [out, unique] */
2146 unsigned long *lpcchBuffer
)
2148 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2149 return ERROR_CALL_NOT_IMPLEMENTED
;
2155 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2156 unsigned int hSCManager
,
2157 char *lpDisplayName
,
2158 char *lpServiceName
, /* [out, unique] */
2159 unsigned long *lpcchBuffer
)
2161 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2162 return ERROR_CALL_NOT_IMPLEMENTED
;
2168 ScmrGetCurrentGroupStateW(handle_t BindingHandle
)
2170 DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
2171 return ERROR_CALL_NOT_IMPLEMENTED
;
2177 ScmrEnumServiceGroupW(handle_t BindingHandle
)
2179 DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
2180 return ERROR_CALL_NOT_IMPLEMENTED
;
2186 ScmrChangeServiceConfig2A(handle_t BindingHandle
,
2187 unsigned int hService
,
2188 unsigned long dwInfoLevel
,
2189 unsigned char *lpInfo
,
2190 unsigned long dwInfoSize
)
2192 DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
2193 return ERROR_CALL_NOT_IMPLEMENTED
;
2199 ScmrChangeServiceConfig2W(handle_t BindingHandle
,
2200 unsigned int hService
,
2201 unsigned long dwInfoLevel
,
2202 unsigned char *lpInfo
,
2203 unsigned long dwInfoSize
)
2205 DPRINT1("ScmrChangeServiceConfig2W() is unimplemented\n");
2206 return ERROR_CALL_NOT_IMPLEMENTED
;
2212 ScmrQueryServiceConfig2A(handle_t BindingHandle
,
2213 unsigned int hService
,
2214 unsigned long dwInfoLevel
,
2215 unsigned char *lpBuffer
,
2216 unsigned long cbBufSize
,
2217 unsigned long *pcbBytesNeeded
)
2219 DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
2220 return ERROR_CALL_NOT_IMPLEMENTED
;
2226 ScmrQueryServiceConfig2W(handle_t BindingHandle
,
2227 unsigned int hService
,
2228 unsigned long dwInfoLevel
,
2229 unsigned char *lpBuffer
,
2230 unsigned long cbBufSize
,
2231 unsigned long *pcbBytesNeeded
)
2233 DPRINT1("ScmrQueryServiceConfig2W() is unimplemented\n");
2234 return ERROR_CALL_NOT_IMPLEMENTED
;
2240 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2241 unsigned int hService
,
2242 unsigned long InfoLevel
,
2243 unsigned char *lpBuffer
, /* out */
2244 unsigned long cbBufSize
,
2245 unsigned long *pcbBytesNeeded
) /* out */
2247 LPSERVICE_STATUS_PROCESS lpStatus
;
2248 PSERVICE_HANDLE hSvc
;
2251 DPRINT("ScmrQueryServiceStatusEx() called\n");
2254 return ERROR_SHUTDOWN_IN_PROGRESS
;
2256 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2257 return ERROR_INVALID_LEVEL
;
2259 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2261 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2262 return ERROR_INSUFFICIENT_BUFFER
;
2264 hSvc
= (PSERVICE_HANDLE
)hService
;
2265 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2267 DPRINT1("Invalid handle tag!\n");
2268 return ERROR_INVALID_HANDLE
;
2271 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2272 SERVICE_QUERY_STATUS
))
2274 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2275 return ERROR_ACCESS_DENIED
;
2278 lpService
= hSvc
->ServiceEntry
;
2279 if (lpService
== NULL
)
2281 DPRINT1("lpService == NULL!\n");
2282 return ERROR_INVALID_HANDLE
;
2285 lpStatus
= (LPSERVICE_STATUS_PROCESS
)lpBuffer
;
2287 /* Return service status information */
2288 RtlCopyMemory(lpStatus
,
2290 sizeof(SERVICE_STATUS
));
2292 lpStatus
->dwProcessId
= lpService
->ProcessId
; /* FIXME */
2293 lpStatus
->dwServiceFlags
= 0; /* FIXME */
2295 return ERROR_SUCCESS
;
2301 ScmrEnumServicesStatusExA(handle_t BindingHandle
,
2302 unsigned int hSCManager
,
2303 unsigned long InfoLevel
,
2304 unsigned long dwServiceType
,
2305 unsigned long dwServiceState
,
2306 unsigned char *lpServices
,
2307 unsigned long dwBufSize
,
2308 unsigned long *pcbBytesNeeded
,
2309 unsigned long *lpServicesReturned
,
2310 unsigned long *lpResumeHandle
,
2313 DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
2314 *pcbBytesNeeded
= 0;
2315 *lpServicesReturned
= 0;
2316 return ERROR_CALL_NOT_IMPLEMENTED
;
2322 ScmrEnumServicesStatusExW(handle_t BindingHandle
,
2323 unsigned int hSCManager
,
2324 unsigned long InfoLevel
,
2325 unsigned long dwServiceType
,
2326 unsigned long dwServiceState
,
2327 unsigned char *lpServices
,
2328 unsigned long dwBufSize
,
2329 unsigned long *pcbBytesNeeded
,
2330 unsigned long *lpServicesReturned
,
2331 unsigned long *lpResumeHandle
,
2332 wchar_t *pszGroupName
)
2334 PMANAGER_HANDLE hManager
;
2336 DWORD dwError
= ERROR_SUCCESS
;
2337 PLIST_ENTRY ServiceEntry
;
2338 PSERVICE CurrentService
;
2340 DWORD dwRequiredSize
;
2341 DWORD dwServiceCount
;
2343 DWORD dwLastResumeCount
;
2344 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
2347 DPRINT("ScmrEnumServicesStatusExW() called\n");
2350 return ERROR_SHUTDOWN_IN_PROGRESS
;
2352 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
2353 return ERROR_INVALID_LEVEL
;
2355 hManager
= (PMANAGER_HANDLE
)hSCManager
;
2356 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
2358 DPRINT1("Invalid manager handle!\n");
2359 return ERROR_INVALID_HANDLE
;
2362 /* Check access rights */
2363 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
2364 SC_MANAGER_ENUMERATE_SERVICE
))
2366 DPRINT1("Insufficient access rights! 0x%lx\n",
2367 hManager
->Handle
.DesiredAccess
);
2368 return ERROR_ACCESS_DENIED
;
2371 *pcbBytesNeeded
= 0;
2372 *lpServicesReturned
= 0;
2374 dwLastResumeCount
= *lpResumeHandle
;
2376 /* Lock the service list shared */
2378 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
2379 if (lpService
== NULL
)
2381 dwError
= ERROR_SUCCESS
;
2388 for (ServiceEntry
= &lpService
->ServiceListEntry
;
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 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2422 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2423 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2425 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2427 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
2428 dwRequiredSize
+= dwSize
;
2430 dwLastResumeCount
= CurrentService
->dwResumeCount
;
2434 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
2440 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
2441 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
2444 ServiceEntry
!= &ServiceListHead
;
2445 ServiceEntry
= ServiceEntry
->Flink
)
2447 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2451 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2454 dwState
= SERVICE_ACTIVE
;
2455 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2456 dwState
= SERVICE_INACTIVE
;
2458 if ((dwState
& dwServiceState
) == 0)
2463 if (*pszGroupName
== 0)
2465 if (CurrentService
->lpGroup
!= NULL
)
2470 if ((CurrentService
->lpGroup
== NULL
) ||
2471 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2476 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2477 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2478 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
2480 dwError
= ERROR_MORE_DATA
;
2483 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
2485 *lpResumeHandle
= dwLastResumeCount
;
2486 *lpServicesReturned
= dwServiceCount
;
2487 *pcbBytesNeeded
= dwRequiredSize
;
2489 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
2490 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
2491 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS_PROCESSW
));
2494 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2495 ServiceEntry
!= &ServiceListHead
;
2496 ServiceEntry
= ServiceEntry
->Flink
)
2498 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2502 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2505 dwState
= SERVICE_ACTIVE
;
2506 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2507 dwState
= SERVICE_INACTIVE
;
2509 if ((dwState
& dwServiceState
) == 0)
2514 if (*pszGroupName
== 0)
2516 if (CurrentService
->lpGroup
!= NULL
)
2521 if ((CurrentService
->lpGroup
== NULL
) ||
2522 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2527 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2528 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2529 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2531 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2533 /* Copy the service name */
2535 CurrentService
->lpServiceName
);
2536 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2537 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
2539 /* Copy the display name */
2541 CurrentService
->lpDisplayName
);
2542 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2543 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
2545 /* Copy the status information */
2546 memcpy(&lpStatusPtr
->ServiceStatusProcess
,
2547 &CurrentService
->Status
,
2548 sizeof(SERVICE_STATUS
));
2549 lpStatusPtr
->ServiceStatusProcess
.dwProcessId
= CurrentService
->ProcessId
; /* FIXME */
2550 lpStatusPtr
->ServiceStatusProcess
.dwServiceFlags
= 0; /* FIXME */
2553 dwRequiredSize
+= dwSize
;
2563 /* Unlock the service list */
2565 DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError
);
2572 /* ScmrSendTSMessage */
2575 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2577 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2581 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2583 HeapFree(GetProcessHeap(), 0, ptr
);