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
112 ChangeServiceConfigW(SC_HANDLE hService
,
115 DWORD dwErrorControl
,
116 LPCWSTR lpBinaryPathName
,
117 LPCWSTR lpLoadOrderGroup
,
119 LPCWSTR lpDependencies
,
120 LPCWSTR lpServiceStartName
,
122 LPCWSTR lpDisplayName
)
125 DWORD dwDependenciesLength
= 0;
129 DPRINT1("ChangeServiceConfigW() called\n");
131 /* Calculate the Dependencies length*/
132 if (lpDependencies
!= NULL
)
134 lpStr
= (LPWSTR
)lpDependencies
;
137 dwLength
= wcslen(lpStr
) + 1;
138 dwDependenciesLength
+= dwLength
;
139 lpStr
= lpStr
+ dwLength
;
141 dwDependenciesLength
++;
144 /* FIXME: Encrypt the password */
148 /* Call to services.exe using RPC */
149 dwError
= ScmrChangeServiceConfigW(BindingHandle
,
150 (unsigned int)hService
,
154 (LPWSTR
)lpBinaryPathName
,
155 (LPWSTR
)lpLoadOrderGroup
,
157 (LPWSTR
)lpDependencies
,
158 dwDependenciesLength
,
159 (LPWSTR
)lpServiceStartName
,
160 NULL
, /* FIXME: lpPassword */
161 0, /* FIXME: dwPasswordLength */
162 (LPWSTR
)lpDisplayName
);
163 if (dwError
!= ERROR_SUCCESS
)
165 DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError
);
166 SetLastError(dwError
);
174 /**********************************************************************
180 CloseServiceHandle(SC_HANDLE hSCObject
)
184 DPRINT("CloseServiceHandle() called\n");
188 /* Call to services.exe using RPC */
189 dwError
= ScmrCloseServiceHandle(BindingHandle
,
190 (unsigned int)hSCObject
);
193 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError
);
194 SetLastError(dwError
);
198 DPRINT("CloseServiceHandle() done\n");
204 /**********************************************************************
210 ControlService(SC_HANDLE hService
,
212 LPSERVICE_STATUS lpServiceStatus
)
216 DPRINT("ControlService(%x, %x, %p)\n",
217 hService
, dwControl
, lpServiceStatus
);
221 /* Call to services.exe using RPC */
222 dwError
= ScmrControlService(BindingHandle
,
223 (unsigned int)hService
,
226 if (dwError
!= ERROR_SUCCESS
)
228 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError
);
229 SetLastError(dwError
);
233 DPRINT("ControlService() done\n");
239 /**********************************************************************
245 ControlServiceEx(IN SC_HANDLE hService
,
247 IN DWORD dwInfoLevel
,
248 IN OUT PVOID pControlParams
)
250 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
251 hService
, dwControl
, dwInfoLevel
, pControlParams
);
252 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
258 /**********************************************************************
266 SC_HANDLE hSCManager
,
267 LPCSTR lpServiceName
,
268 LPCSTR lpDisplayName
,
269 DWORD dwDesiredAccess
,
272 DWORD dwErrorControl
,
273 LPCSTR lpBinaryPathName
,
274 LPCSTR lpLoadOrderGroup
,
276 LPCSTR lpDependencies
,
277 LPCSTR lpServiceStartName
,
280 DPRINT1("CreateServiceA is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
281 return INVALID_HANDLE_VALUE
;
285 /**********************************************************************
291 CreateServiceW(SC_HANDLE hSCManager
,
292 LPCWSTR lpServiceName
,
293 LPCWSTR lpDisplayName
,
294 DWORD dwDesiredAccess
,
297 DWORD dwErrorControl
,
298 LPCWSTR lpBinaryPathName
,
299 LPCWSTR lpLoadOrderGroup
,
301 LPCWSTR lpDependencies
,
302 LPCWSTR lpServiceStartName
,
305 SC_HANDLE hService
= NULL
;
307 DWORD dwDependenciesLength
= 0;
311 DPRINT1("CreateServiceW() called\n");
313 /* Calculate the Dependencies length*/
314 if (lpDependencies
!= NULL
)
316 lpStr
= (LPWSTR
)lpDependencies
;
319 dwLength
= wcslen(lpStr
) + 1;
320 dwDependenciesLength
+= dwLength
;
321 lpStr
= lpStr
+ dwLength
;
323 dwDependenciesLength
++;
326 /* FIXME: Encrypt the password */
330 /* Call to services.exe using RPC */
331 dwError
= ScmrCreateServiceW(BindingHandle
,
332 (unsigned int)hSCManager
,
333 (LPWSTR
)lpServiceName
,
334 (LPWSTR
)lpDisplayName
,
339 (LPWSTR
)lpBinaryPathName
,
340 (LPWSTR
)lpLoadOrderGroup
,
342 (LPWSTR
)lpDependencies
,
343 dwDependenciesLength
,
344 (LPWSTR
)lpServiceStartName
,
345 NULL
, /* FIXME: lpPassword */
346 0, /* FIXME: dwPasswordLength */
347 (unsigned int *)&hService
);
348 if (dwError
!= ERROR_SUCCESS
)
350 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError
);
351 SetLastError(dwError
);
352 return INVALID_HANDLE_VALUE
;
359 /**********************************************************************
365 DeleteService(SC_HANDLE hService
)
369 DPRINT("DeleteService(%x)\n", hService
);
373 /* Call to services.exe using RPC */
374 dwError
= ScmrDeleteService(BindingHandle
,
375 (unsigned int)hService
);
376 if (dwError
!= ERROR_SUCCESS
)
378 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError
);
379 SetLastError(dwError
);
387 /**********************************************************************
388 * EnumDependentServicesA
394 EnumDependentServicesA(
396 DWORD dwServiceState
,
397 LPENUM_SERVICE_STATUSA lpServices
,
399 LPDWORD pcbBytesNeeded
,
400 LPDWORD lpServicesReturned
)
402 DPRINT1("EnumDependentServicesA is unimplemented\n");
403 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
408 /**********************************************************************
409 * EnumDependentServicesW
415 EnumDependentServicesW(
417 DWORD dwServiceState
,
418 LPENUM_SERVICE_STATUSW lpServices
,
420 LPDWORD pcbBytesNeeded
,
421 LPDWORD lpServicesReturned
)
423 DPRINT1("EnumDependentServicesW is unimplemented\n");
424 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
429 /**********************************************************************
447 DPRINT1("EnumServiceGroupW is unimplemented\n");
448 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
453 /**********************************************************************
454 * EnumServicesStatusA
460 EnumServicesStatusA (
461 SC_HANDLE hSCManager
,
463 DWORD dwServiceState
,
464 LPENUM_SERVICE_STATUSA lpServices
,
466 LPDWORD pcbBytesNeeded
,
467 LPDWORD lpServicesReturned
,
468 LPDWORD lpResumeHandle
)
470 DPRINT1("EnumServicesStatusA is unimplemented\n");
471 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
476 /**********************************************************************
477 * EnumServicesStatusExA
483 EnumServicesStatusExA(SC_HANDLE hSCManager
,
484 SC_ENUM_TYPE InfoLevel
,
486 DWORD dwServiceState
,
489 LPDWORD pcbBytesNeeded
,
490 LPDWORD lpServicesReturned
,
491 LPDWORD lpResumeHandle
,
494 DPRINT1("EnumServicesStatusExA is unimplemented\n");
495 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
500 /**********************************************************************
501 * EnumServicesStatusExW
507 EnumServicesStatusExW(SC_HANDLE hSCManager
,
508 SC_ENUM_TYPE InfoLevel
,
510 DWORD dwServiceState
,
513 LPDWORD pcbBytesNeeded
,
514 LPDWORD lpServicesReturned
,
515 LPDWORD lpResumeHandle
,
516 LPCWSTR pszGroupName
)
518 DPRINT1("EnumServicesStatusExW is unimplemented\n");
519 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
524 /**********************************************************************
525 * EnumServicesStatusW
532 SC_HANDLE hSCManager
,
534 DWORD dwServiceState
,
535 LPENUM_SERVICE_STATUSW lpServices
,
537 LPDWORD pcbBytesNeeded
,
538 LPDWORD lpServicesReturned
,
539 LPDWORD lpResumeHandle
)
541 DPRINT1("EnumServicesStatusW is unimplemented\n");
542 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
547 /**********************************************************************
548 * GetServiceDisplayNameA
554 GetServiceDisplayNameA(
555 SC_HANDLE hSCManager
,
556 LPCSTR lpServiceName
,
560 DPRINT1("GetServiceDisplayNameA is unimplemented\n");
561 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
566 /**********************************************************************
567 * GetServiceDisplayNameW
572 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
573 LPCWSTR lpServiceName
,
574 LPWSTR lpDisplayName
,
579 DPRINT("GetServiceDisplayNameW() called\n");
583 dwError
= ScmrGetServiceDisplayNameW(BindingHandle
,
584 (unsigned int)hSCManager
,
585 (LPWSTR
)lpServiceName
,
588 if (dwError
!= ERROR_SUCCESS
)
590 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
591 SetLastError(dwError
);
599 /**********************************************************************
607 SC_HANDLE hSCManager
,
608 LPCSTR lpDisplayName
,
612 DPRINT1("GetServiceKeyNameA is unimplemented\n");
613 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
618 /**********************************************************************
624 GetServiceKeyNameW(SC_HANDLE hSCManager
,
625 LPCWSTR lpDisplayName
,
626 LPWSTR lpServiceName
,
631 DPRINT("GetServiceKeyNameW() called\n");
635 dwError
= ScmrGetServiceKeyNameW(BindingHandle
,
636 (unsigned int)hSCManager
,
637 (LPWSTR
)lpDisplayName
,
640 if (dwError
!= ERROR_SUCCESS
)
642 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
643 SetLastError(dwError
);
651 /**********************************************************************
652 * LockServiceDatabase
657 LockServiceDatabase(SC_HANDLE hSCManager
)
662 DPRINT("LockServiceDatabase(%x)\n", hSCManager
);
666 /* Call to services.exe using RPC */
667 dwError
= ScmrLockServiceDatabase(BindingHandle
,
668 (unsigned int)hSCManager
,
669 (unsigned int *)&hLock
);
670 if (dwError
!= ERROR_SUCCESS
)
672 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError
);
673 SetLastError(dwError
);
677 DPRINT("hLock = %p\n", hLock
);
684 WaitForSCManager(VOID
)
688 DPRINT("WaitForSCManager() called\n");
690 /* Try to open the existing event */
691 hEvent
= OpenEventW(SYNCHRONIZE
,
693 L
"SvcctrlStartEvent_A3725DX");
696 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
699 /* Try to create a new event */
700 hEvent
= CreateEventW(NULL
,
703 L
"SvcctrlStartEvent_A3725DX");
706 /* Try to open the existing event again */
707 hEvent
= OpenEventW(SYNCHRONIZE
,
709 L
"SvcctrlStartEvent_A3725DX");
715 /* Wait for 3 minutes */
716 WaitForSingleObject(hEvent
, 180000);
719 DPRINT("ScmWaitForSCManager() done\n");
723 /**********************************************************************
729 OpenSCManagerA(LPCSTR lpMachineName
,
730 LPCSTR lpDatabaseName
,
731 DWORD dwDesiredAccess
)
733 SC_HANDLE hScm
= NULL
;
736 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
737 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
743 /* Call to services.exe using RPC */
744 dwError
= ScmrOpenSCManagerA(BindingHandle
,
745 (LPSTR
)lpMachineName
,
746 (LPSTR
)lpDatabaseName
,
748 (unsigned int*)&hScm
);
749 if (dwError
!= ERROR_SUCCESS
)
751 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError
);
752 SetLastError(dwError
);
756 DPRINT("hScm = %p\n", hScm
);
762 /**********************************************************************
768 OpenSCManagerW(LPCWSTR lpMachineName
,
769 LPCWSTR lpDatabaseName
,
770 DWORD dwDesiredAccess
)
772 SC_HANDLE hScm
= NULL
;
775 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
776 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
782 /* Call to services.exe using RPC */
783 dwError
= ScmrOpenSCManagerW(BindingHandle
,
784 (LPWSTR
)lpMachineName
,
785 (LPWSTR
)lpDatabaseName
,
787 (unsigned int*)&hScm
);
788 if (dwError
!= ERROR_SUCCESS
)
790 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError
);
791 SetLastError(dwError
);
795 DPRINT("hScm = %p\n", hScm
);
801 /**********************************************************************
807 OpenServiceA(SC_HANDLE hSCManager
,
808 LPCSTR lpServiceName
,
809 DWORD dwDesiredAccess
)
811 SC_HANDLE hService
= NULL
;
814 DPRINT("OpenServiceA(%p, %s, %lx)\n",
815 hSCManager
, lpServiceName
, dwDesiredAccess
);
819 /* Call to services.exe using RPC */
820 dwError
= ScmrOpenServiceA(BindingHandle
,
821 (unsigned int)hSCManager
,
822 (LPSTR
)lpServiceName
,
824 (unsigned int*)&hService
);
825 if (dwError
!= ERROR_SUCCESS
)
827 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError
);
828 SetLastError(dwError
);
832 DPRINT("hService = %p\n", hService
);
838 /**********************************************************************
844 OpenServiceW(SC_HANDLE hSCManager
,
845 LPCWSTR lpServiceName
,
846 DWORD dwDesiredAccess
)
848 SC_HANDLE hService
= NULL
;
851 DPRINT("OpenServiceW(%p, %S, %lx)\n",
852 hSCManager
, lpServiceName
, dwDesiredAccess
);
856 /* Call to services.exe using RPC */
857 dwError
= ScmrOpenServiceW(BindingHandle
,
858 (unsigned int)hSCManager
,
859 (LPWSTR
)lpServiceName
,
861 (unsigned int*)&hService
);
862 if (dwError
!= ERROR_SUCCESS
)
864 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError
);
865 SetLastError(dwError
);
869 DPRINT("hService = %p\n", hService
);
875 /**********************************************************************
876 * QueryServiceConfigA
884 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
886 LPDWORD pcbBytesNeeded
)
888 DPRINT1("QueryServiceConfigA is unimplemented\n");
889 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
894 /**********************************************************************
895 * QueryServiceConfigW
903 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
905 LPDWORD pcbBytesNeeded
)
907 DPRINT1("QueryServiceConfigW is unimplemented\n");
908 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
913 /**********************************************************************
914 * QueryServiceLockStatusA
920 QueryServiceLockStatusA(
921 SC_HANDLE hSCManager
,
922 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
924 LPDWORD pcbBytesNeeded
)
926 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
927 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
932 /**********************************************************************
933 * QueryServiceLockStatusW
939 QueryServiceLockStatusW(
940 SC_HANDLE hSCManager
,
941 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
943 LPDWORD pcbBytesNeeded
)
945 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
946 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
951 /**********************************************************************
952 * QueryServiceObjectSecurity
958 QueryServiceObjectSecurity(
960 SECURITY_INFORMATION dwSecurityInformation
,
961 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
963 LPDWORD pcbBytesNeeded
)
965 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
966 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
971 /**********************************************************************
977 QueryServiceStatus(SC_HANDLE hService
,
978 LPSERVICE_STATUS lpServiceStatus
)
982 DPRINT("QueryServiceStatus(%p, %p)\n",
983 hService
, lpServiceStatus
);
987 /* Call to services.exe using RPC */
988 dwError
= ScmrQueryServiceStatus(BindingHandle
,
989 (unsigned int)hService
,
991 if (dwError
!= ERROR_SUCCESS
)
993 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError
);
994 SetLastError(dwError
);
1002 /**********************************************************************
1003 * QueryServiceStatusEx
1009 QueryServiceStatusEx(SC_HANDLE hService
,
1010 SC_STATUS_TYPE InfoLevel
,
1013 LPDWORD pcbBytesNeeded
)
1015 DPRINT1("QueryServiceStatusEx is unimplemented\n");
1016 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1021 /**********************************************************************
1030 DWORD dwNumServiceArgs
,
1031 LPCSTR
*lpServiceArgVectors
)
1033 DPRINT1("StartServiceA is unimplemented\n");
1034 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1039 /**********************************************************************
1048 DWORD dwNumServiceArgs
,
1049 LPCWSTR
*lpServiceArgVectors
)
1051 DPRINT1("StartServiceW is unimplemented\n");
1052 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1057 /**********************************************************************
1058 * UnlockServiceDatabase
1063 UnlockServiceDatabase(SC_LOCK ScLock
)
1067 DPRINT("UnlockServiceDatabase(%x)\n", ScLock
);
1071 /* Call to services.exe using RPC */
1072 dwError
= ScmrUnlockServiceDatabase(BindingHandle
,
1073 (unsigned int)ScLock
);
1074 if (dwError
!= ERROR_SUCCESS
)
1076 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
1077 SetLastError(dwError
);
1085 /**********************************************************************
1086 * NotifyBootConfigStatus
1091 NotifyBootConfigStatus(BOOL BootAcceptable
)
1095 DPRINT1("NotifyBootConfigStatus()\n");
1099 /* Call to services.exe using RPC */
1100 dwError
= ScmrNotifyBootConfigStatus(BindingHandle
,
1102 if (dwError
!= ERROR_SUCCESS
)
1104 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
1105 SetLastError(dwError
);
1113 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
1115 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1119 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1121 HeapFree(GetProcessHeap(), 0, ptr
);