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
;
285 DPRINT("ScmrControlService() called\n");
288 return ERROR_SHUTDOWN_IN_PROGRESS
;
290 /* Check the service handle */
291 hSvc
= (PSERVICE_HANDLE
)hService
;
292 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
294 DPRINT1("Invalid handle tag!\n");
295 return ERROR_INVALID_HANDLE
;
298 /* Check access rights */
301 case SERVICE_CONTROL_STOP
:
302 DesiredAccess
= SERVICE_STOP
;
305 case SERVICE_CONTROL_PAUSE
:
306 case SERVICE_CONTROL_CONTINUE
:
307 DesiredAccess
= SERVICE_PAUSE_CONTINUE
;
310 case SERVICE_INTERROGATE
:
311 DesiredAccess
= SERVICE_INTERROGATE
;
315 if (dwControl
>= 128 && dwControl
<= 255)
316 DesiredAccess
= SERVICE_USER_DEFINED_CONTROL
;
318 DesiredAccess
= SERVICE_QUERY_CONFIG
|
319 SERVICE_CHANGE_CONFIG
|
320 SERVICE_QUERY_STATUS
|
322 SERVICE_PAUSE_CONTINUE
;
326 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
328 return ERROR_ACCESS_DENIED
;
330 /* Check the service entry point */
331 lpService
= hSvc
->ServiceEntry
;
332 if (lpService
== NULL
)
334 DPRINT1("lpService == NULL!\n");
335 return ERROR_INVALID_HANDLE
;
339 /* FIXME: Send control code to the service */
342 /* Return service status information */
343 RtlCopyMemory(lpServiceStatus
,
345 sizeof(SERVICE_STATUS
));
347 return ERROR_SUCCESS
;
353 ScmrDeleteService(handle_t BindingHandle
,
354 unsigned int hService
)
356 PSERVICE_HANDLE hSvc
;
360 DPRINT("ScmrDeleteService() called\n");
363 return ERROR_SHUTDOWN_IN_PROGRESS
;
365 hSvc
= (PSERVICE_HANDLE
)hService
;
366 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
367 return ERROR_INVALID_HANDLE
;
369 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
370 STANDARD_RIGHTS_REQUIRED
))
371 return ERROR_ACCESS_DENIED
;
373 lpService
= hSvc
->ServiceEntry
;
374 if (lpService
== NULL
)
376 DPRINT1("lpService == NULL!\n");
377 return ERROR_INVALID_HANDLE
;
380 /* FIXME: Acquire service database lock exclusively */
382 if (lpService
->bDeleted
)
384 DPRINT1("The service has already been marked for delete!\n");
385 return ERROR_SERVICE_MARKED_FOR_DELETE
;
388 /* Mark service for delete */
389 lpService
->bDeleted
= TRUE
;
391 dwError
= ScmMarkServiceForDelete(lpService
);
393 /* FIXME: Release service database lock */
395 DPRINT("ScmrDeleteService() done\n");
403 ScmrLockServiceDatabase(handle_t BindingHandle
,
404 unsigned int hSCManager
,
407 PMANAGER_HANDLE hMgr
;
409 DPRINT("ScmrLockServiceDatabase() called\n");
413 hMgr
= (PMANAGER_HANDLE
)hSCManager
;
414 if (hMgr
->Handle
.Tag
!= MANAGER_TAG
)
415 return ERROR_INVALID_HANDLE
;
417 if (!RtlAreAllAccessesGranted(hMgr
->Handle
.DesiredAccess
,
419 return ERROR_ACCESS_DENIED
;
421 /* FIXME: Lock the database */
422 *hLock
= 0x12345678; /* Dummy! */
424 return ERROR_SUCCESS
;
430 ScmrQueryServiceObjectSecurity(handle_t BindingHandle
)
432 DPRINT1("ScmrQueryServiceSecurity() is unimplemented\n");
433 return ERROR_CALL_NOT_IMPLEMENTED
;
439 ScmrSetServiceObjectSecurity(handle_t BindingHandle
)
441 DPRINT1("ScmrSetServiceSecurity() is unimplemented\n");
442 return ERROR_CALL_NOT_IMPLEMENTED
;
448 ScmrQueryServiceStatus(handle_t BindingHandle
,
449 unsigned int hService
,
450 LPSERVICE_STATUS lpServiceStatus
)
452 PSERVICE_HANDLE hSvc
;
455 DPRINT("ScmrQueryServiceStatus() called\n");
458 return ERROR_SHUTDOWN_IN_PROGRESS
;
460 hSvc
= (PSERVICE_HANDLE
)hService
;
461 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
463 DPRINT1("Invalid handle tag!\n");
464 return ERROR_INVALID_HANDLE
;
467 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
468 SERVICE_QUERY_STATUS
))
470 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
471 return ERROR_ACCESS_DENIED
;
474 lpService
= hSvc
->ServiceEntry
;
475 if (lpService
== NULL
)
477 DPRINT1("lpService == NULL!\n");
478 return ERROR_INVALID_HANDLE
;
481 /* Return service status information */
482 RtlCopyMemory(lpServiceStatus
,
484 sizeof(SERVICE_STATUS
));
486 return ERROR_SUCCESS
;
492 ScmrSetServiceStatus(handle_t BindingHandle
)
494 DPRINT1("ScmrSetServiceStatus() is unimplemented\n");
496 return ERROR_CALL_NOT_IMPLEMENTED
;
502 ScmrUnlockServiceDatabase(handle_t BindingHandle
,
505 DPRINT1("ScmrUnlockServiceDatabase() called\n");
507 return ERROR_SUCCESS
;
513 ScmrNotifyBootConfigStatus(handle_t BindingHandle
,
514 unsigned long BootAcceptable
)
516 DPRINT1("ScmrNotifyBootConfigStatus() called\n");
518 return ERROR_SUCCESS
;
524 ScmrChangeServiceConfigW(handle_t BiningHandle
,
525 unsigned int hService
,
526 unsigned long dwServiceType
,
527 unsigned long dwStartType
,
528 unsigned long dwErrorControl
,
529 wchar_t *lpBinaryPathName
,
530 wchar_t *lpLoadOrderGroup
,
531 unsigned long *lpdwTagId
, /* in, out, unique */
532 wchar_t *lpDependencies
,
533 unsigned long dwDependenciesLength
,
534 wchar_t *lpServiceStartName
,
536 unsigned long dwPasswordLength
,
537 wchar_t *lpDisplayName
)
539 DWORD dwError
= ERROR_SUCCESS
;
540 PSERVICE_HANDLE hSvc
;
541 PSERVICE lpService
= NULL
;
542 HKEY hServiceKey
= NULL
;
544 DPRINT("ScmrChangeServiceConfigW() called\n");
545 DPRINT("dwServiceType = %lu\n", dwServiceType
);
546 DPRINT("dwStartType = %lu\n", dwStartType
);
547 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
548 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
549 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
550 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
553 return ERROR_SHUTDOWN_IN_PROGRESS
;
555 hSvc
= (PSERVICE_HANDLE
)hService
;
556 if (hSvc
->Handle
.Tag
!= SERVICE_TAG
)
558 DPRINT1("Invalid handle tag!\n");
559 return ERROR_INVALID_HANDLE
;
562 if (!RtlAreAllAccessesGranted(hSvc
->Handle
.DesiredAccess
,
563 SERVICE_CHANGE_CONFIG
))
565 DPRINT1("Insufficient access rights! 0x%lx\n", hSvc
->Handle
.DesiredAccess
);
566 return ERROR_ACCESS_DENIED
;
569 lpService
= hSvc
->ServiceEntry
;
570 if (lpService
== NULL
)
572 DPRINT1("lpService == NULL!\n");
573 return ERROR_INVALID_HANDLE
;
576 /* FIXME: Lock database exclusively */
578 if (lpService
->bDeleted
)
580 /* FIXME: Unlock database */
581 DPRINT1("The service has already been marked for delete!\n");
582 return ERROR_SERVICE_MARKED_FOR_DELETE
;
585 /* Open the service key */
586 dwError
= ScmOpenServiceKey(lpService
->szServiceName
,
589 if (dwError
!= ERROR_SUCCESS
)
592 /* Write service data to the registry */
593 /* Set the display name */
594 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
596 RegSetValueExW(hServiceKey
,
600 (LPBYTE
)lpDisplayName
,
601 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
604 if (dwServiceType
!= SERVICE_NO_CHANGE
)
606 /* Set the service type */
607 dwError
= RegSetValueExW(hServiceKey
,
611 (LPBYTE
)&dwServiceType
,
613 if (dwError
!= ERROR_SUCCESS
)
617 if (dwStartType
!= SERVICE_NO_CHANGE
)
619 /* Set the start value */
620 dwError
= RegSetValueExW(hServiceKey
,
624 (LPBYTE
)&dwStartType
,
626 if (dwError
!= ERROR_SUCCESS
)
630 if (dwErrorControl
!= SERVICE_NO_CHANGE
)
632 /* Set the error control value */
633 dwError
= RegSetValueExW(hServiceKey
,
637 (LPBYTE
)&dwErrorControl
,
639 if (dwError
!= ERROR_SUCCESS
)
644 /* FIXME: set the new ImagePath value */
646 /* Set the image path */
647 if (dwServiceType
& SERVICE_WIN32
)
649 if (lpBinaryPathName
!= NULL
&& *lpBinaryPathName
!= 0)
651 dwError
= RegSetValueExW(hServiceKey
,
655 (LPBYTE
)lpBinaryPathName
,
656 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
657 if (dwError
!= ERROR_SUCCESS
)
661 else if (dwServiceType
& SERVICE_DRIVER
)
663 if (lpImagePath
!= NULL
&& *lpImagePath
!= 0)
665 dwError
= RegSetValueExW(hServiceKey
,
670 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
671 if (dwError
!= ERROR_SUCCESS
)
677 /* Set the group name */
678 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
680 dwError
= RegSetValueExW(hServiceKey
,
684 (LPBYTE
)lpLoadOrderGroup
,
685 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
686 if (dwError
!= ERROR_SUCCESS
)
690 if (lpdwTagId
!= NULL
)
692 /* FIXME: Write tag */
695 /* Write dependencies */
696 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
698 dwError
= ScmWriteDependencies(hServiceKey
,
700 dwDependenciesLength
);
701 if (dwError
!= ERROR_SUCCESS
)
705 if (lpPassword
!= NULL
)
707 /* FIXME: Write password */
710 /* FIXME: Unlock database */
713 if (hServiceKey
!= NULL
)
714 RegCloseKey(hServiceKey
);
716 DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError
);
724 ScmrCreateServiceW(handle_t BindingHandle
,
725 unsigned int hSCManager
,
726 wchar_t *lpServiceName
,
727 wchar_t *lpDisplayName
,
728 unsigned long dwDesiredAccess
,
729 unsigned long dwServiceType
,
730 unsigned long dwStartType
,
731 unsigned long dwErrorControl
,
732 wchar_t *lpBinaryPathName
,
733 wchar_t *lpLoadOrderGroup
,
734 unsigned long *lpdwTagId
, /* in, out */
735 wchar_t *lpDependencies
,
736 unsigned long dwDependenciesLength
,
737 wchar_t *lpServiceStartName
,
739 unsigned long dwPasswordLength
,
740 unsigned int *hService
) /* out */
742 PMANAGER_HANDLE hManager
;
743 DWORD dwError
= ERROR_SUCCESS
;
744 PSERVICE lpService
= NULL
;
745 SC_HANDLE hServiceHandle
= NULL
;
746 LPWSTR lpImagePath
= NULL
;
747 HKEY hServiceKey
= NULL
;
749 DPRINT("ScmrCreateServiceW() called\n");
750 DPRINT("lpServiceName = %S\n", lpServiceName
);
751 DPRINT("lpDisplayName = %S\n", lpDisplayName
);
752 DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess
);
753 DPRINT("dwServiceType = %lu\n", dwServiceType
);
754 DPRINT("dwStartType = %lu\n", dwStartType
);
755 DPRINT("dwErrorControl = %lu\n", dwErrorControl
);
756 DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName
);
757 DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup
);
760 return ERROR_SHUTDOWN_IN_PROGRESS
;
762 hManager
= (PMANAGER_HANDLE
)hSCManager
;
763 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
765 DPRINT1("Invalid manager handle!\n");
766 return ERROR_INVALID_HANDLE
;
769 /* Check access rights */
770 if (!RtlAreAllAccessesGranted(hManager
->Handle
.DesiredAccess
,
771 SC_MANAGER_CREATE_SERVICE
))
773 DPRINT1("Insufficient access rights! 0x%lx\n",
774 hManager
->Handle
.DesiredAccess
);
775 return ERROR_ACCESS_DENIED
;
778 /* Fail if the service already exists! */
779 if (ScmGetServiceEntryByName(lpServiceName
) != NULL
)
780 return ERROR_SERVICE_EXISTS
;
782 if (dwServiceType
& SERVICE_DRIVER
)
784 /* FIXME: Adjust the image path
785 * Following line is VERY BAD, because it assumes that the
786 * first part of full file name is the OS directory */
787 if (lpBinaryPathName
[1] == ':') lpBinaryPathName
+= GetWindowsDirectoryW(NULL
, 0);
789 lpImagePath
= HeapAlloc(GetProcessHeap(),
791 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
792 if (lpImagePath
== NULL
)
794 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
797 wcscpy(lpImagePath
, lpBinaryPathName
);
800 /* Allocate a new service entry */
801 dwError
= ScmCreateNewServiceRecord(lpServiceName
,
803 if (dwError
!= ERROR_SUCCESS
)
806 /* Fill the new service entry */
807 lpService
->Status
.dwServiceType
= dwServiceType
;
808 lpService
->dwStartType
= dwStartType
;
809 lpService
->dwErrorControl
= dwErrorControl
;
811 /* Fill the display name */
812 if (lpDisplayName
!= NULL
&&
813 *lpDisplayName
!= 0 &&
814 wcsicmp(lpService
->lpDisplayName
, lpDisplayName
) != 0)
816 lpService
->lpDisplayName
= HeapAlloc(GetProcessHeap
, 0,
817 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
818 if (lpService
->lpDisplayName
== NULL
)
820 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
823 wcscpy(lpService
->lpDisplayName
, lpDisplayName
);
826 /* Write service data to the registry */
827 /* Create the service key */
828 dwError
= ScmCreateServiceKey(lpServiceName
,
831 if (dwError
!= ERROR_SUCCESS
)
834 /* Set the display name */
835 if (lpDisplayName
!= NULL
&& *lpDisplayName
!= 0)
837 RegSetValueExW(hServiceKey
,
841 (LPBYTE
)lpDisplayName
,
842 (wcslen(lpDisplayName
) + 1) * sizeof(WCHAR
));
845 /* Set the service type */
846 dwError
= RegSetValueExW(hServiceKey
,
850 (LPBYTE
)&dwServiceType
,
852 if (dwError
!= ERROR_SUCCESS
)
855 /* Set the start value */
856 dwError
= RegSetValueExW(hServiceKey
,
860 (LPBYTE
)&dwStartType
,
862 if (dwError
!= ERROR_SUCCESS
)
865 /* Set the error control value */
866 dwError
= RegSetValueExW(hServiceKey
,
870 (LPBYTE
)&dwErrorControl
,
872 if (dwError
!= ERROR_SUCCESS
)
875 /* Set the image path */
876 if (dwServiceType
& SERVICE_WIN32
)
878 dwError
= RegSetValueExW(hServiceKey
,
882 (LPBYTE
)lpBinaryPathName
,
883 (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
884 if (dwError
!= ERROR_SUCCESS
)
887 else if (dwServiceType
& SERVICE_DRIVER
)
889 dwError
= RegSetValueExW(hServiceKey
,
894 (wcslen(lpImagePath
) + 1) *sizeof(WCHAR
));
895 if (dwError
!= ERROR_SUCCESS
)
899 /* Set the group name */
900 if (lpLoadOrderGroup
!= NULL
&& *lpLoadOrderGroup
!= 0)
902 dwError
= RegSetValueExW(hServiceKey
,
906 (LPBYTE
)lpLoadOrderGroup
,
907 (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
908 if (dwError
!= ERROR_SUCCESS
)
912 if (lpdwTagId
!= NULL
)
914 /* FIXME: Write tag */
917 /* Write dependencies */
918 if (lpDependencies
!= NULL
&& *lpDependencies
!= 0)
920 dwError
= ScmWriteDependencies(hServiceKey
,
922 dwDependenciesLength
);
923 if (dwError
!= ERROR_SUCCESS
)
927 if (lpPassword
!= NULL
)
929 /* FIXME: Write password */
932 dwError
= ScmCreateServiceHandle(lpService
,
934 if (dwError
!= ERROR_SUCCESS
)
937 dwError
= ScmCheckAccess(hServiceHandle
,
939 if (dwError
!= ERROR_SUCCESS
)
943 if (hServiceKey
!= NULL
)
944 RegCloseKey(hServiceKey
);
946 if (dwError
== ERROR_SUCCESS
)
948 DPRINT("hService %lx\n", hServiceHandle
);
949 *hService
= (unsigned int)hServiceHandle
;
951 if (lpdwTagId
!= NULL
)
952 *lpdwTagId
= 0; /* FIXME */
956 /* Release the display name buffer */
957 if (lpService
->lpServiceName
!= lpService
->lpDisplayName
)
958 HeapFree(GetProcessHeap(), 0, lpService
->lpDisplayName
);
960 if (hServiceHandle
!= NULL
)
962 /* Remove the service handle */
963 HeapFree(GetProcessHeap(), 0, hServiceHandle
);
966 if (lpService
!= NULL
)
968 /* FIXME: remove the service entry */
972 if (lpImagePath
!= NULL
)
973 HeapFree(GetProcessHeap(), 0, lpImagePath
);
975 DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError
);
983 ScmrOpenSCManagerW(handle_t BindingHandle
,
984 wchar_t *lpMachineName
,
985 wchar_t *lpDatabaseName
,
986 unsigned long dwDesiredAccess
,
992 DPRINT("ScmrOpenSCManagerW() called\n");
993 DPRINT("lpMachineName = %p\n", lpMachineName
);
994 DPRINT("lpMachineName: %S\n", lpMachineName
);
995 DPRINT("lpDataBaseName = %p\n", lpDatabaseName
);
996 DPRINT("lpDataBaseName: %S\n", lpDatabaseName
);
997 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1000 return ERROR_SHUTDOWN_IN_PROGRESS
;
1002 dwError
= ScmCreateManagerHandle(lpDatabaseName
,
1004 if (dwError
!= ERROR_SUCCESS
)
1006 DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError
);
1010 /* Check the desired access */
1011 dwError
= ScmCheckAccess(hHandle
,
1012 dwDesiredAccess
| SC_MANAGER_CONNECT
);
1013 if (dwError
!= ERROR_SUCCESS
)
1015 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1016 HeapFree(GetProcessHeap(), 0, hHandle
);
1020 *hScm
= (unsigned int)hHandle
;
1021 DPRINT("*hScm = %x\n", *hScm
);
1023 DPRINT("ScmrOpenSCManagerW() done\n");
1025 return ERROR_SUCCESS
;
1031 ScmrOpenServiceW(handle_t BindingHandle
,
1032 unsigned int hSCManager
,
1033 wchar_t *lpServiceName
,
1034 unsigned long dwDesiredAccess
,
1035 unsigned int *hService
)
1038 PMANAGER_HANDLE hManager
;
1042 DPRINT("ScmrOpenServiceW() called\n");
1043 DPRINT("hSCManager = %x\n", hSCManager
);
1044 DPRINT("lpServiceName = %p\n", lpServiceName
);
1045 DPRINT("lpServiceName: %S\n", lpServiceName
);
1046 DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess
);
1049 return ERROR_SHUTDOWN_IN_PROGRESS
;
1051 hManager
= (PMANAGER_HANDLE
)hSCManager
;
1052 if (hManager
->Handle
.Tag
!= MANAGER_TAG
)
1054 DPRINT1("Invalid manager handle!\n");
1055 return ERROR_INVALID_HANDLE
;
1058 /* FIXME: Lock the service list */
1060 /* Get service database entry */
1061 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1062 if (lpService
== NULL
)
1064 DPRINT("Could not find a service!\n");
1065 return ERROR_SERVICE_DOES_NOT_EXIST
;
1068 /* Create a service handle */
1069 dwError
= ScmCreateServiceHandle(lpService
,
1071 if (dwError
!= ERROR_SUCCESS
)
1073 DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError
);
1077 /* Check the desired access */
1078 dwError
= ScmCheckAccess(hHandle
,
1080 if (dwError
!= ERROR_SUCCESS
)
1082 DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError
);
1083 HeapFree(GetProcessHeap(), 0, hHandle
);
1087 *hService
= (unsigned int)hHandle
;
1088 DPRINT("*hService = %x\n", *hService
);
1090 DPRINT("ScmrOpenServiceW() done\n");
1092 return ERROR_SUCCESS
;
1098 ScmrGetServiceDisplayNameW(handle_t BindingHandle
,
1099 unsigned int hSCManager
,
1100 wchar_t *lpServiceName
,
1101 wchar_t *lpDisplayName
, /* [out, unique] */
1102 unsigned long *lpcchBuffer
)
1104 // PMANAGER_HANDLE hManager;
1109 DPRINT1("ScmrGetServiceDisplayNameW() called\n");
1110 DPRINT1("hSCManager = %x\n", hSCManager
);
1111 DPRINT1("lpServiceName: %S\n", lpServiceName
);
1112 DPRINT1("lpDisplayName: %p\n", lpDisplayName
);
1113 DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1115 // hManager = (PMANAGER_HANDLE)hSCManager;
1116 // if (hManager->Handle.Tag != MANAGER_TAG)
1118 // DPRINT1("Invalid manager handle!\n");
1119 // return ERROR_INVALID_HANDLE;
1122 /* Get service database entry */
1123 lpService
= ScmGetServiceEntryByName(lpServiceName
);
1124 if (lpService
== NULL
)
1126 DPRINT1("Could not find a service!\n");
1127 return ERROR_SERVICE_DOES_NOT_EXIST
;
1130 dwLength
= wcslen(lpService
->lpDisplayName
) + 1;
1132 if (lpDisplayName
!= NULL
&&
1133 *lpcchBuffer
>= dwLength
)
1135 wcscpy(lpDisplayName
, lpService
->lpDisplayName
);
1138 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1140 *lpcchBuffer
= dwLength
;
1148 ScmrGetServiceKeyNameW(handle_t BindingHandle
,
1149 unsigned int hSCManager
,
1150 wchar_t *lpDisplayName
,
1151 wchar_t *lpServiceName
, /* [out, unique] */
1152 unsigned long *lpcchBuffer
)
1154 // PMANAGER_HANDLE hManager;
1159 DPRINT1("ScmrGetServiceKeyNameW() called\n");
1160 DPRINT1("hSCManager = %x\n", hSCManager
);
1161 DPRINT1("lpDisplayName: %S\n", lpDisplayName
);
1162 DPRINT1("lpServiceName: %p\n", lpServiceName
);
1163 DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer
);
1165 // hManager = (PMANAGER_HANDLE)hSCManager;
1166 // if (hManager->Handle.Tag != MANAGER_TAG)
1168 // DPRINT1("Invalid manager handle!\n");
1169 // return ERROR_INVALID_HANDLE;
1172 /* Get service database entry */
1173 lpService
= ScmGetServiceEntryByDisplayName(lpDisplayName
);
1174 if (lpService
== NULL
)
1176 DPRINT1("Could not find a service!\n");
1177 return ERROR_SERVICE_DOES_NOT_EXIST
;
1180 dwLength
= wcslen(lpService
->lpServiceName
) + 1;
1182 if (lpServiceName
!= NULL
&&
1183 *lpcchBuffer
>= dwLength
)
1185 wcscpy(lpServiceName
, lpService
->lpServiceName
);
1188 dwError
= (*lpcchBuffer
> dwLength
) ? ERROR_SUCCESS
: ERROR_INSUFFICIENT_BUFFER
;
1190 *lpcchBuffer
= dwLength
;
1198 ScmrOpenSCManagerA(handle_t BindingHandle
,
1199 char *lpMachineName
,
1200 char *lpDatabaseName
,
1201 unsigned long dwDesiredAccess
,
1204 UNICODE_STRING MachineName
;
1205 UNICODE_STRING DatabaseName
;
1208 DPRINT("ScmrOpenSCManagerA() called\n");
1211 RtlCreateUnicodeStringFromAsciiz(&MachineName
,
1215 RtlCreateUnicodeStringFromAsciiz(&DatabaseName
,
1218 dwError
= ScmrOpenSCManagerW(BindingHandle
,
1219 lpMachineName
? MachineName
.Buffer
: NULL
,
1220 lpDatabaseName
? DatabaseName
.Buffer
: NULL
,
1225 RtlFreeUnicodeString(&MachineName
);
1228 RtlFreeUnicodeString(&DatabaseName
);
1236 ScmrOpenServiceA(handle_t BindingHandle
,
1237 unsigned int hSCManager
,
1238 char *lpServiceName
,
1239 unsigned long dwDesiredAccess
,
1240 unsigned int *hService
)
1242 UNICODE_STRING ServiceName
;
1245 DPRINT("ScmrOpenServiceA() called\n");
1247 RtlCreateUnicodeStringFromAsciiz(&ServiceName
,
1250 dwError
= ScmrOpenServiceW(BindingHandle
,
1256 RtlFreeUnicodeString(&ServiceName
);
1263 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
1265 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1269 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1271 HeapFree(GetProcessHeap(), 0, ptr
);