5 /* INCLUDES ****************************************************************/
14 /* GLOBALS *****************************************************************/
16 #define MANAGER_TAG 0x72674D68 /* 'hMgr' */
17 #define SERVICE_TAG 0x63765368 /* 'hSvc' */
19 typedef struct _SCMGR_HANDLE
27 typedef struct _MANAGER_HANDLE
31 /* FIXME: Insert more data here */
33 WCHAR DatabaseName
[1];
34 } MANAGER_HANDLE
, *PMANAGER_HANDLE
;
37 typedef struct _SERVICE_HANDLE
42 PSERVICE ServiceEntry
;
44 /* FIXME: Insert more data here */
46 } SERVICE_HANDLE
, *PSERVICE_HANDLE
;
49 #define SC_MANAGER_READ \
50 (STANDARD_RIGHTS_READ | \
51 SC_MANAGER_QUERY_LOCK_STATUS | \
52 SC_MANAGER_ENUMERATE_SERVICE)
54 #define SC_MANAGER_WRITE \
55 (STANDARD_RIGHTS_WRITE | \
56 SC_MANAGER_MODIFY_BOOT_CONFIG | \
57 SC_MANAGER_CREATE_SERVICE)
59 #define SC_MANAGER_EXECUTE \
60 (STANDARD_RIGHTS_EXECUTE | \
62 SC_MANAGER_ENUMERATE_SERVICE | \
63 SC_MANAGER_CONNECT | \
64 SC_MANAGER_CREATE_SERVICE)
67 #define SERVICE_READ \
68 (STANDARD_RIGHTS_READ | \
69 SERVICE_INTERROGATE | \
70 SERVICE_ENUMERATE_DEPENDENTS | \
71 SERVICE_QUERY_STATUS | \
74 #define SERVICE_WRITE \
75 (STANDARD_RIGHTS_WRITE | \
76 SERVICE_CHANGE_CONFIG)
78 #define SERVICE_EXECUTE \
79 (STANDARD_RIGHTS_EXECUTE | \
80 SERVICE_USER_DEFINED_CONTROL | \
81 SERVICE_PAUSE_CONTINUE | \
86 /* VARIABLES ***************************************************************/
88 static GENERIC_MAPPING
89 ScmManagerMapping
= {SC_MANAGER_READ
,
92 SC_MANAGER_ALL_ACCESS
};
94 static GENERIC_MAPPING
95 ScmServiceMapping
= {SERVICE_READ
,
98 SC_MANAGER_ALL_ACCESS
};
101 /* FUNCTIONS ***************************************************************/
104 ScmStartRpcServer(VOID
)
108 DPRINT("ScmStartRpcServer() called");
110 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
114 if (Status
!= RPC_S_OK
)
116 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
120 Status
= RpcServerRegisterIf(svcctl_ServerIfHandle
,
123 if (Status
!= RPC_S_OK
)
125 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
129 Status
= RpcServerListen(1, 20, TRUE
);
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
136 DPRINT("ScmStartRpcServer() done");
141 ScmCreateManagerHandle(LPWSTR lpDatabaseName
,
146 if (lpDatabaseName
== NULL
)
147 lpDatabaseName
= SERVICES_ACTIVE_DATABASEW
;
149 Ptr
= HeapAlloc(GetProcessHeap(),
151 sizeof(MANAGER_HANDLE
) + wcslen(lpDatabaseName
) * sizeof(WCHAR
));
153 return ERROR_NOT_ENOUGH_MEMORY
;
155 Ptr
->Handle
.Tag
= MANAGER_TAG
;
156 Ptr
->Handle
.RefCount
= 1;
158 /* FIXME: initialize more data here */
160 wcscpy(Ptr
->DatabaseName
, lpDatabaseName
);
162 *Handle
= (SC_HANDLE
)Ptr
;
164 return ERROR_SUCCESS
;
169 ScmCreateServiceHandle(PSERVICE lpServiceEntry
,
174 Ptr
= HeapAlloc(GetProcessHeap(),
176 sizeof(SERVICE_HANDLE
));
178 return ERROR_NOT_ENOUGH_MEMORY
;
180 Ptr
->Handle
.Tag
= SERVICE_TAG
;
181 Ptr
->Handle
.RefCount
= 1;
183 /* FIXME: initialize more data here */
184 Ptr
->ServiceEntry
= lpServiceEntry
;
186 *Handle
= (SC_HANDLE
)Ptr
;
188 return ERROR_SUCCESS
;
193 ScmCheckAccess(SC_HANDLE Handle
,
194 DWORD dwDesiredAccess
)
196 PMANAGER_HANDLE hMgr
;
198 hMgr
= (PMANAGER_HANDLE
)Handle
;
199 if (hMgr
->Handle
.Tag
== MANAGER_TAG
)
201 RtlMapGenericMask(&dwDesiredAccess
,
204 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
206 return ERROR_SUCCESS
;
208 else if (hMgr
->Handle
.Tag
== SERVICE_TAG
)
210 RtlMapGenericMask(&dwDesiredAccess
,
213 hMgr
->Handle
.DesiredAccess
= dwDesiredAccess
;
215 return ERROR_SUCCESS
;
218 return ERROR_INVALID_HANDLE
;
223 ScmAssignNewTag(LPWSTR lpServiceGroup
,
227 DPRINT("Assigning new tag in group %S\n", lpServiceGroup
);
229 return ERROR_SUCCESS
;
235 ScmrCloseServiceHandle(handle_t BindingHandle
,
236 unsigned int hScObject
)
238 PMANAGER_HANDLE hManager
;
240 DPRINT("ScmrCloseServiceHandle() called\n");
242 DPRINT("hScObject = %X\n", hScObject
);
245 return ERROR_INVALID_HANDLE
;
247 hManager
= (PMANAGER_HANDLE
)hScObject
;
248 if (hManager
->Handle
.Tag
== MANAGER_TAG
)
250 DPRINT("Found manager handle\n");
252 hManager
->Handle
.RefCount
--;
253 if (hManager
->Handle
.RefCount
== 0)
255 /* FIXME: add cleanup code */
257 HeapFree(GetProcessHeap(), 0, hManager
);
260 DPRINT("ScmrCloseServiceHandle() done\n");
261 return ERROR_SUCCESS
;
263 else if (hManager
->Handle
.Tag
== SERVICE_TAG
)
265 DPRINT("Found service handle\n");
267 hManager
->Handle
.RefCount
--;
268 if (hManager
->Handle
.RefCount
== 0)
270 /* FIXME: add cleanup code */
272 HeapFree(GetProcessHeap(), 0, hManager
);
275 DPRINT("ScmrCloseServiceHandle() done\n");
276 return ERROR_SUCCESS
;
279 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager
->Handle
.Tag
);
281 return ERROR_INVALID_HANDLE
;
287 ScmrControlService(handle_t BindingHandle
,
288 unsigned int hService
,
289 unsigned long dwControl
,
290 LPSERVICE_STATUS lpServiceStatus
)
292 PSERVICE_HANDLE hSvc
;
294 ACCESS_MASK DesiredAccess
;
295 DWORD dwError
= ERROR_SUCCESS
;
297 DPRINT("ScmrControlService() called\n");
300 return ERROR_SHUTDOWN_IN_PROGRESS
;
302 /* Check the service handle */
303 hSvc
= (PSERVICE_HANDLE
)hService
;
304 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
306 DPRINT1("Invalid handle tag!\n");
307 return ERROR_INVALID_HANDLE
;
310 /* Check access rights */
313 case SERVICE_CONTROL_STOP
:
314 DesiredAccess
= SERVICE_STOP
;
317 case SERVICE_CONTROL_PAUSE
:
318 case SERVICE_CONTROL_CONTINUE
:
319 DesiredAccess
= SERVICE_PAUSE_CONTINUE
;
322 case SERVICE_INTERROGATE
:
323 DesiredAccess
= SERVICE_INTERROGATE
;
327 if (dwControl
>= 128 && dwControl
<= 255)
328 DesiredAccess
= SERVICE_USER_DEFINED_CONTROL
;
330 DesiredAccess
= SERVICE_QUERY_CONFIG
|
331 SERVICE_CHANGE_CONFIG
|
332 SERVICE_QUERY_STATUS
|
334 SERVICE_PAUSE_CONTINUE
;
338 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
340 return ERROR_ACCESS_DENIED
;
342 /* Check the service entry point */
343 lpService
= hSvc
->ServiceEntry
;
344 if (lpService
== NULL
)
346 DPRINT1("lpService == NULL!\n");
347 return ERROR_INVALID_HANDLE
;
350 if (lpService
->Status
.dwServiceType
& SERVICE_DRIVER
)
352 /* Send control code to the driver */
353 dwError
= ScmControlDriver(lpService
,
359 /* FIXME: Send control code to the service */
361 dwError
= ScmControlService(lpService
,
365 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
368 /* Return service status information */
369 RtlCopyMemory(lpServiceStatus
,
371 sizeof(SERVICE_STATUS
));
379 ScmrDeleteService(handle_t BindingHandle
,
380 unsigned int hService
)
382 PSERVICE_HANDLE hSvc
;
386 DPRINT("ScmrDeleteService() called\n");
389 return ERROR_SHUTDOWN_IN_PROGRESS
;
391 hSvc
= (PSERVICE_HANDLE
)hService
;
392 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
393 return ERROR_INVALID_HANDLE
;
395 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
396 STANDARD_RIGHTS_REQUIRED
))
397 return ERROR_ACCESS_DENIED
;
399 lpService
= hSvc
->ServiceEntry
;
400 if (lpService
== NULL
)
402 DPRINT1("lpService == NULL!\n");
403 return ERROR_INVALID_HANDLE
;
406 /* FIXME: Acquire service database lock exclusively */
408 if (lpService
->bDeleted
)
410 DPRINT1("The service has already been marked for delete!\n");
411 return ERROR_SERVICE_MARKED_FOR_DELETE
;
414 /* Mark service for delete */
415 lpService
->bDeleted
= TRUE
;
417 dwError
= ScmMarkServiceForDelete(lpService
);
419 /* FIXME: Release service database lock */
421 DPRINT("ScmrDeleteService() done\n");
429 ScmrLockServiceDatabase(handle_t BindingHandle
,
430 unsigned int hSCManager
,
433 PMANAGER_HANDLE hMgr
;
435 DPRINT("ScmrLockServiceDatabase() called\n");
439 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
440 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
441 return ERROR_INVALID_HANDLE
;
443 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
445 return ERROR_ACCESS_DENIED
;
447 // return ScmLockDatabase(0, hMgr->0xC, hLock);
449 /* FIXME: Lock the database */
450 *hLock
= 0x12345678; /* Dummy! */
452 return ERROR_SUCCESS
;
458 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
,
459 unsigned int hService
,
460 unsigned long dwSecurityInformation
,
461 unsigned char *lpSecurityDescriptor
,
462 unsigned long dwSecuityDescriptorSize
,
463 unsigned long *pcbBytesNeeded
)
466 PSERVICE_HANDLE hSvc
;
468 ULONG DesiredAccess
= 0;
473 DPRINT("ScmrQueryServiceObjectSecurity() called\n");
475 hSvc
= (PSERVICE_HANDLE
)hService
;
476 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
478 DPRINT1("Invalid handle tag!\n");
479 return ERROR_INVALID_HANDLE
;
482 if (dwSecurityInformation
& (DACL_SECURITY_INFORMATION
||
483 GROUP_SECURITY_INFORMATION
||
484 OWNER_SECURITY_INFORMATION
))
485 DesiredAccess
|= READ_CONTROL
;
487 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
488 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
490 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
493 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
494 return ERROR_ACCESS_DENIED
;
497 lpService
= hSvc
->ServiceEntry
;
498 if (lpService
== NULL
)
500 DPRINT1("lpService == NULL!\n");
501 return ERROR_INVALID_HANDLE
;
504 /* FIXME: Lock the service list */
506 Status
= RtlQuerySecurityObject(lpService
->lpSecurityDescriptor
,
507 dwSecurityInformation
,
508 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
509 dwSecuityDescriptorSize
,
512 /* FIXME: Unlock the service list */
514 if (NT_SUCCESS(Status
))
516 *pcbBytesNeeded
= dwBytesNeeded
;
517 dwError
= STATUS_SUCCESS
;
519 else if (Status
== STATUS_BUFFER_TOO_SMALL
)
521 *pcbBytesNeeded
= dwBytesNeeded
;
522 dwError
= ERROR_INSUFFICIENT_BUFFER
;
524 else if (Status
== STATUS_BAD_DESCRIPTOR_FORMAT
)
526 dwError
= ERROR_GEN_FAILURE
;
530 dwError
= RtlNtStatusToDosError(Status
);
535 DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
536 return ERROR_CALL_NOT_IMPLEMENTED
;
542 ScmrSetServiceObjectSecurity(handle_t BindingHandle
,
543 unsigned int hService
,
544 unsigned long dwSecurityInformation
,
545 unsigned char *lpSecurityDescriptor
,
546 unsigned long dwSecuityDescriptorSize
)
549 PSERVICE_HANDLE hSvc
;
551 ULONG DesiredAccess
= 0;
552 HANDLE hToken
= NULL
;
557 DPRINT1("ScmrSetServiceObjectSecurity() called\n");
559 hSvc
= (PSERVICE_HANDLE
)hService
;
560 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
562 DPRINT1("Invalid handle tag!\n");
563 return ERROR_INVALID_HANDLE
;
566 if (dwSecurityInformation
== 0 ||
567 dwSecurityInformation
& ~0xF)
570 if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
))
573 if (dwSecurityInformation
& SACL_SECURITY_INFORMATION
)
574 DesiredAccess
|= ACCESS_SYSTEM_SECURITY
;
576 if (dwSecurityInformation
& DACL_SECURITY_INFORMATION
)
577 DesiredAccess
|= 0x40000;
579 if (dwSecurityInformation
& (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
580 DesiredAccess
|= 0x80000;
582 if ((dwSecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
583 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Owner
== NULL
))
586 if ((dwSecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
587 (((PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
)->Group
== NULL
))
590 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
593 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
594 return ERROR_ACCESS_DENIED
;
597 lpService
= hSvc
->ServiceEntry
;
598 if (lpService
== NULL
)
600 DPRINT1("lpService == NULL!\n");
601 return ERROR_INVALID_HANDLE
;
604 if (lpService
->bDeleted
)
607 // RpcImpersonateClient(NULL);
609 Status
= NtOpenThreadToken(NtCurrentThread(),
613 if (!NT_SUCCESS(Status
))
614 return RtlNtStatusToDosError(Status
);
616 // RpcRevertToSelf();
618 /* FIXME: Lock service database */
620 Status
= RtlSetSecurityObject(dwSecurityInformation
,
621 (PSECURITY_DESCRIPTOR
)lpSecurityDescriptor
,
622 &lpService
->lpSecurityDescriptor
,
625 if (!NT_SUCCESS(Status
))
627 dwError
= RtlNtStatusToDosError(Status
);
631 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
634 if (dwError
!= ERROR_SUCCESS
)
637 // dwError = ScmWriteSecurityDescriptor(hServiceKey,
638 // lpService->lpSecurityDescriptor);
640 RegFlushKey(hServiceKey
);
641 RegCloseKey(hServiceKey
);
648 /* FIXME: Unlock service database */
650 DPRINT1("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError
);
655 DPRINT1("ScmrSetServiceObjectSecurity() is unimplemented\n");
656 return ERROR_CALL_NOT_IMPLEMENTED
;
662 ScmrQueryServiceStatus(handle_t BindingHandle
,
663 unsigned int hService
,
664 LPSERVICE_STATUS lpServiceStatus
)
666 PSERVICE_HANDLE hSvc
;
669 DPRINT("ScmrQueryServiceStatus() called\n");
672 return ERROR_SHUTDOWN_IN_PROGRESS
;
674 hSvc
= (PSERVICE_HANDLE
)hService
;
675 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
677 DPRINT1("Invalid handle tag!\n");
678 return ERROR_INVALID_HANDLE
;
681 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
682 SERVICE_QUERY_STATUS
))
684 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
685 return ERROR_ACCESS_DENIED
;
688 lpService
= hSvc
->ServiceEntry
;
689 if (lpService
== NULL
)
691 DPRINT1("lpService == NULL!\n");
692 return ERROR_INVALID_HANDLE
;
695 /* Return service status information */
696 RtlCopyMemory(lpServiceStatus
,
698 sizeof(SERVICE_STATUS
));
700 return ERROR_SUCCESS
;
706 ScmrSetServiceStatus(handle_t BindingHandle
,
707 unsigned long hServiceStatus
) /* FIXME */
709 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
711 return ERROR_CALL_NOT_IMPLEMENTED
;
717 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
720 DPRINT1("ScmrUnlockServiceDatabase() called\n");
722 return ERROR_SUCCESS
;
728 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
729 unsigned long BootAcceptable
)
731 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
733 return ERROR_CALL_NOT_IMPLEMENTED
;
739 ScmrSetServiceBitsW(handle_t BindingHandle
,
740 unsigned long hServiceStatus
,
741 unsigned long dwServiceBits
,
742 unsigned long bSetBitsOn
,
743 unsigned long bUpdateImmediately
,
746 DPRINT1("ScmrSetServiceBitsW() called\n");
748 return ERROR_CALL_NOT_IMPLEMENTED
;
754 ScmrChangeServiceConfigW(handle_t BiningHandle
,
755 unsigned int hService
,
756 unsigned long dwServiceType
,
757 unsigned long dwStartType
,
758 unsigned long dwErrorControl
,
759 wchar_t *lpBinaryPathName
,
760 wchar_t *lpLoadOrderGroup
,
761 unsigned long *lpdwTagId
, /* in, out, unique */
762 wchar_t *lpDependencies
,
763 unsigned long dwDependenciesLength
,
764 wchar_t *lpServiceStartName
,
766 unsigned long dwPasswordLength
,
767 wchar_t *lpDisplayName
)
769 DWORD dwError
= ERROR_SUCCESS
;
770 PSERVICE_HANDLE hSvc
;
771 PSERVICE lpService
= NULL
;
772 HKEY hServiceKey
= NULL
;
774 DPRINT("ScmrChangeServiceConfigW() called\n");
775 DPRINT("dwServiceType = %lu\n", dwServiceType
);
776 DPRINT("dwStartType = %lu\n", dwStartType
);
777 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
778 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
779 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
780 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
783 return ERROR_SHUTDOWN_IN_PROGRESS
;
785 hSvc
= (PSERVICE_HANDLE
)hService
;
786 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
788 DPRINT1("Invalid handle tag!\n");
789 return ERROR_INVALID_HANDLE
;
792 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
793 SERVICE_CHANGE_CONFIG
))
795 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
796 return ERROR_ACCESS_DENIED
;
799 lpService
= hSvc
->ServiceEntry
;
800 if (lpService
== NULL
)
802 DPRINT1("lpService == NULL!\n");
803 return ERROR_INVALID_HANDLE
;
806 /* FIXME: Lock database exclusively */
808 if (lpService
->bDeleted
)
810 /* FIXME: Unlock database */
811 DPRINT1("The service has already been marked for delete!\n");
812 return ERROR_SERVICE_MARKED_FOR_DELETE
;
815 /* Open the service key */
816 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
819 if (dwError
!= ERROR_SUCCESS
)
822 /* Write service data to the registry */
823 /* Set the display name */
824 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
826 RegSetValueExW(hServiceKey
,
830 (LPBYTE
)lpDisplayName
,
831 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
832 /* FIXME: update lpService->lpDisplayName */
835 if (dwServiceType
!= SERVICE_NO_CHANGE
)
837 /* Set the service type */
838 dwError
= RegSetValueExW(hServiceKey
,
842 (LPBYTE
)&dwServiceType
,
844 if (dwError
!= ERROR_SUCCESS
)
847 lpService
->Status
.dwServiceType
= dwServiceType
;
850 if (dwStartType
!= SERVICE_NO_CHANGE
)
852 /* Set the start value */
853 dwError
= RegSetValueExW(hServiceKey
,
857 (LPBYTE
)&dwStartType
,
859 if (dwError
!= ERROR_SUCCESS
)
862 lpService
->dwStartType
= dwStartType
;
865 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
867 /* Set the error control value */
868 dwError
= RegSetValueExW(hServiceKey
,
872 (LPBYTE
)&dwErrorControl
,
874 if (dwError
!= ERROR_SUCCESS
)
877 lpService
->dwErrorControl
= dwErrorControl
;
881 /* FIXME: set the new ImagePath value */
883 /* Set the image path */
884 if (dwServiceType
& SERVICE_WIN32
)
886 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
888 dwError
= RegSetValueExW(hServiceKey
,
892 (LPBYTE
)lpBinaryPathName
,
893 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
894 if (dwError
!= ERROR_SUCCESS
)
898 else if (dwServiceType
& SERVICE_DRIVER
)
900 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
902 dwError
= RegSetValueExW(hServiceKey
,
907 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
908 if (dwError
!= ERROR_SUCCESS
)
914 /* Set the group name */
915 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
917 dwError
= RegSetValueExW(hServiceKey
,
921 (LPBYTE
)lpLoadOrderGroup
,
922 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
923 if (dwError
!= ERROR_SUCCESS
)
925 /* FIXME: update lpService->lpServiceGroup */
928 if (lpdwTagId
!= NULL
)
930 dwError
= ScmAssignNewTag(lpService
->lpServiceGroup
,
932 if (dwError
!= ERROR_SUCCESS
)
934 dwError
= RegSetValueExW(hServiceKey
,
938 (LPBYTE
)&lpService
->dwTag
,
940 if (dwError
!= ERROR_SUCCESS
)
942 *lpdwTagId
= lpService
->dwTag
;
945 /* Write dependencies */
946 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
948 dwError
= ScmWriteDependencies(hServiceKey
,
950 dwDependenciesLength
);
951 if (dwError
!= ERROR_SUCCESS
)
955 if (lpPassword
!= NULL
)
957 /* FIXME: Write password */
960 /* FIXME: Unlock database */
963 if (hServiceKey
!= NULL
)
964 RegCloseKey(hServiceKey
);
966 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
974 ScmrCreateServiceW(handle_t BindingHandle
,
975 unsigned int hSCManager
,
976 wchar_t *lpServiceName
,
977 wchar_t *lpDisplayName
,
978 unsigned long dwDesiredAccess
,
979 unsigned long dwServiceType
,
980 unsigned long dwStartType
,
981 unsigned long dwErrorControl
,
982 wchar_t *lpBinaryPathName
,
983 wchar_t *lpLoadOrderGroup
,
984 unsigned long *lpdwTagId
, /* in, out */
985 wchar_t *lpDependencies
,
986 unsigned long dwDependenciesLength
,
987 wchar_t *lpServiceStartName
,
989 unsigned long dwPasswordLength
,
990 unsigned int *hService
) /* out */
992 PMANAGER_HANDLE hManager
;
993 DWORD dwError
= ERROR_SUCCESS
;
994 PSERVICE lpService
= NULL
;
995 SC_HANDLE hServiceHandle
= NULL
;
996 LPWSTR lpImagePath
= NULL
;
997 HKEY hServiceKey
= NULL
;
999 DPRINT("ScmrCreateServiceW() called\n");
1000 DPRINT("lpServiceName = %S\n", lpServiceName
);
1001 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
1002 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess
);
1003 DPRINT("dwServiceType = %lu\n", dwServiceType
);
1004 DPRINT("dwStartType = %lu\n", dwStartType
);
1005 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
1006 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
1007 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
1010 return ERROR_SHUTDOWN_IN_PROGRESS
;
1012 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1013 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1015 DPRINT1("Invalid manager handle!\n");
1016 return ERROR_INVALID_HANDLE
;
1019 /* Check access rights */
1020 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1021 SC_MANAGER_CREATE_SERVICE
))
1023 DPRINT1("Insufficient access rights! 0x%lx\n",
1024 hManager
->Handle
.DesiredAccess
);
1025 return ERROR_ACCESS_DENIED
;
1028 /* Fail if the service already exists! */
1029 if (ScmGetServiceEntryByName(lpServiceName
) != NULL
)
1030 return ERROR_SERVICE_EXISTS
;
1032 if (dwServiceType
& SERVICE_DRIVER
)
1034 /* FIXME: Adjust the image path
1035 * Following line is VERY BAD, because it assumes that the
1036 * first part of full file name is the OS directory */
1037 if (lpBinaryPathName
[1] == ':') lpBinaryPathName
+= GetWindowsDirectoryW(NULL
, 0);
1039 lpImagePath
= HeapAlloc(GetProcessHeap(),
1041 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1042 if (lpImagePath
== NULL
)
1044 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1047 wcscpy(lpImagePath
, lpBinaryPathName
);
1050 /* Allocate a new service entry */
1051 dwError
= ScmCreateNewServiceRecord(lpServiceName
,
1053 if (dwError
!= ERROR_SUCCESS
)
1056 /* Fill the new service entry */
1057 lpService
->Status
.dwServiceType
= dwServiceType
;
1058 lpService
->dwStartType
= dwStartType
;
1059 lpService
->dwErrorControl
= dwErrorControl
;
1061 /* Fill the display name */
1062 if (lpDisplayName
!= NULL
&&
1063 *lpDisplayName
!= 0 &&
1064 wcsicmp(lpService
->lpDisplayName
, lpDisplayName
) != 0)
1066 lpService
->lpDisplayName
= HeapAlloc(GetProcessHeap(), 0,
1067 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1068 if (lpService
->lpDisplayName
== NULL
)
1070 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
1073 wcscpy(lpService
->lpDisplayName
, lpDisplayName
);
1076 /* Write service data to the registry */
1077 /* Create the service key */
1078 dwError
= ScmCreateServiceKey(lpServiceName
,
1081 if (dwError
!= ERROR_SUCCESS
)
1084 /* Set the display name */
1085 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
1087 RegSetValueExW(hServiceKey
,
1091 (LPBYTE
)lpDisplayName
,
1092 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
1095 /* Set the service type */
1096 dwError
= RegSetValueExW(hServiceKey
,
1100 (LPBYTE
)&dwServiceType
,
1102 if (dwError
!= ERROR_SUCCESS
)
1105 /* Set the start value */
1106 dwError
= RegSetValueExW(hServiceKey
,
1110 (LPBYTE
)&dwStartType
,
1112 if (dwError
!= ERROR_SUCCESS
)
1115 /* Set the error control value */
1116 dwError
= RegSetValueExW(hServiceKey
,
1120 (LPBYTE
)&dwErrorControl
,
1122 if (dwError
!= ERROR_SUCCESS
)
1125 /* Set the image path */
1126 if (dwServiceType
& SERVICE_WIN32
)
1128 dwError
= RegSetValueExW(hServiceKey
,
1132 (LPBYTE
)lpBinaryPathName
,
1133 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
1134 if (dwError
!= ERROR_SUCCESS
)
1137 else if (dwServiceType
& SERVICE_DRIVER
)
1139 dwError
= RegSetValueExW(hServiceKey
,
1143 (LPBYTE
)lpImagePath
,
1144 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
1145 if (dwError
!= ERROR_SUCCESS
)
1149 /* Set the group name */
1150 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
1152 dwError
= RegSetValueExW(hServiceKey
,
1156 (LPBYTE
)lpLoadOrderGroup
,
1157 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
1158 if (dwError
!= ERROR_SUCCESS
)
1162 if (lpdwTagId
!= NULL
)
1164 dwError
= ScmAssignNewTag(lpService
->lpServiceGroup
,
1166 if (dwError
!= ERROR_SUCCESS
)
1168 dwError
= RegSetValueExW(hServiceKey
,
1172 (LPBYTE
)&lpService
->dwTag
,
1174 if (dwError
!= ERROR_SUCCESS
)
1178 /* Write dependencies */
1179 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
1181 dwError
= ScmWriteDependencies(hServiceKey
,
1183 dwDependenciesLength
);
1184 if (dwError
!= ERROR_SUCCESS
)
1188 if (lpPassword
!= NULL
)
1190 /* FIXME: Write password */
1193 dwError
= ScmCreateServiceHandle(lpService
,
1195 if (dwError
!= ERROR_SUCCESS
)
1198 dwError
= ScmCheckAccess(hServiceHandle
,
1200 if (dwError
!= ERROR_SUCCESS
)
1204 if (hServiceKey
!= NULL
)
1205 RegCloseKey(hServiceKey
);
1207 if (dwError
== ERROR_SUCCESS
)
1209 DPRINT("hService %lx\n", hServiceHandle
);
1210 *hService
= (unsigned int)hServiceHandle
;
1212 if (lpdwTagId
!= NULL
)
1213 *lpdwTagId
= lpService
->dwTag
;
1217 /* Release the display name buffer */
1218 if (lpService
->lpServiceName
!= lpService
->lpDisplayName
)
1219 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
1221 if (hServiceHandle
!= NULL
)
1223 /* Remove the service handle */
1224 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
1227 if (lpService
!= NULL
)
1229 /* FIXME: remove the service entry */
1233 if (lpImagePath
!= NULL
)
1234 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1236 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
1244 ScmrEnumDependentServicesW(handle_t BindingHandle
,
1245 unsigned int hService
,
1246 unsigned long dwServiceState
,
1247 unsigned char *lpServices
,
1248 unsigned long cbBufSize
,
1249 unsigned long *pcbBytesNeeded
,
1250 unsigned long *lpServicesReturned
)
1252 DWORD dwError
= ERROR_SUCCESS
;
1254 DPRINT1("ScmrEnumDependentServicesW() called\n");
1256 DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError
);
1264 ScmrEnumServicesStatusW(handle_t BindingHandle
,
1265 unsigned int hSCManager
,
1266 unsigned long dwServiceType
,
1267 unsigned long dwServiceState
,
1268 unsigned char *lpServices
,
1269 unsigned long dwBufSize
,
1270 unsigned long *pcbBytesNeeded
,
1271 unsigned long *lpServicesReturned
,
1272 unsigned long *lpResumeHandle
)
1274 PMANAGER_HANDLE hManager
;
1276 DWORD dwError
= ERROR_SUCCESS
;
1277 PLIST_ENTRY ServiceEntry
;
1278 PSERVICE CurrentService
;
1280 DWORD dwRequiredSize
;
1281 DWORD dwServiceCount
;
1283 DWORD dwLastResumeCount
;
1284 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1287 DPRINT("ScmrEnumServicesStatusW() called\n");
1290 return ERROR_SHUTDOWN_IN_PROGRESS
;
1292 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1293 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1295 DPRINT1("Invalid manager handle!\n");
1296 return ERROR_INVALID_HANDLE
;
1299 /* Check access rights */
1300 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
1301 SC_MANAGER_ENUMERATE_SERVICE
))
1303 DPRINT1("Insufficient access rights! 0x%lx\n",
1304 hManager
->Handle
.DesiredAccess
);
1305 return ERROR_ACCESS_DENIED
;
1308 *pcbBytesNeeded
= 0;
1309 *lpServicesReturned
= 0;
1311 dwLastResumeCount
= *lpResumeHandle
;
1313 /* Lock the service list shared */
1315 lpService
= ScmGetServiceEntryByResumeCount(dwLastResumeCount
);
1316 if (lpService
== NULL
)
1318 dwError
= ERROR_SUCCESS
;
1325 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1326 ServiceEntry
!= &ServiceListHead
;
1327 ServiceEntry
= ServiceEntry
->Flink
)
1329 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1333 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1336 dwState
= SERVICE_ACTIVE
;
1337 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1338 dwState
= SERVICE_INACTIVE
;
1340 if ((dwState
& dwServiceState
) == 0)
1343 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1344 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1345 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1347 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1349 DPRINT("Service name: %S fit\n", CurrentService
->lpServiceName
);
1350 dwRequiredSize
+= dwSize
;
1352 dwLastResumeCount
= CurrentService
->dwResumeCount
;
1356 DPRINT("Service name: %S no fit\n", CurrentService
->lpServiceName
);
1362 DPRINT("dwRequiredSize: %lu\n", dwRequiredSize
);
1363 DPRINT("dwServiceCount: %lu\n", dwServiceCount
);
1366 ServiceEntry
!= &ServiceListHead
;
1367 ServiceEntry
= ServiceEntry
->Flink
)
1369 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1373 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1376 dwState
= SERVICE_ACTIVE
;
1377 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1378 dwState
= SERVICE_INACTIVE
;
1380 if ((dwState
& dwServiceState
) == 0)
1383 dwRequiredSize
+= (sizeof(ENUM_SERVICE_STATUSW
) +
1384 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1385 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
)));
1387 dwError
= ERROR_MORE_DATA
;
1390 DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize
);
1392 *lpResumeHandle
= dwLastResumeCount
;
1393 *lpServicesReturned
= dwServiceCount
;
1394 *pcbBytesNeeded
= dwRequiredSize
;
1396 lpStatusPtr
= (LPENUM_SERVICE_STATUS
)lpServices
;
1397 lpStringPtr
= (LPWSTR
)((ULONG_PTR
)lpServices
+
1398 dwServiceCount
* sizeof(ENUM_SERVICE_STATUS
));
1401 for (ServiceEntry
= &lpService
->ServiceListEntry
;
1402 ServiceEntry
!= &ServiceListHead
;
1403 ServiceEntry
= ServiceEntry
->Flink
)
1405 CurrentService
= CONTAINING_RECORD(ServiceEntry
,
1409 if ((CurrentService
->Status
.dwServiceType
& dwServiceType
) == 0)
1412 dwState
= SERVICE_ACTIVE
;
1413 if (CurrentService
->Status
.dwCurrentState
== SERVICE_STOPPED
)
1414 dwState
= SERVICE_INACTIVE
;
1416 if ((dwState
& dwServiceState
) == 0)
1419 dwSize
= sizeof(ENUM_SERVICE_STATUSW
) +
1420 ((wcslen(CurrentService
->lpServiceName
) + 1) * sizeof(WCHAR
)) +
1421 ((wcslen(CurrentService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1423 if (dwRequiredSize
+ dwSize
<= dwBufSize
)
1425 /* Copy the service name */
1427 CurrentService
->lpServiceName
);
1428 lpStatusPtr
->lpServiceName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1429 lpStringPtr
+= (wcslen(CurrentService
->lpServiceName
) + 1);
1431 /* Copy the display name */
1433 CurrentService
->lpDisplayName
);
1434 lpStatusPtr
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStringPtr
- (ULONG_PTR
)lpServices
);
1435 lpStringPtr
+= (wcslen(CurrentService
->lpDisplayName
) + 1);
1437 /* Copy the status information */
1438 memcpy(&lpStatusPtr
->ServiceStatus
,
1439 &CurrentService
->Status
,
1440 sizeof(SERVICE_STATUS
));
1443 dwRequiredSize
+= dwSize
;
1453 /* Unlock the service list */
1455 DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError
);
1463 ScmrOpenSCManagerW(handle_t BindingHandle
,
1464 wchar_t *lpMachineName
,
1465 wchar_t *lpDatabaseName
,
1466 unsigned long dwDesiredAccess
,
1472 DPRINT("ScmrOpenSCManagerW() called\n");
1473 DPRINT("lpMachineName = %p\n", lpMachineName
);
1474 DPRINT("lpMachineName: %S\n", lpMachineName
);
1475 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
1476 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
1477 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1480 return ERROR_SHUTDOWN_IN_PROGRESS
;
1482 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1484 if (dwError
!= ERROR_SUCCESS
)
1486 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1490 /* Check the desired access */
1491 dwError
= ScmCheckAccess(hHandle
,
1492 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1493 if (dwError
!= ERROR_SUCCESS
)
1495 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1496 HeapFree(GetProcessHeap(), 0, hHandle
);
1500 *hScm
= (unsigned int)hHandle
;
1501 DPRINT("*hScm = %x\n", *hScm
);
1503 DPRINT("ScmrOpenSCManagerW() done\n");
1505 return ERROR_SUCCESS
;
1511 ScmrOpenServiceW(handle_t BindingHandle
,
1512 unsigned int hSCManager
,
1513 wchar_t *lpServiceName
,
1514 unsigned long dwDesiredAccess
,
1515 unsigned int *hService
)
1518 PMANAGER_HANDLE hManager
;
1522 DPRINT("ScmrOpenServiceW() called\n");
1523 DPRINT("hSCManager = %x\n", hSCManager
);
1524 DPRINT("lpServiceName = %p\n", lpServiceName
);
1525 DPRINT("lpServiceName: %S\n", lpServiceName
);
1526 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1529 return ERROR_SHUTDOWN_IN_PROGRESS
;
1531 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1532 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1534 DPRINT1("Invalid manager handle!\n");
1535 return ERROR_INVALID_HANDLE
;
1538 /* FIXME: Lock the service list */
1540 /* Get service database entry */
1541 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1542 if (lpService
== NULL
)
1544 DPRINT("Could not find a service!\n");
1545 return ERROR_SERVICE_DOES_NOT_EXIST
;
1548 /* Create a service handle */
1549 dwError
= ScmCreateServiceHandle(lpService
,
1551 if (dwError
!= ERROR_SUCCESS
)
1553 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1557 /* Check the desired access */
1558 dwError
= ScmCheckAccess(hHandle
,
1560 if (dwError
!= ERROR_SUCCESS
)
1562 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1563 HeapFree(GetProcessHeap(), 0, hHandle
);
1567 *hService
= (unsigned int)hHandle
;
1568 DPRINT("*hService = %x\n", *hService
);
1570 DPRINT("ScmrOpenServiceW() done\n");
1572 return ERROR_SUCCESS
;
1578 ScmrQueryServiceConfigW(handle_t BindingHandle
,
1579 unsigned int hService
,
1580 unsigned char *lpServiceConfig
,
1581 unsigned long cbBufSize
,
1582 unsigned long *pcbBytesNeeded
)
1584 DWORD dwError
= ERROR_SUCCESS
;
1585 PSERVICE_HANDLE hSvc
;
1586 PSERVICE lpService
= NULL
;
1587 HKEY hServiceKey
= NULL
;
1588 LPWSTR lpImagePath
= NULL
;
1589 DWORD dwRequiredSize
;
1590 LPQUERY_SERVICE_CONFIGW lpConfig
;
1593 DPRINT1("ScmrQueryServiceConfigW() called\n");
1596 return ERROR_SHUTDOWN_IN_PROGRESS
;
1598 hSvc
= (PSERVICE_HANDLE
)hService
;
1599 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
1601 DPRINT1("Invalid handle tag!\n");
1602 return ERROR_INVALID_HANDLE
;
1605 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
1606 SERVICE_QUERY_CONFIG
))
1608 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
1609 return ERROR_ACCESS_DENIED
;
1612 lpService
= hSvc
->ServiceEntry
;
1613 if (lpService
== NULL
)
1615 DPRINT1("lpService == NULL!\n");
1616 return ERROR_INVALID_HANDLE
;
1619 /* FIXME: Lock the service database shared */
1621 dwError
= ScmOpenServiceKey(lpService
->lpServiceName
,
1624 if (dwError
!= ERROR_SUCCESS
)
1627 dwError
= ScmReadString(hServiceKey
,
1630 if (dwError
!= ERROR_SUCCESS
)
1633 dwRequiredSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1635 if (lpImagePath
!= NULL
)
1636 dwRequiredSize
+= ((wcslen(lpImagePath
) + 1) * sizeof(WCHAR
));
1638 if (lpService
->lpServiceGroup
!= NULL
)
1639 dwRequiredSize
+= ((wcslen(lpService
->lpServiceGroup
) + 1) * sizeof(WCHAR
));
1641 /* FIXME: Add Dependencies length*/
1643 /* FIXME: Add ServiceStartName length*/
1645 if (lpService
->lpDisplayName
!= NULL
)
1646 dwRequiredSize
+= ((wcslen(lpService
->lpDisplayName
) + 1) * sizeof(WCHAR
));
1648 if (lpServiceConfig
== NULL
|| cbBufSize
< dwRequiredSize
)
1650 dwError
= ERROR_INSUFFICIENT_BUFFER
;
1654 lpConfig
= (LPQUERY_SERVICE_CONFIGW
)lpServiceConfig
;
1655 lpConfig
->dwServiceType
= lpService
->Status
.dwServiceType
;
1656 lpConfig
->dwStartType
= lpService
->dwStartType
;
1657 lpConfig
->dwErrorControl
= lpService
->dwErrorControl
;
1658 lpConfig
->dwTagId
= lpService
->dwTag
;
1660 lpStr
= (LPWSTR
)(lpConfig
+ 1);
1662 if (lpImagePath
!= NULL
)
1664 wcscpy(lpStr
, lpImagePath
);
1665 lpConfig
->lpBinaryPathName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1666 lpStr
+= (wcslen(lpImagePath
) + 1);
1670 lpConfig
->lpBinaryPathName
= NULL
;
1673 if (lpService
->lpServiceGroup
!= NULL
)
1675 wcscpy(lpStr
, lpService
->lpServiceGroup
);
1676 lpConfig
->lpLoadOrderGroup
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1677 lpStr
+= (wcslen(lpService
->lpServiceGroup
) + 1);
1681 lpConfig
->lpLoadOrderGroup
= NULL
;
1684 /* FIXME: Append Dependencies */
1685 lpConfig
->lpDependencies
= NULL
;
1687 /* FIXME: Append ServiceStartName */
1688 lpConfig
->lpServiceStartName
= NULL
;
1690 if (lpService
->lpDisplayName
!= NULL
)
1692 wcscpy(lpStr
, lpService
->lpDisplayName
);
1693 lpConfig
->lpDisplayName
= (LPWSTR
)((ULONG_PTR
)lpStr
- (ULONG_PTR
)lpConfig
);
1697 lpConfig
->lpDisplayName
= NULL
;
1701 if (pcbBytesNeeded
!= NULL
)
1702 *pcbBytesNeeded
= dwRequiredSize
;
1705 if (lpImagePath
!= NULL
)
1706 HeapFree(GetProcessHeap(), 0, lpImagePath
);
1708 if (hServiceKey
!= NULL
)
1709 RegCloseKey(hServiceKey
);
1711 /* FIXME: Unlock the service database */
1713 DPRINT1("ScmrQueryServiceConfigW() done\n");
1721 ScmrQueryServiceLockStatusW(handle_t BindingHandle
,
1722 unsigned int hSCManager
,
1723 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
1724 unsigned long cbBufSize
, /* [in] */
1725 unsigned long *pcbBytesNeeded
) /* [out] */
1727 DPRINT1("ScmrQueryServiceLockStatusW() called\n");
1728 return ERROR_CALL_NOT_IMPLEMENTED
;
1733 /* ScmrStartServiceW */
1738 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1739 unsigned int hSCManager
,
1740 wchar_t *lpServiceName
,
1741 wchar_t *lpDisplayName
, /* [out, unique] */
1742 unsigned long *lpcchBuffer
)
1744 // PMANAGER_HANDLE hManager;
1749 DPRINT("ScmrGetServiceDisplayNameW() called\n");
1750 DPRINT("hSCManager = %x\n", hSCManager
);
1751 DPRINT("lpServiceName: %S\n", lpServiceName
);
1752 DPRINT("lpDisplayName: %p\n", lpDisplayName
);
1753 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1755 // hManager = (PMANAGER_HANDLE)hSCManager;
1756 // if (hManager->Handle.Tag != MANAGER_TAG)
1758 // DPRINT1("Invalid manager handle!\n");
1759 // return ERROR_INVALID_HANDLE;
1762 /* Get service database entry */
1763 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1764 if (lpService
== NULL
)
1766 DPRINT1("Could not find a service!\n");
1767 return ERROR_SERVICE_DOES_NOT_EXIST
;
1770 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1772 if (lpDisplayName
!= NULL
&&
1773 *lpcchBuffer
>= dwLength
)
1775 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1778 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1780 *lpcchBuffer
= dwLength
;
1788 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1789 unsigned int hSCManager
,
1790 wchar_t *lpDisplayName
,
1791 wchar_t *lpServiceName
, /* [out, unique] */
1792 unsigned long *lpcchBuffer
)
1794 // PMANAGER_HANDLE hManager;
1799 DPRINT("ScmrGetServiceKeyNameW() called\n");
1800 DPRINT("hSCManager = %x\n", hSCManager
);
1801 DPRINT("lpDisplayName: %S\n", lpDisplayName
);
1802 DPRINT("lpServiceName: %p\n", lpServiceName
);
1803 DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1805 // hManager = (PMANAGER_HANDLE)hSCManager;
1806 // if (hManager->Handle.Tag != MANAGER_TAG)
1808 // DPRINT1("Invalid manager handle!\n");
1809 // return ERROR_INVALID_HANDLE;
1812 /* Get service database entry */
1813 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1814 if (lpService
== NULL
)
1816 DPRINT1("Could not find a service!\n");
1817 return ERROR_SERVICE_DOES_NOT_EXIST
;
1820 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1822 if (lpServiceName
!= NULL
&&
1823 *lpcchBuffer
>= dwLength
)
1825 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1828 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1830 *lpcchBuffer
= dwLength
;
1838 ScmrSetServiceBitsA(handle_t BindingHandle
,
1839 unsigned long hServiceStatus
,
1840 unsigned long dwServiceBits
,
1841 unsigned long bSetBitsOn
,
1842 unsigned long bUpdateImmediately
,
1845 DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
1846 return ERROR_CALL_NOT_IMPLEMENTED
;
1852 ScmrChangeServiceConfigA(handle_t BiningHandle
,
1853 unsigned int hService
,
1854 unsigned long dwServiceType
,
1855 unsigned long dwStartType
,
1856 unsigned long dwErrorControl
,
1857 char *lpBinaryPathName
,
1858 char *lpLoadOrderGroup
,
1859 unsigned long *lpdwTagId
,
1860 char *lpDependencies
,
1861 unsigned long dwDependenciesLength
,
1862 char *lpServiceStartName
,
1864 unsigned long dwPasswordLength
,
1865 char *lpDisplayName
)
1867 DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
1868 return ERROR_CALL_NOT_IMPLEMENTED
;
1874 ScmrCreateServiceA(handle_t BindingHandle
,
1875 unsigned int hSCManager
,
1876 char *lpServiceName
,
1877 char *lpDisplayName
,
1878 unsigned long dwDesiredAccess
,
1879 unsigned long dwServiceType
,
1880 unsigned long dwStartType
,
1881 unsigned long dwErrorControl
,
1882 char *lpBinaryPathName
,
1883 char *lpLoadOrderGroup
,
1884 unsigned long *lpdwTagId
, /* in, out */
1885 char *lpDependencies
,
1886 unsigned long dwDependenciesLength
,
1887 char *lpServiceStartName
,
1889 unsigned long dwPasswordLength
,
1890 unsigned int *hService
) /* out */
1892 DPRINT1("ScmrCreateServiceA() is unimplemented\n");
1893 return ERROR_CALL_NOT_IMPLEMENTED
;
1899 ScmrEnumDependentServicesA(handle_t BindingHandle
,
1900 unsigned int hService
,
1901 unsigned long dwServiceState
,
1902 unsigned char *lpServices
,
1903 unsigned long cbBufSize
,
1904 unsigned long *pcbBytesNeeded
,
1905 unsigned long *lpServicesReturned
)
1907 DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
1908 return ERROR_CALL_NOT_IMPLEMENTED
;
1914 ScmrEnumServicesStatusA(handle_t BindingHandle
,
1915 unsigned int hSCManager
,
1916 unsigned long dwServiceType
,
1917 unsigned long dwServiceState
,
1918 unsigned char *lpServices
,
1919 unsigned long dwBufSize
,
1920 unsigned long *pcbBytesNeeded
,
1921 unsigned long *lpServicesReturned
,
1922 unsigned long *lpResumeHandle
)
1924 DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
1925 return ERROR_CALL_NOT_IMPLEMENTED
;
1931 ScmrOpenSCManagerA(handle_t BindingHandle
,
1932 char *lpMachineName
,
1933 char *lpDatabaseName
,
1934 unsigned long dwDesiredAccess
,
1937 UNICODE_STRING MachineName
;
1938 UNICODE_STRING DatabaseName
;
1941 DPRINT("ScmrOpenSCManagerA() called\n");
1944 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
1948 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
1951 dwError
= ScmrOpenSCManagerW(BindingHandle
,
1952 lpMachineName
? MachineName
.Buffer
: NULL
,
1953 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
1958 RtlFreeUnicodeString(&MachineName
);
1961 RtlFreeUnicodeString(&DatabaseName
);
1969 ScmrOpenServiceA(handle_t BindingHandle
,
1970 unsigned int hSCManager
,
1971 char *lpServiceName
,
1972 unsigned long dwDesiredAccess
,
1973 unsigned int *hService
)
1975 UNICODE_STRING ServiceName
;
1978 DPRINT("ScmrOpenServiceA() called\n");
1980 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
1983 dwError
= ScmrOpenServiceW(BindingHandle
,
1989 RtlFreeUnicodeString(&ServiceName
);
1997 ScmrQueryServiceConfigA(handle_t BindingHandle
,
1998 unsigned int hService
,
1999 unsigned char *lpServiceConfig
,
2000 unsigned long cbBufSize
,
2001 unsigned long *pcbBytesNeeded
)
2003 DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
2004 return ERROR_CALL_NOT_IMPLEMENTED
;
2010 ScmrQueryServiceLockStatusA(handle_t BindingHandle
,
2011 unsigned int hSCManager
,
2012 unsigned char *lpLockStatus
, /* [out, unique, size_is(cbBufSize)] */
2013 unsigned long cbBufSize
, /* [in] */
2014 unsigned long *pcbBytesNeeded
) /* [out] */
2016 DPRINT1("ScmrQueryServiceLockStatusA() called\n");
2017 return ERROR_CALL_NOT_IMPLEMENTED
;
2022 /* ScmrStartServiceA */
2027 ScmrGetServiceDisplayNameA(handle_t BindingHandle
,
2028 unsigned int hSCManager
,
2029 char *lpServiceName
,
2030 char *lpDisplayName
, /* [out, unique] */
2031 unsigned long *lpcchBuffer
)
2033 DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
2034 return ERROR_CALL_NOT_IMPLEMENTED
;
2040 ScmrGetServiceKeyNameA(handle_t BindingHandle
,
2041 unsigned int hSCManager
,
2042 char *lpDisplayName
,
2043 char *lpServiceName
, /* [out, unique] */
2044 unsigned long *lpcchBuffer
)
2046 DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
2047 return ERROR_CALL_NOT_IMPLEMENTED
;
2052 /* ScmrGetCurrentGroupStateW */
2056 /* ScmrEnumServiceGroupW */
2060 /* ScmrChangeServiceConfig2A */
2064 /* ScmrChangeServiceConfig2W */
2068 /* ScmrQueryServiceConfig2A */
2072 /* ScmrQueryServiceConfig2W */
2077 ScmrQueryServiceStatusEx(handle_t BindingHandle
,
2078 unsigned int hService
,
2079 unsigned long InfoLevel
,
2080 unsigned char *lpBuffer
, /* out */
2081 unsigned long cbBufSize
,
2082 unsigned long *pcbBytesNeeded
) /* out */
2084 DPRINT1("ScmrQueryServiceStatusEx() is unimplemented\n");
2085 return ERROR_CALL_NOT_IMPLEMENTED
;
2090 /* ScmrEnumServicesStatusExA */
2094 /* ScmrEnumServicesStatusExW */
2098 /* ScmrSendTSMessage */
2101 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
2103 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
2107 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
2109 HeapFree(GetProcessHeap(), 0, ptr
);