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 * ChangeServiceConfig2W
86 ChangeServiceConfig2W(SC_HANDLE hService
,
93 DPRINT("ChangeServiceConfig2W() called\n");
95 /* Determine the length of the lpInfo parameter */
98 case SERVICE_CONFIG_DESCRIPTION
:
99 lpInfoSize
= sizeof(SERVICE_DESCRIPTION
);
101 case SERVICE_CONFIG_FAILURE_ACTIONS
:
102 lpInfoSize
= sizeof(SERVICE_FAILURE_ACTIONS
);
105 DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel
);
106 SetLastError(ERROR_INVALID_PARAMETER
);
115 dwError
= ScmrChangeServiceConfig2W(BindingHandle
,
116 (unsigned int)hService
,
120 if (dwError
!= ERROR_SUCCESS
)
122 DPRINT1("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
123 SetLastError(dwError
);
131 /**********************************************************************
132 * ChangeServiceConfigA
137 ChangeServiceConfigA(SC_HANDLE hService
,
140 DWORD dwErrorControl
,
141 LPCSTR lpBinaryPathName
,
142 LPCSTR lpLoadOrderGroup
,
144 LPCSTR lpDependencies
,
145 LPCSTR lpServiceStartName
,
147 LPCSTR lpDisplayName
)
150 DWORD dwDependenciesLength
= 0;
154 DPRINT("ChangeServiceConfigA() called\n");
156 /* Calculate the Dependencies length*/
157 if (lpDependencies
!= NULL
)
159 lpStr
= (LPSTR
)lpDependencies
;
162 dwLength
= strlen(lpStr
) + 1;
163 dwDependenciesLength
+= dwLength
;
164 lpStr
= lpStr
+ dwLength
;
166 dwDependenciesLength
++;
169 /* FIXME: Encrypt the password */
173 /* Call to services.exe using RPC */
174 dwError
= ScmrChangeServiceConfigA(BindingHandle
,
175 (unsigned int)hService
,
179 (LPSTR
)lpBinaryPathName
,
180 (LPSTR
)lpLoadOrderGroup
,
182 (LPSTR
)lpDependencies
,
183 dwDependenciesLength
,
184 (LPSTR
)lpServiceStartName
,
185 NULL
, /* FIXME: lpPassword */
186 0, /* FIXME: dwPasswordLength */
187 (LPSTR
)lpDisplayName
);
188 if (dwError
!= ERROR_SUCCESS
)
190 DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError
);
191 SetLastError(dwError
);
199 /**********************************************************************
200 * ChangeServiceConfigW
205 ChangeServiceConfigW(SC_HANDLE hService
,
208 DWORD dwErrorControl
,
209 LPCWSTR lpBinaryPathName
,
210 LPCWSTR lpLoadOrderGroup
,
212 LPCWSTR lpDependencies
,
213 LPCWSTR lpServiceStartName
,
215 LPCWSTR lpDisplayName
)
218 DWORD dwDependenciesLength
= 0;
222 DPRINT("ChangeServiceConfigW() called\n");
224 /* Calculate the Dependencies length*/
225 if (lpDependencies
!= NULL
)
227 lpStr
= (LPWSTR
)lpDependencies
;
230 dwLength
= wcslen(lpStr
) + 1;
231 dwDependenciesLength
+= dwLength
;
232 lpStr
= lpStr
+ dwLength
;
234 dwDependenciesLength
++;
237 /* FIXME: Encrypt the password */
241 /* Call to services.exe using RPC */
242 dwError
= ScmrChangeServiceConfigW(BindingHandle
,
243 (unsigned int)hService
,
247 (LPWSTR
)lpBinaryPathName
,
248 (LPWSTR
)lpLoadOrderGroup
,
250 (LPWSTR
)lpDependencies
,
251 dwDependenciesLength
,
252 (LPWSTR
)lpServiceStartName
,
253 NULL
, /* FIXME: lpPassword */
254 0, /* FIXME: dwPasswordLength */
255 (LPWSTR
)lpDisplayName
);
256 if (dwError
!= ERROR_SUCCESS
)
258 DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError
);
259 SetLastError(dwError
);
267 /**********************************************************************
273 CloseServiceHandle(SC_HANDLE hSCObject
)
277 DPRINT("CloseServiceHandle() called\n");
281 /* Call to services.exe using RPC */
282 dwError
= ScmrCloseServiceHandle(BindingHandle
,
283 (unsigned int)hSCObject
);
286 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError
);
287 SetLastError(dwError
);
291 DPRINT("CloseServiceHandle() done\n");
297 /**********************************************************************
303 ControlService(SC_HANDLE hService
,
305 LPSERVICE_STATUS lpServiceStatus
)
309 DPRINT("ControlService(%x, %x, %p)\n",
310 hService
, dwControl
, lpServiceStatus
);
314 /* Call to services.exe using RPC */
315 dwError
= ScmrControlService(BindingHandle
,
316 (unsigned int)hService
,
319 if (dwError
!= ERROR_SUCCESS
)
321 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError
);
322 SetLastError(dwError
);
326 DPRINT("ControlService() done\n");
332 /**********************************************************************
338 ControlServiceEx(IN SC_HANDLE hService
,
340 IN DWORD dwInfoLevel
,
341 IN OUT PVOID pControlParams
)
343 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
344 hService
, dwControl
, dwInfoLevel
, pControlParams
);
345 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
351 /**********************************************************************
358 CreateServiceA(SC_HANDLE hSCManager
,
359 LPCSTR lpServiceName
,
360 LPCSTR lpDisplayName
,
361 DWORD dwDesiredAccess
,
364 DWORD dwErrorControl
,
365 LPCSTR lpBinaryPathName
,
366 LPCSTR lpLoadOrderGroup
,
368 LPCSTR lpDependencies
,
369 LPCSTR lpServiceStartName
,
372 SC_HANDLE RetVal
= NULL
;
373 LPWSTR lpServiceNameW
= NULL
;
374 LPWSTR lpDisplayNameW
= NULL
;
375 LPWSTR lpBinaryPathNameW
= NULL
;
376 LPWSTR lpLoadOrderGroupW
= NULL
;
377 LPWSTR lpDependenciesW
= NULL
;
378 LPWSTR lpServiceStartNameW
= NULL
;
379 LPWSTR lpPasswordW
= NULL
;
380 DWORD dwDependenciesLength
= 0;
384 int len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, NULL
, 0);
385 lpServiceNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
388 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
391 MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, lpServiceNameW
, len
);
393 len
= MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, NULL
, 0);
394 lpDisplayNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
397 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
400 MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, lpDisplayNameW
, len
);
402 len
= MultiByteToWideChar(CP_ACP
, 0, lpBinaryPathName
, -1, NULL
, 0);
403 lpBinaryPathNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
404 if (!lpBinaryPathNameW
)
406 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
409 MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, lpBinaryPathNameW
, len
);
411 len
= MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, NULL
, 0);
412 lpLoadOrderGroupW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
413 if (!lpLoadOrderGroupW
)
415 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
418 MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, lpLoadOrderGroupW
, len
);
420 if (lpDependencies
!= NULL
)
422 lpStr
= (LPSTR
)lpDependencies
;
425 dwLength
= strlen(lpStr
) + 1;
426 dwDependenciesLength
+= dwLength
;
427 lpStr
= lpStr
+ dwLength
;
429 dwDependenciesLength
++;
432 lpDependenciesW
= HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength
* sizeof(WCHAR
));
433 if (!lpDependenciesW
)
435 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
438 MultiByteToWideChar(CP_ACP
, 0, lpDependencies
, -1, lpDependenciesW
, dwDependenciesLength
);
440 len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, NULL
, 0);
441 lpServiceStartName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
442 if (!lpServiceStartNameW
)
444 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
447 MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, lpServiceStartNameW
, len
);
449 len
= MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, NULL
, 0);
450 lpPasswordW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
453 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
456 MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, lpPasswordW
, len
);
458 RetVal
= CreateServiceW(hSCManager
,
473 HeapFree(GetProcessHeap(), 0, lpServiceNameW
);
474 HeapFree(GetProcessHeap(), 0, lpDisplayNameW
);
475 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW
);
476 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW
);
477 HeapFree(GetProcessHeap(), 0, lpDependenciesW
);
478 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW
);
479 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
485 /**********************************************************************
491 CreateServiceW(SC_HANDLE hSCManager
,
492 LPCWSTR lpServiceName
,
493 LPCWSTR lpDisplayName
,
494 DWORD dwDesiredAccess
,
497 DWORD dwErrorControl
,
498 LPCWSTR lpBinaryPathName
,
499 LPCWSTR lpLoadOrderGroup
,
501 LPCWSTR lpDependencies
,
502 LPCWSTR lpServiceStartName
,
505 SC_HANDLE hService
= NULL
;
507 DWORD dwDependenciesLength
= 0;
511 DPRINT1("CreateServiceW() called\n");
513 /* Calculate the Dependencies length*/
514 if (lpDependencies
!= NULL
)
516 lpStr
= (LPWSTR
)lpDependencies
;
519 dwLength
= wcslen(lpStr
) + 1;
520 dwDependenciesLength
+= dwLength
;
521 lpStr
= lpStr
+ dwLength
;
523 dwDependenciesLength
++;
526 /* FIXME: Encrypt the password */
530 /* Call to services.exe using RPC */
531 dwError
= ScmrCreateServiceW(BindingHandle
,
532 (unsigned int)hSCManager
,
533 (LPWSTR
)lpServiceName
,
534 (LPWSTR
)lpDisplayName
,
539 (LPWSTR
)lpBinaryPathName
,
540 (LPWSTR
)lpLoadOrderGroup
,
542 (LPWSTR
)lpDependencies
,
543 dwDependenciesLength
,
544 (LPWSTR
)lpServiceStartName
,
545 NULL
, /* FIXME: lpPassword */
546 0, /* FIXME: dwPasswordLength */
547 (unsigned int *)&hService
);
548 if (dwError
!= ERROR_SUCCESS
)
550 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError
);
551 SetLastError(dwError
);
559 /**********************************************************************
565 DeleteService(SC_HANDLE hService
)
569 DPRINT("DeleteService(%x)\n", hService
);
573 /* Call to services.exe using RPC */
574 dwError
= ScmrDeleteService(BindingHandle
,
575 (unsigned int)hService
);
576 if (dwError
!= ERROR_SUCCESS
)
578 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError
);
579 SetLastError(dwError
);
587 /**********************************************************************
588 * EnumDependentServicesA
594 EnumDependentServicesA(
596 DWORD dwServiceState
,
597 LPENUM_SERVICE_STATUSA lpServices
,
599 LPDWORD pcbBytesNeeded
,
600 LPDWORD lpServicesReturned
)
602 DPRINT1("EnumDependentServicesA is unimplemented\n");
603 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
608 /**********************************************************************
609 * EnumDependentServicesW
615 EnumDependentServicesW(SC_HANDLE hService
,
616 DWORD dwServiceState
,
617 LPENUM_SERVICE_STATUSW lpServices
,
619 LPDWORD pcbBytesNeeded
,
620 LPDWORD lpServicesReturned
)
622 DPRINT1("EnumDependentServicesW is unimplemented\n");
623 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
628 /**********************************************************************
636 SC_HANDLE hSCManager
,
638 DWORD dwServiceState
,
639 LPENUM_SERVICE_STATUSA lpServices
,
641 LPDWORD pcbBytesNeeded
,
642 LPDWORD lpServicesReturned
,
643 LPDWORD lpResumeHandle
,
646 DPRINT1("EnumServiceGroupW is unimplemented\n");
647 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
652 /**********************************************************************
653 * EnumServicesStatusA
660 SC_HANDLE hSCManager
,
662 DWORD dwServiceState
,
663 LPENUM_SERVICE_STATUSA lpServices
,
665 LPDWORD pcbBytesNeeded
,
666 LPDWORD lpServicesReturned
,
667 LPDWORD lpResumeHandle
)
669 DPRINT1("EnumServicesStatusA is unimplemented\n");
670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
675 /**********************************************************************
676 * EnumServicesStatusW
681 EnumServicesStatusW(SC_HANDLE hSCManager
,
683 DWORD dwServiceState
,
684 LPENUM_SERVICE_STATUSW lpServices
,
686 LPDWORD pcbBytesNeeded
,
687 LPDWORD lpServicesReturned
,
688 LPDWORD lpResumeHandle
)
690 LPENUM_SERVICE_STATUSW lpStatusPtr
;
691 DWORD dwError
= ERROR_SUCCESS
;
694 DPRINT("EnumServicesStatusW() called\n");
698 dwError
= ScmrEnumServicesStatusW(BindingHandle
,
699 (unsigned int)hSCManager
,
702 (unsigned char *)lpServices
,
708 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
709 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
711 if (lpStatusPtr
->lpServiceName
)
712 lpStatusPtr
->lpServiceName
=
713 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
715 if (lpStatusPtr
->lpDisplayName
)
716 lpStatusPtr
->lpDisplayName
=
717 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
722 if (dwError
!= ERROR_SUCCESS
)
724 DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError
);
725 SetLastError(dwError
);
729 DPRINT("ScmrEnumServicesStatusW() done\n");
735 /**********************************************************************
736 * EnumServicesStatusExA
742 EnumServicesStatusExA(SC_HANDLE hSCManager
,
743 SC_ENUM_TYPE InfoLevel
,
745 DWORD dwServiceState
,
748 LPDWORD pcbBytesNeeded
,
749 LPDWORD lpServicesReturned
,
750 LPDWORD lpResumeHandle
,
753 DPRINT1("EnumServicesStatusExA is unimplemented\n");
754 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
759 /**********************************************************************
760 * EnumServicesStatusExW
765 EnumServicesStatusExW(SC_HANDLE hSCManager
,
766 SC_ENUM_TYPE InfoLevel
,
768 DWORD dwServiceState
,
771 LPDWORD pcbBytesNeeded
,
772 LPDWORD lpServicesReturned
,
773 LPDWORD lpResumeHandle
,
774 LPCWSTR pszGroupName
)
776 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
777 DWORD dwError
= ERROR_SUCCESS
;
780 DPRINT1("EnumServicesStatusExW() called\n");
784 dwError
= ScmrEnumServicesStatusExW(BindingHandle
,
785 (unsigned int)hSCManager
,
786 (unsigned long)InfoLevel
,
789 (unsigned char *)lpServices
,
794 (wchar_t *)pszGroupName
);
796 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
797 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
799 if (lpStatusPtr
->lpServiceName
)
800 lpStatusPtr
->lpServiceName
=
801 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
803 if (lpStatusPtr
->lpDisplayName
)
804 lpStatusPtr
->lpDisplayName
=
805 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
810 if (dwError
!= ERROR_SUCCESS
)
812 DPRINT1("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError
);
813 SetLastError(dwError
);
817 DPRINT1("ScmrEnumServicesStatusExW() done\n");
823 /**********************************************************************
824 * GetServiceDisplayNameA
829 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
830 LPCSTR lpServiceName
,
836 DPRINT("GetServiceDisplayNameA() called\n");
840 dwError
= ScmrGetServiceDisplayNameA(BindingHandle
,
841 (unsigned int)hSCManager
,
842 (LPSTR
)lpServiceName
,
845 if (dwError
!= ERROR_SUCCESS
)
847 DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
848 SetLastError(dwError
);
858 /**********************************************************************
859 * GetServiceDisplayNameW
864 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
865 LPCWSTR lpServiceName
,
866 LPWSTR lpDisplayName
,
871 DPRINT("GetServiceDisplayNameW() called\n");
875 dwError
= ScmrGetServiceDisplayNameW(BindingHandle
,
876 (unsigned int)hSCManager
,
877 (LPWSTR
)lpServiceName
,
880 if (dwError
!= ERROR_SUCCESS
)
882 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
883 SetLastError(dwError
);
893 /**********************************************************************
899 GetServiceKeyNameA(SC_HANDLE hSCManager
,
900 LPCSTR lpDisplayName
,
906 DPRINT("GetServiceKeyNameA() called\n");
910 dwError
= ScmrGetServiceKeyNameA(BindingHandle
,
911 (unsigned int)hSCManager
,
912 (LPSTR
)lpDisplayName
,
915 if (dwError
!= ERROR_SUCCESS
)
917 DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
918 SetLastError(dwError
);
928 /**********************************************************************
934 GetServiceKeyNameW(SC_HANDLE hSCManager
,
935 LPCWSTR lpDisplayName
,
936 LPWSTR lpServiceName
,
941 DPRINT("GetServiceKeyNameW() called\n");
945 dwError
= ScmrGetServiceKeyNameW(BindingHandle
,
946 (unsigned int)hSCManager
,
947 (LPWSTR
)lpDisplayName
,
950 if (dwError
!= ERROR_SUCCESS
)
952 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
953 SetLastError(dwError
);
963 /**********************************************************************
964 * LockServiceDatabase
969 LockServiceDatabase(SC_HANDLE hSCManager
)
974 DPRINT("LockServiceDatabase(%x)\n", hSCManager
);
978 /* Call to services.exe using RPC */
979 dwError
= ScmrLockServiceDatabase(BindingHandle
,
980 (unsigned int)hSCManager
,
981 (unsigned int *)&hLock
);
982 if (dwError
!= ERROR_SUCCESS
)
984 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError
);
985 SetLastError(dwError
);
989 DPRINT("hLock = %p\n", hLock
);
996 WaitForSCManager(VOID
)
1000 DPRINT("WaitForSCManager() called\n");
1002 /* Try to open the existing event */
1003 hEvent
= OpenEventW(SYNCHRONIZE
,
1005 L
"SvcctrlStartEvent_A3725DX");
1008 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1011 /* Try to create a new event */
1012 hEvent
= CreateEventW(NULL
,
1015 L
"SvcctrlStartEvent_A3725DX");
1018 /* Try to open the existing event again */
1019 hEvent
= OpenEventW(SYNCHRONIZE
,
1021 L
"SvcctrlStartEvent_A3725DX");
1027 /* Wait for 3 minutes */
1028 WaitForSingleObject(hEvent
, 180000);
1029 CloseHandle(hEvent
);
1031 DPRINT("ScmWaitForSCManager() done\n");
1035 /**********************************************************************
1041 OpenSCManagerA(LPCSTR lpMachineName
,
1042 LPCSTR lpDatabaseName
,
1043 DWORD dwDesiredAccess
)
1045 SC_HANDLE hScm
= NULL
;
1048 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
1049 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1055 /* Call to services.exe using RPC */
1056 dwError
= ScmrOpenSCManagerA(BindingHandle
,
1057 (LPSTR
)lpMachineName
,
1058 (LPSTR
)lpDatabaseName
,
1060 (unsigned int*)&hScm
);
1061 if (dwError
!= ERROR_SUCCESS
)
1063 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError
);
1064 SetLastError(dwError
);
1068 DPRINT("hScm = %p\n", hScm
);
1074 /**********************************************************************
1080 OpenSCManagerW(LPCWSTR lpMachineName
,
1081 LPCWSTR lpDatabaseName
,
1082 DWORD dwDesiredAccess
)
1084 SC_HANDLE hScm
= NULL
;
1087 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
1088 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1094 /* Call to services.exe using RPC */
1095 dwError
= ScmrOpenSCManagerW(BindingHandle
,
1096 (LPWSTR
)lpMachineName
,
1097 (LPWSTR
)lpDatabaseName
,
1099 (unsigned int*)&hScm
);
1100 if (dwError
!= ERROR_SUCCESS
)
1102 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError
);
1103 SetLastError(dwError
);
1107 DPRINT("hScm = %p\n", hScm
);
1113 /**********************************************************************
1119 OpenServiceA(SC_HANDLE hSCManager
,
1120 LPCSTR lpServiceName
,
1121 DWORD dwDesiredAccess
)
1123 SC_HANDLE hService
= NULL
;
1126 DPRINT("OpenServiceA(%p, %s, %lx)\n",
1127 hSCManager
, lpServiceName
, dwDesiredAccess
);
1131 /* Call to services.exe using RPC */
1132 dwError
= ScmrOpenServiceA(BindingHandle
,
1133 (unsigned int)hSCManager
,
1134 (LPSTR
)lpServiceName
,
1136 (unsigned int*)&hService
);
1137 if (dwError
!= ERROR_SUCCESS
)
1139 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError
);
1140 SetLastError(dwError
);
1144 DPRINT("hService = %p\n", hService
);
1150 /**********************************************************************
1156 OpenServiceW(SC_HANDLE hSCManager
,
1157 LPCWSTR lpServiceName
,
1158 DWORD dwDesiredAccess
)
1160 SC_HANDLE hService
= NULL
;
1163 DPRINT("OpenServiceW(%p, %S, %lx)\n",
1164 hSCManager
, lpServiceName
, dwDesiredAccess
);
1168 /* Call to services.exe using RPC */
1169 dwError
= ScmrOpenServiceW(BindingHandle
,
1170 (unsigned int)hSCManager
,
1171 (LPWSTR
)lpServiceName
,
1173 (unsigned int*)&hService
);
1174 if (dwError
!= ERROR_SUCCESS
)
1176 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError
);
1177 SetLastError(dwError
);
1181 DPRINT("hService = %p\n", hService
);
1187 /**********************************************************************
1188 * QueryServiceConfigA
1193 QueryServiceConfigA(SC_HANDLE hService
,
1194 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1196 LPDWORD pcbBytesNeeded
)
1200 DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1201 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1205 /* Call to services.exe using RPC */
1206 dwError
= ScmrQueryServiceConfigA(BindingHandle
,
1207 (unsigned int)hService
,
1208 (unsigned char *)lpServiceConfig
,
1211 if (dwError
!= ERROR_SUCCESS
)
1213 DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1214 SetLastError(dwError
);
1218 /* Adjust the pointers */
1219 if (lpServiceConfig
->lpBinaryPathName
)
1220 lpServiceConfig
->lpBinaryPathName
=
1221 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1222 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1224 if (lpServiceConfig
->lpLoadOrderGroup
)
1225 lpServiceConfig
->lpLoadOrderGroup
=
1226 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1227 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1229 if (lpServiceConfig
->lpDependencies
)
1230 lpServiceConfig
->lpDependencies
=
1231 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1232 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1234 if (lpServiceConfig
->lpServiceStartName
)
1235 lpServiceConfig
->lpServiceStartName
=
1236 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1237 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1239 if (lpServiceConfig
->lpDisplayName
)
1240 lpServiceConfig
->lpDisplayName
=
1241 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1242 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1244 DPRINT("QueryServiceConfigA() done\n");
1250 /**********************************************************************
1251 * QueryServiceConfigW
1256 QueryServiceConfigW(SC_HANDLE hService
,
1257 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1259 LPDWORD pcbBytesNeeded
)
1263 DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1264 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1268 /* Call to services.exe using RPC */
1269 dwError
= ScmrQueryServiceConfigW(BindingHandle
,
1270 (unsigned int)hService
,
1271 (unsigned char *)lpServiceConfig
,
1274 if (dwError
!= ERROR_SUCCESS
)
1276 DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1277 SetLastError(dwError
);
1281 /* Adjust the pointers */
1282 if (lpServiceConfig
->lpBinaryPathName
)
1283 lpServiceConfig
->lpBinaryPathName
=
1284 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1285 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1287 if (lpServiceConfig
->lpLoadOrderGroup
)
1288 lpServiceConfig
->lpLoadOrderGroup
=
1289 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1290 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1292 if (lpServiceConfig
->lpDependencies
)
1293 lpServiceConfig
->lpDependencies
=
1294 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1295 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1297 if (lpServiceConfig
->lpServiceStartName
)
1298 lpServiceConfig
->lpServiceStartName
=
1299 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1300 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1302 if (lpServiceConfig
->lpDisplayName
)
1303 lpServiceConfig
->lpDisplayName
=
1304 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1305 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1307 DPRINT("QueryServiceConfigW() done\n");
1313 /**********************************************************************
1314 * QueryServiceConfig2A
1320 QueryServiceConfig2A(
1325 LPDWORD pcbBytesNeeded
)
1327 DPRINT1("QueryServiceConfig2A is unimplemented\n");
1332 /**********************************************************************
1333 * QueryServiceConfig2W
1339 QueryServiceConfig2W(
1344 LPDWORD pcbBytesNeeded
)
1346 DPRINT1("QueryServiceConfig2W is unimplemented\n");
1351 /**********************************************************************
1352 * QueryServiceLockStatusA
1358 QueryServiceLockStatusA(
1359 SC_HANDLE hSCManager
,
1360 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
1362 LPDWORD pcbBytesNeeded
)
1364 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1365 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1370 /**********************************************************************
1371 * QueryServiceLockStatusW
1377 QueryServiceLockStatusW(
1378 SC_HANDLE hSCManager
,
1379 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
1381 LPDWORD pcbBytesNeeded
)
1383 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1384 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1389 /**********************************************************************
1390 * QueryServiceObjectSecurity
1395 QueryServiceObjectSecurity(SC_HANDLE hService
,
1396 SECURITY_INFORMATION dwSecurityInformation
,
1397 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
1399 LPDWORD pcbBytesNeeded
)
1403 DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
1404 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
1408 /* Call to services.exe using RPC */
1409 dwError
= ScmrQueryServiceObjectSecurity(BindingHandle
,
1410 (unsigned int)hService
,
1411 dwSecurityInformation
,
1412 (unsigned char *)lpSecurityDescriptor
,
1415 if (dwError
!= ERROR_SUCCESS
)
1417 DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
1418 SetLastError(dwError
);
1426 /**********************************************************************
1427 * QueryServiceStatus
1432 QueryServiceStatus(SC_HANDLE hService
,
1433 LPSERVICE_STATUS lpServiceStatus
)
1437 DPRINT("QueryServiceStatus(%p, %p)\n",
1438 hService
, lpServiceStatus
);
1442 /* Call to services.exe using RPC */
1443 dwError
= ScmrQueryServiceStatus(BindingHandle
,
1444 (unsigned int)hService
,
1446 if (dwError
!= ERROR_SUCCESS
)
1448 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError
);
1449 SetLastError(dwError
);
1457 /**********************************************************************
1458 * QueryServiceStatusEx
1463 QueryServiceStatusEx(SC_HANDLE hService
,
1464 SC_STATUS_TYPE InfoLevel
,
1467 LPDWORD pcbBytesNeeded
)
1471 DPRINT("QueryServiceStatusEx() called\n");
1475 /* Call to services.exe using RPC */
1476 dwError
= ScmrQueryServiceStatusEx(BindingHandle
,
1477 (unsigned int)hService
,
1482 if (dwError
!= ERROR_SUCCESS
)
1484 DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
1485 SetLastError(dwError
);
1493 /**********************************************************************
1494 * SetServiceObjectSecurity
1499 SetServiceObjectSecurity(SC_HANDLE hService
,
1500 SECURITY_INFORMATION dwSecurityInformation
,
1501 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
1503 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
1509 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
1512 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1514 SetLastError(ERROR_INVALID_PARAMETER
);
1518 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
1519 if (SelfRelativeSD
== NULL
)
1521 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1525 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
1528 if (!NT_SUCCESS(Status
))
1530 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
1531 SetLastError(RtlNtStatusToDosError(Status
));
1537 /* Call to services.exe using RPC */
1538 dwError
= ScmrSetServiceObjectSecurity(BindingHandle
,
1539 (unsigned int)hService
,
1540 dwSecurityInformation
,
1541 (unsigned char *)SelfRelativeSD
,
1544 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
1546 if (dwError
!= ERROR_SUCCESS
)
1548 DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError
);
1549 SetLastError(dwError
);
1557 /**********************************************************************
1563 StartServiceA(SC_HANDLE hService
,
1564 DWORD dwNumServiceArgs
,
1565 LPCSTR
*lpServiceArgVectors
)
1570 DPRINT("StartServiceA()\n");
1574 /* Call to services.exe using RPC */
1575 dwError
= ScmrStartServiceA(BindingHandle
,
1578 lpServiceArgVectors
);
1579 if (dwError
!= ERROR_SUCCESS
)
1581 DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError
);
1582 SetLastError(dwError
);
1595 for (i
= 0; i
< dwNumServiceArgs
; i
++)
1597 dwBufSize
+= (strlen(lpServiceArgVectors
[i
]) + 1);
1599 DPRINT1("dwBufSize: %lu\n", dwBufSize
);
1601 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, dwBufSize
);
1602 if (lpBuffer
== NULL
)
1604 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1609 for (i
= 0; i
< dwNumServiceArgs
; i
++)
1611 strcpy(lpStr
, lpServiceArgVectors
[i
]);
1612 lpStr
+= (strlen(lpServiceArgVectors
[i
]) + 1);
1615 dwError
= ScmrStartServiceA(BindingHandle
,
1616 (unsigned int)hService
,
1618 (unsigned char *)lpBuffer
,
1621 HeapFree(GetProcessHeap(), 0, lpBuffer
);
1623 if (dwError
!= ERROR_SUCCESS
)
1625 DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError
);
1626 SetLastError(dwError
);
1634 /**********************************************************************
1640 StartServiceW(SC_HANDLE hService
,
1641 DWORD dwNumServiceArgs
,
1642 LPCWSTR
*lpServiceArgVectors
)
1647 DPRINT("StartServiceW()\n");
1651 /* Call to services.exe using RPC */
1652 dwError
= ScmrStartServiceW(BindingHandle
,
1655 lpServiceArgVectors
);
1656 if (dwError
!= ERROR_SUCCESS
)
1658 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError
);
1659 SetLastError(dwError
);
1672 for (i
= 0; i
< dwNumServiceArgs
; i
++)
1674 dwBufSize
+= ((wcslen(lpServiceArgVectors
[i
]) + 1) * sizeof(WCHAR
));
1676 DPRINT1("dwBufSize: %lu\n", dwBufSize
);
1678 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, dwBufSize
);
1679 if (lpBuffer
== NULL
)
1681 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1686 for (i
= 0; i
< dwNumServiceArgs
; i
++)
1688 wcscpy(lpStr
, lpServiceArgVectors
[i
]);
1689 lpStr
+= (wcslen(lpServiceArgVectors
[i
]) + 1);
1692 dwError
= ScmrStartServiceW(BindingHandle
,
1693 (unsigned int)hService
,
1695 (unsigned char *)lpBuffer
,
1698 HeapFree(GetProcessHeap(), 0, lpBuffer
);
1700 if (dwError
!= ERROR_SUCCESS
)
1702 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError
);
1703 SetLastError(dwError
);
1711 /**********************************************************************
1712 * UnlockServiceDatabase
1717 UnlockServiceDatabase(SC_LOCK ScLock
)
1721 DPRINT("UnlockServiceDatabase(%x)\n", ScLock
);
1725 /* Call to services.exe using RPC */
1726 dwError
= ScmrUnlockServiceDatabase(BindingHandle
,
1727 (unsigned int)ScLock
);
1728 if (dwError
!= ERROR_SUCCESS
)
1730 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
1731 SetLastError(dwError
);
1739 /**********************************************************************
1740 * NotifyBootConfigStatus
1745 NotifyBootConfigStatus(BOOL BootAcceptable
)
1749 DPRINT1("NotifyBootConfigStatus()\n");
1753 /* Call to services.exe using RPC */
1754 dwError
= ScmrNotifyBootConfigStatus(BindingHandle
,
1756 if (dwError
!= ERROR_SUCCESS
)
1758 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
1759 SetLastError(dwError
);
1767 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
1769 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1773 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1775 HeapFree(GetProcessHeap(), 0, ptr
);