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 ******************************************************************/
17 #include "wine/debug.h"
19 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
22 /* FUNCTIONS *****************************************************************/
25 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName
)
27 handle_t hBinding
= NULL
;
28 UCHAR
*pszStringBinding
;
31 TRACE("SVCCTL_HANDLEA_bind() called\n");
33 status
= RpcStringBindingComposeA(NULL
,
35 (UCHAR
*)szMachineName
,
36 (UCHAR
*)"\\pipe\\ntsvcs",
38 (UCHAR
**)&pszStringBinding
);
39 if (status
!= RPC_S_OK
)
41 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
45 /* Set the binding handle that will be used to bind to the server. */
46 status
= RpcBindingFromStringBindingA(pszStringBinding
,
48 if (status
!= RPC_S_OK
)
50 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
53 status
= RpcStringFreeA(&pszStringBinding
);
54 if (status
!= RPC_S_OK
)
56 ERR("RpcStringFree returned 0x%x\n", status
);
64 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName
,
69 TRACE("SVCCTL_HANDLEA_unbind() called\n");
71 status
= RpcBindingFree(&hBinding
);
72 if (status
!= RPC_S_OK
)
74 ERR("RpcBindingFree returned 0x%x\n", status
);
80 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName
)
82 handle_t hBinding
= NULL
;
83 LPWSTR pszStringBinding
;
86 TRACE("SVCCTL_HANDLEW_bind() called\n");
88 status
= RpcStringBindingComposeW(NULL
,
94 if (status
!= RPC_S_OK
)
96 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
100 /* Set the binding handle that will be used to bind to the server. */
101 status
= RpcBindingFromStringBindingW(pszStringBinding
,
103 if (status
!= RPC_S_OK
)
105 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
108 status
= RpcStringFreeW(&pszStringBinding
);
109 if (status
!= RPC_S_OK
)
111 ERR("RpcStringFree returned 0x%x\n", status
);
119 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName
,
124 TRACE("SVCCTL_HANDLEW_unbind() called\n");
126 status
= RpcBindingFree(&hBinding
);
127 if (status
!= RPC_S_OK
)
129 ERR("RpcBindingFree returned 0x%x\n", status
);
135 RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus
)
137 handle_t hBinding
= NULL
;
138 LPWSTR pszStringBinding
;
141 TRACE("RPC_SERVICE_STATUS_HANDLE_bind() called\n");
143 status
= RpcStringBindingComposeW(NULL
,
149 if (status
!= RPC_S_OK
)
151 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
155 /* Set the binding handle that will be used to bind to the server. */
156 status
= RpcBindingFromStringBindingW(pszStringBinding
,
158 if (status
!= RPC_S_OK
)
160 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
163 status
= RpcStringFreeW(&pszStringBinding
);
164 if (status
!= RPC_S_OK
)
166 ERR("RpcStringFree returned 0x%x\n", status
);
174 RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus
,
179 TRACE("RPC_SERVICE_STATUS_HANDLE_unbind() called\n");
181 status
= RpcBindingFree(&hBinding
);
182 if (status
!= RPC_S_OK
)
184 ERR("RpcBindingFree returned 0x%x\n", status
);
190 ScmRpcStatusToWinError(RPC_STATUS Status
)
194 case RPC_S_INVALID_BINDING
:
195 case RPC_X_SS_IN_NULL_CONTEXT
:
196 return ERROR_INVALID_HANDLE
;
198 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
199 case RPC_X_BYTE_COUNT_TOO_SMALL
:
200 return ERROR_INVALID_PARAMETER
;
202 case RPC_X_NULL_REF_POINTER
:
203 return ERROR_INVALID_ADDRESS
;
206 return (DWORD
)Status
;
211 /**********************************************************************
212 * ChangeServiceConfig2A
217 ChangeServiceConfig2A(SC_HANDLE hService
,
221 SC_RPC_CONFIG_INFOA Info
;
224 TRACE("ChangeServiceConfig2A() called\n");
226 /* Fill relevent field of the Info structure */
227 Info
.dwInfoLevel
= dwInfoLevel
;
230 case SERVICE_CONFIG_DESCRIPTION
:
231 Info
.psd
= (LPSERVICE_DESCRIPTIONA
)&lpInfo
;
232 Info
.lpDescription
= ((LPSERVICE_DESCRIPTIONA
)lpInfo
)->lpDescription
; //HACK
235 case SERVICE_CONFIG_FAILURE_ACTIONS
:
236 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSA
)lpInfo
;
240 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
241 SetLastError(ERROR_INVALID_PARAMETER
);
250 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
253 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
255 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
259 if (dwError
!= ERROR_SUCCESS
)
261 ERR("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
262 SetLastError(dwError
);
270 /**********************************************************************
271 * ChangeServiceConfig2W
276 ChangeServiceConfig2W(SC_HANDLE hService
,
280 SC_RPC_CONFIG_INFOW Info
;
283 TRACE("ChangeServiceConfig2W() called\n");
285 /* Fill relevent field of the Info structure */
286 Info
.dwInfoLevel
= dwInfoLevel
;
289 case SERVICE_CONFIG_DESCRIPTION
:
291 Info
.psd
= (LPSERVICE_DESCRIPTIONW
)&lpInfo
;
295 case SERVICE_CONFIG_FAILURE_ACTIONS
:
296 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSW
)&lpInfo
;
300 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
301 SetLastError(ERROR_INVALID_PARAMETER
);
310 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
313 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
315 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
319 if (dwError
!= ERROR_SUCCESS
)
321 ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
322 SetLastError(dwError
);
330 /**********************************************************************
331 * ChangeServiceConfigA
336 ChangeServiceConfigA(SC_HANDLE hService
,
339 DWORD dwErrorControl
,
340 LPCSTR lpBinaryPathName
,
341 LPCSTR lpLoadOrderGroup
,
343 LPCSTR lpDependencies
,
344 LPCSTR lpServiceStartName
,
346 LPCSTR lpDisplayName
)
349 DWORD dwDependenciesLength
= 0;
353 TRACE("ChangeServiceConfigA() called\n");
355 /* Calculate the Dependencies length*/
356 if (lpDependencies
!= NULL
)
358 lpStr
= (LPSTR
)lpDependencies
;
361 dwLength
= strlen(lpStr
) + 1;
362 dwDependenciesLength
+= dwLength
;
363 lpStr
= lpStr
+ dwLength
;
365 dwDependenciesLength
++;
368 /* FIXME: Encrypt the password */
372 /* Call to services.exe using RPC */
373 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
377 (LPSTR
)lpBinaryPathName
,
378 (LPSTR
)lpLoadOrderGroup
,
380 (LPSTR
)lpDependencies
,
381 dwDependenciesLength
,
382 (LPSTR
)lpServiceStartName
,
383 NULL
, /* FIXME: lpPassword */
384 0, /* FIXME: dwPasswordLength */
385 (LPSTR
)lpDisplayName
);
387 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
389 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
393 if (dwError
!= ERROR_SUCCESS
)
395 ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
396 SetLastError(dwError
);
404 /**********************************************************************
405 * ChangeServiceConfigW
410 ChangeServiceConfigW(SC_HANDLE hService
,
413 DWORD dwErrorControl
,
414 LPCWSTR lpBinaryPathName
,
415 LPCWSTR lpLoadOrderGroup
,
417 LPCWSTR lpDependencies
,
418 LPCWSTR lpServiceStartName
,
420 LPCWSTR lpDisplayName
)
423 DWORD dwDependenciesLength
= 0;
427 TRACE("ChangeServiceConfigW() called\n");
429 /* Calculate the Dependencies length*/
430 if (lpDependencies
!= NULL
)
432 lpStr
= (LPWSTR
)lpDependencies
;
435 dwLength
= wcslen(lpStr
) + 1;
436 dwDependenciesLength
+= dwLength
;
437 lpStr
= lpStr
+ dwLength
;
439 dwDependenciesLength
++;
442 /* FIXME: Encrypt the password */
446 /* Call to services.exe using RPC */
447 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
451 (LPWSTR
)lpBinaryPathName
,
452 (LPWSTR
)lpLoadOrderGroup
,
454 (LPBYTE
)lpDependencies
,
455 dwDependenciesLength
,
456 (LPWSTR
)lpServiceStartName
,
457 NULL
, /* FIXME: lpPassword */
458 0, /* FIXME: dwPasswordLength */
459 (LPWSTR
)lpDisplayName
);
461 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
463 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
467 if (dwError
!= ERROR_SUCCESS
)
469 ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
470 SetLastError(dwError
);
478 /**********************************************************************
484 CloseServiceHandle(SC_HANDLE hSCObject
)
488 TRACE("CloseServiceHandle() called\n");
492 SetLastError(ERROR_INVALID_HANDLE
);
498 /* Call to services.exe using RPC */
499 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
501 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
503 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
509 ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
510 SetLastError(dwError
);
514 TRACE("CloseServiceHandle() done\n");
520 /**********************************************************************
526 ControlService(SC_HANDLE hService
,
528 LPSERVICE_STATUS lpServiceStatus
)
532 TRACE("ControlService(%x, %x, %p)\n",
533 hService
, dwControl
, lpServiceStatus
);
537 /* Call to services.exe using RPC */
538 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
542 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
544 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
548 if (dwError
!= ERROR_SUCCESS
)
550 ERR("RControlService() failed (Error %lu)\n", dwError
);
551 SetLastError(dwError
);
555 TRACE("ControlService() done\n");
561 /**********************************************************************
567 ControlServiceEx(IN SC_HANDLE hService
,
569 IN DWORD dwInfoLevel
,
570 IN OUT PVOID pControlParams
)
572 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
573 hService
, dwControl
, dwInfoLevel
, pControlParams
);
574 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
579 /**********************************************************************
585 CreateServiceA(SC_HANDLE hSCManager
,
586 LPCSTR lpServiceName
,
587 LPCSTR lpDisplayName
,
588 DWORD dwDesiredAccess
,
591 DWORD dwErrorControl
,
592 LPCSTR lpBinaryPathName
,
593 LPCSTR lpLoadOrderGroup
,
595 LPCSTR lpDependencies
,
596 LPCSTR lpServiceStartName
,
599 SC_HANDLE RetVal
= NULL
;
600 LPWSTR lpServiceNameW
= NULL
;
601 LPWSTR lpDisplayNameW
= NULL
;
602 LPWSTR lpBinaryPathNameW
= NULL
;
603 LPWSTR lpLoadOrderGroupW
= NULL
;
604 LPWSTR lpDependenciesW
= NULL
;
605 LPWSTR lpServiceStartNameW
= NULL
;
606 LPWSTR lpPasswordW
= NULL
;
607 DWORD dwDependenciesLength
= 0;
614 SetLastError(ERROR_INVALID_HANDLE
);
620 len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, NULL
, 0);
621 lpServiceNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
624 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
627 MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, lpServiceNameW
, len
);
632 len
= MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, NULL
, 0);
633 lpDisplayNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
636 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
639 MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, lpDisplayNameW
, len
);
642 if (lpBinaryPathName
)
644 len
= MultiByteToWideChar(CP_ACP
, 0, lpBinaryPathName
, -1, NULL
, 0);
645 lpBinaryPathNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
646 if (!lpBinaryPathNameW
)
648 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
651 MultiByteToWideChar(CP_ACP
, 0, lpBinaryPathName
, -1, lpBinaryPathNameW
, len
);
654 if (lpLoadOrderGroup
)
656 len
= MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, NULL
, 0);
657 lpLoadOrderGroupW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
658 if (!lpLoadOrderGroupW
)
660 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
663 MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, lpLoadOrderGroupW
, len
);
668 lpStr
= (LPSTR
)lpDependencies
;
671 dwLength
= strlen(lpStr
) + 1;
672 dwDependenciesLength
+= dwLength
;
673 lpStr
= lpStr
+ dwLength
;
675 dwDependenciesLength
++;
677 lpDependenciesW
= HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength
* sizeof(WCHAR
));
678 if (!lpDependenciesW
)
680 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
683 MultiByteToWideChar(CP_ACP
, 0, lpDependencies
, dwDependenciesLength
, lpDependenciesW
, dwDependenciesLength
);
686 if (lpServiceStartName
)
688 len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, NULL
, 0);
689 lpServiceStartNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
690 if (!lpServiceStartNameW
)
692 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
695 MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, lpServiceStartNameW
, len
);
700 len
= MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, NULL
, 0);
701 lpPasswordW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
704 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
707 MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, lpPasswordW
, len
);
710 RetVal
= CreateServiceW(hSCManager
,
725 if (lpServiceNameW
!=NULL
)
726 HeapFree(GetProcessHeap(), 0, lpServiceNameW
);
728 if (lpDisplayNameW
!= NULL
)
729 HeapFree(GetProcessHeap(), 0, lpDisplayNameW
);
731 if (lpBinaryPathNameW
!= NULL
)
732 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW
);
734 if (lpLoadOrderGroupW
!= NULL
)
735 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW
);
737 if (lpDependenciesW
!= NULL
)
738 HeapFree(GetProcessHeap(), 0, lpDependenciesW
);
740 if (lpServiceStartNameW
!= NULL
)
741 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW
);
743 if (lpPasswordW
!= NULL
)
744 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
750 /**********************************************************************
756 CreateServiceW(SC_HANDLE hSCManager
,
757 LPCWSTR lpServiceName
,
758 LPCWSTR lpDisplayName
,
759 DWORD dwDesiredAccess
,
762 DWORD dwErrorControl
,
763 LPCWSTR lpBinaryPathName
,
764 LPCWSTR lpLoadOrderGroup
,
766 LPCWSTR lpDependencies
,
767 LPCWSTR lpServiceStartName
,
770 SC_HANDLE hService
= NULL
;
771 DWORD dwDependenciesLength
= 0;
776 TRACE("CreateServiceW() called\n");
777 TRACE("%p %S %S\n", hSCManager
,
778 lpServiceName
, lpDisplayName
);
782 SetLastError(ERROR_INVALID_HANDLE
);
786 /* Calculate the Dependencies length*/
787 if (lpDependencies
!= NULL
)
789 lpStr
= (LPWSTR
)lpDependencies
;
792 dwLength
= wcslen(lpStr
) + 1;
793 dwDependenciesLength
+= dwLength
;
794 lpStr
= lpStr
+ dwLength
;
796 dwDependenciesLength
++;
798 dwDependenciesLength
*= sizeof(WCHAR
);
801 /* FIXME: Encrypt the password */
805 /* Call to services.exe using RPC */
806 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
816 (LPBYTE
)lpDependencies
,
817 dwDependenciesLength
,
819 NULL
, /* FIXME: lpPassword */
820 0, /* FIXME: dwPasswordLength */
821 (SC_RPC_HANDLE
*)&hService
);
823 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
825 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
829 if (dwError
!= ERROR_SUCCESS
)
831 ERR("RCreateServiceW() failed (Error %lu)\n", dwError
);
832 SetLastError(dwError
);
840 /**********************************************************************
846 DeleteService(SC_HANDLE hService
)
850 TRACE("DeleteService(%x)\n", hService
);
854 /* Call to services.exe using RPC */
855 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
857 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
859 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
863 if (dwError
!= ERROR_SUCCESS
)
865 ERR("RDeleteService() failed (Error %lu)\n", dwError
);
866 SetLastError(dwError
);
874 /**********************************************************************
875 * EnumDependentServicesA
880 EnumDependentServicesA(SC_HANDLE hService
,
881 DWORD dwServiceState
,
882 LPENUM_SERVICE_STATUSA lpServices
,
884 LPDWORD pcbBytesNeeded
,
885 LPDWORD lpServicesReturned
)
887 LPENUM_SERVICE_STATUSA lpStatusPtr
;
891 TRACE("EnumServicesStatusA() called\n");
895 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
902 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
904 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
908 if (dwError
!= ERROR_SUCCESS
)
910 ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
911 SetLastError(dwError
);
915 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
916 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
918 if (lpStatusPtr
->lpServiceName
)
919 lpStatusPtr
->lpServiceName
=
920 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
922 if (lpStatusPtr
->lpDisplayName
)
923 lpStatusPtr
->lpDisplayName
=
924 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
929 TRACE("EnumDependentServicesA() done\n");
935 /**********************************************************************
936 * EnumDependentServicesW
941 EnumDependentServicesW(SC_HANDLE hService
,
942 DWORD dwServiceState
,
943 LPENUM_SERVICE_STATUSW lpServices
,
945 LPDWORD pcbBytesNeeded
,
946 LPDWORD lpServicesReturned
)
948 LPENUM_SERVICE_STATUSW lpStatusPtr
;
952 TRACE("EnumServicesStatusW() called\n");
956 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
963 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
965 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
969 if (dwError
!= ERROR_SUCCESS
)
971 ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
972 SetLastError(dwError
);
976 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
977 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
979 if (lpStatusPtr
->lpServiceName
)
980 lpStatusPtr
->lpServiceName
=
981 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
983 if (lpStatusPtr
->lpDisplayName
)
984 lpStatusPtr
->lpDisplayName
=
985 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
990 TRACE("EnumDependentServicesW() done\n");
996 /**********************************************************************
1004 SC_HANDLE hSCManager
,
1005 DWORD dwServiceType
,
1006 DWORD dwServiceState
,
1007 LPENUM_SERVICE_STATUSW lpServices
,
1009 LPDWORD pcbBytesNeeded
,
1010 LPDWORD lpServicesReturned
,
1011 LPDWORD lpResumeHandle
,
1014 FIXME("EnumServiceGroupW is unimplemented\n");
1015 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1020 /**********************************************************************
1021 * EnumServicesStatusA
1026 EnumServicesStatusA(SC_HANDLE hSCManager
,
1027 DWORD dwServiceType
,
1028 DWORD dwServiceState
,
1029 LPENUM_SERVICE_STATUSA lpServices
,
1031 LPDWORD pcbBytesNeeded
,
1032 LPDWORD lpServicesReturned
,
1033 LPDWORD lpResumeHandle
)
1035 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1039 TRACE("EnumServicesStatusA() called\n");
1043 SetLastError(ERROR_INVALID_HANDLE
);
1047 if (dwServiceType
!= SERVICE_DRIVER
&& dwServiceType
!= SERVICE_WIN32
)
1049 if (pcbBytesNeeded
&& lpServicesReturned
)
1051 *pcbBytesNeeded
= 0;
1052 *lpServicesReturned
= 0;
1055 SetLastError(ERROR_INVALID_PARAMETER
);
1059 if (dwServiceState
!= SERVICE_ACTIVE
&& dwServiceState
!= SERVICE_INACTIVE
&& dwServiceState
!= SERVICE_STATE_ALL
)
1062 *pcbBytesNeeded
= 0;
1064 if (lpServicesReturned
)
1065 *lpServicesReturned
= 0;
1067 SetLastError(ERROR_INVALID_PARAMETER
);
1071 if (!pcbBytesNeeded
|| !lpServicesReturned
)
1073 SetLastError(ERROR_INVALID_ADDRESS
);
1077 if (!lpServices
&& cbBufSize
!= 0)
1079 SetLastError(ERROR_INVALID_ADDRESS
);
1085 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1094 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1096 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1100 if (dwError
!= ERROR_SUCCESS
)
1102 ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1103 SetLastError(dwError
);
1107 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
1108 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1110 if (lpStatusPtr
->lpServiceName
)
1111 lpStatusPtr
->lpServiceName
=
1112 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1114 if (lpStatusPtr
->lpDisplayName
)
1115 lpStatusPtr
->lpDisplayName
=
1116 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1121 TRACE("EnumServicesStatusA() done\n");
1127 /**********************************************************************
1128 * EnumServicesStatusW
1133 EnumServicesStatusW(SC_HANDLE hSCManager
,
1134 DWORD dwServiceType
,
1135 DWORD dwServiceState
,
1136 LPENUM_SERVICE_STATUSW lpServices
,
1138 LPDWORD pcbBytesNeeded
,
1139 LPDWORD lpServicesReturned
,
1140 LPDWORD lpResumeHandle
)
1142 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1146 TRACE("EnumServicesStatusW() called\n");
1150 SetLastError(ERROR_INVALID_HANDLE
);
1156 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1165 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1167 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1171 if (dwError
!= ERROR_SUCCESS
)
1173 ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1174 SetLastError(dwError
);
1178 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1179 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1181 if (lpStatusPtr
->lpServiceName
)
1182 lpStatusPtr
->lpServiceName
=
1183 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1185 if (lpStatusPtr
->lpDisplayName
)
1186 lpStatusPtr
->lpDisplayName
=
1187 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1192 TRACE("EnumServicesStatusW() done\n");
1198 /**********************************************************************
1199 * EnumServicesStatusExA
1204 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1205 SC_ENUM_TYPE InfoLevel
,
1206 DWORD dwServiceType
,
1207 DWORD dwServiceState
,
1210 LPDWORD pcbBytesNeeded
,
1211 LPDWORD lpServicesReturned
,
1212 LPDWORD lpResumeHandle
,
1213 LPCSTR pszGroupName
)
1215 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1219 TRACE("EnumServicesStatusExA() called\n");
1221 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1223 SetLastError(ERROR_INVALID_LEVEL
);
1229 SetLastError(ERROR_INVALID_HANDLE
);
1236 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1245 (LPSTR
)pszGroupName
);
1247 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1249 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1253 if (dwError
== ERROR_MORE_DATA
)
1255 WARN("Required buffer size %ul\n", *pcbBytesNeeded
);
1256 SetLastError(dwError
);
1259 else if (dwError
== ERROR_SUCCESS
)
1261 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1262 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1264 if (lpStatusPtr
->lpServiceName
)
1265 lpStatusPtr
->lpServiceName
=
1266 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1268 if (lpStatusPtr
->lpDisplayName
)
1269 lpStatusPtr
->lpDisplayName
=
1270 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1277 ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1278 SetLastError(dwError
);
1282 TRACE("EnumServicesStatusExA() done\n");
1288 /**********************************************************************
1289 * EnumServicesStatusExW
1294 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1295 SC_ENUM_TYPE InfoLevel
,
1296 DWORD dwServiceType
,
1297 DWORD dwServiceState
,
1300 LPDWORD pcbBytesNeeded
,
1301 LPDWORD lpServicesReturned
,
1302 LPDWORD lpResumeHandle
,
1303 LPCWSTR pszGroupName
)
1305 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1309 TRACE("EnumServicesStatusExW() called\n");
1313 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1322 (LPWSTR
)pszGroupName
);
1324 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1326 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1330 if (dwError
== ERROR_MORE_DATA
)
1332 WARN("Required buffer size %ul\n", *pcbBytesNeeded
);
1333 SetLastError(dwError
);
1336 else if (dwError
== ERROR_SUCCESS
)
1338 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1339 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1341 if (lpStatusPtr
->lpServiceName
)
1342 lpStatusPtr
->lpServiceName
=
1343 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1345 if (lpStatusPtr
->lpDisplayName
)
1346 lpStatusPtr
->lpDisplayName
=
1347 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1354 ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1355 SetLastError(dwError
);
1359 TRACE("EnumServicesStatusExW() done\n");
1365 /**********************************************************************
1366 * GetServiceDisplayNameA
1371 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1372 LPCSTR lpServiceName
,
1373 LPSTR lpDisplayName
,
1374 LPDWORD lpcchBuffer
)
1378 TRACE("GetServiceDisplayNameA() called\n");
1379 TRACE("%p %s %p %p\n", hSCManager
,
1380 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1384 SetLastError(ERROR_INVALID_HANDLE
);
1393 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1398 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1400 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1401 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1407 if (dwError
!= ERROR_SUCCESS
)
1409 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1410 SetLastError(dwError
);
1418 /**********************************************************************
1419 * GetServiceDisplayNameW
1424 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1425 LPCWSTR lpServiceName
,
1426 LPWSTR lpDisplayName
,
1427 LPDWORD lpcchBuffer
)
1431 TRACE("GetServiceDisplayNameW() called\n");
1435 SetLastError(ERROR_INVALID_HANDLE
);
1444 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1449 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1451 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1455 if (dwError
!= ERROR_SUCCESS
)
1457 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1458 SetLastError(dwError
);
1466 /**********************************************************************
1467 * GetServiceKeyNameA
1472 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1473 LPCSTR lpDisplayName
,
1474 LPSTR lpServiceName
,
1475 LPDWORD lpcchBuffer
)
1479 TRACE("GetServiceKeyNameA() called\n");
1483 SetLastError(ERROR_INVALID_HANDLE
);
1489 SetLastError(ERROR_INVALID_ADDRESS
);
1501 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1506 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1508 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1512 if (dwError
!= ERROR_SUCCESS
)
1514 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1515 SetLastError(dwError
);
1523 /**********************************************************************
1524 * GetServiceKeyNameW
1529 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1530 LPCWSTR lpDisplayName
,
1531 LPWSTR lpServiceName
,
1532 LPDWORD lpcchBuffer
)
1536 TRACE("GetServiceKeyNameW() called\n");
1540 SetLastError(ERROR_INVALID_HANDLE
);
1546 SetLastError(ERROR_INVALID_ADDRESS
);
1558 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1563 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1565 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1569 if (dwError
!= ERROR_SUCCESS
)
1571 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1572 SetLastError(dwError
);
1580 /**********************************************************************
1581 * LockServiceDatabase
1586 LockServiceDatabase(SC_HANDLE hSCManager
)
1591 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1595 /* Call to services.exe using RPC */
1596 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1597 (SC_RPC_LOCK
*)&hLock
);
1599 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1601 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1605 if (dwError
!= ERROR_SUCCESS
)
1607 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1608 SetLastError(dwError
);
1612 TRACE("hLock = %p\n", hLock
);
1619 WaitForSCManager(VOID
)
1623 TRACE("WaitForSCManager() called\n");
1625 /* Try to open the existing event */
1626 hEvent
= OpenEventW(SYNCHRONIZE
,
1628 L
"SvcctrlStartEvent_A3752DX");
1631 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1634 /* Try to create a new event */
1635 hEvent
= CreateEventW(NULL
,
1638 L
"SvcctrlStartEvent_A3752DX");
1641 /* Try to open the existing event again */
1642 hEvent
= OpenEventW(SYNCHRONIZE
,
1644 L
"SvcctrlStartEvent_A3752DX");
1650 /* Wait for 3 minutes */
1651 WaitForSingleObject(hEvent
, 180000);
1652 CloseHandle(hEvent
);
1654 TRACE("ScmWaitForSCManager() done\n");
1658 /**********************************************************************
1664 OpenSCManagerA(LPCSTR lpMachineName
,
1665 LPCSTR lpDatabaseName
,
1666 DWORD dwDesiredAccess
)
1668 SC_HANDLE hScm
= NULL
;
1671 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1672 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1678 /* Call to services.exe using RPC */
1679 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1680 (LPSTR
)lpDatabaseName
,
1682 (SC_RPC_HANDLE
*)&hScm
);
1684 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1686 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1690 if (dwError
!= ERROR_SUCCESS
)
1692 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1693 SetLastError(dwError
);
1697 TRACE("hScm = %p\n", hScm
);
1703 /**********************************************************************
1709 OpenSCManagerW(LPCWSTR lpMachineName
,
1710 LPCWSTR lpDatabaseName
,
1711 DWORD dwDesiredAccess
)
1713 SC_HANDLE hScm
= NULL
;
1716 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1717 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1723 /* Call to services.exe using RPC */
1724 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1725 (LPWSTR
)lpDatabaseName
,
1727 (SC_RPC_HANDLE
*)&hScm
);
1729 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1731 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1735 if (dwError
!= ERROR_SUCCESS
)
1737 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1738 SetLastError(dwError
);
1742 TRACE("hScm = %p\n", hScm
);
1748 /**********************************************************************
1754 OpenServiceA(SC_HANDLE hSCManager
,
1755 LPCSTR lpServiceName
,
1756 DWORD dwDesiredAccess
)
1758 SC_HANDLE hService
= NULL
;
1761 TRACE("OpenServiceA(%p, %s, %lx)\n",
1762 hSCManager
, lpServiceName
, dwDesiredAccess
);
1766 SetLastError(ERROR_INVALID_HANDLE
);
1772 /* Call to services.exe using RPC */
1773 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1774 (LPSTR
)lpServiceName
,
1776 (SC_RPC_HANDLE
*)&hService
);
1778 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1780 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1784 if (dwError
!= ERROR_SUCCESS
)
1786 ERR("ROpenServiceA() failed (Error %lu)\n", dwError
);
1787 SetLastError(dwError
);
1791 TRACE("hService = %p\n", hService
);
1797 /**********************************************************************
1803 OpenServiceW(SC_HANDLE hSCManager
,
1804 LPCWSTR lpServiceName
,
1805 DWORD dwDesiredAccess
)
1807 SC_HANDLE hService
= NULL
;
1810 TRACE("OpenServiceW(%p, %S, %lx)\n",
1811 hSCManager
, lpServiceName
, dwDesiredAccess
);
1815 SetLastError(ERROR_INVALID_HANDLE
);
1821 /* Call to services.exe using RPC */
1822 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1823 (LPWSTR
)lpServiceName
,
1825 (SC_RPC_HANDLE
*)&hService
);
1827 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1829 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1833 if (dwError
!= ERROR_SUCCESS
)
1835 if (dwError
== ERROR_SERVICE_DOES_NOT_EXIST
)
1836 WARN("ROpenServiceW() failed (Error %lu)\n", dwError
);
1838 ERR("ROpenServiceW() failed (Error %lu)\n", dwError
);
1839 SetLastError(dwError
);
1843 TRACE("hService = %p\n", hService
);
1849 /**********************************************************************
1850 * QueryServiceConfigA
1855 QueryServiceConfigA(SC_HANDLE hService
,
1856 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1858 LPDWORD pcbBytesNeeded
)
1862 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1863 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1867 /* Call to services.exe using RPC */
1868 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1869 (LPBYTE
)lpServiceConfig
,
1873 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1875 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1879 if (dwError
!= ERROR_SUCCESS
)
1881 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1882 SetLastError(dwError
);
1886 /* Adjust the pointers */
1887 if (lpServiceConfig
->lpBinaryPathName
)
1888 lpServiceConfig
->lpBinaryPathName
=
1889 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1890 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1892 if (lpServiceConfig
->lpLoadOrderGroup
)
1893 lpServiceConfig
->lpLoadOrderGroup
=
1894 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1895 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1897 if (lpServiceConfig
->lpDependencies
)
1898 lpServiceConfig
->lpDependencies
=
1899 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1900 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1902 if (lpServiceConfig
->lpServiceStartName
)
1903 lpServiceConfig
->lpServiceStartName
=
1904 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1905 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1907 if (lpServiceConfig
->lpDisplayName
)
1908 lpServiceConfig
->lpDisplayName
=
1909 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1910 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1912 TRACE("QueryServiceConfigA() done\n");
1918 /**********************************************************************
1919 * QueryServiceConfigW
1924 QueryServiceConfigW(SC_HANDLE hService
,
1925 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1927 LPDWORD pcbBytesNeeded
)
1931 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1932 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1936 /* Call to services.exe using RPC */
1937 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1938 (LPBYTE
)lpServiceConfig
,
1942 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1944 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1948 if (dwError
!= ERROR_SUCCESS
)
1950 if (dwError
== ERROR_INSUFFICIENT_BUFFER
)
1951 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1953 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1954 SetLastError(dwError
);
1958 /* Adjust the pointers */
1959 if (lpServiceConfig
->lpBinaryPathName
)
1960 lpServiceConfig
->lpBinaryPathName
=
1961 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1962 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1964 if (lpServiceConfig
->lpLoadOrderGroup
)
1965 lpServiceConfig
->lpLoadOrderGroup
=
1966 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1967 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1969 if (lpServiceConfig
->lpDependencies
)
1970 lpServiceConfig
->lpDependencies
=
1971 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1972 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1974 if (lpServiceConfig
->lpServiceStartName
)
1975 lpServiceConfig
->lpServiceStartName
=
1976 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1977 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1979 if (lpServiceConfig
->lpDisplayName
)
1980 lpServiceConfig
->lpDisplayName
=
1981 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1982 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1984 TRACE("QueryServiceConfigW() done\n");
1990 /**********************************************************************
1991 * QueryServiceConfig2A
1996 QueryServiceConfig2A(SC_HANDLE hService
,
2000 LPDWORD pcbBytesNeeded
)
2004 DbgPrint("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2005 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2007 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2008 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2010 SetLastError(ERROR_INVALID_LEVEL
);
2014 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2015 pcbBytesNeeded
== NULL
)
2017 SetLastError(ERROR_INVALID_ADDRESS
);
2023 /* Call to services.exe using RPC */
2024 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2030 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2032 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2036 if (dwError
!= ERROR_SUCCESS
)
2038 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2039 SetLastError(dwError
);
2043 switch (dwInfoLevel
)
2045 case SERVICE_CONFIG_DESCRIPTION
:
2047 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
2049 if (lpPtr
->lpDescription
!= NULL
)
2050 lpPtr
->lpDescription
=
2051 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2055 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2057 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
2059 if (lpPtr
->lpRebootMsg
!= NULL
)
2060 lpPtr
->lpRebootMsg
=
2061 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2063 if (lpPtr
->lpCommand
!= NULL
)
2065 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2067 if (lpPtr
->lpsaActions
!= NULL
)
2068 lpPtr
->lpsaActions
=
2069 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2074 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2075 SetLastError(ERROR_INVALID_PARAMETER
);
2079 TRACE("QueryServiceConfig2A() done\n");
2085 /**********************************************************************
2086 * QueryServiceConfig2W
2091 QueryServiceConfig2W(SC_HANDLE hService
,
2095 LPDWORD pcbBytesNeeded
)
2099 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2100 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2102 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2103 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2105 SetLastError(ERROR_INVALID_LEVEL
);
2109 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2110 pcbBytesNeeded
== NULL
)
2112 SetLastError(ERROR_INVALID_ADDRESS
);
2118 /* Call to services.exe using RPC */
2119 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2125 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2127 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2131 if (dwError
!= ERROR_SUCCESS
)
2133 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2134 SetLastError(dwError
);
2138 switch (dwInfoLevel
)
2140 case SERVICE_CONFIG_DESCRIPTION
:
2142 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2144 if (lpPtr
->lpDescription
!= NULL
)
2145 lpPtr
->lpDescription
=
2146 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2150 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2152 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2154 if (lpPtr
->lpRebootMsg
!= NULL
)
2155 lpPtr
->lpRebootMsg
=
2156 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2158 if (lpPtr
->lpCommand
!= NULL
)
2160 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2162 if (lpPtr
->lpsaActions
!= NULL
)
2163 lpPtr
->lpsaActions
=
2164 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2169 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2170 SetLastError(ERROR_INVALID_PARAMETER
);
2174 TRACE("QueryServiceConfig2W() done\n");
2180 /**********************************************************************
2181 * QueryServiceLockStatusA
2186 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2187 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2189 LPDWORD pcbBytesNeeded
)
2193 TRACE("QueryServiceLockStatusA() called\n");
2197 /* Call to services.exe using RPC */
2198 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2203 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2205 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2209 if (dwError
!= ERROR_SUCCESS
)
2211 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2212 SetLastError(dwError
);
2216 if (lpLockStatus
->lpLockOwner
!= NULL
)
2218 lpLockStatus
->lpLockOwner
=
2219 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2222 TRACE("QueryServiceLockStatusA() done\n");
2228 /**********************************************************************
2229 * QueryServiceLockStatusW
2234 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2235 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2237 LPDWORD pcbBytesNeeded
)
2241 TRACE("QueryServiceLockStatusW() called\n");
2245 /* Call to services.exe using RPC */
2246 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2251 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2253 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2257 if (dwError
!= ERROR_SUCCESS
)
2259 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2260 SetLastError(dwError
);
2264 if (lpLockStatus
->lpLockOwner
!= NULL
)
2266 lpLockStatus
->lpLockOwner
=
2267 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2270 TRACE("QueryServiceLockStatusW() done\n");
2276 /**********************************************************************
2277 * QueryServiceObjectSecurity
2282 QueryServiceObjectSecurity(SC_HANDLE hService
,
2283 SECURITY_INFORMATION dwSecurityInformation
,
2284 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2286 LPDWORD pcbBytesNeeded
)
2290 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2291 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2295 /* Call to services.exe using RPC */
2296 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2297 dwSecurityInformation
,
2298 (LPBYTE
)lpSecurityDescriptor
,
2302 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2304 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2308 if (dwError
!= ERROR_SUCCESS
)
2310 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2311 SetLastError(dwError
);
2318 /**********************************************************************
2319 * SetServiceObjectSecurity
2324 SetServiceObjectSecurity(SC_HANDLE hService
,
2325 SECURITY_INFORMATION dwSecurityInformation
,
2326 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2328 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2334 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2337 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2339 SetLastError(ERROR_INVALID_PARAMETER
);
2343 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2344 if (SelfRelativeSD
== NULL
)
2346 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2350 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2353 if (!NT_SUCCESS(Status
))
2355 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2356 SetLastError(RtlNtStatusToDosError(Status
));
2362 /* Call to services.exe using RPC */
2363 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2364 dwSecurityInformation
,
2365 (LPBYTE
)SelfRelativeSD
,
2368 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2370 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2374 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2376 if (dwError
!= ERROR_SUCCESS
)
2378 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2379 SetLastError(dwError
);
2387 /**********************************************************************
2388 * QueryServiceStatus
2393 QueryServiceStatus(SC_HANDLE hService
,
2394 LPSERVICE_STATUS lpServiceStatus
)
2398 TRACE("QueryServiceStatus(%p, %p)\n",
2399 hService
, lpServiceStatus
);
2403 SetLastError(ERROR_INVALID_HANDLE
);
2409 /* Call to services.exe using RPC */
2410 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2413 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2415 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2419 if (dwError
!= ERROR_SUCCESS
)
2421 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2422 SetLastError(dwError
);
2430 /**********************************************************************
2431 * QueryServiceStatusEx
2436 QueryServiceStatusEx(SC_HANDLE hService
,
2437 SC_STATUS_TYPE InfoLevel
,
2440 LPDWORD pcbBytesNeeded
)
2444 TRACE("QueryServiceStatusEx() called\n");
2446 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2448 SetLastError(ERROR_INVALID_LEVEL
);
2454 /* Call to services.exe using RPC */
2455 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2461 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2463 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2467 if (dwError
!= ERROR_SUCCESS
)
2469 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2470 SetLastError(dwError
);
2478 /**********************************************************************
2484 StartServiceA(SC_HANDLE hService
,
2485 DWORD dwNumServiceArgs
,
2486 LPCSTR
*lpServiceArgVectors
)
2492 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2494 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2496 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2498 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2502 if (dwError
!= ERROR_SUCCESS
)
2504 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2505 SetLastError(dwError
);
2513 /**********************************************************************
2519 StartServiceW(SC_HANDLE hService
,
2520 DWORD dwNumServiceArgs
,
2521 LPCWSTR
*lpServiceArgVectors
)
2527 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2529 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2531 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2533 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2537 if (dwError
!= ERROR_SUCCESS
)
2539 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2540 SetLastError(dwError
);
2548 /**********************************************************************
2549 * UnlockServiceDatabase
2554 UnlockServiceDatabase(SC_LOCK ScLock
)
2558 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2562 /* Call to services.exe using RPC */
2563 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2565 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2567 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2571 if (dwError
!= ERROR_SUCCESS
)
2573 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2574 SetLastError(dwError
);
2582 /**********************************************************************
2583 * NotifyBootConfigStatus
2588 NotifyBootConfigStatus(BOOL BootAcceptable
)
2592 TRACE("NotifyBootConfigStatus()\n");
2596 /* Call to services.exe using RPC */
2597 dwError
= RNotifyBootConfigStatus(NULL
,
2600 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2602 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2606 if (dwError
!= ERROR_SUCCESS
)
2608 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2609 SetLastError(dwError
);