2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/service/scm.c
5 * PURPOSE: Service control manager functions
6 * PROGRAMMER: Emanuele Aliberti
13 /* INCLUDES ******************************************************************/
21 /* FUNCTIONS *****************************************************************/
23 handle_t BindingHandle
= NULL
;
28 LPWSTR pszStringBinding
;
31 if (BindingHandle
!= NULL
)
34 status
= RpcStringBindingComposeW(NULL
,
42 DPRINT1("RpcStringBindingCompose returned 0x%x\n", status
);
46 /* Set the binding handle that will be used to bind to the server. */
47 status
= RpcBindingFromStringBindingW(pszStringBinding
,
51 DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status
);
54 status
= RpcStringFreeW(&pszStringBinding
);
57 DPRINT1("RpcStringFree returned 0x%x\n", status
);
68 if (BindingHandle
== NULL
)
71 status
= RpcBindingFree(&BindingHandle
);
74 DPRINT1("RpcBindingFree returned 0x%x\n", status
);
80 /**********************************************************************
81 * ChangeServiceConfigA
92 LPCSTR lpBinaryPathName
,
93 LPCSTR lpLoadOrderGroup
,
95 LPCSTR lpDependencies
,
96 LPCSTR lpServiceStartName
,
100 DPRINT1("ChangeServiceConfigA is unimplemented\n");
101 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
106 /**********************************************************************
107 * ChangeServiceConfigW
113 ChangeServiceConfigW(
117 DWORD dwErrorControl
,
118 LPCWSTR lpBinaryPathName
,
119 LPCWSTR lpLoadOrderGroup
,
121 LPCWSTR lpDependencies
,
122 LPCWSTR lpServiceStartName
,
124 LPCWSTR lpDisplayName
)
126 DPRINT1("ChangeServiceConfigW is unimplemented\n");
127 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
132 /**********************************************************************
138 CloseServiceHandle(SC_HANDLE hSCObject
)
142 DPRINT("CloseServiceHandle() called\n");
146 /* Call to services.exe using RPC */
147 dwError
= ScmrCloseServiceHandle(BindingHandle
,
148 (unsigned int)hSCObject
);
151 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError
);
152 SetLastError(dwError
);
156 DPRINT("CloseServiceHandle() done\n");
162 /**********************************************************************
168 ControlService(SC_HANDLE hService
,
170 LPSERVICE_STATUS lpServiceStatus
)
174 DPRINT("ControlService(%x, %x, %p)\n",
175 hService
, dwControl
, lpServiceStatus
);
179 /* Call to services.exe using RPC */
180 dwError
= ScmrControlService(BindingHandle
,
181 (unsigned int)hService
,
184 if (dwError
!= ERROR_SUCCESS
)
186 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError
);
187 SetLastError(dwError
);
191 DPRINT("ControlService() done\n");
197 /**********************************************************************
203 ControlServiceEx(IN SC_HANDLE hService
,
205 IN DWORD dwInfoLevel
,
206 IN OUT PVOID pControlParams
)
208 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
209 hService
, dwControl
, dwInfoLevel
, pControlParams
);
210 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
216 /**********************************************************************
224 SC_HANDLE hSCManager
,
225 LPCSTR lpServiceName
,
226 LPCSTR lpDisplayName
,
227 DWORD dwDesiredAccess
,
230 DWORD dwErrorControl
,
231 LPCSTR lpBinaryPathName
,
232 LPCSTR lpLoadOrderGroup
,
234 LPCSTR lpDependencies
,
235 LPCSTR lpServiceStartName
,
238 DPRINT1("CreateServiceA is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
239 return INVALID_HANDLE_VALUE
;
243 /**********************************************************************
249 CreateServiceW(SC_HANDLE hSCManager
,
250 LPCWSTR lpServiceName
,
251 LPCWSTR lpDisplayName
,
252 DWORD dwDesiredAccess
,
255 DWORD dwErrorControl
,
256 LPCWSTR lpBinaryPathName
,
257 LPCWSTR lpLoadOrderGroup
,
259 LPCWSTR lpDependencies
,
260 LPCWSTR lpServiceStartName
,
263 SC_HANDLE hService
= NULL
;
267 DPRINT1("CreateServiceW() called\n");
271 /* Call to services.exe using RPC */
273 dwError
= ScmrCreateServiceW(BindingHandle
,
274 (unsigned int)hSCManager
,
275 (LPWSTR
)lpServiceName
,
276 (LPWSTR
)lpDisplayName
,
281 (LPWSTR
)lpBinaryPathName
,
282 (LPWSTR
)lpLoadOrderGroup
,
284 NULL
, /* FIXME: lpDependencies */
285 0, /* FIXME: dwDependenciesLength */
286 (LPWSTR
)lpServiceStartName
,
287 NULL
, /* FIXME: lpPassword */
288 0, /* FIXME: dwPasswordLength */
289 (unsigned int *)&hService
);
291 RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Services", 0, KEY_ENUMERATE_SUB_KEYS
, &hEnumKey
);
292 RegCreateKeyExW(hEnumKey
, lpServiceName
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hKey
, NULL
);
293 RegCloseKey(hEnumKey
);
294 if (lpLoadOrderGroup
)
295 RegSetValueExW(hKey
, L
"Group", 0, REG_SZ
, (const BYTE
*)lpLoadOrderGroup
, (wcslen(lpLoadOrderGroup
) + 1) * sizeof(WCHAR
));
296 RegSetValueExW(hKey
, L
"ImagePath", 0, REG_EXPAND_SZ
, (const BYTE
*)lpBinaryPathName
, (wcslen(lpBinaryPathName
) + 1) * sizeof(WCHAR
));
297 RegSetValueExW(hKey
, L
"ErrorControl", 0, REG_DWORD
, (const BYTE
*)&dwErrorControl
, sizeof(dwErrorControl
));
298 RegSetValueExW(hKey
, L
"Start", 0, REG_DWORD
, (const BYTE
*)&dwStartType
, sizeof(dwStartType
));
299 RegSetValueExW(hKey
, L
"Type", 0, REG_DWORD
, (const BYTE
*)&dwStartType
, sizeof(dwStartType
));
301 hService
= INVALID_HANDLE_VALUE
; dwError
= ERROR_SUCCESS
;
303 if (dwError
!= ERROR_SUCCESS
)
305 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError
);
306 SetLastError(dwError
);
307 return INVALID_HANDLE_VALUE
;
314 /**********************************************************************
320 DeleteService(SC_HANDLE hService
)
324 DPRINT("DeleteService(%x)\n", hService
);
328 /* Call to services.exe using RPC */
329 dwError
= ScmrDeleteService(BindingHandle
,
330 (unsigned int)hService
);
331 if (dwError
!= ERROR_SUCCESS
)
333 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError
);
334 SetLastError(dwError
);
342 /**********************************************************************
343 * EnumDependentServicesA
349 EnumDependentServicesA(
351 DWORD dwServiceState
,
352 LPENUM_SERVICE_STATUSA lpServices
,
354 LPDWORD pcbBytesNeeded
,
355 LPDWORD lpServicesReturned
)
357 DPRINT1("EnumDependentServicesA is unimplemented\n");
358 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
363 /**********************************************************************
364 * EnumDependentServicesW
370 EnumDependentServicesW(
372 DWORD dwServiceState
,
373 LPENUM_SERVICE_STATUSW lpServices
,
375 LPDWORD pcbBytesNeeded
,
376 LPDWORD lpServicesReturned
)
378 DPRINT1("EnumDependentServicesW is unimplemented\n");
379 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
384 /**********************************************************************
402 DPRINT1("EnumServiceGroupW is unimplemented\n");
403 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
408 /**********************************************************************
409 * EnumServicesStatusA
415 EnumServicesStatusA (
416 SC_HANDLE hSCManager
,
418 DWORD dwServiceState
,
419 LPENUM_SERVICE_STATUSA lpServices
,
421 LPDWORD pcbBytesNeeded
,
422 LPDWORD lpServicesReturned
,
423 LPDWORD lpResumeHandle
)
425 DPRINT1("EnumServicesStatusA is unimplemented\n");
426 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
431 /**********************************************************************
432 * EnumServicesStatusExA
438 EnumServicesStatusExA(SC_HANDLE hSCManager
,
439 SC_ENUM_TYPE InfoLevel
,
441 DWORD dwServiceState
,
444 LPDWORD pcbBytesNeeded
,
445 LPDWORD lpServicesReturned
,
446 LPDWORD lpResumeHandle
,
449 DPRINT1("EnumServicesStatusExA is unimplemented\n");
450 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
455 /**********************************************************************
456 * EnumServicesStatusExW
462 EnumServicesStatusExW(SC_HANDLE hSCManager
,
463 SC_ENUM_TYPE InfoLevel
,
465 DWORD dwServiceState
,
468 LPDWORD pcbBytesNeeded
,
469 LPDWORD lpServicesReturned
,
470 LPDWORD lpResumeHandle
,
471 LPCWSTR pszGroupName
)
473 DPRINT1("EnumServicesStatusExW is unimplemented\n");
474 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
479 /**********************************************************************
480 * EnumServicesStatusW
487 SC_HANDLE hSCManager
,
489 DWORD dwServiceState
,
490 LPENUM_SERVICE_STATUSW lpServices
,
492 LPDWORD pcbBytesNeeded
,
493 LPDWORD lpServicesReturned
,
494 LPDWORD lpResumeHandle
)
496 DPRINT1("EnumServicesStatusW is unimplemented\n");
497 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
502 /**********************************************************************
503 * GetServiceDisplayNameA
509 GetServiceDisplayNameA(
510 SC_HANDLE hSCManager
,
511 LPCSTR lpServiceName
,
515 DPRINT1("GetServiceDisplayNameA is unimplemented\n");
516 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
521 /**********************************************************************
522 * GetServiceDisplayNameW
528 GetServiceDisplayNameW(
529 SC_HANDLE hSCManager
,
530 LPCWSTR lpServiceName
,
531 LPWSTR lpDisplayName
,
534 DPRINT1("GetServiceDisplayNameW is unimplemented\n");
535 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
540 /**********************************************************************
548 SC_HANDLE hSCManager
,
549 LPCSTR lpDisplayName
,
553 DPRINT1("GetServiceKeyNameA is unimplemented\n");
554 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
559 /**********************************************************************
567 SC_HANDLE hSCManager
,
568 LPCWSTR lpDisplayName
,
569 LPWSTR lpServiceName
,
572 DPRINT1("GetServiceKeyNameW is unimplemented\n");
573 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
578 /**********************************************************************
579 * LockServiceDatabase
584 LockServiceDatabase(SC_HANDLE hSCManager
)
589 DPRINT("LockServiceDatabase(%x)\n", hSCManager
);
593 /* Call to services.exe using RPC */
594 dwError
= ScmrLockServiceDatabase(BindingHandle
,
595 (unsigned int)hSCManager
,
596 (unsigned int *)&hLock
);
597 if (dwError
!= ERROR_SUCCESS
)
599 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError
);
600 SetLastError(dwError
);
604 DPRINT("hLock = %p\n", hLock
);
611 WaitForSCManager(VOID
)
615 DPRINT("WaitForSCManager() called\n");
617 /* Try to open the existing event */
618 hEvent
= OpenEventW(SYNCHRONIZE
,
620 L
"SvcctrlStartEvent_A3725DX");
623 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
626 /* Try to create a new event */
627 hEvent
= CreateEventW(NULL
,
630 L
"SvcctrlStartEvent_A3725DX");
633 /* Try to open the existing event again */
634 hEvent
= OpenEventW(SYNCHRONIZE
,
636 L
"SvcctrlStartEvent_A3725DX");
642 /* Wait for 3 minutes */
643 WaitForSingleObject(hEvent
, 180000);
646 DPRINT("ScmWaitForSCManager() done\n");
650 /**********************************************************************
656 OpenSCManagerA(LPCSTR lpMachineName
,
657 LPCSTR lpDatabaseName
,
658 DWORD dwDesiredAccess
)
660 SC_HANDLE hScm
= NULL
;
663 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
664 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
670 /* Call to services.exe using RPC */
671 dwError
= ScmrOpenSCManagerA(BindingHandle
,
672 (LPSTR
)lpMachineName
,
673 (LPSTR
)lpDatabaseName
,
675 (unsigned int*)&hScm
);
676 if (dwError
!= ERROR_SUCCESS
)
678 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError
);
679 SetLastError(dwError
);
683 DPRINT("hScm = %p\n", hScm
);
689 /**********************************************************************
695 OpenSCManagerW(LPCWSTR lpMachineName
,
696 LPCWSTR lpDatabaseName
,
697 DWORD dwDesiredAccess
)
699 SC_HANDLE hScm
= NULL
;
702 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
703 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
709 /* Call to services.exe using RPC */
710 dwError
= ScmrOpenSCManagerW(BindingHandle
,
711 (LPWSTR
)lpMachineName
,
712 (LPWSTR
)lpDatabaseName
,
714 (unsigned int*)&hScm
);
715 if (dwError
!= ERROR_SUCCESS
)
717 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError
);
718 SetLastError(dwError
);
722 DPRINT("hScm = %p\n", hScm
);
728 /**********************************************************************
734 OpenServiceA(SC_HANDLE hSCManager
,
735 LPCSTR lpServiceName
,
736 DWORD dwDesiredAccess
)
738 SC_HANDLE hService
= NULL
;
741 DPRINT("OpenServiceA(%p, %s, %lx)\n",
742 hSCManager
, lpServiceName
, dwDesiredAccess
);
746 /* Call to services.exe using RPC */
747 dwError
= ScmrOpenServiceA(BindingHandle
,
748 (unsigned int)hSCManager
,
749 (LPSTR
)lpServiceName
,
751 (unsigned int*)&hService
);
752 if (dwError
!= ERROR_SUCCESS
)
754 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError
);
755 SetLastError(dwError
);
759 DPRINT("hService = %p\n", hService
);
765 /**********************************************************************
771 OpenServiceW(SC_HANDLE hSCManager
,
772 LPCWSTR lpServiceName
,
773 DWORD dwDesiredAccess
)
775 SC_HANDLE hService
= NULL
;
778 DPRINT("OpenServiceW(%p, %S, %lx)\n",
779 hSCManager
, lpServiceName
, dwDesiredAccess
);
783 /* Call to services.exe using RPC */
784 dwError
= ScmrOpenServiceW(BindingHandle
,
785 (unsigned int)hSCManager
,
786 (LPWSTR
)lpServiceName
,
788 (unsigned int*)&hService
);
789 if (dwError
!= ERROR_SUCCESS
)
791 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError
);
792 SetLastError(dwError
);
796 DPRINT("hService = %p\n", hService
);
802 /**********************************************************************
803 * QueryServiceConfigA
811 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
813 LPDWORD pcbBytesNeeded
)
815 DPRINT1("QueryServiceConfigA is unimplemented\n");
816 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
821 /**********************************************************************
822 * QueryServiceConfigW
830 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
832 LPDWORD pcbBytesNeeded
)
834 DPRINT1("QueryServiceConfigW is unimplemented\n");
835 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
840 /**********************************************************************
841 * QueryServiceLockStatusA
847 QueryServiceLockStatusA(
848 SC_HANDLE hSCManager
,
849 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
851 LPDWORD pcbBytesNeeded
)
853 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
854 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
859 /**********************************************************************
860 * QueryServiceLockStatusW
866 QueryServiceLockStatusW(
867 SC_HANDLE hSCManager
,
868 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
870 LPDWORD pcbBytesNeeded
)
872 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
873 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
878 /**********************************************************************
879 * QueryServiceObjectSecurity
885 QueryServiceObjectSecurity(
887 SECURITY_INFORMATION dwSecurityInformation
,
888 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
890 LPDWORD pcbBytesNeeded
)
892 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
893 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
898 /**********************************************************************
904 QueryServiceStatus(SC_HANDLE hService
,
905 LPSERVICE_STATUS lpServiceStatus
)
909 DPRINT("QueryServiceStatus(%p, %p)\n",
910 hService
, lpServiceStatus
);
914 /* Call to services.exe using RPC */
915 dwError
= ScmrQueryServiceStatus(BindingHandle
,
916 (unsigned int)hService
,
918 if (dwError
!= ERROR_SUCCESS
)
920 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError
);
921 SetLastError(dwError
);
929 /**********************************************************************
930 * QueryServiceStatusEx
936 QueryServiceStatusEx(SC_HANDLE hService
,
937 SC_STATUS_TYPE InfoLevel
,
940 LPDWORD pcbBytesNeeded
)
942 DPRINT1("QueryServiceStatusEx is unimplemented\n");
943 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
948 /**********************************************************************
957 DWORD dwNumServiceArgs
,
958 LPCSTR
*lpServiceArgVectors
)
960 DPRINT1("StartServiceA is unimplemented\n");
961 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
966 /**********************************************************************
975 DWORD dwNumServiceArgs
,
976 LPCWSTR
*lpServiceArgVectors
)
978 DPRINT1("StartServiceW is unimplemented\n");
979 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
984 /**********************************************************************
985 * UnlockServiceDatabase
990 UnlockServiceDatabase(SC_LOCK ScLock
)
995 DPRINT("UnlockServiceDatabase(%x)\n", hSCManager
);
1000 /* Call to services.exe using RPC */
1001 dwError
= ScmrUnlockServiceDatabase(BindingHandle
,
1002 (unsigned int)ScLock
);
1003 if (dwError
!= ERROR_SUCCESS
)
1005 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
1006 SetLastError(dwError
);
1014 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
1016 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1019 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1021 HeapFree(GetProcessHeap(), 0, ptr
);