5 /* INCLUDES ****************************************************************/
14 /* GLOBALS *****************************************************************/
16 #define MANAGER_TAG 0x72674D68 /* 'hMgr' */
17 #define SERVICE_TAG 0x63765368 /* 'hSvc' */
19 typedef struct _SCMGR_HANDLE
27 typedef struct _MANAGER_HANDLE
31 /* FIXME: Insert more data here */
33 WCHAR DatabaseName
[1];
34 } MANAGER_HANDLE
, *PMANAGER_HANDLE
;
37 typedef struct _SERVICE_HANDLE
42 PSERVICE ServiceEntry
;
44 /* FIXME: Insert more data here */
46 } SERVICE_HANDLE
, *PSERVICE_HANDLE
;
49 #define SC_MANAGER_READ \
50 (STANDARD_RIGHTS_READ | \
51 SC_MANAGER_QUERY_LOCK_STATUS | \
52 SC_MANAGER_ENUMERATE_SERVICE)
54 #define SC_MANAGER_WRITE \
55 (STANDARD_RIGHTS_WRITE | \
56 SC_MANAGER_MODIFY_BOOT_CONFIG | \
57 SC_MANAGER_CREATE_SERVICE)
59 #define SC_MANAGER_EXECUTE \
60 (STANDARD_RIGHTS_EXECUTE | \
62 SC_MANAGER_ENUMERATE_SERVICE | \
63 SC_MANAGER_CONNECT | \
64 SC_MANAGER_CREATE_SERVICE)
67 #define SERVICE_READ \
68 (STANDARD_RIGHTS_READ | \
69 SERVICE_INTERROGATE | \
70 SERVICE_ENUMERATE_DEPENDENTS | \
71 SERVICE_QUERY_STATUS | \
74 #define SERVICE_WRITE \
75 (STANDARD_RIGHTS_WRITE | \
76 SERVICE_CHANGE_CONFIG)
78 #define SERVICE_EXECUTE \
79 (STANDARD_RIGHTS_EXECUTE | \
80 SERVICE_USER_DEFINED_CONTROL | \
81 SERVICE_PAUSE_CONTINUE | \
86 /* VARIABLES ***************************************************************/
88 static GENERIC_MAPPING
89 ScmManagerMapping
= {SC_MANAGER_READ
,
92 SC_MANAGER_ALL_ACCESS
};
94 static GENERIC_MAPPING
95 ScmServiceMapping
= {SERVICE_READ
,
98 SC_MANAGER_ALL_ACCESS
};
101 /* FUNCTIONS ***************************************************************/
104 ScmStartRpcServer(VOID
)
108 DPRINT("ScmStartRpcServer() called");
110 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
114 if (Status
!= RPC_S_OK
)
116 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
120 Status
= RpcServerRegisterIf(svcctl_ServerIfHandle
,
123 if (Status
!= RPC_S_OK
)
125 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
129 Status
= RpcServerListen(1, 20, TRUE
);
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
136 DPRINT("ScmStartRpcServer() done");
141 ScmCreateManagerHandle(LPWSTR lpDatabaseName
,
146 if (lpDatabaseName
== NULL
)
147 lpDatabaseName
= SERVICES_ACTIVE_DATABASEW
;
149 Ptr
= (MANAGER_HANDLE
*) HeapAlloc(GetProcessHeap(),
151 sizeof(MANAGER_HANDLE
) + wcslen(lpDatabaseName
) * sizeof(WCHAR
));
153 return ERROR_NOT_ENOUGH_MEMORY
;
155 Ptr
->Handle
.Tag
= MANAGER_TAG
;
156 Ptr
->Handle
.RefCount
= 1;
158 /* FIXME: initialize more data here */
160 wcscpy(Ptr
->DatabaseName
, lpDatabaseName
);
162 *Handle
= (SC_HANDLE
)Ptr
;
164 return ERROR_SUCCESS
;
169 ScmCreateServiceHandle(PSERVICE lpServiceEntry
,
174 Ptr
= (SERVICE_HANDLE
*) HeapAlloc(GetProcessHeap(),
176 sizeof(SERVICE_HANDLE
));
178 return ERROR_NOT_ENOUGH_MEMORY
;
180 Ptr
->Handle
.Tag
= SERVICE_TAG
;
181 Ptr
->Handle
.RefCount
= 1;
183 /* FIXME: initialize more data here */
184 Ptr
->ServiceEntry
= lpServiceEntry
;
186 *Handle
= (SC_HANDLE
)Ptr
;
188 return ERROR_SUCCESS
;
193 ScmCheckAccess(SC_HANDLE Handle
,
194 DWORD dwDesiredAccess
)
196 PMANAGER_HANDLE hMgr
;
198 hMgr
= (PMANAGER_HANDLE
)Handle
;
199 if (hMgr
->Handle
.Tag
== MANAGER_TAG
)
201 RtlMapGenericMask(&dwDesiredAccess
,
204 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
206 return ERROR_SUCCESS
;
208 else if (hMgr
->Handle
.Tag
== SERVICE_TAG
)
210 RtlMapGenericMask(&dwDesiredAccess
,
213 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
215 return ERROR_SUCCESS
;
218 return ERROR_INVALID_HANDLE
;
223 ScmAssignNewTag(PSERVICE lpService
)
226 DPRINT("Assigning new tag to service %S\n", lpService
->lpServiceName
);
227 lpService
->dwTag
= 0;
228 return ERROR_SUCCESS
;
234 ScmrCloseServiceHandle(handle_t BindingHandle
,
235 unsigned int hScObject
)
237 PMANAGER_HANDLE hManager
;
239 DPRINT("ScmrCloseServiceHandle() called\n");
241 DPRINT("hScObject = %X\n", hScObject
);
244 return ERROR_INVALID_HANDLE
;
246 hManager
= (PMANAGER_HANDLE
)hScObject
;
247 if (hManager
->Handle
.Tag
== MANAGER_TAG
)
249 DPRINT("Found manager handle\n");
251 hManager
->Handle
.RefCount
--;
252 if (hManager
->Handle
.RefCount
== 0)
254 /* FIXME: add cleanup code */
256 HeapFree(GetProcessHeap(), 0, hManager
);
259 DPRINT("ScmrCloseServiceHandle() done\n");
260 return ERROR_SUCCESS
;
262 else if (hManager
->Handle
.Tag
== SERVICE_TAG
)
264 DPRINT("Found service handle\n");
266 hManager
->Handle
.RefCount
--;
267 if (hManager
->Handle
.RefCount
== 0)
269 /* FIXME: add cleanup code */
271 HeapFree(GetProcessHeap(), 0, hManager
);
274 DPRINT("ScmrCloseServiceHandle() done\n");
275 return ERROR_SUCCESS
;
278 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager
->Handle
.Tag
);
280 return ERROR_INVALID_HANDLE
;
286 ScmrControlService(handle_t BindingHandle
,
287 unsigned int hService
,
288 unsigned long dwControl
,
289 LPSERVICE_STATUS lpServiceStatus
)
291 PSERVICE_HANDLE hSvc
;
293 ACCESS_MASK DesiredAccess
;
294 DWORD dwError
= ERROR_SUCCESS
;
296 DPRINT("ScmrControlService() called\n");
299 return ERROR_SHUTDOWN_IN_PROGRESS
;
301 /* Check the service handle */
302 hSvc
= (PSERVICE_HANDLE
)hService
;
303 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
305 DPRINT1("Invalid handle tag!\n");
306 return ERROR_INVALID_HANDLE
;
309 /* Check access rights */
312 case SERVICE_CONTROL_STOP
:
313 DesiredAccess
= SERVICE_STOP
;
316 case SERVICE_CONTROL_PAUSE
:
317 case SERVICE_CONTROL_CONTINUE
:
318 DesiredAccess
= SERVICE_PAUSE_CONTINUE
;
321 case SERVICE_INTERROGATE
:
322 DesiredAccess
= SERVICE_INTERROGATE
;
326 if (dwControl
>= 128 && dwControl
<= 255)
327 DesiredAccess
= SERVICE_USER_DEFINED_CONTROL
;
329 DesiredAccess
= SERVICE_QUERY_CONFIG
|
330 SERVICE_CHANGE_CONFIG
|
331 SERVICE_QUERY_STATUS
|
333 SERVICE_PAUSE_CONTINUE
;
337 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
339 return ERROR_ACCESS_DENIED
;
341 /* Check the service entry point */
342 lpService
= hSvc
->ServiceEntry
;
343 if (lpService
== NULL
)
345 DPRINT1("lpService == NULL!\n");
346 return ERROR_INVALID_HANDLE
;
349 if (lpService
->Status
.dwServiceType
& SERVICE_DRIVER
)
351 /* Send control code to the driver */
352 dwError
= ScmControlDriver(lpService
,
358 /* Send control code to the service */
359 dwError
= ScmControlService(lpService
,
364 /* Return service status information */
365 RtlCopyMemory(lpServiceStatus
,
367 sizeof(SERVICE_STATUS
));
375 ScmrDeleteService(handle_t BindingHandle
,
376 unsigned int hService
)
378 PSERVICE_HANDLE hSvc
;
382 DPRINT("ScmrDeleteService() called\n");
385 return ERROR_SHUTDOWN_IN_PROGRESS
;
387 hSvc
= (PSERVICE_HANDLE
)hService
;
388 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
389 return ERROR_INVALID_HANDLE
;
391 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
392 STANDARD_RIGHTS_REQUIRED
))
393 return ERROR_ACCESS_DENIED
;
395 lpService
= hSvc
->ServiceEntry
;
396 if (lpService
== NULL
)
398 DPRINT1("lpService == NULL!\n");
399 return ERROR_INVALID_HANDLE
;
402 /* FIXME: Acquire service database lock exclusively */
404 if (lpService
->bDeleted
)
406 DPRINT1("The service has already been marked for delete!\n");
407 return ERROR_SERVICE_MARKED_FOR_DELETE
;
410 /* Mark service for delete */
411 lpService
->bDeleted
= TRUE
;
413 dwError
= ScmMarkServiceForDelete(lpService
);
415 /* FIXME: Release service database lock */
417 DPRINT("ScmrDeleteService() done\n");
425 ScmrLockServiceDatabase(handle_t BindingHandle
,
426 unsigned int hSCManager
,
429 PMANAGER_HANDLE hMgr
;
431 DPRINT("ScmrLockServiceDatabase() called\n");
435 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
436 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
437 return ERROR_INVALID_HANDLE
;
439 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
441 return ERROR_ACCESS_DENIED
;
443 // return ScmLockDatabase(0, hMgr->0xC, hLock);
445 /* FIXME: Lock the database */
446 *hLock
= 0x12345678; /* Dummy! */
448 return ERROR_SUCCESS
;
454 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
,
455 unsigned int hService
,
456 unsigned long dwSecurityInformation
,
457 unsigned char *lpSecurityDescriptor
,
458 unsigned long dwSecuityDescriptorSize
,
459 unsigned long *pcbBytesNeeded
)
462 PSERVICE_HANDLE hSvc
;
464 ULONG DesiredAccess
= 0;
469 DPRINT("ScmrQueryServiceObjectSecurity() called\n");
471 hSvc
= (PSERVICE_HANDLE
)hService
;
472 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
474 DPRINT1("Invalid handle tag!\n");
475 return ERROR_INVALID_HANDLE
;
478 if (dwSecurityInformation
& (DACL_SECURITY_INFORMATION
||
479 GROUP_SECURITY_INFORMATION
||
480 OWNER_SECURITY_INFORMATION
))
481 DesiredAccess
|= READ_CONTROL
;
483 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
484 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
486 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
489 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
490 return ERROR_ACCESS_DENIED
;
493 lpService
= hSvc
->ServiceEntry
;
494 if (lpService
== NULL
)
496 DPRINT1("lpService == NULL!\n");
497 return ERROR_INVALID_HANDLE
;
500 /* FIXME: Lock the service list */
502 Status
= RtlQuerySecurityObject(lpService
->lpSecurityDescriptor
,
503 dwSecurityInformation
,
504 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
505 dwSecuityDescriptorSize
,
508 /* FIXME: Unlock the service list */
510 if (NT_SUCCESS(Status
))
512 *pcbBytesNeeded
= dwBytesNeeded
;
513 dwError
= STATUS_SUCCESS
;
515 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
517 *pcbBytesNeeded
= dwBytesNeeded
;
518 dwError
= ERROR_INSUFFICIENT_BUFFER
;
520 else if (Status
== STATUS_BAD_DESCRIPTOR_FORMAT
)
522 dwError
= ERROR_GEN_FAILURE
;
526 dwError
= RtlNtStatusToDosError(Status
);
531 DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
532 return ERROR_CALL_NOT_IMPLEMENTED
;
538 ScmrSetServiceObjectSecurity(handle_t BindingHandle
,
539 unsigned int hService
,
540 unsigned long dwSecurityInformation
,
541 unsigned char *lpSecurityDescriptor
,
542 unsigned long dwSecuityDescriptorSize
)
544 PSERVICE_HANDLE hSvc
;
546 ULONG DesiredAccess
= 0;
547 HANDLE hToken
= NULL
;
552 DPRINT1("ScmrSetServiceObjectSecurity() called\n");
554 hSvc
= (PSERVICE_HANDLE
)hService
;
555 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
557 DPRINT1("Invalid handle tag!\n");
558 return ERROR_INVALID_HANDLE
;
561 if (dwSecurityInformation
== 0 ||
562 dwSecurityInformation
& ~(OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
563 | DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
))
564 return ERROR_INVALID_PARAMETER
;
566 if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
))
567 return ERROR_INVALID_PARAMETER
;
569 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
570 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
572 if (dwSecurityInformation
& DACL_SECURITY_INFORMATION
)
573 DesiredAccess
|= WRITE_DAC
;
575 if (dwSecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
576 DesiredAccess
|= WRITE_OWNER
;
578 if ((dwSecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
579 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Owner
== NULL
))
580 return ERROR_INVALID_PARAMETER
;
582 if ((dwSecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
583 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Group
== NULL
))
584 return ERROR_INVALID_PARAMETER
;
586 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
589 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
590 return ERROR_ACCESS_DENIED
;
593 lpService
= hSvc
->ServiceEntry
;
594 if (lpService
== NULL
)
596 DPRINT1("lpService == NULL!\n");
597 return ERROR_INVALID_HANDLE
;
600 if (lpService
->bDeleted
)
601 return ERROR_SERVICE_MARKED_FOR_DELETE
;
603 RpcImpersonateClient(NULL
);
605 Status
= NtOpenThreadToken(NtCurrentThread(),
609 if (!NT_SUCCESS(Status
))
610 return RtlNtStatusToDosError(Status
);
614 /* FIXME: Lock service database */
617 Status
= RtlSetSecurityObject(dwSecurityInformation
,
618 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
619 &lpService
->lpSecurityDescriptor
,
622 if (!NT_SUCCESS(Status
))
624 dwError
= RtlNtStatusToDosError(Status
);
629 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
630 READ_CONTROL
| KEY_CREATE_SUB_KEY
| KEY_SET_VALUE
,
632 if (dwError
!= ERROR_SUCCESS
)
635 DPRINT1("Stub: ScmrSetServiceObjectSecurity() is unimplemented\n");
636 dwError
= ERROR_SUCCESS
;
637 // dwError = ScmWriteSecurityDescriptor(hServiceKey,
638 // lpService->lpSecurityDescriptor);
640 RegFlushKey(hServiceKey
);
641 RegCloseKey(hServiceKey
);
648 /* FIXME: Unlock service database */
650 DPRINT("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError
);
658 ScmrQueryServiceStatus(handle_t BindingHandle
,
659 unsigned int hService
,
660 LPSERVICE_STATUS lpServiceStatus
)
662 PSERVICE_HANDLE hSvc
;
665 DPRINT("ScmrQueryServiceStatus() called\n");
668 return ERROR_SHUTDOWN_IN_PROGRESS
;
670 hSvc
= (PSERVICE_HANDLE
)hService
;
671 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
673 DPRINT1("Invalid handle tag!\n");
674 return ERROR_INVALID_HANDLE
;
677 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
678 SERVICE_QUERY_STATUS
))
680 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
681 return ERROR_ACCESS_DENIED
;
684 lpService
= hSvc
->ServiceEntry
;
685 if (lpService
== NULL
)
687 DPRINT1("lpService == NULL!\n");
688 return ERROR_INVALID_HANDLE
;
691 /* Return service status information */
692 RtlCopyMemory(lpServiceStatus
,
694 sizeof(SERVICE_STATUS
));
696 return ERROR_SUCCESS
;
702 ScmrSetServiceStatus(handle_t BindingHandle
,
703 unsigned long hServiceStatus
) /* FIXME */
705 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
707 return ERROR_CALL_NOT_IMPLEMENTED
;
713 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
716 DPRINT1("ScmrUnlockServiceDatabase() called\n");
718 return ERROR_SUCCESS
;
724 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
725 unsigned long BootAcceptable
)
727 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
729 return ERROR_CALL_NOT_IMPLEMENTED
;
735 ScmrSetServiceBitsW(handle_t BindingHandle
,
736 unsigned long hServiceStatus
,
737 unsigned long dwServiceBits
,
738 unsigned long bSetBitsOn
,
739 unsigned long bUpdateImmediately
,
742 DPRINT1("ScmrSetServiceBitsW() called\n");
744 return ERROR_CALL_NOT_IMPLEMENTED
;
750 ScmrChangeServiceConfigW(handle_t BiningHandle
,
751 unsigned int hService
,
752 unsigned long dwServiceType
,
753 unsigned long dwStartType
,
754 unsigned long dwErrorControl
,
755 wchar_t *lpBinaryPathName
,
756 wchar_t *lpLoadOrderGroup
,
757 unsigned long *lpdwTagId
, /* in, out, unique */
758 wchar_t *lpDependencies
,
759 unsigned long dwDependenciesLength
,
760 wchar_t *lpServiceStartName
,
762 unsigned long dwPasswordLength
,
763 wchar_t *lpDisplayName
)
765 DWORD dwError
= ERROR_SUCCESS
;
766 PSERVICE_HANDLE hSvc
;
767 PSERVICE lpService
= NULL
;
768 HKEY hServiceKey
= NULL
;
770 DPRINT("ScmrChangeServiceConfigW() called\n");
771 DPRINT("dwServiceType = %lu\n", dwServiceType
);
772 DPRINT("dwStartType = %lu\n", dwStartType
);
773 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
774 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
775 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
776 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
779 return ERROR_SHUTDOWN_IN_PROGRESS
;
781 hSvc
= (PSERVICE_HANDLE
)hService
;
782 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
784 DPRINT1("Invalid handle tag!\n");
785 return ERROR_INVALID_HANDLE
;
788 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
789 SERVICE_CHANGE_CONFIG
))
791 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
792 return ERROR_ACCESS_DENIED
;
795 lpService
= hSvc
->ServiceEntry
;
796 if (lpService
== NULL
)
798 DPRINT1("lpService == NULL!\n");
799 return ERROR_INVALID_HANDLE
;
802 /* FIXME: Lock database exclusively */
804 if (lpService
->bDeleted
)
806 /* FIXME: Unlock database */
807 DPRINT1("The service has already been marked for delete!\n");
808 return ERROR_SERVICE_MARKED_FOR_DELETE
;
811 /* Open the service key */
812 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
815 if (dwError
!= ERROR_SUCCESS
)
818 /* Write service data to the registry */
819 /* Set the display name */
820 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
822 RegSetValueExW(hServiceKey
,
826 (LPBYTE
)lpDisplayName
,
827 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
828 /* FIXME: update lpService->lpDisplayName */
831 if (dwServiceType
!= SERVICE_NO_CHANGE
)
833 /* Set the service type */
834 dwError
= RegSetValueExW(hServiceKey
,
838 (LPBYTE
)&dwServiceType
,
840 if (dwError
!= ERROR_SUCCESS
)
843 lpService
->Status
.dwServiceType
= dwServiceType
;
846 if (dwStartType
!= SERVICE_NO_CHANGE
)
848 /* Set the start value */
849 dwError
= RegSetValueExW(hServiceKey
,
853 (LPBYTE
)&dwStartType
,
855 if (dwError
!= ERROR_SUCCESS
)
858 lpService
->dwStartType
= dwStartType
;
861 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
863 /* Set the error control value */
864 dwError
= RegSetValueExW(hServiceKey
,
868 (LPBYTE
)&dwErrorControl
,
870 if (dwError
!= ERROR_SUCCESS
)
873 lpService
->dwErrorControl
= dwErrorControl
;
877 /* FIXME: set the new ImagePath value */
879 /* Set the image path */
880 if (dwServiceType
& SERVICE_WIN32
)
882 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
884 dwError
= RegSetValueExW(hServiceKey
,
888 (LPBYTE
)lpBinaryPathName
,
889 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
890 if (dwError
!= ERROR_SUCCESS
)
894 else if (dwServiceType
& SERVICE_DRIVER
)
896 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
898 dwError
= RegSetValueExW(hServiceKey
,
903 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
904 if (dwError
!= ERROR_SUCCESS
)
910 /* Set the group name */
911 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
913 dwError
= RegSetValueExW(hServiceKey
,
917 (LPBYTE
)lpLoadOrderGroup
,
918 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
919 if (dwError
!= ERROR_SUCCESS
)
921 /* FIXME: update lpService->lpServiceGroup */
924 if (lpdwTagId
!= NULL
)
926 dwError
= ScmAssignNewTag(lpService
);
927 if (dwError
!= ERROR_SUCCESS
)
930 dwError
= RegSetValueExW(hServiceKey
,
934 (LPBYTE
)&lpService
->dwTag
,
936 if (dwError
!= ERROR_SUCCESS
)
939 *lpdwTagId
= lpService
->dwTag
;
942 /* Write dependencies */
943 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
945 dwError
= ScmWriteDependencies(hServiceKey
,
947 dwDependenciesLength
);
948 if (dwError
!= ERROR_SUCCESS
)
952 if (lpPassword
!= NULL
)
954 /* FIXME: Write password */
957 /* FIXME: Unlock database */
960 if (hServiceKey
!= NULL
)
961 RegCloseKey(hServiceKey
);
963 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
971 ScmrCreateServiceW(handle_t BindingHandle
,
972 unsigned int hSCManager
,
973 wchar_t *lpServiceName
,
974 wchar_t *lpDisplayName
,
975 unsigned long dwDesiredAccess
,
976 unsigned long dwServiceType
,
977 unsigned long dwStartType
,
978 unsigned long dwErrorControl
,
979 wchar_t *lpBinaryPathName
,
980 wchar_t *lpLoadOrderGroup
,
981 unsigned long *lpdwTagId
, /* in, out */
982 wchar_t *lpDependencies
,
983 unsigned long dwDependenciesLength
,
984 wchar_t *lpServiceStartName
,
986 unsigned long dwPasswordLength
,
987 unsigned int *hService
) /* out */
989 PMANAGER_HANDLE hManager
;
990 DWORD dwError
= ERROR_SUCCESS
;
991 PSERVICE lpService
= NULL
;
992 SC_HANDLE hServiceHandle
= NULL
;
993 LPWSTR lpImagePath
= NULL
;
994 HKEY hServiceKey
= NULL
;
996 DPRINT("ScmrCreateServiceW() called\n");
997 DPRINT("lpServiceName = %S\n", lpServiceName
);
998 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
999 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess
);
1000 DPRINT("dwServiceType = %lu\n", dwServiceType
);
1001 DPRINT("dwStartType = %lu\n", dwStartType
);
1002 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
1003 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
1004 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
1007 return ERROR_SHUTDOWN_IN_PROGRESS
;
1009 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1010 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1012 DPRINT1("Invalid manager handle!\n");
1013 return ERROR_INVALID_HANDLE
;
1016 /* Check access rights */
1017 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1018 SC_MANAGER_CREATE_SERVICE
))
1020 DPRINT1("Insufficient access rights! 0x%lx\n",
1021 hManager
->Handle
.DesiredAccess
);
1022 return ERROR_ACCESS_DENIED
;
1025 /* Fail if the service already exists! */
1026 if (ScmGetServiceEntryByName(lpServiceName
) != NULL
)
1027 return ERROR_SERVICE_EXISTS
;
1029 if (dwServiceType
& SERVICE_DRIVER
)
1031 /* FIXME: Adjust the image path
1032 * Following line is VERY BAD, because it assumes that the
1033 * first part of full file name is the OS directory */
1034 if (lpBinaryPathName
[1] == ':') lpBinaryPathName
+= GetWindowsDirectoryW(NULL
, 0);
1036 lpImagePath
= (WCHAR
*) HeapAlloc(GetProcessHeap(),
1038 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1039 if (lpImagePath
== NULL
)
1041 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1044 wcscpy(lpImagePath
, lpBinaryPathName
);
1047 /* Allocate a new service entry */
1048 dwError
= ScmCreateNewServiceRecord(lpServiceName
,
1050 if (dwError
!= ERROR_SUCCESS
)
1053 /* Fill the new service entry */
1054 lpService
->Status
.dwServiceType
= dwServiceType
;
1055 lpService
->dwStartType
= dwStartType
;
1056 lpService
->dwErrorControl
= dwErrorControl
;
1058 /* Fill the display name */
1059 if (lpDisplayName
!= NULL
&&
1060 *lpDisplayName
!= 0 &&
1061 wcsicmp(lpService
->lpDisplayName
, lpDisplayName
) != 0)
1063 lpService
->lpDisplayName
= (WCHAR
*) HeapAlloc(GetProcessHeap(), 0,
1064 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1065 if (lpService
->lpDisplayName
== NULL
)
1067 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1070 wcscpy(lpService
->lpDisplayName
, lpDisplayName
);
1073 /* Assign the service to a group */
1074 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1076 dwError
= ScmSetServiceGroup(lpService
,
1078 if (dwError
!= ERROR_SUCCESS
)
1082 /* Assign a new tag */
1083 if (lpdwTagId
!= NULL
)
1085 dwError
= ScmAssignNewTag(lpService
);
1086 if (dwError
!= ERROR_SUCCESS
)
1090 /* Write service data to the registry */
1091 /* Create the service key */
1092 dwError
= ScmCreateServiceKey(lpServiceName
,
1095 if (dwError
!= ERROR_SUCCESS
)
1098 /* Set the display name */
1099 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
1101 RegSetValueExW(hServiceKey
,
1105 (LPBYTE
)lpDisplayName
,
1106 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1109 /* Set the service type */
1110 dwError
= RegSetValueExW(hServiceKey
,
1114 (LPBYTE
)&dwServiceType
,
1116 if (dwError
!= ERROR_SUCCESS
)
1119 /* Set the start value */
1120 dwError
= RegSetValueExW(hServiceKey
,
1124 (LPBYTE
)&dwStartType
,
1126 if (dwError
!= ERROR_SUCCESS
)
1129 /* Set the error control value */
1130 dwError
= RegSetValueExW(hServiceKey
,
1134 (LPBYTE
)&dwErrorControl
,
1136 if (dwError
!= ERROR_SUCCESS
)
1139 /* Set the image path */
1140 if (dwServiceType
& SERVICE_WIN32
)
1142 dwError
= RegSetValueExW(hServiceKey
,
1146 (LPBYTE
)lpBinaryPathName
,
1147 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1148 if (dwError
!= ERROR_SUCCESS
)
1151 else if (dwServiceType
& SERVICE_DRIVER
)
1153 dwError
= RegSetValueExW(hServiceKey
,
1157 (LPBYTE
)lpImagePath
,
1158 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
1159 if (dwError
!= ERROR_SUCCESS
)
1163 /* Set the group name */
1164 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1166 dwError
= RegSetValueExW(hServiceKey
,
1170 (LPBYTE
)lpLoadOrderGroup
,
1171 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
1172 if (dwError
!= ERROR_SUCCESS
)
1176 if (lpdwTagId
!= NULL
)
1178 dwError
= RegSetValueExW(hServiceKey
,
1182 (LPBYTE
)&lpService
->dwTag
,
1184 if (dwError
!= ERROR_SUCCESS
)
1188 /* Write dependencies */
1189 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
1191 dwError
= ScmWriteDependencies(hServiceKey
,
1193 dwDependenciesLength
);
1194 if (dwError
!= ERROR_SUCCESS
)
1198 if (lpPassword
!= NULL
)
1200 /* FIXME: Write password */
1203 dwError
= ScmCreateServiceHandle(lpService
,
1205 if (dwError
!= ERROR_SUCCESS
)
1208 dwError
= ScmCheckAccess(hServiceHandle
,
1210 if (dwError
!= ERROR_SUCCESS
)
1214 if (hServiceKey
!= NULL
)
1215 RegCloseKey(hServiceKey
);
1217 if (dwError
== ERROR_SUCCESS
)
1219 DPRINT("hService %lx\n", hServiceHandle
);
1220 *hService
= (unsigned int)hServiceHandle
;
1222 if (lpdwTagId
!= NULL
)
1223 *lpdwTagId
= lpService
->dwTag
;
1227 /* Release the display name buffer */
1228 if (lpService
->lpServiceName
!= lpService
->lpDisplayName
)
1229 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
1231 if (hServiceHandle
!= NULL
)
1233 /* Remove the service handle */
1234 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
1237 if (lpService
!= NULL
)
1239 /* FIXME: remove the service entry */
1243 if (lpImagePath
!= NULL
)
1244 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1246 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
1254 ScmrEnumDependentServicesW(handle_t BindingHandle
,
1255 unsigned int hService
,
1256 unsigned long dwServiceState
,
1257 unsigned char *lpServices
,
1258 unsigned long cbBufSize
,
1259 unsigned long *pcbBytesNeeded
,
1260 unsigned long *lpServicesReturned
)
1262 DWORD dwError
= ERROR_SUCCESS
;
1264 DPRINT1("ScmrEnumDependentServicesW() called\n");
1265 *pcbBytesNeeded
= 0;
1266 *lpServicesReturned
= 0;
1268 DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError
);
1276 ScmrEnumServicesStatusW(handle_t BindingHandle
,
1277 unsigned int hSCManager
,
1278 unsigned long dwServiceType
,
1279 unsigned long dwServiceState
,
1280 unsigned char *lpServices
,
1281 unsigned long dwBufSize
,
1282 unsigned long *pcbBytesNeeded
,
1283 unsigned long *lpServicesReturned
,
1284 unsigned long *lpResumeHandle
)
1286 PMANAGER_HANDLE hManager
;
1288 DWORD dwError
= ERROR_SUCCESS
;
1289 PLIST_ENTRY ServiceEntry
;
1290 PSERVICE CurrentService
;
1292 DWORD dwRequiredSize
;
1293 DWORD dwServiceCount
;
1295 DWORD dwLastResumeCount
;
1296 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1299 DPRINT("ScmrEnumServicesStatusW() called\n");
1302 return ERROR_SHUTDOWN_IN_PROGRESS
;
1304 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1305 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1307 DPRINT1("Invalid manager handle!\n");
1308 return ERROR_INVALID_HANDLE
;
1311 /* Check access rights */
1312 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1313 SC_MANAGER_ENUMERATE_SERVICE
))
1315 DPRINT1("Insufficient access rights! 0x%lx\n",
1316 hManager
->Handle
.DesiredAccess
);
1317 return ERROR_ACCESS_DENIED
;
1320 *pcbBytesNeeded
= 0;
1321 *lpServicesReturned
= 0;
1323 dwLastResumeCount
= *lpResumeHandle
;
1325 /* FIXME: Lock the service list shared */
1327 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
1328 if (lpService
== NULL
)
1330 dwError
= ERROR_SUCCESS
;
1337 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1338 ServiceEntry
!= &ServiceListHead
;
1339 ServiceEntry
= ServiceEntry
->Flink
)
1341 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1345 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1348 dwState
= SERVICE_ACTIVE
;
1349 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1350 dwState
= SERVICE_INACTIVE
;
1352 if ((dwState
& dwServiceState
) == 0)
1355 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1356 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1357 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1359 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1361 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
1362 dwRequiredSize
+= dwSize
;
1364 dwLastResumeCount
= CurrentService
->dwResumeCount
;
1368 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
1374 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
1375 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
1378 ServiceEntry
!= &ServiceListHead
;
1379 ServiceEntry
= ServiceEntry
->Flink
)
1381 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1385 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1388 dwState
= SERVICE_ACTIVE
;
1389 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1390 dwState
= SERVICE_INACTIVE
;
1392 if ((dwState
& dwServiceState
) == 0)
1395 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUSW
) +
1396 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1397 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
1399 dwError
= ERROR_MORE_DATA
;
1402 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
1404 *lpResumeHandle
= dwLastResumeCount
;
1405 *lpServicesReturned
= dwServiceCount
;
1406 *pcbBytesNeeded
= dwRequiredSize
;
1408 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1409 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
1410 dwServiceCount
* sizeof(ENUM_SERVICE_STATUSW
));
1413 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1414 ServiceEntry
!= &ServiceListHead
;
1415 ServiceEntry
= ServiceEntry
->Flink
)
1417 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1421 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1424 dwState
= SERVICE_ACTIVE
;
1425 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1426 dwState
= SERVICE_INACTIVE
;
1428 if ((dwState
& dwServiceState
) == 0)
1431 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1432 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1433 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1435 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1437 /* Copy the service name */
1439 CurrentService
->lpServiceName
);
1440 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1441 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
1443 /* Copy the display name */
1445 CurrentService
->lpDisplayName
);
1446 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1447 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
1449 /* Copy the status information */
1450 memcpy(&lpStatusPtr
->ServiceStatus
,
1451 &CurrentService
->Status
,
1452 sizeof(SERVICE_STATUS
));
1455 dwRequiredSize
+= dwSize
;
1465 /* FIXME: Unlock the service list */
1467 DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError
);
1475 ScmrOpenSCManagerW(handle_t BindingHandle
,
1476 wchar_t *lpMachineName
,
1477 wchar_t *lpDatabaseName
,
1478 unsigned long dwDesiredAccess
,
1484 DPRINT("ScmrOpenSCManagerW() called\n");
1485 DPRINT("lpMachineName = %p\n", lpMachineName
);
1486 DPRINT("lpMachineName: %S\n", lpMachineName
);
1487 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
1488 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
1489 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1492 return ERROR_SHUTDOWN_IN_PROGRESS
;
1494 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1496 if (dwError
!= ERROR_SUCCESS
)
1498 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1502 /* Check the desired access */
1503 dwError
= ScmCheckAccess(hHandle
,
1504 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1505 if (dwError
!= ERROR_SUCCESS
)
1507 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1508 HeapFree(GetProcessHeap(), 0, hHandle
);
1512 *hScm
= (unsigned int)hHandle
;
1513 DPRINT("*hScm = %x\n", *hScm
);
1515 DPRINT("ScmrOpenSCManagerW() done\n");
1517 return ERROR_SUCCESS
;
1523 ScmrOpenServiceW(handle_t BindingHandle
,
1524 unsigned int hSCManager
,
1525 wchar_t *lpServiceName
,
1526 unsigned long dwDesiredAccess
,
1527 unsigned int *hService
)
1530 PMANAGER_HANDLE hManager
;
1534 DPRINT("ScmrOpenServiceW() called\n");
1535 DPRINT("hSCManager = %x\n", hSCManager
);
1536 DPRINT("lpServiceName = %p\n", lpServiceName
);
1537 DPRINT("lpServiceName: %S\n", lpServiceName
);
1538 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1541 return ERROR_SHUTDOWN_IN_PROGRESS
;
1543 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1544 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1546 DPRINT1("Invalid manager handle!\n");
1547 return ERROR_INVALID_HANDLE
;
1550 /* FIXME: Lock the service list */
1552 /* Get service database entry */
1553 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1554 if (lpService
== NULL
)
1556 DPRINT("Could not find a service!\n");
1557 return ERROR_SERVICE_DOES_NOT_EXIST
;
1560 /* Create a service handle */
1561 dwError
= ScmCreateServiceHandle(lpService
,
1563 if (dwError
!= ERROR_SUCCESS
)
1565 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1569 /* Check the desired access */
1570 dwError
= ScmCheckAccess(hHandle
,
1572 if (dwError
!= ERROR_SUCCESS
)
1574 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1575 HeapFree(GetProcessHeap(), 0, hHandle
);
1579 *hService
= (unsigned int)hHandle
;
1580 DPRINT("*hService = %x\n", *hService
);
1582 DPRINT("ScmrOpenServiceW() done\n");
1584 return ERROR_SUCCESS
;
1590 ScmrQueryServiceConfigW(handle_t BindingHandle
,
1591 unsigned int hService
,
1592 unsigned char *lpServiceConfig
,
1593 unsigned long cbBufSize
,
1594 unsigned long *pcbBytesNeeded
)
1596 DWORD dwError
= ERROR_SUCCESS
;
1597 PSERVICE_HANDLE hSvc
;
1598 PSERVICE lpService
= NULL
;
1599 HKEY hServiceKey
= NULL
;
1600 LPWSTR lpImagePath
= NULL
;
1601 DWORD dwRequiredSize
;
1602 LPQUERY_SERVICE_CONFIGW lpConfig
;
1605 DPRINT("ScmrQueryServiceConfigW() called\n");
1608 return ERROR_SHUTDOWN_IN_PROGRESS
;
1610 hSvc
= (PSERVICE_HANDLE
)hService
;
1611 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1613 DPRINT1("Invalid handle tag!\n");
1614 return ERROR_INVALID_HANDLE
;
1617 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1618 SERVICE_QUERY_CONFIG
))
1620 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1621 return ERROR_ACCESS_DENIED
;
1624 lpService
= hSvc
->ServiceEntry
;
1625 if (lpService
== NULL
)
1627 DPRINT1("lpService == NULL!\n");
1628 return ERROR_INVALID_HANDLE
;
1631 /* FIXME: Lock the service database shared */
1633 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
1636 if (dwError
!= ERROR_SUCCESS
)
1639 dwError
= ScmReadString(hServiceKey
,
1642 if (dwError
!= ERROR_SUCCESS
)
1645 dwRequiredSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1647 if (lpImagePath
!= NULL
)
1648 dwRequiredSize
+= ((wcslen(lpImagePath
) + 1) * sizeof(WCHAR
));
1650 if (lpService
->lpGroup
!= NULL
)
1651 dwRequiredSize
+= ((wcslen(lpService
->lpGroup
->lpGroupName
) + 1) * sizeof(WCHAR
));
1653 /* FIXME: Add Dependencies length*/
1655 /* FIXME: Add ServiceStartName length*/
1657 if (lpService
->lpDisplayName
!= NULL
)
1658 dwRequiredSize
+= ((wcslen(lpService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1660 if (lpServiceConfig
== NULL
|| cbBufSize
< dwRequiredSize
)
1662 dwError
= ERROR_INSUFFICIENT_BUFFER
;
1666 lpConfig
= (LPQUERY_SERVICE_CONFIGW
)lpServiceConfig
;
1667 lpConfig
->dwServiceType
= lpService
->Status
.dwServiceType
;
1668 lpConfig
->dwStartType
= lpService
->dwStartType
;
1669 lpConfig
->dwErrorControl
= lpService
->dwErrorControl
;
1670 lpConfig
->dwTagId
= lpService
->dwTag
;
1672 lpStr
= (LPWSTR
)(lpConfig
+ 1);
1674 if (lpImagePath
!= NULL
)
1676 wcscpy(lpStr
, lpImagePath
);
1677 lpConfig
->lpBinaryPathName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1678 lpStr
+= (wcslen(lpImagePath
) + 1);
1682 lpConfig
->lpBinaryPathName
= NULL
;
1685 if (lpService
->lpGroup
!= NULL
)
1687 wcscpy(lpStr
, lpService
->lpGroup
->lpGroupName
);
1688 lpConfig
->lpLoadOrderGroup
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1689 lpStr
+= (wcslen(lpService
->lpGroup
->lpGroupName
) + 1);
1693 lpConfig
->lpLoadOrderGroup
= NULL
;
1696 /* FIXME: Append Dependencies */
1697 lpConfig
->lpDependencies
= NULL
;
1699 /* FIXME: Append ServiceStartName */
1700 lpConfig
->lpServiceStartName
= NULL
;
1702 if (lpService
->lpDisplayName
!= NULL
)
1704 wcscpy(lpStr
, lpService
->lpDisplayName
);
1705 lpConfig
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1709 lpConfig
->lpDisplayName
= NULL
;
1713 if (pcbBytesNeeded
!= NULL
)
1714 *pcbBytesNeeded
= dwRequiredSize
;
1717 if (lpImagePath
!= NULL
)
1718 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1720 if (hServiceKey
!= NULL
)
1721 RegCloseKey(hServiceKey
);
1723 /* FIXME: Unlock the service database */
1725 DPRINT("ScmrQueryServiceConfigW() done\n");
1733 ScmrQueryServiceLockStatusW(handle_t BindingHandle
,
1734 unsigned int hSCManager
,
1735 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
1736 unsigned long cbBufSize
, /* [in] */
1737 unsigned long *pcbBytesNeeded
) /* [out] */
1739 DPRINT1("ScmrQueryServiceLockStatusW() called\n");
1740 return ERROR_CALL_NOT_IMPLEMENTED
;
1746 ScmrStartServiceW(handle_t BindingHandle
,
1747 unsigned int hService
,
1748 unsigned long dwNumServiceArgs
,
1749 unsigned char *lpServiceArgBuffer
,
1750 unsigned long cbBufSize
)
1752 DWORD dwError
= ERROR_SUCCESS
;
1753 PSERVICE_HANDLE hSvc
;
1754 PSERVICE lpService
= NULL
;
1756 DPRINT("ScmrStartServiceW() called\n");
1759 return ERROR_SHUTDOWN_IN_PROGRESS
;
1761 hSvc
= (PSERVICE_HANDLE
)hService
;
1762 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1764 DPRINT1("Invalid handle tag!\n");
1765 return ERROR_INVALID_HANDLE
;
1768 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1771 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1772 return ERROR_ACCESS_DENIED
;
1775 lpService
= hSvc
->ServiceEntry
;
1776 if (lpService
== NULL
)
1778 DPRINT1("lpService == NULL!\n");
1779 return ERROR_INVALID_HANDLE
;
1782 if (lpService
->dwStartType
== SERVICE_DISABLED
)
1783 return ERROR_SERVICE_DISABLED
;
1785 if (lpService
->bDeleted
)
1786 return ERROR_SERVICE_MARKED_FOR_DELETE
;
1788 /* Start the service */
1789 dwError
= ScmStartService(lpService
, (LPWSTR
)lpServiceArgBuffer
);
1797 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1798 unsigned int hSCManager
,
1799 wchar_t *lpServiceName
,
1800 wchar_t *lpDisplayName
, /* [out, unique] */
1801 unsigned long *lpcchBuffer
)
1803 // PMANAGER_HANDLE hManager;
1808 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1809 DPRINT("hSCManager = %x\n", hSCManager
);
1810 DPRINT("lpServiceName: %S\n", lpServiceName
);
1811 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1812 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1814 // hManager = (PMANAGER_HANDLE)hSCManager;
1815 // if (hManager->Handle.Tag != MANAGER_TAG)
1817 // DPRINT1("Invalid manager handle!\n");
1818 // return ERROR_INVALID_HANDLE;
1821 /* Get service database entry */
1822 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1823 if (lpService
== NULL
)
1825 DPRINT1("Could not find a service!\n");
1826 return ERROR_SERVICE_DOES_NOT_EXIST
;
1829 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1831 if (lpDisplayName
!= NULL
&&
1832 *lpcchBuffer
>= dwLength
)
1834 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1837 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1839 *lpcchBuffer
= dwLength
;
1847 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1848 unsigned int hSCManager
,
1849 wchar_t *lpDisplayName
,
1850 wchar_t *lpServiceName
, /* [out, unique] */
1851 unsigned long *lpcchBuffer
)
1853 // PMANAGER_HANDLE hManager;
1858 DPRINT("ScmrGetServiceKeyNameW() called\n");
1859 DPRINT("hSCManager = %x\n", hSCManager
);
1860 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1861 DPRINT("lpServiceName: %p\n", lpServiceName
);
1862 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1864 // hManager = (PMANAGER_HANDLE)hSCManager;
1865 // if (hManager->Handle.Tag != MANAGER_TAG)
1867 // DPRINT1("Invalid manager handle!\n");
1868 // return ERROR_INVALID_HANDLE;
1871 /* Get service database entry */
1872 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1873 if (lpService
== NULL
)
1875 DPRINT1("Could not find a service!\n");
1876 return ERROR_SERVICE_DOES_NOT_EXIST
;
1879 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1881 if (lpServiceName
!= NULL
&&
1882 *lpcchBuffer
>= dwLength
)
1884 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1887 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1889 *lpcchBuffer
= dwLength
;
1897 ScmrSetServiceBitsA(handle_t BindingHandle
,
1898 unsigned long hServiceStatus
,
1899 unsigned long dwServiceBits
,
1900 unsigned long bSetBitsOn
,
1901 unsigned long bUpdateImmediately
,
1904 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1905 return ERROR_CALL_NOT_IMPLEMENTED
;
1911 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1912 unsigned int hService
,
1913 unsigned long dwServiceType
,
1914 unsigned long dwStartType
,
1915 unsigned long dwErrorControl
,
1916 char *lpBinaryPathName
,
1917 char *lpLoadOrderGroup
,
1918 unsigned long *lpdwTagId
,
1919 char *lpDependencies
,
1920 unsigned long dwDependenciesLength
,
1921 char *lpServiceStartName
,
1923 unsigned long dwPasswordLength
,
1924 char *lpDisplayName
)
1926 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1927 return ERROR_CALL_NOT_IMPLEMENTED
;
1933 ScmrCreateServiceA(handle_t BindingHandle
,
1934 unsigned int hSCManager
,
1935 char *lpServiceName
,
1936 char *lpDisplayName
,
1937 unsigned long dwDesiredAccess
,
1938 unsigned long dwServiceType
,
1939 unsigned long dwStartType
,
1940 unsigned long dwErrorControl
,
1941 char *lpBinaryPathName
,
1942 char *lpLoadOrderGroup
,
1943 unsigned long *lpdwTagId
, /* in, out */
1944 char *lpDependencies
,
1945 unsigned long dwDependenciesLength
,
1946 char *lpServiceStartName
,
1948 unsigned long dwPasswordLength
,
1949 unsigned int *hService
) /* out */
1951 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1952 return ERROR_CALL_NOT_IMPLEMENTED
;
1958 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1959 unsigned int hService
,
1960 unsigned long dwServiceState
,
1961 unsigned char *lpServices
,
1962 unsigned long cbBufSize
,
1963 unsigned long *pcbBytesNeeded
,
1964 unsigned long *lpServicesReturned
)
1966 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
1967 *pcbBytesNeeded
= 0;
1968 *lpServicesReturned
= 0;
1969 return ERROR_CALL_NOT_IMPLEMENTED
;
1975 ScmrEnumServicesStatusA(handle_t BindingHandle
,
1976 unsigned int hSCManager
,
1977 unsigned long dwServiceType
,
1978 unsigned long dwServiceState
,
1979 unsigned char *lpServices
,
1980 unsigned long dwBufSize
,
1981 unsigned long *pcbBytesNeeded
,
1982 unsigned long *lpServicesReturned
,
1983 unsigned long *lpResumeHandle
)
1985 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
1986 return ERROR_CALL_NOT_IMPLEMENTED
;
1992 ScmrOpenSCManagerA(handle_t BindingHandle
,
1993 char *lpMachineName
,
1994 char *lpDatabaseName
,
1995 unsigned long dwDesiredAccess
,
1998 UNICODE_STRING MachineName
;
1999 UNICODE_STRING DatabaseName
;
2002 DPRINT("ScmrOpenSCManagerA() called\n");
2005 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
2009 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
2012 dwError
= ScmrOpenSCManagerW(BindingHandle
,
2013 lpMachineName
? MachineName
.Buffer
: NULL
,
2014 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
2019 RtlFreeUnicodeString(&MachineName
);
2022 RtlFreeUnicodeString(&DatabaseName
);
2030 ScmrOpenServiceA(handle_t BindingHandle
,
2031 unsigned int hSCManager
,
2032 char *lpServiceName
,
2033 unsigned long dwDesiredAccess
,
2034 unsigned int *hService
)
2036 UNICODE_STRING ServiceName
;
2039 DPRINT("ScmrOpenServiceA() called\n");
2041 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
2044 dwError
= ScmrOpenServiceW(BindingHandle
,
2050 RtlFreeUnicodeString(&ServiceName
);
2058 ScmrQueryServiceConfigA(handle_t BindingHandle
,
2059 unsigned int hService
,
2060 unsigned char *lpServiceConfig
,
2061 unsigned long cbBufSize
,
2062 unsigned long *pcbBytesNeeded
)
2064 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2065 return ERROR_CALL_NOT_IMPLEMENTED
;
2071 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2072 unsigned int hSCManager
,
2073 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2074 unsigned long cbBufSize
, /* [in] */
2075 unsigned long *pcbBytesNeeded
) /* [out] */
2077 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2078 return ERROR_CALL_NOT_IMPLEMENTED
;
2084 ScmrStartServiceA(handle_t BindingHandle
,
2085 unsigned int hService
,
2086 unsigned long dwNumServiceArgs
,
2087 unsigned char *lpServiceArgBuffer
,
2088 unsigned long cbBufSize
)
2090 DWORD dwError
= ERROR_SUCCESS
;
2091 PSERVICE_HANDLE hSvc
;
2092 PSERVICE lpService
= NULL
;
2094 DPRINT1("ScmrStartServiceA() called\n");
2097 return ERROR_SHUTDOWN_IN_PROGRESS
;
2099 hSvc
= (PSERVICE_HANDLE
)hService
;
2100 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2102 DPRINT1("Invalid handle tag!\n");
2103 return ERROR_INVALID_HANDLE
;
2106 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2109 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2110 return ERROR_ACCESS_DENIED
;
2113 lpService
= hSvc
->ServiceEntry
;
2114 if (lpService
== NULL
)
2116 DPRINT1("lpService == NULL!\n");
2117 return ERROR_INVALID_HANDLE
;
2120 if (lpService
->dwStartType
== SERVICE_DISABLED
)
2121 return ERROR_SERVICE_DISABLED
;
2123 if (lpService
->bDeleted
)
2124 return ERROR_SERVICE_MARKED_FOR_DELETE
;
2126 /* FIXME: Convert argument vector to Unicode */
2128 /* Start the service */
2129 dwError
= ScmStartService(lpService
, NULL
);
2131 /* FIXME: Free argument vector */
2139 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2140 unsigned int hSCManager
,
2141 char *lpServiceName
,
2142 char *lpDisplayName
, /* [out, unique] */
2143 unsigned long *lpcchBuffer
)
2145 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2146 return ERROR_CALL_NOT_IMPLEMENTED
;
2152 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2153 unsigned int hSCManager
,
2154 char *lpDisplayName
,
2155 char *lpServiceName
, /* [out, unique] */
2156 unsigned long *lpcchBuffer
)
2158 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2159 return ERROR_CALL_NOT_IMPLEMENTED
;
2165 ScmrGetCurrentGroupStateW(handle_t BindingHandle
)
2167 DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
2168 return ERROR_CALL_NOT_IMPLEMENTED
;
2174 ScmrEnumServiceGroupW(handle_t BindingHandle
)
2176 DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
2177 return ERROR_CALL_NOT_IMPLEMENTED
;
2183 ScmrChangeServiceConfig2A(handle_t BindingHandle
,
2184 unsigned int hService
,
2185 unsigned long dwInfoLevel
,
2186 unsigned char *lpInfo
,
2187 unsigned long dwInfoSize
)
2189 DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
2190 return ERROR_CALL_NOT_IMPLEMENTED
;
2196 ScmrChangeServiceConfig2W(handle_t BindingHandle
,
2197 unsigned int hService
,
2198 unsigned long dwInfoLevel
,
2199 unsigned char *lpInfo
,
2200 unsigned long dwInfoSize
)
2202 DPRINT1("ScmrChangeServiceConfig2W() is unimplemented\n");
2203 return ERROR_CALL_NOT_IMPLEMENTED
;
2209 ScmrQueryServiceConfig2A(handle_t BindingHandle
,
2210 unsigned int hService
,
2211 unsigned long dwInfoLevel
,
2212 unsigned char *lpBuffer
,
2213 unsigned long cbBufSize
,
2214 unsigned long *pcbBytesNeeded
)
2216 DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
2217 return ERROR_CALL_NOT_IMPLEMENTED
;
2223 ScmrQueryServiceConfig2W(handle_t BindingHandle
,
2224 unsigned int hService
,
2225 unsigned long dwInfoLevel
,
2226 unsigned char *lpBuffer
,
2227 unsigned long cbBufSize
,
2228 unsigned long *pcbBytesNeeded
)
2230 DPRINT1("ScmrQueryServiceConfig2W() is unimplemented\n");
2231 return ERROR_CALL_NOT_IMPLEMENTED
;
2237 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2238 unsigned int hService
,
2239 unsigned long InfoLevel
,
2240 unsigned char *lpBuffer
, /* out */
2241 unsigned long cbBufSize
,
2242 unsigned long *pcbBytesNeeded
) /* out */
2244 LPSERVICE_STATUS_PROCESS lpStatus
;
2245 PSERVICE_HANDLE hSvc
;
2248 DPRINT("ScmrQueryServiceStatusEx() called\n");
2251 return ERROR_SHUTDOWN_IN_PROGRESS
;
2253 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2254 return ERROR_INVALID_LEVEL
;
2256 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2258 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2259 return ERROR_INSUFFICIENT_BUFFER
;
2261 hSvc
= (PSERVICE_HANDLE
)hService
;
2262 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
2264 DPRINT1("Invalid handle tag!\n");
2265 return ERROR_INVALID_HANDLE
;
2268 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
2269 SERVICE_QUERY_STATUS
))
2271 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
2272 return ERROR_ACCESS_DENIED
;
2275 lpService
= hSvc
->ServiceEntry
;
2276 if (lpService
== NULL
)
2278 DPRINT1("lpService == NULL!\n");
2279 return ERROR_INVALID_HANDLE
;
2282 lpStatus
= (LPSERVICE_STATUS_PROCESS
)lpBuffer
;
2284 /* Return service status information */
2285 RtlCopyMemory(lpStatus
,
2287 sizeof(SERVICE_STATUS
));
2289 lpStatus
->dwProcessId
= lpService
->ProcessId
; /* FIXME */
2290 lpStatus
->dwServiceFlags
= 0; /* FIXME */
2292 return ERROR_SUCCESS
;
2298 ScmrEnumServicesStatusExA(handle_t BindingHandle
,
2299 unsigned int hSCManager
,
2300 unsigned long InfoLevel
,
2301 unsigned long dwServiceType
,
2302 unsigned long dwServiceState
,
2303 unsigned char *lpServices
,
2304 unsigned long dwBufSize
,
2305 unsigned long *pcbBytesNeeded
,
2306 unsigned long *lpServicesReturned
,
2307 unsigned long *lpResumeHandle
,
2310 DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
2311 *pcbBytesNeeded
= 0;
2312 *lpServicesReturned
= 0;
2313 return ERROR_CALL_NOT_IMPLEMENTED
;
2319 ScmrEnumServicesStatusExW(handle_t BindingHandle
,
2320 unsigned int hSCManager
,
2321 unsigned long InfoLevel
,
2322 unsigned long dwServiceType
,
2323 unsigned long dwServiceState
,
2324 unsigned char *lpServices
,
2325 unsigned long dwBufSize
,
2326 unsigned long *pcbBytesNeeded
,
2327 unsigned long *lpServicesReturned
,
2328 unsigned long *lpResumeHandle
,
2329 wchar_t *pszGroupName
)
2331 PMANAGER_HANDLE hManager
;
2333 DWORD dwError
= ERROR_SUCCESS
;
2334 PLIST_ENTRY ServiceEntry
;
2335 PSERVICE CurrentService
;
2337 DWORD dwRequiredSize
;
2338 DWORD dwServiceCount
;
2340 DWORD dwLastResumeCount
;
2341 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
2344 DPRINT("ScmrEnumServicesStatusExW() called\n");
2347 return ERROR_SHUTDOWN_IN_PROGRESS
;
2349 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
2350 return ERROR_INVALID_LEVEL
;
2352 hManager
= (PMANAGER_HANDLE
)hSCManager
;
2353 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
2355 DPRINT1("Invalid manager handle!\n");
2356 return ERROR_INVALID_HANDLE
;
2359 /* Check access rights */
2360 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
2361 SC_MANAGER_ENUMERATE_SERVICE
))
2363 DPRINT1("Insufficient access rights! 0x%lx\n",
2364 hManager
->Handle
.DesiredAccess
);
2365 return ERROR_ACCESS_DENIED
;
2368 *pcbBytesNeeded
= 0;
2369 *lpServicesReturned
= 0;
2371 dwLastResumeCount
= *lpResumeHandle
;
2373 /* Lock the service list shared */
2375 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
2376 if (lpService
== NULL
)
2378 dwError
= ERROR_SUCCESS
;
2385 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2386 ServiceEntry
!= &ServiceListHead
;
2387 ServiceEntry
= ServiceEntry
->Flink
)
2389 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2393 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2396 dwState
= SERVICE_ACTIVE
;
2397 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2398 dwState
= SERVICE_INACTIVE
;
2400 if ((dwState
& dwServiceState
) == 0)
2405 if (*pszGroupName
== 0)
2407 if (CurrentService
->lpGroup
!= NULL
)
2412 if ((CurrentService
->lpGroup
== NULL
) ||
2413 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2418 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2419 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2420 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2422 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2424 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
2425 dwRequiredSize
+= dwSize
;
2427 dwLastResumeCount
= CurrentService
->dwResumeCount
;
2431 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
2437 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
2438 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
2441 ServiceEntry
!= &ServiceListHead
;
2442 ServiceEntry
= ServiceEntry
->Flink
)
2444 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2448 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2451 dwState
= SERVICE_ACTIVE
;
2452 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2453 dwState
= SERVICE_INACTIVE
;
2455 if ((dwState
& dwServiceState
) == 0)
2460 if (*pszGroupName
== 0)
2462 if (CurrentService
->lpGroup
!= NULL
)
2467 if ((CurrentService
->lpGroup
== NULL
) ||
2468 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2473 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2474 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2475 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
2477 dwError
= ERROR_MORE_DATA
;
2480 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
2482 *lpResumeHandle
= dwLastResumeCount
;
2483 *lpServicesReturned
= dwServiceCount
;
2484 *pcbBytesNeeded
= dwRequiredSize
;
2486 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
2487 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
2488 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS_PROCESSW
));
2491 for (ServiceEntry
= &lpService
->ServiceListEntry
;
2492 ServiceEntry
!= &ServiceListHead
;
2493 ServiceEntry
= ServiceEntry
->Flink
)
2495 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
2499 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
2502 dwState
= SERVICE_ACTIVE
;
2503 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
2504 dwState
= SERVICE_INACTIVE
;
2506 if ((dwState
& dwServiceState
) == 0)
2511 if (*pszGroupName
== 0)
2513 if (CurrentService
->lpGroup
!= NULL
)
2518 if ((CurrentService
->lpGroup
== NULL
) ||
2519 _wcsicmp(pszGroupName
, CurrentService
->lpGroup
->lpGroupName
))
2524 dwSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
) +
2525 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
2526 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
2528 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
2530 /* Copy the service name */
2532 CurrentService
->lpServiceName
);
2533 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2534 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
2536 /* Copy the display name */
2538 CurrentService
->lpDisplayName
);
2539 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
2540 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
2542 /* Copy the status information */
2543 memcpy(&lpStatusPtr
->ServiceStatusProcess
,
2544 &CurrentService
->Status
,
2545 sizeof(SERVICE_STATUS
));
2546 lpStatusPtr
->ServiceStatusProcess
.dwProcessId
= CurrentService
->ProcessId
; /* FIXME */
2547 lpStatusPtr
->ServiceStatusProcess
.dwServiceFlags
= 0; /* FIXME */
2550 dwRequiredSize
+= dwSize
;
2560 /* Unlock the service list */
2562 DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError
);
2569 /* ScmrSendTSMessage */
2572 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2574 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2578 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2580 HeapFree(GetProcessHeap(), 0, ptr
);