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 ScmRpcStatusToWinError(RPC_STATUS Status
)
139 case RPC_S_INVALID_BINDING
:
140 case RPC_X_SS_IN_NULL_CONTEXT
:
141 return ERROR_INVALID_HANDLE
;
143 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
144 case RPC_X_BYTE_COUNT_TOO_SMALL
:
145 return ERROR_INVALID_PARAMETER
;
147 case RPC_X_NULL_REF_POINTER
:
148 return ERROR_INVALID_ADDRESS
;
151 return (DWORD
)Status
;
156 /**********************************************************************
157 * ChangeServiceConfig2A
162 ChangeServiceConfig2A(SC_HANDLE hService
,
166 SC_RPC_CONFIG_INFOA Info
;
169 TRACE("ChangeServiceConfig2A() called\n");
171 /* Fill relevent field of the Info structure */
172 Info
.dwInfoLevel
= dwInfoLevel
;
175 case SERVICE_CONFIG_DESCRIPTION
:
176 Info
.psd
= (LPSERVICE_DESCRIPTIONA
)&lpInfo
;
177 Info
.lpDescription
= ((LPSERVICE_DESCRIPTIONA
)lpInfo
)->lpDescription
; //HACK
180 case SERVICE_CONFIG_FAILURE_ACTIONS
:
181 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSA
)lpInfo
;
185 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
186 SetLastError(ERROR_INVALID_PARAMETER
);
195 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
198 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
200 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
204 if (dwError
!= ERROR_SUCCESS
)
206 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
207 SetLastError(dwError
);
215 /**********************************************************************
216 * ChangeServiceConfig2W
221 ChangeServiceConfig2W(SC_HANDLE hService
,
225 SC_RPC_CONFIG_INFOW Info
;
228 TRACE("ChangeServiceConfig2W() called\n");
230 /* Fill relevent field of the Info structure */
231 Info
.dwInfoLevel
= dwInfoLevel
;
234 case SERVICE_CONFIG_DESCRIPTION
:
235 Info
.psd
= (LPSERVICE_DESCRIPTIONW
)&lpInfo
;
238 case SERVICE_CONFIG_FAILURE_ACTIONS
:
239 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSW
)&lpInfo
;
243 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
244 SetLastError(ERROR_INVALID_PARAMETER
);
253 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
256 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
258 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
262 if (dwError
!= ERROR_SUCCESS
)
264 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
265 SetLastError(dwError
);
273 /**********************************************************************
274 * ChangeServiceConfigA
279 ChangeServiceConfigA(SC_HANDLE hService
,
282 DWORD dwErrorControl
,
283 LPCSTR lpBinaryPathName
,
284 LPCSTR lpLoadOrderGroup
,
286 LPCSTR lpDependencies
,
287 LPCSTR lpServiceStartName
,
289 LPCSTR lpDisplayName
)
292 DWORD dwDependenciesLength
= 0;
296 TRACE("ChangeServiceConfigA() called\n");
298 /* Calculate the Dependencies length*/
299 if (lpDependencies
!= NULL
)
301 lpStr
= (LPSTR
)lpDependencies
;
304 dwLength
= strlen(lpStr
) + 1;
305 dwDependenciesLength
+= dwLength
;
306 lpStr
= lpStr
+ dwLength
;
308 dwDependenciesLength
++;
311 /* FIXME: Encrypt the password */
315 /* Call to services.exe using RPC */
316 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
320 (LPSTR
)lpBinaryPathName
,
321 (LPSTR
)lpLoadOrderGroup
,
323 (LPSTR
)lpDependencies
,
324 dwDependenciesLength
,
325 (LPSTR
)lpServiceStartName
,
326 NULL
, /* FIXME: lpPassword */
327 0, /* FIXME: dwPasswordLength */
328 (LPSTR
)lpDisplayName
);
330 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
332 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
336 if (dwError
!= ERROR_SUCCESS
)
338 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
339 SetLastError(dwError
);
347 /**********************************************************************
348 * ChangeServiceConfigW
353 ChangeServiceConfigW(SC_HANDLE hService
,
356 DWORD dwErrorControl
,
357 LPCWSTR lpBinaryPathName
,
358 LPCWSTR lpLoadOrderGroup
,
360 LPCWSTR lpDependencies
,
361 LPCWSTR lpServiceStartName
,
363 LPCWSTR lpDisplayName
)
366 DWORD dwDependenciesLength
= 0;
370 TRACE("ChangeServiceConfigW() called\n");
372 /* Calculate the Dependencies length*/
373 if (lpDependencies
!= NULL
)
375 lpStr
= (LPWSTR
)lpDependencies
;
378 dwLength
= wcslen(lpStr
) + 1;
379 dwDependenciesLength
+= dwLength
;
380 lpStr
= lpStr
+ dwLength
;
382 dwDependenciesLength
++;
385 /* FIXME: Encrypt the password */
389 /* Call to services.exe using RPC */
390 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
394 (LPWSTR
)lpBinaryPathName
,
395 (LPWSTR
)lpLoadOrderGroup
,
397 (LPBYTE
)lpDependencies
,
398 dwDependenciesLength
,
399 (LPWSTR
)lpServiceStartName
,
400 NULL
, /* FIXME: lpPassword */
401 0, /* FIXME: dwPasswordLength */
402 (LPWSTR
)lpDisplayName
);
404 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
406 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
410 if (dwError
!= ERROR_SUCCESS
)
412 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
413 SetLastError(dwError
);
421 /**********************************************************************
427 CloseServiceHandle(SC_HANDLE hSCObject
)
431 TRACE("CloseServiceHandle() called\n");
435 SetLastError(ERROR_INVALID_HANDLE
);
441 /* Call to services.exe using RPC */
442 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
444 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
446 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
452 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
453 SetLastError(dwError
);
457 TRACE("CloseServiceHandle() done\n");
463 /**********************************************************************
469 ControlService(SC_HANDLE hService
,
471 LPSERVICE_STATUS lpServiceStatus
)
475 TRACE("ControlService(%x, %x, %p)\n",
476 hService
, dwControl
, lpServiceStatus
);
480 /* Call to services.exe using RPC */
481 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
485 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
487 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
491 if (dwError
!= ERROR_SUCCESS
)
493 TRACE("RControlService() failed (Error %lu)\n", dwError
);
494 SetLastError(dwError
);
498 TRACE("ControlService() done\n");
504 /**********************************************************************
510 ControlServiceEx(IN SC_HANDLE hService
,
512 IN DWORD dwInfoLevel
,
513 IN OUT PVOID pControlParams
)
515 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
516 hService
, dwControl
, dwInfoLevel
, pControlParams
);
517 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
522 /**********************************************************************
528 CreateServiceA(SC_HANDLE hSCManager
,
529 LPCSTR lpServiceName
,
530 LPCSTR lpDisplayName
,
531 DWORD dwDesiredAccess
,
534 DWORD dwErrorControl
,
535 LPCSTR lpBinaryPathName
,
536 LPCSTR lpLoadOrderGroup
,
538 LPCSTR lpDependencies
,
539 LPCSTR lpServiceStartName
,
542 SC_HANDLE hService
= NULL
;
543 DWORD dwDependenciesLength
= 0;
548 TRACE("CreateServiceA() called\n");
549 TRACE("%p %s %s\n", hSCManager
,
550 lpServiceName
, lpDisplayName
);
554 SetLastError(ERROR_INVALID_HANDLE
);
558 /* Calculate the Dependencies length*/
559 if (lpDependencies
!= NULL
)
561 lpStr
= (LPSTR
)lpDependencies
;
564 dwLength
= strlen(lpStr
) + 1;
565 dwDependenciesLength
+= dwLength
;
566 lpStr
= lpStr
+ dwLength
;
568 dwDependenciesLength
++;
571 /* FIXME: Encrypt the password */
575 /* Call to services.exe using RPC */
576 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
577 (LPSTR
)lpServiceName
,
578 (LPSTR
)lpDisplayName
,
583 (LPSTR
)lpBinaryPathName
,
584 (LPSTR
)lpLoadOrderGroup
,
586 (LPBYTE
)lpDependencies
,
587 dwDependenciesLength
,
588 (LPSTR
)lpServiceStartName
,
589 NULL
, /* FIXME: lpPassword */
590 0, /* FIXME: dwPasswordLength */
591 (SC_RPC_HANDLE
*)&hService
);
593 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
595 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
599 if (dwError
!= ERROR_SUCCESS
)
601 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
602 SetLastError(dwError
);
610 /**********************************************************************
616 CreateServiceW(SC_HANDLE hSCManager
,
617 LPCWSTR lpServiceName
,
618 LPCWSTR lpDisplayName
,
619 DWORD dwDesiredAccess
,
622 DWORD dwErrorControl
,
623 LPCWSTR lpBinaryPathName
,
624 LPCWSTR lpLoadOrderGroup
,
626 LPCWSTR lpDependencies
,
627 LPCWSTR lpServiceStartName
,
630 SC_HANDLE hService
= NULL
;
631 DWORD dwDependenciesLength
= 0;
636 TRACE("CreateServiceW() called\n");
637 TRACE("%p %S %S\n", hSCManager
,
638 lpServiceName
, lpDisplayName
);
642 SetLastError(ERROR_INVALID_HANDLE
);
646 /* Calculate the Dependencies length*/
647 if (lpDependencies
!= NULL
)
649 lpStr
= (LPWSTR
)lpDependencies
;
652 dwLength
= wcslen(lpStr
) + 1;
653 dwDependenciesLength
+= dwLength
;
654 lpStr
= lpStr
+ dwLength
;
656 dwDependenciesLength
++;
658 dwDependenciesLength
*= sizeof(WCHAR
);
661 /* FIXME: Encrypt the password */
665 /* Call to services.exe using RPC */
666 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
676 (LPBYTE
)lpDependencies
,
677 dwDependenciesLength
,
679 NULL
, /* FIXME: lpPassword */
680 0, /* FIXME: dwPasswordLength */
681 (SC_RPC_HANDLE
*)&hService
);
683 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
685 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
689 if (dwError
!= ERROR_SUCCESS
)
691 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
692 SetLastError(dwError
);
700 /**********************************************************************
706 DeleteService(SC_HANDLE hService
)
710 TRACE("DeleteService(%x)\n", hService
);
714 /* Call to services.exe using RPC */
715 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
717 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
719 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
723 if (dwError
!= ERROR_SUCCESS
)
725 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
726 SetLastError(dwError
);
734 /**********************************************************************
735 * EnumDependentServicesA
740 EnumDependentServicesA(SC_HANDLE hService
,
741 DWORD dwServiceState
,
742 LPENUM_SERVICE_STATUSA lpServices
,
744 LPDWORD pcbBytesNeeded
,
745 LPDWORD lpServicesReturned
)
747 LPENUM_SERVICE_STATUSA lpStatusPtr
;
751 TRACE("EnumServicesStatusA() called\n");
755 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
762 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
764 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
768 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
770 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
771 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
773 if (lpStatusPtr
->lpServiceName
)
774 lpStatusPtr
->lpServiceName
=
775 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
777 if (lpStatusPtr
->lpDisplayName
)
778 lpStatusPtr
->lpDisplayName
=
779 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
785 if (dwError
!= ERROR_SUCCESS
)
787 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
788 SetLastError(dwError
);
792 TRACE("EnumDependentServicesA() done\n");
798 /**********************************************************************
799 * EnumDependentServicesW
804 EnumDependentServicesW(SC_HANDLE hService
,
805 DWORD dwServiceState
,
806 LPENUM_SERVICE_STATUSW lpServices
,
808 LPDWORD pcbBytesNeeded
,
809 LPDWORD lpServicesReturned
)
811 LPENUM_SERVICE_STATUSW lpStatusPtr
;
815 TRACE("EnumServicesStatusW() called\n");
819 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
826 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
828 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
832 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
834 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
835 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
837 if (lpStatusPtr
->lpServiceName
)
838 lpStatusPtr
->lpServiceName
=
839 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
841 if (lpStatusPtr
->lpDisplayName
)
842 lpStatusPtr
->lpDisplayName
=
843 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
849 if (dwError
!= ERROR_SUCCESS
)
851 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
852 SetLastError(dwError
);
856 TRACE("EnumDependentServicesW() done\n");
862 /**********************************************************************
870 SC_HANDLE hSCManager
,
872 DWORD dwServiceState
,
873 LPENUM_SERVICE_STATUSW lpServices
,
875 LPDWORD pcbBytesNeeded
,
876 LPDWORD lpServicesReturned
,
877 LPDWORD lpResumeHandle
,
880 FIXME("EnumServiceGroupW is unimplemented\n");
881 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
886 /**********************************************************************
887 * EnumServicesStatusA
892 EnumServicesStatusA(SC_HANDLE hSCManager
,
894 DWORD dwServiceState
,
895 LPENUM_SERVICE_STATUSA lpServices
,
897 LPDWORD pcbBytesNeeded
,
898 LPDWORD lpServicesReturned
,
899 LPDWORD lpResumeHandle
)
901 LPENUM_SERVICE_STATUSA lpStatusPtr
;
905 TRACE("EnumServicesStatusA() called\n");
909 SetLastError(ERROR_INVALID_HANDLE
);
913 if (dwServiceType
!= SERVICE_DRIVER
&& dwServiceType
!= SERVICE_WIN32
)
915 if (pcbBytesNeeded
&& lpServicesReturned
)
918 *lpServicesReturned
= 0;
921 SetLastError(ERROR_INVALID_PARAMETER
);
925 if (dwServiceState
!= SERVICE_ACTIVE
&& dwServiceState
!= SERVICE_INACTIVE
&& dwServiceState
!= SERVICE_STATE_ALL
)
930 if (lpServicesReturned
)
931 *lpServicesReturned
= 0;
933 SetLastError(ERROR_INVALID_PARAMETER
);
937 if (!pcbBytesNeeded
|| !lpServicesReturned
)
939 SetLastError(ERROR_INVALID_ADDRESS
);
943 if (!lpServices
&& cbBufSize
!= 0)
945 SetLastError(ERROR_INVALID_ADDRESS
);
951 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
960 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
962 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
966 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
968 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
969 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
971 if (lpStatusPtr
->lpServiceName
)
972 lpStatusPtr
->lpServiceName
=
973 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
975 if (lpStatusPtr
->lpDisplayName
)
976 lpStatusPtr
->lpDisplayName
=
977 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
983 if (dwError
!= ERROR_SUCCESS
)
985 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
986 SetLastError(dwError
);
990 TRACE("EnumServicesStatusA() done\n");
996 /**********************************************************************
997 * EnumServicesStatusW
1002 EnumServicesStatusW(SC_HANDLE hSCManager
,
1003 DWORD dwServiceType
,
1004 DWORD dwServiceState
,
1005 LPENUM_SERVICE_STATUSW lpServices
,
1007 LPDWORD pcbBytesNeeded
,
1008 LPDWORD lpServicesReturned
,
1009 LPDWORD lpResumeHandle
)
1011 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1015 TRACE("EnumServicesStatusW() called\n");
1019 SetLastError(ERROR_INVALID_HANDLE
);
1025 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1034 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1036 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1040 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1042 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1043 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1045 if (lpStatusPtr
->lpServiceName
)
1046 lpStatusPtr
->lpServiceName
=
1047 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1049 if (lpStatusPtr
->lpDisplayName
)
1050 lpStatusPtr
->lpDisplayName
=
1051 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1057 if (dwError
!= ERROR_SUCCESS
)
1059 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1060 SetLastError(dwError
);
1064 TRACE("EnumServicesStatusW() done\n");
1070 /**********************************************************************
1071 * EnumServicesStatusExA
1076 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1077 SC_ENUM_TYPE InfoLevel
,
1078 DWORD dwServiceType
,
1079 DWORD dwServiceState
,
1082 LPDWORD pcbBytesNeeded
,
1083 LPDWORD lpServicesReturned
,
1084 LPDWORD lpResumeHandle
,
1085 LPCSTR pszGroupName
)
1087 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1091 TRACE("EnumServicesStatusExA() called\n");
1093 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1095 SetLastError(ERROR_INVALID_LEVEL
);
1101 SetLastError(ERROR_INVALID_HANDLE
);
1107 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1116 (LPSTR
)pszGroupName
);
1118 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1120 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1124 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1126 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1127 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1129 if (lpStatusPtr
->lpServiceName
)
1130 lpStatusPtr
->lpServiceName
=
1131 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1133 if (lpStatusPtr
->lpDisplayName
)
1134 lpStatusPtr
->lpDisplayName
=
1135 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1141 if (dwError
!= ERROR_SUCCESS
)
1143 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1144 SetLastError(dwError
);
1148 TRACE("EnumServicesStatusExA() done\n");
1154 /**********************************************************************
1155 * EnumServicesStatusExW
1160 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1161 SC_ENUM_TYPE InfoLevel
,
1162 DWORD dwServiceType
,
1163 DWORD dwServiceState
,
1166 LPDWORD pcbBytesNeeded
,
1167 LPDWORD lpServicesReturned
,
1168 LPDWORD lpResumeHandle
,
1169 LPCWSTR pszGroupName
)
1171 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1175 TRACE("EnumServicesStatusExW() called\n");
1179 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1188 (LPWSTR
)pszGroupName
);
1190 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1192 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1196 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1198 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1199 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1201 if (lpStatusPtr
->lpServiceName
)
1202 lpStatusPtr
->lpServiceName
=
1203 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1205 if (lpStatusPtr
->lpDisplayName
)
1206 lpStatusPtr
->lpDisplayName
=
1207 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1213 if (dwError
!= ERROR_SUCCESS
)
1215 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1216 SetLastError(dwError
);
1220 TRACE("EnumServicesStatusExW() done\n");
1226 /**********************************************************************
1227 * GetServiceDisplayNameA
1232 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1233 LPCSTR lpServiceName
,
1234 LPSTR lpDisplayName
,
1235 LPDWORD lpcchBuffer
)
1239 CHAR szEmptyName
[] = "";
1241 TRACE("GetServiceDisplayNameA() called\n");
1242 TRACE("%p %s %p %p\n", hSCManager
,
1243 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1247 SetLastError(ERROR_INVALID_HANDLE
);
1251 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1253 lpNameBuffer
= szEmptyName
;
1254 *lpcchBuffer
= sizeof(CHAR
);
1258 lpNameBuffer
= lpDisplayName
;
1263 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1268 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1270 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1271 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1275 if (dwError
!= ERROR_SUCCESS
)
1277 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1278 SetLastError(dwError
);
1286 /**********************************************************************
1287 * GetServiceDisplayNameW
1292 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1293 LPCWSTR lpServiceName
,
1294 LPWSTR lpDisplayName
,
1295 LPDWORD lpcchBuffer
)
1298 LPWSTR lpNameBuffer
;
1299 WCHAR szEmptyName
[] = L
"";
1301 TRACE("GetServiceDisplayNameW() called\n");
1305 SetLastError(ERROR_INVALID_HANDLE
);
1309 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1311 lpNameBuffer
= szEmptyName
;
1312 *lpcchBuffer
= sizeof(WCHAR
);
1316 lpNameBuffer
= lpDisplayName
;
1321 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1326 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1328 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1332 if (dwError
!= ERROR_SUCCESS
)
1334 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1335 SetLastError(dwError
);
1343 /**********************************************************************
1344 * GetServiceKeyNameA
1349 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1350 LPCSTR lpDisplayName
,
1351 LPSTR lpServiceName
,
1352 LPDWORD lpcchBuffer
)
1356 CHAR szEmptyName
[] = "";
1358 TRACE("GetServiceKeyNameA() called\n");
1362 SetLastError(ERROR_INVALID_HANDLE
);
1366 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1368 lpNameBuffer
= szEmptyName
;
1369 *lpcchBuffer
= sizeof(CHAR
);
1373 lpNameBuffer
= lpServiceName
;
1378 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1383 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1385 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1389 if (dwError
!= ERROR_SUCCESS
)
1391 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1392 SetLastError(dwError
);
1400 /**********************************************************************
1401 * GetServiceKeyNameW
1406 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1407 LPCWSTR lpDisplayName
,
1408 LPWSTR lpServiceName
,
1409 LPDWORD lpcchBuffer
)
1412 LPWSTR lpNameBuffer
;
1413 WCHAR szEmptyName
[] = L
"";
1415 TRACE("GetServiceKeyNameW() called\n");
1419 SetLastError(ERROR_INVALID_HANDLE
);
1423 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1425 lpNameBuffer
= szEmptyName
;
1426 *lpcchBuffer
= sizeof(WCHAR
);
1430 lpNameBuffer
= lpServiceName
;
1435 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1440 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1442 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1446 if (dwError
!= ERROR_SUCCESS
)
1448 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1449 SetLastError(dwError
);
1457 /**********************************************************************
1458 * LockServiceDatabase
1463 LockServiceDatabase(SC_HANDLE hSCManager
)
1468 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1472 /* Call to services.exe using RPC */
1473 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1474 (SC_RPC_LOCK
*)&hLock
);
1476 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1478 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1482 if (dwError
!= ERROR_SUCCESS
)
1484 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1485 SetLastError(dwError
);
1489 TRACE("hLock = %p\n", hLock
);
1496 WaitForSCManager(VOID
)
1500 TRACE("WaitForSCManager() called\n");
1502 /* Try to open the existing event */
1503 hEvent
= OpenEventW(SYNCHRONIZE
,
1505 L
"SvcctrlStartEvent_A3752DX");
1508 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1511 /* Try to create a new event */
1512 hEvent
= CreateEventW(NULL
,
1515 L
"SvcctrlStartEvent_A3752DX");
1518 /* Try to open the existing event again */
1519 hEvent
= OpenEventW(SYNCHRONIZE
,
1521 L
"SvcctrlStartEvent_A3752DX");
1527 /* Wait for 3 minutes */
1528 WaitForSingleObject(hEvent
, 180000);
1529 CloseHandle(hEvent
);
1531 TRACE("ScmWaitForSCManager() done\n");
1535 /**********************************************************************
1541 OpenSCManagerA(LPCSTR lpMachineName
,
1542 LPCSTR lpDatabaseName
,
1543 DWORD dwDesiredAccess
)
1545 SC_HANDLE hScm
= NULL
;
1548 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1549 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1555 /* Call to services.exe using RPC */
1556 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1557 (LPSTR
)lpDatabaseName
,
1559 (SC_RPC_HANDLE
*)&hScm
);
1561 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1563 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1567 if (dwError
!= ERROR_SUCCESS
)
1569 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1570 SetLastError(dwError
);
1574 TRACE("hScm = %p\n", hScm
);
1580 /**********************************************************************
1586 OpenSCManagerW(LPCWSTR lpMachineName
,
1587 LPCWSTR lpDatabaseName
,
1588 DWORD dwDesiredAccess
)
1590 SC_HANDLE hScm
= NULL
;
1593 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1594 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1600 /* Call to services.exe using RPC */
1601 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1602 (LPWSTR
)lpDatabaseName
,
1604 (SC_RPC_HANDLE
*)&hScm
);
1606 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1608 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1612 if (dwError
!= ERROR_SUCCESS
)
1614 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1615 SetLastError(dwError
);
1619 TRACE("hScm = %p\n", hScm
);
1625 /**********************************************************************
1631 OpenServiceA(SC_HANDLE hSCManager
,
1632 LPCSTR lpServiceName
,
1633 DWORD dwDesiredAccess
)
1635 SC_HANDLE hService
= NULL
;
1638 TRACE("OpenServiceA(%p, %s, %lx)\n",
1639 hSCManager
, lpServiceName
, dwDesiredAccess
);
1643 SetLastError(ERROR_INVALID_HANDLE
);
1649 /* Call to services.exe using RPC */
1650 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1651 (LPSTR
)lpServiceName
,
1653 (SC_RPC_HANDLE
*)&hService
);
1655 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1657 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1661 if (dwError
!= ERROR_SUCCESS
)
1663 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1664 SetLastError(dwError
);
1668 TRACE("hService = %p\n", hService
);
1674 /**********************************************************************
1680 OpenServiceW(SC_HANDLE hSCManager
,
1681 LPCWSTR lpServiceName
,
1682 DWORD dwDesiredAccess
)
1684 SC_HANDLE hService
= NULL
;
1687 TRACE("OpenServiceW(%p, %S, %lx)\n",
1688 hSCManager
, lpServiceName
, dwDesiredAccess
);
1692 SetLastError(ERROR_INVALID_HANDLE
);
1698 /* Call to services.exe using RPC */
1699 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1700 (LPWSTR
)lpServiceName
,
1702 (SC_RPC_HANDLE
*)&hService
);
1704 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1706 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1710 if (dwError
!= ERROR_SUCCESS
)
1712 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1713 SetLastError(dwError
);
1717 TRACE("hService = %p\n", hService
);
1723 /**********************************************************************
1724 * QueryServiceConfigA
1729 QueryServiceConfigA(SC_HANDLE hService
,
1730 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1732 LPDWORD pcbBytesNeeded
)
1736 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1737 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1741 /* Call to services.exe using RPC */
1742 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1743 (LPBYTE
)lpServiceConfig
,
1747 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1749 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1753 if (dwError
!= ERROR_SUCCESS
)
1755 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1756 SetLastError(dwError
);
1760 /* Adjust the pointers */
1761 if (lpServiceConfig
->lpBinaryPathName
)
1762 lpServiceConfig
->lpBinaryPathName
=
1763 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1764 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1766 if (lpServiceConfig
->lpLoadOrderGroup
)
1767 lpServiceConfig
->lpLoadOrderGroup
=
1768 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1769 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1771 if (lpServiceConfig
->lpDependencies
)
1772 lpServiceConfig
->lpDependencies
=
1773 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1774 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1776 if (lpServiceConfig
->lpServiceStartName
)
1777 lpServiceConfig
->lpServiceStartName
=
1778 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1779 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1781 if (lpServiceConfig
->lpDisplayName
)
1782 lpServiceConfig
->lpDisplayName
=
1783 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1784 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1786 TRACE("QueryServiceConfigA() done\n");
1792 /**********************************************************************
1793 * QueryServiceConfigW
1798 QueryServiceConfigW(SC_HANDLE hService
,
1799 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1801 LPDWORD pcbBytesNeeded
)
1805 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1806 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1810 /* Call to services.exe using RPC */
1811 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1812 (LPBYTE
)lpServiceConfig
,
1816 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1818 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1822 if (dwError
!= ERROR_SUCCESS
)
1824 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1825 SetLastError(dwError
);
1829 /* Adjust the pointers */
1830 if (lpServiceConfig
->lpBinaryPathName
)
1831 lpServiceConfig
->lpBinaryPathName
=
1832 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1833 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1835 if (lpServiceConfig
->lpLoadOrderGroup
)
1836 lpServiceConfig
->lpLoadOrderGroup
=
1837 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1838 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1840 if (lpServiceConfig
->lpDependencies
)
1841 lpServiceConfig
->lpDependencies
=
1842 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1843 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1845 if (lpServiceConfig
->lpServiceStartName
)
1846 lpServiceConfig
->lpServiceStartName
=
1847 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1848 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1850 if (lpServiceConfig
->lpDisplayName
)
1851 lpServiceConfig
->lpDisplayName
=
1852 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1853 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1855 TRACE("QueryServiceConfigW() done\n");
1861 /**********************************************************************
1862 * QueryServiceConfig2A
1867 QueryServiceConfig2A(SC_HANDLE hService
,
1871 LPDWORD pcbBytesNeeded
)
1875 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
1876 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
1878 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
1879 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
1881 SetLastError(ERROR_INVALID_LEVEL
);
1885 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
1886 pcbBytesNeeded
== NULL
)
1888 SetLastError(ERROR_INVALID_ADDRESS
);
1894 /* Call to services.exe using RPC */
1895 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
1901 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1903 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1907 if (dwError
!= ERROR_SUCCESS
)
1909 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
1910 SetLastError(dwError
);
1914 switch (dwInfoLevel
)
1916 case SERVICE_CONFIG_DESCRIPTION
:
1918 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
1920 if (lpPtr
->lpDescription
!= NULL
)
1921 lpPtr
->lpDescription
=
1922 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
1926 case SERVICE_CONFIG_FAILURE_ACTIONS
:
1928 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
1930 if (lpPtr
->lpRebootMsg
!= NULL
)
1931 lpPtr
->lpRebootMsg
=
1932 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
1934 if (lpPtr
->lpCommand
!= NULL
)
1936 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
1938 if (lpPtr
->lpsaActions
!= NULL
)
1939 lpPtr
->lpsaActions
=
1940 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
1945 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
1946 SetLastError(ERROR_INVALID_PARAMETER
);
1950 TRACE("QueryServiceConfig2A() done\n");
1956 /**********************************************************************
1957 * QueryServiceConfig2W
1962 QueryServiceConfig2W(SC_HANDLE hService
,
1966 LPDWORD pcbBytesNeeded
)
1970 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
1971 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
1973 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
1974 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
1976 SetLastError(ERROR_INVALID_LEVEL
);
1980 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
1981 pcbBytesNeeded
== NULL
)
1983 SetLastError(ERROR_INVALID_ADDRESS
);
1989 /* Call to services.exe using RPC */
1990 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
1996 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1998 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2002 if (dwError
!= ERROR_SUCCESS
)
2004 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2005 SetLastError(dwError
);
2009 switch (dwInfoLevel
)
2011 case SERVICE_CONFIG_DESCRIPTION
:
2013 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2015 if (lpPtr
->lpDescription
!= NULL
)
2016 lpPtr
->lpDescription
=
2017 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2021 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2023 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2025 if (lpPtr
->lpRebootMsg
!= NULL
)
2026 lpPtr
->lpRebootMsg
=
2027 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2029 if (lpPtr
->lpCommand
!= NULL
)
2031 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2033 if (lpPtr
->lpsaActions
!= NULL
)
2034 lpPtr
->lpsaActions
=
2035 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2040 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2041 SetLastError(ERROR_INVALID_PARAMETER
);
2045 TRACE("QueryServiceConfig2W() done\n");
2051 /**********************************************************************
2052 * QueryServiceLockStatusA
2057 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2058 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2060 LPDWORD pcbBytesNeeded
)
2064 TRACE("QueryServiceLockStatusA() called\n");
2068 /* Call to services.exe using RPC */
2069 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2074 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2076 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2080 if (dwError
!= ERROR_SUCCESS
)
2082 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2083 SetLastError(dwError
);
2087 if (lpLockStatus
->lpLockOwner
!= NULL
)
2089 lpLockStatus
->lpLockOwner
=
2090 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2093 TRACE("QueryServiceLockStatusA() done\n");
2099 /**********************************************************************
2100 * QueryServiceLockStatusW
2105 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2106 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2108 LPDWORD pcbBytesNeeded
)
2112 TRACE("QueryServiceLockStatusW() called\n");
2116 /* Call to services.exe using RPC */
2117 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2122 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2124 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2128 if (dwError
!= ERROR_SUCCESS
)
2130 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2131 SetLastError(dwError
);
2135 if (lpLockStatus
->lpLockOwner
!= NULL
)
2137 lpLockStatus
->lpLockOwner
=
2138 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2141 TRACE("QueryServiceLockStatusW() done\n");
2147 /**********************************************************************
2148 * QueryServiceObjectSecurity
2153 QueryServiceObjectSecurity(SC_HANDLE hService
,
2154 SECURITY_INFORMATION dwSecurityInformation
,
2155 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2157 LPDWORD pcbBytesNeeded
)
2161 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2162 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2166 /* Call to services.exe using RPC */
2167 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2168 dwSecurityInformation
,
2169 (LPBYTE
)lpSecurityDescriptor
,
2173 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2175 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2179 if (dwError
!= ERROR_SUCCESS
)
2181 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2182 SetLastError(dwError
);
2189 /**********************************************************************
2190 * SetServiceObjectSecurity
2195 SetServiceObjectSecurity(SC_HANDLE hService
,
2196 SECURITY_INFORMATION dwSecurityInformation
,
2197 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2199 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2205 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2208 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2210 SetLastError(ERROR_INVALID_PARAMETER
);
2214 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2215 if (SelfRelativeSD
== NULL
)
2217 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2221 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2224 if (!NT_SUCCESS(Status
))
2226 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2227 SetLastError(RtlNtStatusToDosError(Status
));
2233 /* Call to services.exe using RPC */
2234 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2235 dwSecurityInformation
,
2236 (LPBYTE
)SelfRelativeSD
,
2239 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2241 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2245 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2247 if (dwError
!= ERROR_SUCCESS
)
2249 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2250 SetLastError(dwError
);
2258 /**********************************************************************
2259 * QueryServiceStatus
2264 QueryServiceStatus(SC_HANDLE hService
,
2265 LPSERVICE_STATUS lpServiceStatus
)
2269 TRACE("QueryServiceStatus(%p, %p)\n",
2270 hService
, lpServiceStatus
);
2274 SetLastError(ERROR_INVALID_HANDLE
);
2280 /* Call to services.exe using RPC */
2281 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2284 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2286 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2290 if (dwError
!= ERROR_SUCCESS
)
2292 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2293 SetLastError(dwError
);
2301 /**********************************************************************
2302 * QueryServiceStatusEx
2307 QueryServiceStatusEx(SC_HANDLE hService
,
2308 SC_STATUS_TYPE InfoLevel
,
2311 LPDWORD pcbBytesNeeded
)
2315 TRACE("QueryServiceStatusEx() called\n");
2317 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2319 SetLastError(ERROR_INVALID_LEVEL
);
2325 /* Call to services.exe using RPC */
2326 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2332 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2334 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2338 if (dwError
!= ERROR_SUCCESS
)
2340 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2341 SetLastError(dwError
);
2349 /**********************************************************************
2355 StartServiceA(SC_HANDLE hService
,
2356 DWORD dwNumServiceArgs
,
2357 LPCSTR
*lpServiceArgVectors
)
2363 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2365 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2367 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2369 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2373 if (dwError
!= ERROR_SUCCESS
)
2375 TRACE("RStartServiceA() failed (Error %lu)\n", dwError
);
2376 SetLastError(dwError
);
2384 /**********************************************************************
2390 StartServiceW(SC_HANDLE hService
,
2391 DWORD dwNumServiceArgs
,
2392 LPCWSTR
*lpServiceArgVectors
)
2398 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2400 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2402 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2404 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2408 if (dwError
!= ERROR_SUCCESS
)
2410 TRACE("RStartServiceW() failed (Error %lu)\n", dwError
);
2411 SetLastError(dwError
);
2419 /**********************************************************************
2420 * UnlockServiceDatabase
2425 UnlockServiceDatabase(SC_LOCK ScLock
)
2429 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2433 /* Call to services.exe using RPC */
2434 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2436 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2438 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2442 if (dwError
!= ERROR_SUCCESS
)
2444 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2445 SetLastError(dwError
);
2453 /**********************************************************************
2454 * NotifyBootConfigStatus
2459 NotifyBootConfigStatus(BOOL BootAcceptable
)
2463 TRACE("NotifyBootConfigStatus()\n");
2467 /* Call to services.exe using RPC */
2468 dwError
= RNotifyBootConfigStatus(NULL
,
2471 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2473 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2477 if (dwError
!= ERROR_SUCCESS
)
2479 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2480 SetLastError(dwError
);