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
);
100 case SERVICE_CONFIG_FAILURE_ACTIONS
:
101 lpInfoSize
= sizeof(SERVICE_FAILURE_ACTIONS
);
103 DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel
);
104 SetLastError(ERROR_INVALID_PARAMETER
);
113 dwError
= ScmrChangeServiceConfig2W(BindingHandle
,
114 (unsigned int)hService
,
118 if (dwError
!= ERROR_SUCCESS
)
120 DPRINT1("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
121 SetLastError(dwError
);
127 /**********************************************************************
128 * ChangeServiceConfigA
133 ChangeServiceConfigA(SC_HANDLE hService
,
136 DWORD dwErrorControl
,
137 LPCSTR lpBinaryPathName
,
138 LPCSTR lpLoadOrderGroup
,
140 LPCSTR lpDependencies
,
141 LPCSTR lpServiceStartName
,
143 LPCSTR lpDisplayName
)
146 DWORD dwDependenciesLength
= 0;
150 DPRINT("ChangeServiceConfigA() called\n");
152 /* Calculate the Dependencies length*/
153 if (lpDependencies
!= NULL
)
155 lpStr
= (LPSTR
)lpDependencies
;
158 dwLength
= strlen(lpStr
) + 1;
159 dwDependenciesLength
+= dwLength
;
160 lpStr
= lpStr
+ dwLength
;
162 dwDependenciesLength
++;
165 /* FIXME: Encrypt the password */
169 /* Call to services.exe using RPC */
170 dwError
= ScmrChangeServiceConfigA(BindingHandle
,
171 (unsigned int)hService
,
175 (LPSTR
)lpBinaryPathName
,
176 (LPSTR
)lpLoadOrderGroup
,
178 (LPSTR
)lpDependencies
,
179 dwDependenciesLength
,
180 (LPSTR
)lpServiceStartName
,
181 NULL
, /* FIXME: lpPassword */
182 0, /* FIXME: dwPasswordLength */
183 (LPSTR
)lpDisplayName
);
184 if (dwError
!= ERROR_SUCCESS
)
186 DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError
);
187 SetLastError(dwError
);
195 /**********************************************************************
196 * ChangeServiceConfigW
201 ChangeServiceConfigW(SC_HANDLE hService
,
204 DWORD dwErrorControl
,
205 LPCWSTR lpBinaryPathName
,
206 LPCWSTR lpLoadOrderGroup
,
208 LPCWSTR lpDependencies
,
209 LPCWSTR lpServiceStartName
,
211 LPCWSTR lpDisplayName
)
214 DWORD dwDependenciesLength
= 0;
218 DPRINT("ChangeServiceConfigW() called\n");
220 /* Calculate the Dependencies length*/
221 if (lpDependencies
!= NULL
)
223 lpStr
= (LPWSTR
)lpDependencies
;
226 dwLength
= wcslen(lpStr
) + 1;
227 dwDependenciesLength
+= dwLength
;
228 lpStr
= lpStr
+ dwLength
;
230 dwDependenciesLength
++;
233 /* FIXME: Encrypt the password */
237 /* Call to services.exe using RPC */
238 dwError
= ScmrChangeServiceConfigW(BindingHandle
,
239 (unsigned int)hService
,
243 (LPWSTR
)lpBinaryPathName
,
244 (LPWSTR
)lpLoadOrderGroup
,
246 (LPWSTR
)lpDependencies
,
247 dwDependenciesLength
,
248 (LPWSTR
)lpServiceStartName
,
249 NULL
, /* FIXME: lpPassword */
250 0, /* FIXME: dwPasswordLength */
251 (LPWSTR
)lpDisplayName
);
252 if (dwError
!= ERROR_SUCCESS
)
254 DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError
);
255 SetLastError(dwError
);
263 /**********************************************************************
269 CloseServiceHandle(SC_HANDLE hSCObject
)
273 DPRINT("CloseServiceHandle() called\n");
277 /* Call to services.exe using RPC */
278 dwError
= ScmrCloseServiceHandle(BindingHandle
,
279 (unsigned int)hSCObject
);
282 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError
);
283 SetLastError(dwError
);
287 DPRINT("CloseServiceHandle() done\n");
293 /**********************************************************************
299 ControlService(SC_HANDLE hService
,
301 LPSERVICE_STATUS lpServiceStatus
)
305 DPRINT("ControlService(%x, %x, %p)\n",
306 hService
, dwControl
, lpServiceStatus
);
310 /* Call to services.exe using RPC */
311 dwError
= ScmrControlService(BindingHandle
,
312 (unsigned int)hService
,
315 if (dwError
!= ERROR_SUCCESS
)
317 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError
);
318 SetLastError(dwError
);
322 DPRINT("ControlService() done\n");
328 /**********************************************************************
334 ControlServiceEx(IN SC_HANDLE hService
,
336 IN DWORD dwInfoLevel
,
337 IN OUT PVOID pControlParams
)
339 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
340 hService
, dwControl
, dwInfoLevel
, pControlParams
);
341 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
347 /**********************************************************************
354 CreateServiceA(SC_HANDLE hSCManager
,
355 LPCSTR lpServiceName
,
356 LPCSTR lpDisplayName
,
357 DWORD dwDesiredAccess
,
360 DWORD dwErrorControl
,
361 LPCSTR lpBinaryPathName
,
362 LPCSTR lpLoadOrderGroup
,
364 LPCSTR lpDependencies
,
365 LPCSTR lpServiceStartName
,
368 SC_HANDLE RetVal
= NULL
;
369 LPWSTR lpServiceNameW
= NULL
;
370 LPWSTR lpDisplayNameW
= NULL
;
371 LPWSTR lpBinaryPathNameW
= NULL
;
372 LPWSTR lpLoadOrderGroupW
= NULL
;
373 LPWSTR lpDependenciesW
= NULL
;
374 LPWSTR lpServiceStartNameW
= NULL
;
375 LPWSTR lpPasswordW
= NULL
;
376 DWORD dwDependenciesLength
= 0;
380 int len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, NULL
, 0);
381 lpServiceNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
384 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
387 MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, lpServiceNameW
, len
);
389 len
= MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, NULL
, 0);
390 lpDisplayNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
393 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
396 MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, lpDisplayNameW
, len
);
398 len
= MultiByteToWideChar(CP_ACP
, 0, lpBinaryPathName
, -1, NULL
, 0);
399 lpBinaryPathNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
400 if (!lpBinaryPathNameW
)
402 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
405 MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, lpBinaryPathNameW
, len
);
407 len
= MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, NULL
, 0);
408 lpLoadOrderGroupW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
409 if (!lpLoadOrderGroupW
)
411 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
414 MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, lpLoadOrderGroupW
, len
);
416 if (lpDependencies
!= NULL
)
418 lpStr
= (LPSTR
)lpDependencies
;
421 dwLength
= strlen(lpStr
) + 1;
422 dwDependenciesLength
+= dwLength
;
423 lpStr
= lpStr
+ dwLength
;
425 dwDependenciesLength
++;
428 lpDependenciesW
= HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength
* sizeof(WCHAR
));
429 if (!lpDependenciesW
)
431 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
434 MultiByteToWideChar(CP_ACP
, 0, lpDependencies
, -1, lpDependenciesW
, dwDependenciesLength
);
436 len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, NULL
, 0);
437 lpServiceStartName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
438 if (!lpServiceStartNameW
)
440 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
443 MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, lpServiceStartNameW
, len
);
445 len
= MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, NULL
, 0);
446 lpPasswordW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
449 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
452 MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, lpPasswordW
, len
);
454 RetVal
= CreateServiceW(hSCManager
,
469 HeapFree(GetProcessHeap(), 0, lpServiceNameW
);
470 HeapFree(GetProcessHeap(), 0, lpDisplayNameW
);
471 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW
);
472 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW
);
473 HeapFree(GetProcessHeap(), 0, lpDependenciesW
);
474 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW
);
475 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
481 /**********************************************************************
487 CreateServiceW(SC_HANDLE hSCManager
,
488 LPCWSTR lpServiceName
,
489 LPCWSTR lpDisplayName
,
490 DWORD dwDesiredAccess
,
493 DWORD dwErrorControl
,
494 LPCWSTR lpBinaryPathName
,
495 LPCWSTR lpLoadOrderGroup
,
497 LPCWSTR lpDependencies
,
498 LPCWSTR lpServiceStartName
,
501 SC_HANDLE hService
= NULL
;
503 DWORD dwDependenciesLength
= 0;
507 DPRINT1("CreateServiceW() called\n");
509 /* Calculate the Dependencies length*/
510 if (lpDependencies
!= NULL
)
512 lpStr
= (LPWSTR
)lpDependencies
;
515 dwLength
= wcslen(lpStr
) + 1;
516 dwDependenciesLength
+= dwLength
;
517 lpStr
= lpStr
+ dwLength
;
519 dwDependenciesLength
++;
522 /* FIXME: Encrypt the password */
526 /* Call to services.exe using RPC */
527 dwError
= ScmrCreateServiceW(BindingHandle
,
528 (unsigned int)hSCManager
,
529 (LPWSTR
)lpServiceName
,
530 (LPWSTR
)lpDisplayName
,
535 (LPWSTR
)lpBinaryPathName
,
536 (LPWSTR
)lpLoadOrderGroup
,
538 (LPWSTR
)lpDependencies
,
539 dwDependenciesLength
,
540 (LPWSTR
)lpServiceStartName
,
541 NULL
, /* FIXME: lpPassword */
542 0, /* FIXME: dwPasswordLength */
543 (unsigned int *)&hService
);
544 if (dwError
!= ERROR_SUCCESS
)
546 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError
);
547 SetLastError(dwError
);
555 /**********************************************************************
561 DeleteService(SC_HANDLE hService
)
565 DPRINT("DeleteService(%x)\n", hService
);
569 /* Call to services.exe using RPC */
570 dwError
= ScmrDeleteService(BindingHandle
,
571 (unsigned int)hService
);
572 if (dwError
!= ERROR_SUCCESS
)
574 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError
);
575 SetLastError(dwError
);
583 /**********************************************************************
584 * EnumDependentServicesA
590 EnumDependentServicesA(
592 DWORD dwServiceState
,
593 LPENUM_SERVICE_STATUSA lpServices
,
595 LPDWORD pcbBytesNeeded
,
596 LPDWORD lpServicesReturned
)
598 DPRINT1("EnumDependentServicesA is unimplemented\n");
599 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
604 /**********************************************************************
605 * EnumDependentServicesW
611 EnumDependentServicesW(SC_HANDLE hService
,
612 DWORD dwServiceState
,
613 LPENUM_SERVICE_STATUSW lpServices
,
615 LPDWORD pcbBytesNeeded
,
616 LPDWORD lpServicesReturned
)
618 DPRINT1("EnumDependentServicesW is unimplemented\n");
619 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
624 /**********************************************************************
632 SC_HANDLE hSCManager
,
634 DWORD dwServiceState
,
635 LPENUM_SERVICE_STATUSA lpServices
,
637 LPDWORD pcbBytesNeeded
,
638 LPDWORD lpServicesReturned
,
639 LPDWORD lpResumeHandle
,
642 DPRINT1("EnumServiceGroupW is unimplemented\n");
643 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
648 /**********************************************************************
649 * EnumServicesStatusA
656 SC_HANDLE hSCManager
,
658 DWORD dwServiceState
,
659 LPENUM_SERVICE_STATUSA lpServices
,
661 LPDWORD pcbBytesNeeded
,
662 LPDWORD lpServicesReturned
,
663 LPDWORD lpResumeHandle
)
665 DPRINT1("EnumServicesStatusA is unimplemented\n");
666 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
671 /**********************************************************************
672 * EnumServicesStatusW
677 EnumServicesStatusW(SC_HANDLE hSCManager
,
679 DWORD dwServiceState
,
680 LPENUM_SERVICE_STATUSW lpServices
,
682 LPDWORD pcbBytesNeeded
,
683 LPDWORD lpServicesReturned
,
684 LPDWORD lpResumeHandle
)
686 LPENUM_SERVICE_STATUSW lpStatusPtr
;
687 DWORD dwError
= ERROR_SUCCESS
;
690 DPRINT("EnumServicesStatusW() called\n");
694 dwError
= ScmrEnumServicesStatusW(BindingHandle
,
695 (unsigned int)hSCManager
,
698 (unsigned char *)lpServices
,
704 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
705 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
707 if (lpStatusPtr
->lpServiceName
)
708 lpStatusPtr
->lpServiceName
=
709 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
711 if (lpStatusPtr
->lpDisplayName
)
712 lpStatusPtr
->lpDisplayName
=
713 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
718 if (dwError
!= ERROR_SUCCESS
)
720 DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError
);
721 SetLastError(dwError
);
725 DPRINT("ScmrEnumServicesStatusW() done\n");
731 /**********************************************************************
732 * EnumServicesStatusExA
738 EnumServicesStatusExA(SC_HANDLE hSCManager
,
739 SC_ENUM_TYPE InfoLevel
,
741 DWORD dwServiceState
,
744 LPDWORD pcbBytesNeeded
,
745 LPDWORD lpServicesReturned
,
746 LPDWORD lpResumeHandle
,
749 DPRINT1("EnumServicesStatusExA is unimplemented\n");
750 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
755 /**********************************************************************
756 * EnumServicesStatusExW
761 EnumServicesStatusExW(SC_HANDLE hSCManager
,
762 SC_ENUM_TYPE InfoLevel
,
764 DWORD dwServiceState
,
767 LPDWORD pcbBytesNeeded
,
768 LPDWORD lpServicesReturned
,
769 LPDWORD lpResumeHandle
,
770 LPCWSTR pszGroupName
)
772 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
773 DWORD dwError
= ERROR_SUCCESS
;
776 DPRINT1("EnumServicesStatusExW() called\n");
780 dwError
= ScmrEnumServicesStatusExW(BindingHandle
,
781 (unsigned int)hSCManager
,
782 (unsigned long)InfoLevel
,
785 (unsigned char *)lpServices
,
790 (wchar_t *)pszGroupName
);
792 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
793 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
795 if (lpStatusPtr
->lpServiceName
)
796 lpStatusPtr
->lpServiceName
=
797 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
799 if (lpStatusPtr
->lpDisplayName
)
800 lpStatusPtr
->lpDisplayName
=
801 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
806 if (dwError
!= ERROR_SUCCESS
)
808 DPRINT1("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError
);
809 SetLastError(dwError
);
813 DPRINT1("ScmrEnumServicesStatusExW() done\n");
819 /**********************************************************************
820 * GetServiceDisplayNameA
825 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
826 LPCSTR lpServiceName
,
832 DPRINT("GetServiceDisplayNameA() called\n");
836 dwError
= ScmrGetServiceDisplayNameA(BindingHandle
,
837 (unsigned int)hSCManager
,
838 (LPSTR
)lpServiceName
,
841 if (dwError
!= ERROR_SUCCESS
)
843 DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
844 SetLastError(dwError
);
854 /**********************************************************************
855 * GetServiceDisplayNameW
860 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
861 LPCWSTR lpServiceName
,
862 LPWSTR lpDisplayName
,
867 DPRINT("GetServiceDisplayNameW() called\n");
871 dwError
= ScmrGetServiceDisplayNameW(BindingHandle
,
872 (unsigned int)hSCManager
,
873 (LPWSTR
)lpServiceName
,
876 if (dwError
!= ERROR_SUCCESS
)
878 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
879 SetLastError(dwError
);
889 /**********************************************************************
895 GetServiceKeyNameA(SC_HANDLE hSCManager
,
896 LPCSTR lpDisplayName
,
902 DPRINT("GetServiceKeyNameA() called\n");
906 dwError
= ScmrGetServiceKeyNameA(BindingHandle
,
907 (unsigned int)hSCManager
,
908 (LPSTR
)lpDisplayName
,
911 if (dwError
!= ERROR_SUCCESS
)
913 DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
914 SetLastError(dwError
);
924 /**********************************************************************
930 GetServiceKeyNameW(SC_HANDLE hSCManager
,
931 LPCWSTR lpDisplayName
,
932 LPWSTR lpServiceName
,
937 DPRINT("GetServiceKeyNameW() called\n");
941 dwError
= ScmrGetServiceKeyNameW(BindingHandle
,
942 (unsigned int)hSCManager
,
943 (LPWSTR
)lpDisplayName
,
946 if (dwError
!= ERROR_SUCCESS
)
948 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
949 SetLastError(dwError
);
959 /**********************************************************************
960 * LockServiceDatabase
965 LockServiceDatabase(SC_HANDLE hSCManager
)
970 DPRINT("LockServiceDatabase(%x)\n", hSCManager
);
974 /* Call to services.exe using RPC */
975 dwError
= ScmrLockServiceDatabase(BindingHandle
,
976 (unsigned int)hSCManager
,
977 (unsigned int *)&hLock
);
978 if (dwError
!= ERROR_SUCCESS
)
980 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError
);
981 SetLastError(dwError
);
985 DPRINT("hLock = %p\n", hLock
);
992 WaitForSCManager(VOID
)
996 DPRINT("WaitForSCManager() called\n");
998 /* Try to open the existing event */
999 hEvent
= OpenEventW(SYNCHRONIZE
,
1001 L
"SvcctrlStartEvent_A3725DX");
1004 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1007 /* Try to create a new event */
1008 hEvent
= CreateEventW(NULL
,
1011 L
"SvcctrlStartEvent_A3725DX");
1014 /* Try to open the existing event again */
1015 hEvent
= OpenEventW(SYNCHRONIZE
,
1017 L
"SvcctrlStartEvent_A3725DX");
1023 /* Wait for 3 minutes */
1024 WaitForSingleObject(hEvent
, 180000);
1025 CloseHandle(hEvent
);
1027 DPRINT("ScmWaitForSCManager() done\n");
1031 /**********************************************************************
1037 OpenSCManagerA(LPCSTR lpMachineName
,
1038 LPCSTR lpDatabaseName
,
1039 DWORD dwDesiredAccess
)
1041 SC_HANDLE hScm
= NULL
;
1044 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
1045 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1051 /* Call to services.exe using RPC */
1052 dwError
= ScmrOpenSCManagerA(BindingHandle
,
1053 (LPSTR
)lpMachineName
,
1054 (LPSTR
)lpDatabaseName
,
1056 (unsigned int*)&hScm
);
1057 if (dwError
!= ERROR_SUCCESS
)
1059 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError
);
1060 SetLastError(dwError
);
1064 DPRINT("hScm = %p\n", hScm
);
1070 /**********************************************************************
1076 OpenSCManagerW(LPCWSTR lpMachineName
,
1077 LPCWSTR lpDatabaseName
,
1078 DWORD dwDesiredAccess
)
1080 SC_HANDLE hScm
= NULL
;
1083 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
1084 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1090 /* Call to services.exe using RPC */
1091 dwError
= ScmrOpenSCManagerW(BindingHandle
,
1092 (LPWSTR
)lpMachineName
,
1093 (LPWSTR
)lpDatabaseName
,
1095 (unsigned int*)&hScm
);
1096 if (dwError
!= ERROR_SUCCESS
)
1098 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError
);
1099 SetLastError(dwError
);
1103 DPRINT("hScm = %p\n", hScm
);
1109 /**********************************************************************
1115 OpenServiceA(SC_HANDLE hSCManager
,
1116 LPCSTR lpServiceName
,
1117 DWORD dwDesiredAccess
)
1119 SC_HANDLE hService
= NULL
;
1122 DPRINT("OpenServiceA(%p, %s, %lx)\n",
1123 hSCManager
, lpServiceName
, dwDesiredAccess
);
1127 /* Call to services.exe using RPC */
1128 dwError
= ScmrOpenServiceA(BindingHandle
,
1129 (unsigned int)hSCManager
,
1130 (LPSTR
)lpServiceName
,
1132 (unsigned int*)&hService
);
1133 if (dwError
!= ERROR_SUCCESS
)
1135 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError
);
1136 SetLastError(dwError
);
1140 DPRINT("hService = %p\n", hService
);
1146 /**********************************************************************
1152 OpenServiceW(SC_HANDLE hSCManager
,
1153 LPCWSTR lpServiceName
,
1154 DWORD dwDesiredAccess
)
1156 SC_HANDLE hService
= NULL
;
1159 DPRINT("OpenServiceW(%p, %S, %lx)\n",
1160 hSCManager
, lpServiceName
, dwDesiredAccess
);
1164 /* Call to services.exe using RPC */
1165 dwError
= ScmrOpenServiceW(BindingHandle
,
1166 (unsigned int)hSCManager
,
1167 (LPWSTR
)lpServiceName
,
1169 (unsigned int*)&hService
);
1170 if (dwError
!= ERROR_SUCCESS
)
1172 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError
);
1173 SetLastError(dwError
);
1177 DPRINT("hService = %p\n", hService
);
1183 /**********************************************************************
1184 * QueryServiceConfigA
1189 QueryServiceConfigA(SC_HANDLE hService
,
1190 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1192 LPDWORD pcbBytesNeeded
)
1196 DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1197 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1201 /* Call to services.exe using RPC */
1202 dwError
= ScmrQueryServiceConfigA(BindingHandle
,
1203 (unsigned int)hService
,
1204 (unsigned char *)lpServiceConfig
,
1207 if (dwError
!= ERROR_SUCCESS
)
1209 DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1210 SetLastError(dwError
);
1214 /* Adjust the pointers */
1215 if (lpServiceConfig
->lpBinaryPathName
)
1216 lpServiceConfig
->lpBinaryPathName
=
1217 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1218 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1220 if (lpServiceConfig
->lpLoadOrderGroup
)
1221 lpServiceConfig
->lpLoadOrderGroup
=
1222 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1223 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1225 if (lpServiceConfig
->lpDependencies
)
1226 lpServiceConfig
->lpDependencies
=
1227 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1228 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1230 if (lpServiceConfig
->lpServiceStartName
)
1231 lpServiceConfig
->lpServiceStartName
=
1232 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1233 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1235 if (lpServiceConfig
->lpDisplayName
)
1236 lpServiceConfig
->lpDisplayName
=
1237 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1238 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1240 DPRINT("QueryServiceConfigA() done\n");
1246 /**********************************************************************
1247 * QueryServiceConfigW
1252 QueryServiceConfigW(SC_HANDLE hService
,
1253 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1255 LPDWORD pcbBytesNeeded
)
1259 DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1260 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1264 /* Call to services.exe using RPC */
1265 dwError
= ScmrQueryServiceConfigW(BindingHandle
,
1266 (unsigned int)hService
,
1267 (unsigned char *)lpServiceConfig
,
1270 if (dwError
!= ERROR_SUCCESS
)
1272 DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1273 SetLastError(dwError
);
1277 /* Adjust the pointers */
1278 if (lpServiceConfig
->lpBinaryPathName
)
1279 lpServiceConfig
->lpBinaryPathName
=
1280 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1281 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1283 if (lpServiceConfig
->lpLoadOrderGroup
)
1284 lpServiceConfig
->lpLoadOrderGroup
=
1285 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1286 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1288 if (lpServiceConfig
->lpDependencies
)
1289 lpServiceConfig
->lpDependencies
=
1290 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1291 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1293 if (lpServiceConfig
->lpServiceStartName
)
1294 lpServiceConfig
->lpServiceStartName
=
1295 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1296 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1298 if (lpServiceConfig
->lpDisplayName
)
1299 lpServiceConfig
->lpDisplayName
=
1300 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1301 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1303 DPRINT("QueryServiceConfigW() done\n");
1309 /**********************************************************************
1310 * QueryServiceConfig2A
1316 QueryServiceConfig2A(
1321 LPDWORD pcbBytesNeeded
)
1323 DPRINT1("QueryServiceConfig2A is unimplemented\n");
1328 /**********************************************************************
1329 * QueryServiceConfig2W
1335 QueryServiceConfig2W(
1340 LPDWORD pcbBytesNeeded
)
1342 DPRINT1("QueryServiceConfig2W is unimplemented\n");
1347 /**********************************************************************
1348 * QueryServiceLockStatusA
1354 QueryServiceLockStatusA(
1355 SC_HANDLE hSCManager
,
1356 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
1358 LPDWORD pcbBytesNeeded
)
1360 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1361 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1366 /**********************************************************************
1367 * QueryServiceLockStatusW
1373 QueryServiceLockStatusW(
1374 SC_HANDLE hSCManager
,
1375 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
1377 LPDWORD pcbBytesNeeded
)
1379 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1380 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1385 /**********************************************************************
1386 * QueryServiceObjectSecurity
1391 QueryServiceObjectSecurity(SC_HANDLE hService
,
1392 SECURITY_INFORMATION dwSecurityInformation
,
1393 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
1395 LPDWORD pcbBytesNeeded
)
1399 DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
1400 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
1404 /* Call to services.exe using RPC */
1405 dwError
= ScmrQueryServiceObjectSecurity(BindingHandle
,
1406 (unsigned int)hService
,
1407 dwSecurityInformation
,
1408 (unsigned char *)lpSecurityDescriptor
,
1411 if (dwError
!= ERROR_SUCCESS
)
1413 DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
1414 SetLastError(dwError
);
1422 /**********************************************************************
1423 * QueryServiceStatus
1428 QueryServiceStatus(SC_HANDLE hService
,
1429 LPSERVICE_STATUS lpServiceStatus
)
1433 DPRINT("QueryServiceStatus(%p, %p)\n",
1434 hService
, lpServiceStatus
);
1438 /* Call to services.exe using RPC */
1439 dwError
= ScmrQueryServiceStatus(BindingHandle
,
1440 (unsigned int)hService
,
1442 if (dwError
!= ERROR_SUCCESS
)
1444 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError
);
1445 SetLastError(dwError
);
1453 /**********************************************************************
1454 * QueryServiceStatusEx
1459 QueryServiceStatusEx(SC_HANDLE hService
,
1460 SC_STATUS_TYPE InfoLevel
,
1463 LPDWORD pcbBytesNeeded
)
1467 DPRINT("QueryServiceStatusEx() called\n");
1471 /* Call to services.exe using RPC */
1472 dwError
= ScmrQueryServiceStatusEx(BindingHandle
,
1473 (unsigned int)hService
,
1478 if (dwError
!= ERROR_SUCCESS
)
1480 DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
1481 SetLastError(dwError
);
1489 /**********************************************************************
1490 * SetServiceObjectSecurity
1495 SetServiceObjectSecurity(SC_HANDLE hService
,
1496 SECURITY_INFORMATION dwSecurityInformation
,
1497 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
1499 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
1505 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
1508 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1510 SetLastError(ERROR_INVALID_PARAMETER
);
1514 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
1515 if (SelfRelativeSD
== NULL
)
1517 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1521 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
1524 if (!NT_SUCCESS(Status
))
1526 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
1527 SetLastError(RtlNtStatusToDosError(Status
));
1533 /* Call to services.exe using RPC */
1534 dwError
= ScmrSetServiceObjectSecurity(BindingHandle
,
1535 (unsigned int)hService
,
1536 dwSecurityInformation
,
1537 (unsigned char *)SelfRelativeSD
,
1540 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
1542 if (dwError
!= ERROR_SUCCESS
)
1544 DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError
);
1545 SetLastError(dwError
);
1553 /**********************************************************************
1562 DWORD dwNumServiceArgs
,
1563 LPCSTR
*lpServiceArgVectors
)
1565 DPRINT1("StartServiceA is unimplemented\n");
1566 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1571 /**********************************************************************
1580 DWORD dwNumServiceArgs
,
1581 LPCWSTR
*lpServiceArgVectors
)
1586 DPRINT("StartServiceW()\n");
1590 /* Call to services.exe using RPC */
1591 dwError
= ScmrStartServiceW(BindingHandle
,
1593 lpServiceArgVectors
);
1594 if (dwError
!= ERROR_SUCCESS
)
1596 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError
);
1597 SetLastError(dwError
);
1603 DPRINT1("StartServiceW is unimplemented, but returns success...\n");
1604 //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1610 /**********************************************************************
1611 * UnlockServiceDatabase
1616 UnlockServiceDatabase(SC_LOCK ScLock
)
1620 DPRINT("UnlockServiceDatabase(%x)\n", ScLock
);
1624 /* Call to services.exe using RPC */
1625 dwError
= ScmrUnlockServiceDatabase(BindingHandle
,
1626 (unsigned int)ScLock
);
1627 if (dwError
!= ERROR_SUCCESS
)
1629 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
1630 SetLastError(dwError
);
1638 /**********************************************************************
1639 * NotifyBootConfigStatus
1644 NotifyBootConfigStatus(BOOL BootAcceptable
)
1648 DPRINT1("NotifyBootConfigStatus()\n");
1652 /* Call to services.exe using RPC */
1653 dwError
= ScmrNotifyBootConfigStatus(BindingHandle
,
1655 if (dwError
!= ERROR_SUCCESS
)
1657 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
1658 SetLastError(dwError
);
1666 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
1668 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
1672 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
1674 HeapFree(GetProcessHeap(), 0, ptr
);