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
|| dwError
== ERROR_MORE_DATA
)
825 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
826 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
828 if (lpStatusPtr
->lpServiceName
)
829 lpStatusPtr
->lpServiceName
=
830 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
832 if (lpStatusPtr
->lpDisplayName
)
833 lpStatusPtr
->lpDisplayName
=
834 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
840 if (dwError
!= ERROR_SUCCESS
)
842 ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
843 SetLastError(dwError
);
847 TRACE("EnumDependentServicesA() done\n");
853 /**********************************************************************
854 * EnumDependentServicesW
859 EnumDependentServicesW(SC_HANDLE hService
,
860 DWORD dwServiceState
,
861 LPENUM_SERVICE_STATUSW lpServices
,
863 LPDWORD pcbBytesNeeded
,
864 LPDWORD lpServicesReturned
)
866 LPENUM_SERVICE_STATUSW lpStatusPtr
;
870 TRACE("EnumServicesStatusW() called\n");
874 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
881 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
883 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
887 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
889 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
890 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
892 if (lpStatusPtr
->lpServiceName
)
893 lpStatusPtr
->lpServiceName
=
894 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
896 if (lpStatusPtr
->lpDisplayName
)
897 lpStatusPtr
->lpDisplayName
=
898 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
904 if (dwError
!= ERROR_SUCCESS
)
906 ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
907 SetLastError(dwError
);
911 TRACE("EnumDependentServicesW() done\n");
917 /**********************************************************************
925 SC_HANDLE hSCManager
,
927 DWORD dwServiceState
,
928 LPENUM_SERVICE_STATUSW lpServices
,
930 LPDWORD pcbBytesNeeded
,
931 LPDWORD lpServicesReturned
,
932 LPDWORD lpResumeHandle
,
935 FIXME("EnumServiceGroupW is unimplemented\n");
936 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
941 /**********************************************************************
942 * EnumServicesStatusA
947 EnumServicesStatusA(SC_HANDLE hSCManager
,
949 DWORD dwServiceState
,
950 LPENUM_SERVICE_STATUSA lpServices
,
952 LPDWORD pcbBytesNeeded
,
953 LPDWORD lpServicesReturned
,
954 LPDWORD lpResumeHandle
)
956 LPENUM_SERVICE_STATUSA lpStatusPtr
;
960 TRACE("EnumServicesStatusA() called\n");
964 SetLastError(ERROR_INVALID_HANDLE
);
968 if (dwServiceType
!= SERVICE_DRIVER
&& dwServiceType
!= SERVICE_WIN32
)
970 if (pcbBytesNeeded
&& lpServicesReturned
)
973 *lpServicesReturned
= 0;
976 SetLastError(ERROR_INVALID_PARAMETER
);
980 if (dwServiceState
!= SERVICE_ACTIVE
&& dwServiceState
!= SERVICE_INACTIVE
&& dwServiceState
!= SERVICE_STATE_ALL
)
985 if (lpServicesReturned
)
986 *lpServicesReturned
= 0;
988 SetLastError(ERROR_INVALID_PARAMETER
);
992 if (!pcbBytesNeeded
|| !lpServicesReturned
)
994 SetLastError(ERROR_INVALID_ADDRESS
);
998 if (!lpServices
&& cbBufSize
!= 0)
1000 SetLastError(ERROR_INVALID_ADDRESS
);
1006 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1015 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1017 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1021 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1023 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
1024 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1026 if (lpStatusPtr
->lpServiceName
)
1027 lpStatusPtr
->lpServiceName
=
1028 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1030 if (lpStatusPtr
->lpDisplayName
)
1031 lpStatusPtr
->lpDisplayName
=
1032 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1038 if (dwError
!= ERROR_SUCCESS
)
1040 ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1041 SetLastError(dwError
);
1045 TRACE("EnumServicesStatusA() done\n");
1051 /**********************************************************************
1052 * EnumServicesStatusW
1057 EnumServicesStatusW(SC_HANDLE hSCManager
,
1058 DWORD dwServiceType
,
1059 DWORD dwServiceState
,
1060 LPENUM_SERVICE_STATUSW lpServices
,
1062 LPDWORD pcbBytesNeeded
,
1063 LPDWORD lpServicesReturned
,
1064 LPDWORD lpResumeHandle
)
1066 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1070 TRACE("EnumServicesStatusW() called\n");
1074 SetLastError(ERROR_INVALID_HANDLE
);
1080 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1089 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1091 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1095 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1097 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1098 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1100 if (lpStatusPtr
->lpServiceName
)
1101 lpStatusPtr
->lpServiceName
=
1102 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1104 if (lpStatusPtr
->lpDisplayName
)
1105 lpStatusPtr
->lpDisplayName
=
1106 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1112 if (dwError
!= ERROR_SUCCESS
)
1114 ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1115 SetLastError(dwError
);
1119 TRACE("EnumServicesStatusW() done\n");
1125 /**********************************************************************
1126 * EnumServicesStatusExA
1131 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1132 SC_ENUM_TYPE InfoLevel
,
1133 DWORD dwServiceType
,
1134 DWORD dwServiceState
,
1137 LPDWORD pcbBytesNeeded
,
1138 LPDWORD lpServicesReturned
,
1139 LPDWORD lpResumeHandle
,
1140 LPCSTR pszGroupName
)
1142 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1146 TRACE("EnumServicesStatusExA() called\n");
1148 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1150 SetLastError(ERROR_INVALID_LEVEL
);
1156 SetLastError(ERROR_INVALID_HANDLE
);
1162 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1171 (LPSTR
)pszGroupName
);
1173 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1175 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1179 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1181 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1182 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1184 if (lpStatusPtr
->lpServiceName
)
1185 lpStatusPtr
->lpServiceName
=
1186 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1188 if (lpStatusPtr
->lpDisplayName
)
1189 lpStatusPtr
->lpDisplayName
=
1190 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1196 if (dwError
!= ERROR_SUCCESS
)
1198 ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1199 SetLastError(dwError
);
1203 TRACE("EnumServicesStatusExA() done\n");
1209 /**********************************************************************
1210 * EnumServicesStatusExW
1215 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1216 SC_ENUM_TYPE InfoLevel
,
1217 DWORD dwServiceType
,
1218 DWORD dwServiceState
,
1221 LPDWORD pcbBytesNeeded
,
1222 LPDWORD lpServicesReturned
,
1223 LPDWORD lpResumeHandle
,
1224 LPCWSTR pszGroupName
)
1226 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1230 TRACE("EnumServicesStatusExW() called\n");
1234 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1243 (LPWSTR
)pszGroupName
);
1245 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1247 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1251 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
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
);
1268 if (dwError
!= ERROR_SUCCESS
)
1270 ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1271 SetLastError(dwError
);
1275 TRACE("EnumServicesStatusExW() done\n");
1281 /**********************************************************************
1282 * GetServiceDisplayNameA
1287 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1288 LPCSTR lpServiceName
,
1289 LPSTR lpDisplayName
,
1290 LPDWORD lpcchBuffer
)
1294 CHAR szEmptyName
[] = "";
1296 TRACE("GetServiceDisplayNameA() called\n");
1297 TRACE("%p %s %p %p\n", hSCManager
,
1298 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1302 SetLastError(ERROR_INVALID_HANDLE
);
1306 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1308 lpNameBuffer
= szEmptyName
;
1309 *lpcchBuffer
= sizeof(CHAR
);
1313 lpNameBuffer
= lpDisplayName
;
1318 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1323 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1325 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1326 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1330 if (dwError
!= ERROR_SUCCESS
)
1332 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1333 SetLastError(dwError
);
1341 /**********************************************************************
1342 * GetServiceDisplayNameW
1347 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1348 LPCWSTR lpServiceName
,
1349 LPWSTR lpDisplayName
,
1350 LPDWORD lpcchBuffer
)
1353 LPWSTR lpNameBuffer
;
1354 WCHAR szEmptyName
[] = L
"";
1356 TRACE("GetServiceDisplayNameW() called\n");
1360 SetLastError(ERROR_INVALID_HANDLE
);
1364 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1366 lpNameBuffer
= szEmptyName
;
1367 *lpcchBuffer
= sizeof(WCHAR
);
1371 lpNameBuffer
= lpDisplayName
;
1376 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1381 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1383 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1387 if (dwError
!= ERROR_SUCCESS
)
1389 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1390 SetLastError(dwError
);
1398 /**********************************************************************
1399 * GetServiceKeyNameA
1404 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1405 LPCSTR lpDisplayName
,
1406 LPSTR lpServiceName
,
1407 LPDWORD lpcchBuffer
)
1411 CHAR szEmptyName
[] = "";
1413 TRACE("GetServiceKeyNameA() called\n");
1417 SetLastError(ERROR_INVALID_HANDLE
);
1421 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1423 lpNameBuffer
= szEmptyName
;
1424 *lpcchBuffer
= sizeof(CHAR
);
1428 lpNameBuffer
= lpServiceName
;
1433 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1438 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1440 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1444 if (dwError
!= ERROR_SUCCESS
)
1446 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1447 SetLastError(dwError
);
1455 /**********************************************************************
1456 * GetServiceKeyNameW
1461 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1462 LPCWSTR lpDisplayName
,
1463 LPWSTR lpServiceName
,
1464 LPDWORD lpcchBuffer
)
1467 LPWSTR lpNameBuffer
;
1468 WCHAR szEmptyName
[] = L
"";
1470 TRACE("GetServiceKeyNameW() called\n");
1474 SetLastError(ERROR_INVALID_HANDLE
);
1478 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1480 lpNameBuffer
= szEmptyName
;
1481 *lpcchBuffer
= sizeof(WCHAR
);
1485 lpNameBuffer
= lpServiceName
;
1490 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1495 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1497 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1501 if (dwError
!= ERROR_SUCCESS
)
1503 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1504 SetLastError(dwError
);
1512 /**********************************************************************
1513 * LockServiceDatabase
1518 LockServiceDatabase(SC_HANDLE hSCManager
)
1523 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1527 /* Call to services.exe using RPC */
1528 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1529 (SC_RPC_LOCK
*)&hLock
);
1531 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1533 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1537 if (dwError
!= ERROR_SUCCESS
)
1539 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1540 SetLastError(dwError
);
1544 TRACE("hLock = %p\n", hLock
);
1551 WaitForSCManager(VOID
)
1555 TRACE("WaitForSCManager() called\n");
1557 /* Try to open the existing event */
1558 hEvent
= OpenEventW(SYNCHRONIZE
,
1560 L
"SvcctrlStartEvent_A3752DX");
1563 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1566 /* Try to create a new event */
1567 hEvent
= CreateEventW(NULL
,
1570 L
"SvcctrlStartEvent_A3752DX");
1573 /* Try to open the existing event again */
1574 hEvent
= OpenEventW(SYNCHRONIZE
,
1576 L
"SvcctrlStartEvent_A3752DX");
1582 /* Wait for 3 minutes */
1583 WaitForSingleObject(hEvent
, 180000);
1584 CloseHandle(hEvent
);
1586 TRACE("ScmWaitForSCManager() done\n");
1590 /**********************************************************************
1596 OpenSCManagerA(LPCSTR lpMachineName
,
1597 LPCSTR lpDatabaseName
,
1598 DWORD dwDesiredAccess
)
1600 SC_HANDLE hScm
= NULL
;
1603 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1604 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1610 /* Call to services.exe using RPC */
1611 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1612 (LPSTR
)lpDatabaseName
,
1614 (SC_RPC_HANDLE
*)&hScm
);
1616 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1618 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1622 if (dwError
!= ERROR_SUCCESS
)
1624 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1625 SetLastError(dwError
);
1629 TRACE("hScm = %p\n", hScm
);
1635 /**********************************************************************
1641 OpenSCManagerW(LPCWSTR lpMachineName
,
1642 LPCWSTR lpDatabaseName
,
1643 DWORD dwDesiredAccess
)
1645 SC_HANDLE hScm
= NULL
;
1648 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1649 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1655 /* Call to services.exe using RPC */
1656 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1657 (LPWSTR
)lpDatabaseName
,
1659 (SC_RPC_HANDLE
*)&hScm
);
1661 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1663 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1667 if (dwError
!= ERROR_SUCCESS
)
1669 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1670 SetLastError(dwError
);
1674 TRACE("hScm = %p\n", hScm
);
1680 /**********************************************************************
1686 OpenServiceA(SC_HANDLE hSCManager
,
1687 LPCSTR lpServiceName
,
1688 DWORD dwDesiredAccess
)
1690 SC_HANDLE hService
= NULL
;
1693 TRACE("OpenServiceA(%p, %s, %lx)\n",
1694 hSCManager
, lpServiceName
, dwDesiredAccess
);
1698 SetLastError(ERROR_INVALID_HANDLE
);
1704 /* Call to services.exe using RPC */
1705 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1706 (LPSTR
)lpServiceName
,
1708 (SC_RPC_HANDLE
*)&hService
);
1710 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1712 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1716 if (dwError
!= ERROR_SUCCESS
)
1718 ERR("ROpenServiceA() failed (Error %lu)\n", dwError
);
1719 SetLastError(dwError
);
1723 TRACE("hService = %p\n", hService
);
1729 /**********************************************************************
1735 OpenServiceW(SC_HANDLE hSCManager
,
1736 LPCWSTR lpServiceName
,
1737 DWORD dwDesiredAccess
)
1739 SC_HANDLE hService
= NULL
;
1742 TRACE("OpenServiceW(%p, %S, %lx)\n",
1743 hSCManager
, lpServiceName
, dwDesiredAccess
);
1747 SetLastError(ERROR_INVALID_HANDLE
);
1753 /* Call to services.exe using RPC */
1754 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1755 (LPWSTR
)lpServiceName
,
1757 (SC_RPC_HANDLE
*)&hService
);
1759 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1761 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1765 if (dwError
!= ERROR_SUCCESS
)
1767 if (dwError
== ERROR_SERVICE_DOES_NOT_EXIST
)
1768 WARN("ROpenServiceW() failed (Error %lu)\n", dwError
);
1770 ERR("ROpenServiceW() failed (Error %lu)\n", dwError
);
1771 SetLastError(dwError
);
1775 TRACE("hService = %p\n", hService
);
1781 /**********************************************************************
1782 * QueryServiceConfigA
1787 QueryServiceConfigA(SC_HANDLE hService
,
1788 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1790 LPDWORD pcbBytesNeeded
)
1794 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1795 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1799 /* Call to services.exe using RPC */
1800 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1801 (LPBYTE
)lpServiceConfig
,
1805 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1807 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1811 if (dwError
!= ERROR_SUCCESS
)
1813 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1814 SetLastError(dwError
);
1818 /* Adjust the pointers */
1819 if (lpServiceConfig
->lpBinaryPathName
)
1820 lpServiceConfig
->lpBinaryPathName
=
1821 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1822 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1824 if (lpServiceConfig
->lpLoadOrderGroup
)
1825 lpServiceConfig
->lpLoadOrderGroup
=
1826 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1827 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1829 if (lpServiceConfig
->lpDependencies
)
1830 lpServiceConfig
->lpDependencies
=
1831 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1832 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1834 if (lpServiceConfig
->lpServiceStartName
)
1835 lpServiceConfig
->lpServiceStartName
=
1836 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1837 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1839 if (lpServiceConfig
->lpDisplayName
)
1840 lpServiceConfig
->lpDisplayName
=
1841 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1842 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1844 TRACE("QueryServiceConfigA() done\n");
1850 /**********************************************************************
1851 * QueryServiceConfigW
1856 QueryServiceConfigW(SC_HANDLE hService
,
1857 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1859 LPDWORD pcbBytesNeeded
)
1863 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1864 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1868 /* Call to services.exe using RPC */
1869 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1870 (LPBYTE
)lpServiceConfig
,
1874 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1876 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1880 if (dwError
!= ERROR_SUCCESS
)
1882 if (dwError
== ERROR_INSUFFICIENT_BUFFER
)
1883 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1885 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1886 SetLastError(dwError
);
1890 /* Adjust the pointers */
1891 if (lpServiceConfig
->lpBinaryPathName
)
1892 lpServiceConfig
->lpBinaryPathName
=
1893 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1894 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1896 if (lpServiceConfig
->lpLoadOrderGroup
)
1897 lpServiceConfig
->lpLoadOrderGroup
=
1898 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1899 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1901 if (lpServiceConfig
->lpDependencies
)
1902 lpServiceConfig
->lpDependencies
=
1903 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1904 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1906 if (lpServiceConfig
->lpServiceStartName
)
1907 lpServiceConfig
->lpServiceStartName
=
1908 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1909 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1911 if (lpServiceConfig
->lpDisplayName
)
1912 lpServiceConfig
->lpDisplayName
=
1913 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1914 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1916 TRACE("QueryServiceConfigW() done\n");
1922 /**********************************************************************
1923 * QueryServiceConfig2A
1928 QueryServiceConfig2A(SC_HANDLE hService
,
1932 LPDWORD pcbBytesNeeded
)
1936 DbgPrint("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
1937 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
1939 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
1940 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
1942 SetLastError(ERROR_INVALID_LEVEL
);
1946 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
1947 pcbBytesNeeded
== NULL
)
1949 SetLastError(ERROR_INVALID_ADDRESS
);
1955 /* Call to services.exe using RPC */
1956 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
1962 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1964 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1968 if (dwError
!= ERROR_SUCCESS
)
1970 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
1971 SetLastError(dwError
);
1975 switch (dwInfoLevel
)
1977 case SERVICE_CONFIG_DESCRIPTION
:
1979 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
1981 if (lpPtr
->lpDescription
!= NULL
)
1982 lpPtr
->lpDescription
=
1983 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
1987 case SERVICE_CONFIG_FAILURE_ACTIONS
:
1989 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
1991 if (lpPtr
->lpRebootMsg
!= NULL
)
1992 lpPtr
->lpRebootMsg
=
1993 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
1995 if (lpPtr
->lpCommand
!= NULL
)
1997 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
1999 if (lpPtr
->lpsaActions
!= NULL
)
2000 lpPtr
->lpsaActions
=
2001 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2006 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2007 SetLastError(ERROR_INVALID_PARAMETER
);
2011 TRACE("QueryServiceConfig2A() done\n");
2017 /**********************************************************************
2018 * QueryServiceConfig2W
2023 QueryServiceConfig2W(SC_HANDLE hService
,
2027 LPDWORD pcbBytesNeeded
)
2031 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2032 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2034 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2035 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2037 SetLastError(ERROR_INVALID_LEVEL
);
2041 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2042 pcbBytesNeeded
== NULL
)
2044 SetLastError(ERROR_INVALID_ADDRESS
);
2050 /* Call to services.exe using RPC */
2051 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2057 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2059 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2063 if (dwError
!= ERROR_SUCCESS
)
2065 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2066 SetLastError(dwError
);
2070 switch (dwInfoLevel
)
2072 case SERVICE_CONFIG_DESCRIPTION
:
2074 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2076 if (lpPtr
->lpDescription
!= NULL
)
2077 lpPtr
->lpDescription
=
2078 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2082 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2084 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2086 if (lpPtr
->lpRebootMsg
!= NULL
)
2087 lpPtr
->lpRebootMsg
=
2088 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2090 if (lpPtr
->lpCommand
!= NULL
)
2092 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2094 if (lpPtr
->lpsaActions
!= NULL
)
2095 lpPtr
->lpsaActions
=
2096 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2101 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2102 SetLastError(ERROR_INVALID_PARAMETER
);
2106 TRACE("QueryServiceConfig2W() done\n");
2112 /**********************************************************************
2113 * QueryServiceLockStatusA
2118 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2119 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2121 LPDWORD pcbBytesNeeded
)
2125 TRACE("QueryServiceLockStatusA() called\n");
2129 /* Call to services.exe using RPC */
2130 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2135 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2137 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2141 if (dwError
!= ERROR_SUCCESS
)
2143 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2144 SetLastError(dwError
);
2148 if (lpLockStatus
->lpLockOwner
!= NULL
)
2150 lpLockStatus
->lpLockOwner
=
2151 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2154 TRACE("QueryServiceLockStatusA() done\n");
2160 /**********************************************************************
2161 * QueryServiceLockStatusW
2166 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2167 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2169 LPDWORD pcbBytesNeeded
)
2173 TRACE("QueryServiceLockStatusW() called\n");
2177 /* Call to services.exe using RPC */
2178 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2183 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2185 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2189 if (dwError
!= ERROR_SUCCESS
)
2191 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2192 SetLastError(dwError
);
2196 if (lpLockStatus
->lpLockOwner
!= NULL
)
2198 lpLockStatus
->lpLockOwner
=
2199 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2202 TRACE("QueryServiceLockStatusW() done\n");
2208 /**********************************************************************
2209 * QueryServiceObjectSecurity
2214 QueryServiceObjectSecurity(SC_HANDLE hService
,
2215 SECURITY_INFORMATION dwSecurityInformation
,
2216 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2218 LPDWORD pcbBytesNeeded
)
2222 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2223 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2227 /* Call to services.exe using RPC */
2228 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2229 dwSecurityInformation
,
2230 (LPBYTE
)lpSecurityDescriptor
,
2234 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2236 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2240 if (dwError
!= ERROR_SUCCESS
)
2242 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2243 SetLastError(dwError
);
2250 /**********************************************************************
2251 * SetServiceObjectSecurity
2256 SetServiceObjectSecurity(SC_HANDLE hService
,
2257 SECURITY_INFORMATION dwSecurityInformation
,
2258 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2260 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2266 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2269 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2271 SetLastError(ERROR_INVALID_PARAMETER
);
2275 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2276 if (SelfRelativeSD
== NULL
)
2278 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2282 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2285 if (!NT_SUCCESS(Status
))
2287 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2288 SetLastError(RtlNtStatusToDosError(Status
));
2294 /* Call to services.exe using RPC */
2295 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2296 dwSecurityInformation
,
2297 (LPBYTE
)SelfRelativeSD
,
2300 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2302 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2306 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2308 if (dwError
!= ERROR_SUCCESS
)
2310 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2311 SetLastError(dwError
);
2319 /**********************************************************************
2320 * QueryServiceStatus
2325 QueryServiceStatus(SC_HANDLE hService
,
2326 LPSERVICE_STATUS lpServiceStatus
)
2330 TRACE("QueryServiceStatus(%p, %p)\n",
2331 hService
, lpServiceStatus
);
2335 SetLastError(ERROR_INVALID_HANDLE
);
2341 /* Call to services.exe using RPC */
2342 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2345 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2347 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2351 if (dwError
!= ERROR_SUCCESS
)
2353 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2354 SetLastError(dwError
);
2362 /**********************************************************************
2363 * QueryServiceStatusEx
2368 QueryServiceStatusEx(SC_HANDLE hService
,
2369 SC_STATUS_TYPE InfoLevel
,
2372 LPDWORD pcbBytesNeeded
)
2376 TRACE("QueryServiceStatusEx() called\n");
2378 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2380 SetLastError(ERROR_INVALID_LEVEL
);
2386 /* Call to services.exe using RPC */
2387 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2393 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2395 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2399 if (dwError
!= ERROR_SUCCESS
)
2401 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2402 SetLastError(dwError
);
2410 /**********************************************************************
2416 StartServiceA(SC_HANDLE hService
,
2417 DWORD dwNumServiceArgs
,
2418 LPCSTR
*lpServiceArgVectors
)
2424 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2426 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2428 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2430 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2434 if (dwError
!= ERROR_SUCCESS
)
2436 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2437 SetLastError(dwError
);
2445 /**********************************************************************
2451 StartServiceW(SC_HANDLE hService
,
2452 DWORD dwNumServiceArgs
,
2453 LPCWSTR
*lpServiceArgVectors
)
2459 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2461 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2463 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2465 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2469 if (dwError
!= ERROR_SUCCESS
)
2471 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2472 SetLastError(dwError
);
2480 /**********************************************************************
2481 * UnlockServiceDatabase
2486 UnlockServiceDatabase(SC_LOCK ScLock
)
2490 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2494 /* Call to services.exe using RPC */
2495 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2497 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2499 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2503 if (dwError
!= ERROR_SUCCESS
)
2505 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2506 SetLastError(dwError
);
2514 /**********************************************************************
2515 * NotifyBootConfigStatus
2520 NotifyBootConfigStatus(BOOL BootAcceptable
)
2524 TRACE("NotifyBootConfigStatus()\n");
2528 /* Call to services.exe using RPC */
2529 dwError
= RNotifyBootConfigStatus(NULL
,
2532 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2534 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2538 if (dwError
!= ERROR_SUCCESS
)
2540 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2541 SetLastError(dwError
);