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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1768 SetLastError(dwError
);
1772 TRACE("hService = %p\n", hService
);
1778 /**********************************************************************
1779 * QueryServiceConfigA
1784 QueryServiceConfigA(SC_HANDLE hService
,
1785 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1787 LPDWORD pcbBytesNeeded
)
1791 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1792 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1796 /* Call to services.exe using RPC */
1797 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1798 (LPBYTE
)lpServiceConfig
,
1802 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1804 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1808 if (dwError
!= ERROR_SUCCESS
)
1810 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1811 SetLastError(dwError
);
1815 /* Adjust the pointers */
1816 if (lpServiceConfig
->lpBinaryPathName
)
1817 lpServiceConfig
->lpBinaryPathName
=
1818 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1819 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1821 if (lpServiceConfig
->lpLoadOrderGroup
)
1822 lpServiceConfig
->lpLoadOrderGroup
=
1823 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1824 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1826 if (lpServiceConfig
->lpDependencies
)
1827 lpServiceConfig
->lpDependencies
=
1828 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1829 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1831 if (lpServiceConfig
->lpServiceStartName
)
1832 lpServiceConfig
->lpServiceStartName
=
1833 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1834 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1836 if (lpServiceConfig
->lpDisplayName
)
1837 lpServiceConfig
->lpDisplayName
=
1838 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1839 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1841 TRACE("QueryServiceConfigA() done\n");
1847 /**********************************************************************
1848 * QueryServiceConfigW
1853 QueryServiceConfigW(SC_HANDLE hService
,
1854 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1856 LPDWORD pcbBytesNeeded
)
1860 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1861 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1865 /* Call to services.exe using RPC */
1866 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1867 (LPBYTE
)lpServiceConfig
,
1871 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1873 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1877 if (dwError
!= ERROR_SUCCESS
)
1879 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1880 SetLastError(dwError
);
1884 /* Adjust the pointers */
1885 if (lpServiceConfig
->lpBinaryPathName
)
1886 lpServiceConfig
->lpBinaryPathName
=
1887 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1888 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1890 if (lpServiceConfig
->lpLoadOrderGroup
)
1891 lpServiceConfig
->lpLoadOrderGroup
=
1892 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1893 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1895 if (lpServiceConfig
->lpDependencies
)
1896 lpServiceConfig
->lpDependencies
=
1897 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1898 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1900 if (lpServiceConfig
->lpServiceStartName
)
1901 lpServiceConfig
->lpServiceStartName
=
1902 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1903 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1905 if (lpServiceConfig
->lpDisplayName
)
1906 lpServiceConfig
->lpDisplayName
=
1907 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1908 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1910 TRACE("QueryServiceConfigW() done\n");
1916 /**********************************************************************
1917 * QueryServiceConfig2A
1922 QueryServiceConfig2A(SC_HANDLE hService
,
1926 LPDWORD pcbBytesNeeded
)
1930 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
1931 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
1933 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
1934 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
1936 SetLastError(ERROR_INVALID_LEVEL
);
1940 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
1941 pcbBytesNeeded
== NULL
)
1943 SetLastError(ERROR_INVALID_ADDRESS
);
1949 /* Call to services.exe using RPC */
1950 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
1956 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1958 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1962 if (dwError
!= ERROR_SUCCESS
)
1964 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
1965 SetLastError(dwError
);
1969 switch (dwInfoLevel
)
1971 case SERVICE_CONFIG_DESCRIPTION
:
1973 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
1975 if (lpPtr
->lpDescription
!= NULL
)
1976 lpPtr
->lpDescription
=
1977 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
1981 case SERVICE_CONFIG_FAILURE_ACTIONS
:
1983 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
1985 if (lpPtr
->lpRebootMsg
!= NULL
)
1986 lpPtr
->lpRebootMsg
=
1987 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
1989 if (lpPtr
->lpCommand
!= NULL
)
1991 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
1993 if (lpPtr
->lpsaActions
!= NULL
)
1994 lpPtr
->lpsaActions
=
1995 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2000 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2001 SetLastError(ERROR_INVALID_PARAMETER
);
2005 TRACE("QueryServiceConfig2A() done\n");
2011 /**********************************************************************
2012 * QueryServiceConfig2W
2017 QueryServiceConfig2W(SC_HANDLE hService
,
2021 LPDWORD pcbBytesNeeded
)
2025 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2026 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2028 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2029 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2031 SetLastError(ERROR_INVALID_LEVEL
);
2035 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2036 pcbBytesNeeded
== NULL
)
2038 SetLastError(ERROR_INVALID_ADDRESS
);
2044 /* Call to services.exe using RPC */
2045 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2051 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2053 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2057 if (dwError
!= ERROR_SUCCESS
)
2059 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2060 SetLastError(dwError
);
2064 switch (dwInfoLevel
)
2066 case SERVICE_CONFIG_DESCRIPTION
:
2068 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2070 if (lpPtr
->lpDescription
!= NULL
)
2071 lpPtr
->lpDescription
=
2072 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2076 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2078 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2080 if (lpPtr
->lpRebootMsg
!= NULL
)
2081 lpPtr
->lpRebootMsg
=
2082 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2084 if (lpPtr
->lpCommand
!= NULL
)
2086 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2088 if (lpPtr
->lpsaActions
!= NULL
)
2089 lpPtr
->lpsaActions
=
2090 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2095 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2096 SetLastError(ERROR_INVALID_PARAMETER
);
2100 TRACE("QueryServiceConfig2W() done\n");
2106 /**********************************************************************
2107 * QueryServiceLockStatusA
2112 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2113 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2115 LPDWORD pcbBytesNeeded
)
2119 TRACE("QueryServiceLockStatusA() called\n");
2123 /* Call to services.exe using RPC */
2124 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2129 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2131 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2135 if (dwError
!= ERROR_SUCCESS
)
2137 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2138 SetLastError(dwError
);
2142 if (lpLockStatus
->lpLockOwner
!= NULL
)
2144 lpLockStatus
->lpLockOwner
=
2145 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2148 TRACE("QueryServiceLockStatusA() done\n");
2154 /**********************************************************************
2155 * QueryServiceLockStatusW
2160 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2161 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2163 LPDWORD pcbBytesNeeded
)
2167 TRACE("QueryServiceLockStatusW() called\n");
2171 /* Call to services.exe using RPC */
2172 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2177 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2179 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2183 if (dwError
!= ERROR_SUCCESS
)
2185 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2186 SetLastError(dwError
);
2190 if (lpLockStatus
->lpLockOwner
!= NULL
)
2192 lpLockStatus
->lpLockOwner
=
2193 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2196 TRACE("QueryServiceLockStatusW() done\n");
2202 /**********************************************************************
2203 * QueryServiceObjectSecurity
2208 QueryServiceObjectSecurity(SC_HANDLE hService
,
2209 SECURITY_INFORMATION dwSecurityInformation
,
2210 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2212 LPDWORD pcbBytesNeeded
)
2216 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2217 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2221 /* Call to services.exe using RPC */
2222 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2223 dwSecurityInformation
,
2224 (LPBYTE
)lpSecurityDescriptor
,
2228 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2230 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2234 if (dwError
!= ERROR_SUCCESS
)
2236 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2237 SetLastError(dwError
);
2244 /**********************************************************************
2245 * SetServiceObjectSecurity
2250 SetServiceObjectSecurity(SC_HANDLE hService
,
2251 SECURITY_INFORMATION dwSecurityInformation
,
2252 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2254 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2260 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2263 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2265 SetLastError(ERROR_INVALID_PARAMETER
);
2269 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2270 if (SelfRelativeSD
== NULL
)
2272 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2276 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2279 if (!NT_SUCCESS(Status
))
2281 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2282 SetLastError(RtlNtStatusToDosError(Status
));
2288 /* Call to services.exe using RPC */
2289 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2290 dwSecurityInformation
,
2291 (LPBYTE
)SelfRelativeSD
,
2294 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2296 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2300 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2302 if (dwError
!= ERROR_SUCCESS
)
2304 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2305 SetLastError(dwError
);
2313 /**********************************************************************
2314 * QueryServiceStatus
2319 QueryServiceStatus(SC_HANDLE hService
,
2320 LPSERVICE_STATUS lpServiceStatus
)
2324 TRACE("QueryServiceStatus(%p, %p)\n",
2325 hService
, lpServiceStatus
);
2329 SetLastError(ERROR_INVALID_HANDLE
);
2335 /* Call to services.exe using RPC */
2336 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2339 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2341 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2345 if (dwError
!= ERROR_SUCCESS
)
2347 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2348 SetLastError(dwError
);
2356 /**********************************************************************
2357 * QueryServiceStatusEx
2362 QueryServiceStatusEx(SC_HANDLE hService
,
2363 SC_STATUS_TYPE InfoLevel
,
2366 LPDWORD pcbBytesNeeded
)
2370 TRACE("QueryServiceStatusEx() called\n");
2372 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2374 SetLastError(ERROR_INVALID_LEVEL
);
2380 /* Call to services.exe using RPC */
2381 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2387 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2389 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2393 if (dwError
!= ERROR_SUCCESS
)
2395 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2396 SetLastError(dwError
);
2404 /**********************************************************************
2410 StartServiceA(SC_HANDLE hService
,
2411 DWORD dwNumServiceArgs
,
2412 LPCSTR
*lpServiceArgVectors
)
2418 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2420 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2422 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2424 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2428 if (dwError
!= ERROR_SUCCESS
)
2430 TRACE("RStartServiceA() failed (Error %lu)\n", dwError
);
2431 SetLastError(dwError
);
2439 /**********************************************************************
2445 StartServiceW(SC_HANDLE hService
,
2446 DWORD dwNumServiceArgs
,
2447 LPCWSTR
*lpServiceArgVectors
)
2453 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2455 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2457 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2459 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2463 if (dwError
!= ERROR_SUCCESS
)
2465 TRACE("RStartServiceW() failed (Error %lu)\n", dwError
);
2466 SetLastError(dwError
);
2474 /**********************************************************************
2475 * UnlockServiceDatabase
2480 UnlockServiceDatabase(SC_LOCK ScLock
)
2484 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2488 /* Call to services.exe using RPC */
2489 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2491 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2493 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2497 if (dwError
!= ERROR_SUCCESS
)
2499 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2500 SetLastError(dwError
);
2508 /**********************************************************************
2509 * NotifyBootConfigStatus
2514 NotifyBootConfigStatus(BOOL BootAcceptable
)
2518 TRACE("NotifyBootConfigStatus()\n");
2522 /* Call to services.exe using RPC */
2523 dwError
= RNotifyBootConfigStatus(NULL
,
2526 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2528 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2532 if (dwError
!= ERROR_SUCCESS
)
2534 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2535 SetLastError(dwError
);