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
:
290 Info
.psd
= (LPSERVICE_DESCRIPTIONW
)&lpInfo
;
293 case SERVICE_CONFIG_FAILURE_ACTIONS
:
294 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSW
)&lpInfo
;
298 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
299 SetLastError(ERROR_INVALID_PARAMETER
);
308 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
311 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
313 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
317 if (dwError
!= ERROR_SUCCESS
)
319 ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
320 SetLastError(dwError
);
328 /**********************************************************************
329 * ChangeServiceConfigA
334 ChangeServiceConfigA(SC_HANDLE hService
,
337 DWORD dwErrorControl
,
338 LPCSTR lpBinaryPathName
,
339 LPCSTR lpLoadOrderGroup
,
341 LPCSTR lpDependencies
,
342 LPCSTR lpServiceStartName
,
344 LPCSTR lpDisplayName
)
347 DWORD dwDependenciesLength
= 0;
351 TRACE("ChangeServiceConfigA() called\n");
353 /* Calculate the Dependencies length*/
354 if (lpDependencies
!= NULL
)
356 lpStr
= (LPSTR
)lpDependencies
;
359 dwLength
= strlen(lpStr
) + 1;
360 dwDependenciesLength
+= dwLength
;
361 lpStr
= lpStr
+ dwLength
;
363 dwDependenciesLength
++;
366 /* FIXME: Encrypt the password */
370 /* Call to services.exe using RPC */
371 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
375 (LPSTR
)lpBinaryPathName
,
376 (LPSTR
)lpLoadOrderGroup
,
378 (LPSTR
)lpDependencies
,
379 dwDependenciesLength
,
380 (LPSTR
)lpServiceStartName
,
381 NULL
, /* FIXME: lpPassword */
382 0, /* FIXME: dwPasswordLength */
383 (LPSTR
)lpDisplayName
);
385 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
387 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
391 if (dwError
!= ERROR_SUCCESS
)
393 ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
394 SetLastError(dwError
);
402 /**********************************************************************
403 * ChangeServiceConfigW
408 ChangeServiceConfigW(SC_HANDLE hService
,
411 DWORD dwErrorControl
,
412 LPCWSTR lpBinaryPathName
,
413 LPCWSTR lpLoadOrderGroup
,
415 LPCWSTR lpDependencies
,
416 LPCWSTR lpServiceStartName
,
418 LPCWSTR lpDisplayName
)
421 DWORD dwDependenciesLength
= 0;
425 TRACE("ChangeServiceConfigW() called\n");
427 /* Calculate the Dependencies length*/
428 if (lpDependencies
!= NULL
)
430 lpStr
= (LPWSTR
)lpDependencies
;
433 dwLength
= wcslen(lpStr
) + 1;
434 dwDependenciesLength
+= dwLength
;
435 lpStr
= lpStr
+ dwLength
;
437 dwDependenciesLength
++;
440 /* FIXME: Encrypt the password */
444 /* Call to services.exe using RPC */
445 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
449 (LPWSTR
)lpBinaryPathName
,
450 (LPWSTR
)lpLoadOrderGroup
,
452 (LPBYTE
)lpDependencies
,
453 dwDependenciesLength
,
454 (LPWSTR
)lpServiceStartName
,
455 NULL
, /* FIXME: lpPassword */
456 0, /* FIXME: dwPasswordLength */
457 (LPWSTR
)lpDisplayName
);
459 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
461 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
465 if (dwError
!= ERROR_SUCCESS
)
467 ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
468 SetLastError(dwError
);
476 /**********************************************************************
482 CloseServiceHandle(SC_HANDLE hSCObject
)
486 TRACE("CloseServiceHandle() called\n");
490 SetLastError(ERROR_INVALID_HANDLE
);
496 /* Call to services.exe using RPC */
497 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
499 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
501 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
507 ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
508 SetLastError(dwError
);
512 TRACE("CloseServiceHandle() done\n");
518 /**********************************************************************
524 ControlService(SC_HANDLE hService
,
526 LPSERVICE_STATUS lpServiceStatus
)
530 TRACE("ControlService(%x, %x, %p)\n",
531 hService
, dwControl
, lpServiceStatus
);
535 /* Call to services.exe using RPC */
536 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
540 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
542 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
546 if (dwError
!= ERROR_SUCCESS
)
548 ERR("RControlService() failed (Error %lu)\n", dwError
);
549 SetLastError(dwError
);
553 TRACE("ControlService() done\n");
559 /**********************************************************************
565 ControlServiceEx(IN SC_HANDLE hService
,
567 IN DWORD dwInfoLevel
,
568 IN OUT PVOID pControlParams
)
570 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
571 hService
, dwControl
, dwInfoLevel
, pControlParams
);
572 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
577 /**********************************************************************
583 CreateServiceA(SC_HANDLE hSCManager
,
584 LPCSTR lpServiceName
,
585 LPCSTR lpDisplayName
,
586 DWORD dwDesiredAccess
,
589 DWORD dwErrorControl
,
590 LPCSTR lpBinaryPathName
,
591 LPCSTR lpLoadOrderGroup
,
593 LPCSTR lpDependencies
,
594 LPCSTR lpServiceStartName
,
597 SC_HANDLE hService
= NULL
;
598 DWORD dwDependenciesLength
= 0;
603 TRACE("CreateServiceA() called\n");
604 TRACE("%p %s %s\n", hSCManager
,
605 lpServiceName
, lpDisplayName
);
609 SetLastError(ERROR_INVALID_HANDLE
);
613 /* Calculate the Dependencies length*/
614 if (lpDependencies
!= NULL
)
616 lpStr
= (LPSTR
)lpDependencies
;
619 dwLength
= strlen(lpStr
) + 1;
620 dwDependenciesLength
+= dwLength
;
621 lpStr
= lpStr
+ dwLength
;
623 dwDependenciesLength
++;
626 /* FIXME: Encrypt the password */
630 /* Call to services.exe using RPC */
631 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
632 (LPSTR
)lpServiceName
,
633 (LPSTR
)lpDisplayName
,
638 (LPSTR
)lpBinaryPathName
,
639 (LPSTR
)lpLoadOrderGroup
,
641 (LPBYTE
)lpDependencies
,
642 dwDependenciesLength
,
643 (LPSTR
)lpServiceStartName
,
644 NULL
, /* FIXME: lpPassword */
645 0, /* FIXME: dwPasswordLength */
646 (SC_RPC_HANDLE
*)&hService
);
648 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
650 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
654 if (dwError
!= ERROR_SUCCESS
)
656 ERR("RCreateServiceA() failed (Error %lu)\n", dwError
);
657 SetLastError(dwError
);
665 /**********************************************************************
671 CreateServiceW(SC_HANDLE hSCManager
,
672 LPCWSTR lpServiceName
,
673 LPCWSTR lpDisplayName
,
674 DWORD dwDesiredAccess
,
677 DWORD dwErrorControl
,
678 LPCWSTR lpBinaryPathName
,
679 LPCWSTR lpLoadOrderGroup
,
681 LPCWSTR lpDependencies
,
682 LPCWSTR lpServiceStartName
,
685 SC_HANDLE hService
= NULL
;
686 DWORD dwDependenciesLength
= 0;
691 TRACE("CreateServiceW() called\n");
692 TRACE("%p %S %S\n", hSCManager
,
693 lpServiceName
, lpDisplayName
);
697 SetLastError(ERROR_INVALID_HANDLE
);
701 /* Calculate the Dependencies length*/
702 if (lpDependencies
!= NULL
)
704 lpStr
= (LPWSTR
)lpDependencies
;
707 dwLength
= wcslen(lpStr
) + 1;
708 dwDependenciesLength
+= dwLength
;
709 lpStr
= lpStr
+ dwLength
;
711 dwDependenciesLength
++;
713 dwDependenciesLength
*= sizeof(WCHAR
);
716 /* FIXME: Encrypt the password */
720 /* Call to services.exe using RPC */
721 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
731 (LPBYTE
)lpDependencies
,
732 dwDependenciesLength
,
734 NULL
, /* FIXME: lpPassword */
735 0, /* FIXME: dwPasswordLength */
736 (SC_RPC_HANDLE
*)&hService
);
738 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
740 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
744 if (dwError
!= ERROR_SUCCESS
)
746 ERR("RCreateServiceW() failed (Error %lu)\n", dwError
);
747 SetLastError(dwError
);
755 /**********************************************************************
761 DeleteService(SC_HANDLE hService
)
765 TRACE("DeleteService(%x)\n", hService
);
769 /* Call to services.exe using RPC */
770 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
772 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
774 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
778 if (dwError
!= ERROR_SUCCESS
)
780 ERR("RDeleteService() failed (Error %lu)\n", dwError
);
781 SetLastError(dwError
);
789 /**********************************************************************
790 * EnumDependentServicesA
795 EnumDependentServicesA(SC_HANDLE hService
,
796 DWORD dwServiceState
,
797 LPENUM_SERVICE_STATUSA lpServices
,
799 LPDWORD pcbBytesNeeded
,
800 LPDWORD lpServicesReturned
)
802 LPENUM_SERVICE_STATUSA lpStatusPtr
;
806 TRACE("EnumServicesStatusA() called\n");
810 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
817 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
819 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
823 if (dwError
!= ERROR_SUCCESS
)
825 ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
826 SetLastError(dwError
);
830 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
831 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
833 if (lpStatusPtr
->lpServiceName
)
834 lpStatusPtr
->lpServiceName
=
835 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
837 if (lpStatusPtr
->lpDisplayName
)
838 lpStatusPtr
->lpDisplayName
=
839 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
844 TRACE("EnumDependentServicesA() done\n");
850 /**********************************************************************
851 * EnumDependentServicesW
856 EnumDependentServicesW(SC_HANDLE hService
,
857 DWORD dwServiceState
,
858 LPENUM_SERVICE_STATUSW lpServices
,
860 LPDWORD pcbBytesNeeded
,
861 LPDWORD lpServicesReturned
)
863 LPENUM_SERVICE_STATUSW lpStatusPtr
;
867 TRACE("EnumServicesStatusW() called\n");
871 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
878 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
880 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
884 if (dwError
!= ERROR_SUCCESS
)
886 ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
887 SetLastError(dwError
);
891 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
892 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
894 if (lpStatusPtr
->lpServiceName
)
895 lpStatusPtr
->lpServiceName
=
896 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
898 if (lpStatusPtr
->lpDisplayName
)
899 lpStatusPtr
->lpDisplayName
=
900 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
905 TRACE("EnumDependentServicesW() done\n");
911 /**********************************************************************
919 SC_HANDLE hSCManager
,
921 DWORD dwServiceState
,
922 LPENUM_SERVICE_STATUSW lpServices
,
924 LPDWORD pcbBytesNeeded
,
925 LPDWORD lpServicesReturned
,
926 LPDWORD lpResumeHandle
,
929 FIXME("EnumServiceGroupW is unimplemented\n");
930 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
935 /**********************************************************************
936 * EnumServicesStatusA
941 EnumServicesStatusA(SC_HANDLE hSCManager
,
943 DWORD dwServiceState
,
944 LPENUM_SERVICE_STATUSA lpServices
,
946 LPDWORD pcbBytesNeeded
,
947 LPDWORD lpServicesReturned
,
948 LPDWORD lpResumeHandle
)
950 LPENUM_SERVICE_STATUSA lpStatusPtr
;
954 TRACE("EnumServicesStatusA() called\n");
958 SetLastError(ERROR_INVALID_HANDLE
);
962 if (dwServiceType
!= SERVICE_DRIVER
&& dwServiceType
!= SERVICE_WIN32
)
964 if (pcbBytesNeeded
&& lpServicesReturned
)
967 *lpServicesReturned
= 0;
970 SetLastError(ERROR_INVALID_PARAMETER
);
974 if (dwServiceState
!= SERVICE_ACTIVE
&& dwServiceState
!= SERVICE_INACTIVE
&& dwServiceState
!= SERVICE_STATE_ALL
)
979 if (lpServicesReturned
)
980 *lpServicesReturned
= 0;
982 SetLastError(ERROR_INVALID_PARAMETER
);
986 if (!pcbBytesNeeded
|| !lpServicesReturned
)
988 SetLastError(ERROR_INVALID_ADDRESS
);
992 if (!lpServices
&& cbBufSize
!= 0)
994 SetLastError(ERROR_INVALID_ADDRESS
);
1000 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1009 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1011 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1015 if (dwError
!= ERROR_SUCCESS
)
1017 ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1018 SetLastError(dwError
);
1022 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
1023 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1025 if (lpStatusPtr
->lpServiceName
)
1026 lpStatusPtr
->lpServiceName
=
1027 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1029 if (lpStatusPtr
->lpDisplayName
)
1030 lpStatusPtr
->lpDisplayName
=
1031 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1036 TRACE("EnumServicesStatusA() done\n");
1042 /**********************************************************************
1043 * EnumServicesStatusW
1048 EnumServicesStatusW(SC_HANDLE hSCManager
,
1049 DWORD dwServiceType
,
1050 DWORD dwServiceState
,
1051 LPENUM_SERVICE_STATUSW lpServices
,
1053 LPDWORD pcbBytesNeeded
,
1054 LPDWORD lpServicesReturned
,
1055 LPDWORD lpResumeHandle
)
1057 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1061 TRACE("EnumServicesStatusW() called\n");
1065 SetLastError(ERROR_INVALID_HANDLE
);
1071 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1080 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1082 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1086 if (dwError
!= ERROR_SUCCESS
)
1088 ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1089 SetLastError(dwError
);
1093 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1094 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1096 if (lpStatusPtr
->lpServiceName
)
1097 lpStatusPtr
->lpServiceName
=
1098 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1100 if (lpStatusPtr
->lpDisplayName
)
1101 lpStatusPtr
->lpDisplayName
=
1102 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1107 TRACE("EnumServicesStatusW() done\n");
1113 /**********************************************************************
1114 * EnumServicesStatusExA
1119 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1120 SC_ENUM_TYPE InfoLevel
,
1121 DWORD dwServiceType
,
1122 DWORD dwServiceState
,
1125 LPDWORD pcbBytesNeeded
,
1126 LPDWORD lpServicesReturned
,
1127 LPDWORD lpResumeHandle
,
1128 LPCSTR pszGroupName
)
1130 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1134 TRACE("EnumServicesStatusExA() called\n");
1136 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1138 SetLastError(ERROR_INVALID_LEVEL
);
1144 SetLastError(ERROR_INVALID_HANDLE
);
1151 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1160 (LPSTR
)pszGroupName
);
1162 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1164 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1168 if (dwError
== ERROR_MORE_DATA
)
1170 WARN("Required buffer size %ul\n", *pcbBytesNeeded
);
1171 SetLastError(dwError
);
1174 else if (dwError
== ERROR_SUCCESS
)
1176 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1177 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1179 if (lpStatusPtr
->lpServiceName
)
1180 lpStatusPtr
->lpServiceName
=
1181 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1183 if (lpStatusPtr
->lpDisplayName
)
1184 lpStatusPtr
->lpDisplayName
=
1185 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1192 ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1193 SetLastError(dwError
);
1197 TRACE("EnumServicesStatusExA() done\n");
1203 /**********************************************************************
1204 * EnumServicesStatusExW
1209 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1210 SC_ENUM_TYPE InfoLevel
,
1211 DWORD dwServiceType
,
1212 DWORD dwServiceState
,
1215 LPDWORD pcbBytesNeeded
,
1216 LPDWORD lpServicesReturned
,
1217 LPDWORD lpResumeHandle
,
1218 LPCWSTR pszGroupName
)
1220 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1224 TRACE("EnumServicesStatusExW() called\n");
1228 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1237 (LPWSTR
)pszGroupName
);
1239 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1241 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1245 if (dwError
== ERROR_MORE_DATA
)
1247 WARN("Required buffer size %ul\n", *pcbBytesNeeded
);
1248 SetLastError(dwError
);
1251 else if (dwError
== ERROR_SUCCESS
)
1253 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1254 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1256 if (lpStatusPtr
->lpServiceName
)
1257 lpStatusPtr
->lpServiceName
=
1258 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1260 if (lpStatusPtr
->lpDisplayName
)
1261 lpStatusPtr
->lpDisplayName
=
1262 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1269 ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1270 SetLastError(dwError
);
1274 TRACE("EnumServicesStatusExW() done\n");
1280 /**********************************************************************
1281 * GetServiceDisplayNameA
1286 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1287 LPCSTR lpServiceName
,
1288 LPSTR lpDisplayName
,
1289 LPDWORD lpcchBuffer
)
1293 CHAR szEmptyName
[] = "";
1295 TRACE("GetServiceDisplayNameA() called\n");
1296 TRACE("%p %s %p %p\n", hSCManager
,
1297 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1301 SetLastError(ERROR_INVALID_HANDLE
);
1305 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1307 lpNameBuffer
= szEmptyName
;
1308 *lpcchBuffer
= sizeof(CHAR
);
1312 lpNameBuffer
= lpDisplayName
;
1317 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1322 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1324 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1325 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1329 if (dwError
!= ERROR_SUCCESS
)
1331 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1332 SetLastError(dwError
);
1340 /**********************************************************************
1341 * GetServiceDisplayNameW
1346 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1347 LPCWSTR lpServiceName
,
1348 LPWSTR lpDisplayName
,
1349 LPDWORD lpcchBuffer
)
1352 LPWSTR lpNameBuffer
;
1353 WCHAR szEmptyName
[] = L
"";
1355 TRACE("GetServiceDisplayNameW() called\n");
1359 SetLastError(ERROR_INVALID_HANDLE
);
1363 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1365 lpNameBuffer
= szEmptyName
;
1366 *lpcchBuffer
= sizeof(WCHAR
);
1370 lpNameBuffer
= lpDisplayName
;
1375 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1380 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1382 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1386 if (dwError
!= ERROR_SUCCESS
)
1388 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1389 SetLastError(dwError
);
1397 /**********************************************************************
1398 * GetServiceKeyNameA
1403 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1404 LPCSTR lpDisplayName
,
1405 LPSTR lpServiceName
,
1406 LPDWORD lpcchBuffer
)
1410 CHAR szEmptyName
[] = "";
1412 TRACE("GetServiceKeyNameA() called\n");
1416 SetLastError(ERROR_INVALID_HANDLE
);
1420 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1422 lpNameBuffer
= szEmptyName
;
1423 *lpcchBuffer
= sizeof(CHAR
);
1427 lpNameBuffer
= lpServiceName
;
1432 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1437 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1439 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1443 if (dwError
!= ERROR_SUCCESS
)
1445 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1446 SetLastError(dwError
);
1454 /**********************************************************************
1455 * GetServiceKeyNameW
1460 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1461 LPCWSTR lpDisplayName
,
1462 LPWSTR lpServiceName
,
1463 LPDWORD lpcchBuffer
)
1466 LPWSTR lpNameBuffer
;
1467 WCHAR szEmptyName
[] = L
"";
1469 TRACE("GetServiceKeyNameW() called\n");
1473 SetLastError(ERROR_INVALID_HANDLE
);
1477 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1479 lpNameBuffer
= szEmptyName
;
1480 *lpcchBuffer
= sizeof(WCHAR
);
1484 lpNameBuffer
= lpServiceName
;
1489 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1494 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1496 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1500 if (dwError
!= ERROR_SUCCESS
)
1502 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1503 SetLastError(dwError
);
1511 /**********************************************************************
1512 * LockServiceDatabase
1517 LockServiceDatabase(SC_HANDLE hSCManager
)
1522 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1526 /* Call to services.exe using RPC */
1527 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1528 (SC_RPC_LOCK
*)&hLock
);
1530 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1532 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1536 if (dwError
!= ERROR_SUCCESS
)
1538 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1539 SetLastError(dwError
);
1543 TRACE("hLock = %p\n", hLock
);
1550 WaitForSCManager(VOID
)
1554 TRACE("WaitForSCManager() called\n");
1556 /* Try to open the existing event */
1557 hEvent
= OpenEventW(SYNCHRONIZE
,
1559 L
"SvcctrlStartEvent_A3752DX");
1562 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1565 /* Try to create a new event */
1566 hEvent
= CreateEventW(NULL
,
1569 L
"SvcctrlStartEvent_A3752DX");
1572 /* Try to open the existing event again */
1573 hEvent
= OpenEventW(SYNCHRONIZE
,
1575 L
"SvcctrlStartEvent_A3752DX");
1581 /* Wait for 3 minutes */
1582 WaitForSingleObject(hEvent
, 180000);
1583 CloseHandle(hEvent
);
1585 TRACE("ScmWaitForSCManager() done\n");
1589 /**********************************************************************
1595 OpenSCManagerA(LPCSTR lpMachineName
,
1596 LPCSTR lpDatabaseName
,
1597 DWORD dwDesiredAccess
)
1599 SC_HANDLE hScm
= NULL
;
1602 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1603 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1609 /* Call to services.exe using RPC */
1610 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1611 (LPSTR
)lpDatabaseName
,
1613 (SC_RPC_HANDLE
*)&hScm
);
1615 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1617 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1621 if (dwError
!= ERROR_SUCCESS
)
1623 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1624 SetLastError(dwError
);
1628 TRACE("hScm = %p\n", hScm
);
1634 /**********************************************************************
1640 OpenSCManagerW(LPCWSTR lpMachineName
,
1641 LPCWSTR lpDatabaseName
,
1642 DWORD dwDesiredAccess
)
1644 SC_HANDLE hScm
= NULL
;
1647 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1648 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1654 /* Call to services.exe using RPC */
1655 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1656 (LPWSTR
)lpDatabaseName
,
1658 (SC_RPC_HANDLE
*)&hScm
);
1660 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1662 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1666 if (dwError
!= ERROR_SUCCESS
)
1668 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1669 SetLastError(dwError
);
1673 TRACE("hScm = %p\n", hScm
);
1679 /**********************************************************************
1685 OpenServiceA(SC_HANDLE hSCManager
,
1686 LPCSTR lpServiceName
,
1687 DWORD dwDesiredAccess
)
1689 SC_HANDLE hService
= NULL
;
1692 TRACE("OpenServiceA(%p, %s, %lx)\n",
1693 hSCManager
, lpServiceName
, dwDesiredAccess
);
1697 SetLastError(ERROR_INVALID_HANDLE
);
1703 /* Call to services.exe using RPC */
1704 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1705 (LPSTR
)lpServiceName
,
1707 (SC_RPC_HANDLE
*)&hService
);
1709 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1711 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1715 if (dwError
!= ERROR_SUCCESS
)
1717 ERR("ROpenServiceA() failed (Error %lu)\n", dwError
);
1718 SetLastError(dwError
);
1722 TRACE("hService = %p\n", hService
);
1728 /**********************************************************************
1734 OpenServiceW(SC_HANDLE hSCManager
,
1735 LPCWSTR lpServiceName
,
1736 DWORD dwDesiredAccess
)
1738 SC_HANDLE hService
= NULL
;
1741 TRACE("OpenServiceW(%p, %S, %lx)\n",
1742 hSCManager
, lpServiceName
, dwDesiredAccess
);
1746 SetLastError(ERROR_INVALID_HANDLE
);
1752 /* Call to services.exe using RPC */
1753 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1754 (LPWSTR
)lpServiceName
,
1756 (SC_RPC_HANDLE
*)&hService
);
1758 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1760 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1764 if (dwError
!= ERROR_SUCCESS
)
1766 if (dwError
== ERROR_SERVICE_DOES_NOT_EXIST
)
1767 WARN("ROpenServiceW() failed (Error %lu)\n", dwError
);
1769 ERR("ROpenServiceW() failed (Error %lu)\n", dwError
);
1770 SetLastError(dwError
);
1774 TRACE("hService = %p\n", hService
);
1780 /**********************************************************************
1781 * QueryServiceConfigA
1786 QueryServiceConfigA(SC_HANDLE hService
,
1787 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1789 LPDWORD pcbBytesNeeded
)
1793 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1794 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1798 /* Call to services.exe using RPC */
1799 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1800 (LPBYTE
)lpServiceConfig
,
1804 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1806 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1810 if (dwError
!= ERROR_SUCCESS
)
1812 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1813 SetLastError(dwError
);
1817 /* Adjust the pointers */
1818 if (lpServiceConfig
->lpBinaryPathName
)
1819 lpServiceConfig
->lpBinaryPathName
=
1820 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1821 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1823 if (lpServiceConfig
->lpLoadOrderGroup
)
1824 lpServiceConfig
->lpLoadOrderGroup
=
1825 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1826 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1828 if (lpServiceConfig
->lpDependencies
)
1829 lpServiceConfig
->lpDependencies
=
1830 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1831 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1833 if (lpServiceConfig
->lpServiceStartName
)
1834 lpServiceConfig
->lpServiceStartName
=
1835 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1836 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1838 if (lpServiceConfig
->lpDisplayName
)
1839 lpServiceConfig
->lpDisplayName
=
1840 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1841 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1843 TRACE("QueryServiceConfigA() done\n");
1849 /**********************************************************************
1850 * QueryServiceConfigW
1855 QueryServiceConfigW(SC_HANDLE hService
,
1856 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1858 LPDWORD pcbBytesNeeded
)
1862 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1863 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1867 /* Call to services.exe using RPC */
1868 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1869 (LPBYTE
)lpServiceConfig
,
1873 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1875 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1879 if (dwError
!= ERROR_SUCCESS
)
1881 if (dwError
== ERROR_INSUFFICIENT_BUFFER
)
1882 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1884 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1885 SetLastError(dwError
);
1889 /* Adjust the pointers */
1890 if (lpServiceConfig
->lpBinaryPathName
)
1891 lpServiceConfig
->lpBinaryPathName
=
1892 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1893 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1895 if (lpServiceConfig
->lpLoadOrderGroup
)
1896 lpServiceConfig
->lpLoadOrderGroup
=
1897 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1898 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1900 if (lpServiceConfig
->lpDependencies
)
1901 lpServiceConfig
->lpDependencies
=
1902 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1903 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1905 if (lpServiceConfig
->lpServiceStartName
)
1906 lpServiceConfig
->lpServiceStartName
=
1907 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1908 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1910 if (lpServiceConfig
->lpDisplayName
)
1911 lpServiceConfig
->lpDisplayName
=
1912 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1913 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1915 TRACE("QueryServiceConfigW() done\n");
1921 /**********************************************************************
1922 * QueryServiceConfig2A
1927 QueryServiceConfig2A(SC_HANDLE hService
,
1931 LPDWORD pcbBytesNeeded
)
1935 DbgPrint("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
1936 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
1938 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
1939 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
1941 SetLastError(ERROR_INVALID_LEVEL
);
1945 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
1946 pcbBytesNeeded
== NULL
)
1948 SetLastError(ERROR_INVALID_ADDRESS
);
1954 /* Call to services.exe using RPC */
1955 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
1961 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1963 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1967 if (dwError
!= ERROR_SUCCESS
)
1969 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
1970 SetLastError(dwError
);
1974 switch (dwInfoLevel
)
1976 case SERVICE_CONFIG_DESCRIPTION
:
1978 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
1980 if (lpPtr
->lpDescription
!= NULL
)
1981 lpPtr
->lpDescription
=
1982 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
1986 case SERVICE_CONFIG_FAILURE_ACTIONS
:
1988 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
1990 if (lpPtr
->lpRebootMsg
!= NULL
)
1991 lpPtr
->lpRebootMsg
=
1992 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
1994 if (lpPtr
->lpCommand
!= NULL
)
1996 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
1998 if (lpPtr
->lpsaActions
!= NULL
)
1999 lpPtr
->lpsaActions
=
2000 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2005 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2006 SetLastError(ERROR_INVALID_PARAMETER
);
2010 TRACE("QueryServiceConfig2A() done\n");
2016 /**********************************************************************
2017 * QueryServiceConfig2W
2022 QueryServiceConfig2W(SC_HANDLE hService
,
2026 LPDWORD pcbBytesNeeded
)
2030 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2031 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2033 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2034 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2036 SetLastError(ERROR_INVALID_LEVEL
);
2040 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2041 pcbBytesNeeded
== NULL
)
2043 SetLastError(ERROR_INVALID_ADDRESS
);
2049 /* Call to services.exe using RPC */
2050 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2056 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2058 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2062 if (dwError
!= ERROR_SUCCESS
)
2064 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2065 SetLastError(dwError
);
2069 switch (dwInfoLevel
)
2071 case SERVICE_CONFIG_DESCRIPTION
:
2073 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2075 if (lpPtr
->lpDescription
!= NULL
)
2076 lpPtr
->lpDescription
=
2077 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2081 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2083 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2085 if (lpPtr
->lpRebootMsg
!= NULL
)
2086 lpPtr
->lpRebootMsg
=
2087 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2089 if (lpPtr
->lpCommand
!= NULL
)
2091 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2093 if (lpPtr
->lpsaActions
!= NULL
)
2094 lpPtr
->lpsaActions
=
2095 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2100 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2101 SetLastError(ERROR_INVALID_PARAMETER
);
2105 TRACE("QueryServiceConfig2W() done\n");
2111 /**********************************************************************
2112 * QueryServiceLockStatusA
2117 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2118 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2120 LPDWORD pcbBytesNeeded
)
2124 TRACE("QueryServiceLockStatusA() called\n");
2128 /* Call to services.exe using RPC */
2129 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2134 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2136 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2140 if (dwError
!= ERROR_SUCCESS
)
2142 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2143 SetLastError(dwError
);
2147 if (lpLockStatus
->lpLockOwner
!= NULL
)
2149 lpLockStatus
->lpLockOwner
=
2150 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2153 TRACE("QueryServiceLockStatusA() done\n");
2159 /**********************************************************************
2160 * QueryServiceLockStatusW
2165 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2166 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2168 LPDWORD pcbBytesNeeded
)
2172 TRACE("QueryServiceLockStatusW() called\n");
2176 /* Call to services.exe using RPC */
2177 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2182 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2184 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2188 if (dwError
!= ERROR_SUCCESS
)
2190 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2191 SetLastError(dwError
);
2195 if (lpLockStatus
->lpLockOwner
!= NULL
)
2197 lpLockStatus
->lpLockOwner
=
2198 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2201 TRACE("QueryServiceLockStatusW() done\n");
2207 /**********************************************************************
2208 * QueryServiceObjectSecurity
2213 QueryServiceObjectSecurity(SC_HANDLE hService
,
2214 SECURITY_INFORMATION dwSecurityInformation
,
2215 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2217 LPDWORD pcbBytesNeeded
)
2221 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2222 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2226 /* Call to services.exe using RPC */
2227 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2228 dwSecurityInformation
,
2229 (LPBYTE
)lpSecurityDescriptor
,
2233 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2235 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2239 if (dwError
!= ERROR_SUCCESS
)
2241 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2242 SetLastError(dwError
);
2249 /**********************************************************************
2250 * SetServiceObjectSecurity
2255 SetServiceObjectSecurity(SC_HANDLE hService
,
2256 SECURITY_INFORMATION dwSecurityInformation
,
2257 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2259 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2265 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2268 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2270 SetLastError(ERROR_INVALID_PARAMETER
);
2274 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2275 if (SelfRelativeSD
== NULL
)
2277 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2281 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2284 if (!NT_SUCCESS(Status
))
2286 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2287 SetLastError(RtlNtStatusToDosError(Status
));
2293 /* Call to services.exe using RPC */
2294 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2295 dwSecurityInformation
,
2296 (LPBYTE
)SelfRelativeSD
,
2299 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2301 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2305 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2307 if (dwError
!= ERROR_SUCCESS
)
2309 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2310 SetLastError(dwError
);
2318 /**********************************************************************
2319 * QueryServiceStatus
2324 QueryServiceStatus(SC_HANDLE hService
,
2325 LPSERVICE_STATUS lpServiceStatus
)
2329 TRACE("QueryServiceStatus(%p, %p)\n",
2330 hService
, lpServiceStatus
);
2334 SetLastError(ERROR_INVALID_HANDLE
);
2340 /* Call to services.exe using RPC */
2341 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2344 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2346 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2350 if (dwError
!= ERROR_SUCCESS
)
2352 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2353 SetLastError(dwError
);
2361 /**********************************************************************
2362 * QueryServiceStatusEx
2367 QueryServiceStatusEx(SC_HANDLE hService
,
2368 SC_STATUS_TYPE InfoLevel
,
2371 LPDWORD pcbBytesNeeded
)
2375 TRACE("QueryServiceStatusEx() called\n");
2377 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2379 SetLastError(ERROR_INVALID_LEVEL
);
2385 /* Call to services.exe using RPC */
2386 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2392 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2394 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2398 if (dwError
!= ERROR_SUCCESS
)
2400 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2401 SetLastError(dwError
);
2409 /**********************************************************************
2415 StartServiceA(SC_HANDLE hService
,
2416 DWORD dwNumServiceArgs
,
2417 LPCSTR
*lpServiceArgVectors
)
2423 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2425 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2427 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2429 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2433 if (dwError
!= ERROR_SUCCESS
)
2435 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2436 SetLastError(dwError
);
2444 /**********************************************************************
2450 StartServiceW(SC_HANDLE hService
,
2451 DWORD dwNumServiceArgs
,
2452 LPCWSTR
*lpServiceArgVectors
)
2458 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2460 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2462 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2464 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2468 if (dwError
!= ERROR_SUCCESS
)
2470 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2471 SetLastError(dwError
);
2479 /**********************************************************************
2480 * UnlockServiceDatabase
2485 UnlockServiceDatabase(SC_LOCK ScLock
)
2489 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2493 /* Call to services.exe using RPC */
2494 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2496 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2498 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2502 if (dwError
!= ERROR_SUCCESS
)
2504 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2505 SetLastError(dwError
);
2513 /**********************************************************************
2514 * NotifyBootConfigStatus
2519 NotifyBootConfigStatus(BOOL BootAcceptable
)
2523 TRACE("NotifyBootConfigStatus()\n");
2527 /* Call to services.exe using RPC */
2528 dwError
= RNotifyBootConfigStatus(NULL
,
2531 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2533 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2537 if (dwError
!= ERROR_SUCCESS
)
2539 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2540 SetLastError(dwError
);