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
;
224 ScmrCloseServiceHandle(handle_t BindingHandle
,
225 unsigned int hScObject
)
227 PMANAGER_HANDLE hManager
;
229 DPRINT("ScmrCloseServiceHandle() called\n");
231 DPRINT("hScObject = %X\n", hScObject
);
234 return ERROR_INVALID_HANDLE
;
236 hManager
= (PMANAGER_HANDLE
)hScObject
;
237 if (hManager
->Handle
.Tag
== MANAGER_TAG
)
239 DPRINT("Found manager handle\n");
241 hManager
->Handle
.RefCount
--;
242 if (hManager
->Handle
.RefCount
== 0)
244 /* FIXME: add cleanup code */
246 HeapFree(GetProcessHeap(), 0, hManager
);
249 DPRINT("ScmrCloseServiceHandle() done\n");
250 return ERROR_SUCCESS
;
252 else if (hManager
->Handle
.Tag
== SERVICE_TAG
)
254 DPRINT("Found service handle\n");
256 hManager
->Handle
.RefCount
--;
257 if (hManager
->Handle
.RefCount
== 0)
259 /* FIXME: add cleanup code */
261 HeapFree(GetProcessHeap(), 0, hManager
);
264 DPRINT("ScmrCloseServiceHandle() done\n");
265 return ERROR_SUCCESS
;
268 DPRINT1("Invalid handle tag (Tag %lx)\n", hManager
->Handle
.Tag
);
270 return ERROR_INVALID_HANDLE
;
276 ScmrControlService(handle_t BindingHandle
,
277 unsigned int hService
,
278 unsigned long dwControl
,
279 LPSERVICE_STATUS lpServiceStatus
)
281 PSERVICE_HANDLE hSvc
;
283 ACCESS_MASK DesiredAccess
;
284 DWORD dwError
= ERROR_SUCCESS
;
286 DPRINT("ScmrControlService() called\n");
289 return ERROR_SHUTDOWN_IN_PROGRESS
;
291 /* Check the service handle */
292 hSvc
= (PSERVICE_HANDLE
)hService
;
293 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
295 DPRINT1("Invalid handle tag!\n");
296 return ERROR_INVALID_HANDLE
;
299 /* Check access rights */
302 case SERVICE_CONTROL_STOP
:
303 DesiredAccess
= SERVICE_STOP
;
306 case SERVICE_CONTROL_PAUSE
:
307 case SERVICE_CONTROL_CONTINUE
:
308 DesiredAccess
= SERVICE_PAUSE_CONTINUE
;
311 case SERVICE_INTERROGATE
:
312 DesiredAccess
= SERVICE_INTERROGATE
;
316 if (dwControl
>= 128 && dwControl
<= 255)
317 DesiredAccess
= SERVICE_USER_DEFINED_CONTROL
;
319 DesiredAccess
= SERVICE_QUERY_CONFIG
|
320 SERVICE_CHANGE_CONFIG
|
321 SERVICE_QUERY_STATUS
|
323 SERVICE_PAUSE_CONTINUE
;
327 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
329 return ERROR_ACCESS_DENIED
;
331 /* Check the service entry point */
332 lpService
= hSvc
->ServiceEntry
;
333 if (lpService
== NULL
)
335 DPRINT1("lpService == NULL!\n");
336 return ERROR_INVALID_HANDLE
;
339 if (lpService
->Status
.dwServiceType
& SERVICE_DRIVER
)
341 /* Send control code to the driver */
342 dwError
= ScmControlDriver(lpService
,
348 /* FIXME: Send control code to the service */
350 dwError
= ScmControlService(lpService
,
354 dwError
= ERROR_INVALID_SERVICE_CONTROL
;
357 /* Return service status information */
358 RtlCopyMemory(lpServiceStatus
,
360 sizeof(SERVICE_STATUS
));
368 ScmrDeleteService(handle_t BindingHandle
,
369 unsigned int hService
)
371 PSERVICE_HANDLE hSvc
;
375 DPRINT("ScmrDeleteService() called\n");
378 return ERROR_SHUTDOWN_IN_PROGRESS
;
380 hSvc
= (PSERVICE_HANDLE
)hService
;
381 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
382 return ERROR_INVALID_HANDLE
;
384 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
385 STANDARD_RIGHTS_REQUIRED
))
386 return ERROR_ACCESS_DENIED
;
388 lpService
= hSvc
->ServiceEntry
;
389 if (lpService
== NULL
)
391 DPRINT1("lpService == NULL!\n");
392 return ERROR_INVALID_HANDLE
;
395 /* FIXME: Acquire service database lock exclusively */
397 if (lpService
->bDeleted
)
399 DPRINT1("The service has already been marked for delete!\n");
400 return ERROR_SERVICE_MARKED_FOR_DELETE
;
403 /* Mark service for delete */
404 lpService
->bDeleted
= TRUE
;
406 dwError
= ScmMarkServiceForDelete(lpService
);
408 /* FIXME: Release service database lock */
410 DPRINT("ScmrDeleteService() done\n");
418 ScmrLockServiceDatabase(handle_t BindingHandle
,
419 unsigned int hSCManager
,
422 PMANAGER_HANDLE hMgr
;
424 DPRINT("ScmrLockServiceDatabase() called\n");
428 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
429 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
430 return ERROR_INVALID_HANDLE
;
432 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
434 return ERROR_ACCESS_DENIED
;
436 /* FIXME: Lock the database */
437 *hLock
= 0x12345678; /* Dummy! */
439 return ERROR_SUCCESS
;
445 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
)
447 DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");
448 return ERROR_CALL_NOT_IMPLEMENTED
;
454 ScmrSetServiceObjectSecurity(handle_t BindingHandle
)
456 DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
457 return ERROR_CALL_NOT_IMPLEMENTED
;
463 ScmrQueryServiceStatus(handle_t BindingHandle
,
464 unsigned int hService
,
465 LPSERVICE_STATUS lpServiceStatus
)
467 PSERVICE_HANDLE hSvc
;
470 DPRINT("ScmrQueryServiceStatus() called\n");
473 return ERROR_SHUTDOWN_IN_PROGRESS
;
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 (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
483 SERVICE_QUERY_STATUS
))
485 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
486 return ERROR_ACCESS_DENIED
;
489 lpService
= hSvc
->ServiceEntry
;
490 if (lpService
== NULL
)
492 DPRINT1("lpService == NULL!\n");
493 return ERROR_INVALID_HANDLE
;
496 /* Return service status information */
497 RtlCopyMemory(lpServiceStatus
,
499 sizeof(SERVICE_STATUS
));
501 return ERROR_SUCCESS
;
507 ScmrSetServiceStatus(handle_t BindingHandle
)
509 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
511 return ERROR_CALL_NOT_IMPLEMENTED
;
517 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
520 DPRINT1("ScmrUnlockServiceDatabase() called\n");
522 return ERROR_SUCCESS
;
528 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
529 unsigned long BootAcceptable
)
531 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
533 return ERROR_SUCCESS
;
539 ScmrChangeServiceConfigW(handle_t BiningHandle
,
540 unsigned int hService
,
541 unsigned long dwServiceType
,
542 unsigned long dwStartType
,
543 unsigned long dwErrorControl
,
544 wchar_t *lpBinaryPathName
,
545 wchar_t *lpLoadOrderGroup
,
546 unsigned long *lpdwTagId
, /* in, out, unique */
547 wchar_t *lpDependencies
,
548 unsigned long dwDependenciesLength
,
549 wchar_t *lpServiceStartName
,
551 unsigned long dwPasswordLength
,
552 wchar_t *lpDisplayName
)
554 DWORD dwError
= ERROR_SUCCESS
;
555 PSERVICE_HANDLE hSvc
;
556 PSERVICE lpService
= NULL
;
557 HKEY hServiceKey
= NULL
;
559 DPRINT("ScmrChangeServiceConfigW() called\n");
560 DPRINT("dwServiceType = %lu\n", dwServiceType
);
561 DPRINT("dwStartType = %lu\n", dwStartType
);
562 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
563 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
564 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
565 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
568 return ERROR_SHUTDOWN_IN_PROGRESS
;
570 hSvc
= (PSERVICE_HANDLE
)hService
;
571 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
573 DPRINT1("Invalid handle tag!\n");
574 return ERROR_INVALID_HANDLE
;
577 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
578 SERVICE_CHANGE_CONFIG
))
580 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
581 return ERROR_ACCESS_DENIED
;
584 lpService
= hSvc
->ServiceEntry
;
585 if (lpService
== NULL
)
587 DPRINT1("lpService == NULL!\n");
588 return ERROR_INVALID_HANDLE
;
591 /* FIXME: Lock database exclusively */
593 if (lpService
->bDeleted
)
595 /* FIXME: Unlock database */
596 DPRINT1("The service has already been marked for delete!\n");
597 return ERROR_SERVICE_MARKED_FOR_DELETE
;
600 /* Open the service key */
601 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
604 if (dwError
!= ERROR_SUCCESS
)
607 /* Write service data to the registry */
608 /* Set the display name */
609 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
611 RegSetValueExW(hServiceKey
,
615 (LPBYTE
)lpDisplayName
,
616 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
619 if (dwServiceType
!= SERVICE_NO_CHANGE
)
621 /* Set the service type */
622 dwError
= RegSetValueExW(hServiceKey
,
626 (LPBYTE
)&dwServiceType
,
628 if (dwError
!= ERROR_SUCCESS
)
632 if (dwStartType
!= SERVICE_NO_CHANGE
)
634 /* Set the start value */
635 dwError
= RegSetValueExW(hServiceKey
,
639 (LPBYTE
)&dwStartType
,
641 if (dwError
!= ERROR_SUCCESS
)
645 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
647 /* Set the error control value */
648 dwError
= RegSetValueExW(hServiceKey
,
652 (LPBYTE
)&dwErrorControl
,
654 if (dwError
!= ERROR_SUCCESS
)
659 /* FIXME: set the new ImagePath value */
661 /* Set the image path */
662 if (dwServiceType
& SERVICE_WIN32
)
664 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
666 dwError
= RegSetValueExW(hServiceKey
,
670 (LPBYTE
)lpBinaryPathName
,
671 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
672 if (dwError
!= ERROR_SUCCESS
)
676 else if (dwServiceType
& SERVICE_DRIVER
)
678 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
680 dwError
= RegSetValueExW(hServiceKey
,
685 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
686 if (dwError
!= ERROR_SUCCESS
)
692 /* Set the group name */
693 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
695 dwError
= RegSetValueExW(hServiceKey
,
699 (LPBYTE
)lpLoadOrderGroup
,
700 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
701 if (dwError
!= ERROR_SUCCESS
)
705 if (lpdwTagId
!= NULL
)
707 /* FIXME: Write tag */
710 /* Write dependencies */
711 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
713 dwError
= ScmWriteDependencies(hServiceKey
,
715 dwDependenciesLength
);
716 if (dwError
!= ERROR_SUCCESS
)
720 if (lpPassword
!= NULL
)
722 /* FIXME: Write password */
725 /* FIXME: Unlock database */
728 if (hServiceKey
!= NULL
)
729 RegCloseKey(hServiceKey
);
731 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
739 ScmrCreateServiceW(handle_t BindingHandle
,
740 unsigned int hSCManager
,
741 wchar_t *lpServiceName
,
742 wchar_t *lpDisplayName
,
743 unsigned long dwDesiredAccess
,
744 unsigned long dwServiceType
,
745 unsigned long dwStartType
,
746 unsigned long dwErrorControl
,
747 wchar_t *lpBinaryPathName
,
748 wchar_t *lpLoadOrderGroup
,
749 unsigned long *lpdwTagId
, /* in, out */
750 wchar_t *lpDependencies
,
751 unsigned long dwDependenciesLength
,
752 wchar_t *lpServiceStartName
,
754 unsigned long dwPasswordLength
,
755 unsigned int *hService
) /* out */
757 PMANAGER_HANDLE hManager
;
758 DWORD dwError
= ERROR_SUCCESS
;
759 PSERVICE lpService
= NULL
;
760 SC_HANDLE hServiceHandle
= NULL
;
761 LPWSTR lpImagePath
= NULL
;
762 HKEY hServiceKey
= NULL
;
764 DPRINT("ScmrCreateServiceW() called\n");
765 DPRINT("lpServiceName = %S\n", lpServiceName
);
766 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
767 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess
);
768 DPRINT("dwServiceType = %lu\n", dwServiceType
);
769 DPRINT("dwStartType = %lu\n", dwStartType
);
770 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
771 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
772 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
775 return ERROR_SHUTDOWN_IN_PROGRESS
;
777 hManager
= (PMANAGER_HANDLE
)hSCManager
;
778 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
780 DPRINT1("Invalid manager handle!\n");
781 return ERROR_INVALID_HANDLE
;
784 /* Check access rights */
785 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
786 SC_MANAGER_CREATE_SERVICE
))
788 DPRINT1("Insufficient access rights! 0x%lx\n",
789 hManager
->Handle
.DesiredAccess
);
790 return ERROR_ACCESS_DENIED
;
793 /* Fail if the service already exists! */
794 if (ScmGetServiceEntryByName(lpServiceName
) != NULL
)
795 return ERROR_SERVICE_EXISTS
;
797 if (dwServiceType
& SERVICE_DRIVER
)
799 /* FIXME: Adjust the image path
800 * Following line is VERY BAD, because it assumes that the
801 * first part of full file name is the OS directory */
802 if (lpBinaryPathName
[1] == ':') lpBinaryPathName
+= GetWindowsDirectoryW(NULL
, 0);
804 lpImagePath
= HeapAlloc(GetProcessHeap(),
806 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
807 if (lpImagePath
== NULL
)
809 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
812 wcscpy(lpImagePath
, lpBinaryPathName
);
815 /* Allocate a new service entry */
816 dwError
= ScmCreateNewServiceRecord(lpServiceName
,
818 if (dwError
!= ERROR_SUCCESS
)
821 /* Fill the new service entry */
822 lpService
->Status
.dwServiceType
= dwServiceType
;
823 lpService
->dwStartType
= dwStartType
;
824 lpService
->dwErrorControl
= dwErrorControl
;
826 /* Fill the display name */
827 if (lpDisplayName
!= NULL
&&
828 *lpDisplayName
!= 0 &&
829 wcsicmp(lpService
->lpDisplayName
, lpDisplayName
) != 0)
831 lpService
->lpDisplayName
= HeapAlloc(GetProcessHeap
, 0,
832 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
833 if (lpService
->lpDisplayName
== NULL
)
835 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
838 wcscpy(lpService
->lpDisplayName
, lpDisplayName
);
841 /* Write service data to the registry */
842 /* Create the service key */
843 dwError
= ScmCreateServiceKey(lpServiceName
,
846 if (dwError
!= ERROR_SUCCESS
)
849 /* Set the display name */
850 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
852 RegSetValueExW(hServiceKey
,
856 (LPBYTE
)lpDisplayName
,
857 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
860 /* Set the service type */
861 dwError
= RegSetValueExW(hServiceKey
,
865 (LPBYTE
)&dwServiceType
,
867 if (dwError
!= ERROR_SUCCESS
)
870 /* Set the start value */
871 dwError
= RegSetValueExW(hServiceKey
,
875 (LPBYTE
)&dwStartType
,
877 if (dwError
!= ERROR_SUCCESS
)
880 /* Set the error control value */
881 dwError
= RegSetValueExW(hServiceKey
,
885 (LPBYTE
)&dwErrorControl
,
887 if (dwError
!= ERROR_SUCCESS
)
890 /* Set the image path */
891 if (dwServiceType
& SERVICE_WIN32
)
893 dwError
= RegSetValueExW(hServiceKey
,
897 (LPBYTE
)lpBinaryPathName
,
898 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
899 if (dwError
!= ERROR_SUCCESS
)
902 else if (dwServiceType
& SERVICE_DRIVER
)
904 dwError
= RegSetValueExW(hServiceKey
,
909 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
910 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
)
927 if (lpdwTagId
!= NULL
)
929 /* FIXME: Write tag */
932 /* Write dependencies */
933 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
935 dwError
= ScmWriteDependencies(hServiceKey
,
937 dwDependenciesLength
);
938 if (dwError
!= ERROR_SUCCESS
)
942 if (lpPassword
!= NULL
)
944 /* FIXME: Write password */
947 dwError
= ScmCreateServiceHandle(lpService
,
949 if (dwError
!= ERROR_SUCCESS
)
952 dwError
= ScmCheckAccess(hServiceHandle
,
954 if (dwError
!= ERROR_SUCCESS
)
958 if (hServiceKey
!= NULL
)
959 RegCloseKey(hServiceKey
);
961 if (dwError
== ERROR_SUCCESS
)
963 DPRINT("hService %lx\n", hServiceHandle
);
964 *hService
= (unsigned int)hServiceHandle
;
966 if (lpdwTagId
!= NULL
)
967 *lpdwTagId
= 0; /* FIXME */
971 /* Release the display name buffer */
972 if (lpService
->lpServiceName
!= lpService
->lpDisplayName
)
973 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
975 if (hServiceHandle
!= NULL
)
977 /* Remove the service handle */
978 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
981 if (lpService
!= NULL
)
983 /* FIXME: remove the service entry */
987 if (lpImagePath
!= NULL
)
988 HeapFree(GetProcessHeap(), 0, lpImagePath
);
990 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
998 ScmrOpenSCManagerW(handle_t BindingHandle
,
999 wchar_t *lpMachineName
,
1000 wchar_t *lpDatabaseName
,
1001 unsigned long dwDesiredAccess
,
1007 DPRINT("ScmrOpenSCManagerW() called\n");
1008 DPRINT("lpMachineName = %p\n", lpMachineName
);
1009 DPRINT("lpMachineName: %S\n", lpMachineName
);
1010 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
1011 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
1012 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1015 return ERROR_SHUTDOWN_IN_PROGRESS
;
1017 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1019 if (dwError
!= ERROR_SUCCESS
)
1021 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1025 /* Check the desired access */
1026 dwError
= ScmCheckAccess(hHandle
,
1027 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1028 if (dwError
!= ERROR_SUCCESS
)
1030 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1031 HeapFree(GetProcessHeap(), 0, hHandle
);
1035 *hScm
= (unsigned int)hHandle
;
1036 DPRINT("*hScm = %x\n", *hScm
);
1038 DPRINT("ScmrOpenSCManagerW() done\n");
1040 return ERROR_SUCCESS
;
1046 ScmrOpenServiceW(handle_t BindingHandle
,
1047 unsigned int hSCManager
,
1048 wchar_t *lpServiceName
,
1049 unsigned long dwDesiredAccess
,
1050 unsigned int *hService
)
1053 PMANAGER_HANDLE hManager
;
1057 DPRINT("ScmrOpenServiceW() called\n");
1058 DPRINT("hSCManager = %x\n", hSCManager
);
1059 DPRINT("lpServiceName = %p\n", lpServiceName
);
1060 DPRINT("lpServiceName: %S\n", lpServiceName
);
1061 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1064 return ERROR_SHUTDOWN_IN_PROGRESS
;
1066 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1067 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1069 DPRINT1("Invalid manager handle!\n");
1070 return ERROR_INVALID_HANDLE
;
1073 /* FIXME: Lock the service list */
1075 /* Get service database entry */
1076 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1077 if (lpService
== NULL
)
1079 DPRINT("Could not find a service!\n");
1080 return ERROR_SERVICE_DOES_NOT_EXIST
;
1083 /* Create a service handle */
1084 dwError
= ScmCreateServiceHandle(lpService
,
1086 if (dwError
!= ERROR_SUCCESS
)
1088 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1092 /* Check the desired access */
1093 dwError
= ScmCheckAccess(hHandle
,
1095 if (dwError
!= ERROR_SUCCESS
)
1097 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1098 HeapFree(GetProcessHeap(), 0, hHandle
);
1102 *hService
= (unsigned int)hHandle
;
1103 DPRINT("*hService = %x\n", *hService
);
1105 DPRINT("ScmrOpenServiceW() done\n");
1107 return ERROR_SUCCESS
;
1113 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1114 unsigned int hSCManager
,
1115 wchar_t *lpServiceName
,
1116 wchar_t *lpDisplayName
, /* [out, unique] */
1117 unsigned long *lpcchBuffer
)
1119 // PMANAGER_HANDLE hManager;
1124 DPRINT1("ScmrGetServiceDisplayNameW() called\n");
1125 DPRINT1("hSCManager = %x\n", hSCManager
);
1126 DPRINT1("lpServiceName: %S\n", lpServiceName
);
1127 DPRINT1("lpDisplayName: %p\n", lpDisplayName
);
1128 DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1130 // hManager = (PMANAGER_HANDLE)hSCManager;
1131 // if (hManager->Handle.Tag != MANAGER_TAG)
1133 // DPRINT1("Invalid manager handle!\n");
1134 // return ERROR_INVALID_HANDLE;
1137 /* Get service database entry */
1138 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1139 if (lpService
== NULL
)
1141 DPRINT1("Could not find a service!\n");
1142 return ERROR_SERVICE_DOES_NOT_EXIST
;
1145 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1147 if (lpDisplayName
!= NULL
&&
1148 *lpcchBuffer
>= dwLength
)
1150 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1153 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1155 *lpcchBuffer
= dwLength
;
1163 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1164 unsigned int hSCManager
,
1165 wchar_t *lpDisplayName
,
1166 wchar_t *lpServiceName
, /* [out, unique] */
1167 unsigned long *lpcchBuffer
)
1169 // PMANAGER_HANDLE hManager;
1174 DPRINT1("ScmrGetServiceKeyNameW() called\n");
1175 DPRINT1("hSCManager = %x\n", hSCManager
);
1176 DPRINT1("lpDisplayName: %S\n", lpDisplayName
);
1177 DPRINT1("lpServiceName: %p\n", lpServiceName
);
1178 DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1180 // hManager = (PMANAGER_HANDLE)hSCManager;
1181 // if (hManager->Handle.Tag != MANAGER_TAG)
1183 // DPRINT1("Invalid manager handle!\n");
1184 // return ERROR_INVALID_HANDLE;
1187 /* Get service database entry */
1188 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1189 if (lpService
== NULL
)
1191 DPRINT1("Could not find a service!\n");
1192 return ERROR_SERVICE_DOES_NOT_EXIST
;
1195 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1197 if (lpServiceName
!= NULL
&&
1198 *lpcchBuffer
>= dwLength
)
1200 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1203 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1205 *lpcchBuffer
= dwLength
;
1213 ScmrOpenSCManagerA(handle_t BindingHandle
,
1214 char *lpMachineName
,
1215 char *lpDatabaseName
,
1216 unsigned long dwDesiredAccess
,
1219 UNICODE_STRING MachineName
;
1220 UNICODE_STRING DatabaseName
;
1223 DPRINT("ScmrOpenSCManagerA() called\n");
1226 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
1230 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
1233 dwError
= ScmrOpenSCManagerW(BindingHandle
,
1234 lpMachineName
? MachineName
.Buffer
: NULL
,
1235 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
1240 RtlFreeUnicodeString(&MachineName
);
1243 RtlFreeUnicodeString(&DatabaseName
);
1251 ScmrOpenServiceA(handle_t BindingHandle
,
1252 unsigned int hSCManager
,
1253 char *lpServiceName
,
1254 unsigned long dwDesiredAccess
,
1255 unsigned int *hService
)
1257 UNICODE_STRING ServiceName
;
1260 DPRINT("ScmrOpenServiceA() called\n");
1262 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
1265 dwError
= ScmrOpenServiceW(BindingHandle
,
1271 RtlFreeUnicodeString(&ServiceName
);
1278 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
1280 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1284 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1286 HeapFree(GetProcessHeap(), 0, ptr
);