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 /**********************************************************************
868 EnumServiceGroupW(SC_HANDLE hSCManager
,
870 DWORD dwServiceState
,
871 LPENUM_SERVICE_STATUSW lpServices
,
873 LPDWORD pcbBytesNeeded
,
874 LPDWORD lpServicesReturned
,
875 LPDWORD lpResumeHandle
,
878 LPENUM_SERVICE_STATUSW lpStatusPtr
;
882 TRACE("EnumServiceGroupW() called\n");
886 SetLastError(ERROR_INVALID_HANDLE
);
894 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
905 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
916 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
918 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
922 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
924 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
925 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
927 if (lpStatusPtr
->lpServiceName
)
928 lpStatusPtr
->lpServiceName
=
929 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
931 if (lpStatusPtr
->lpDisplayName
)
932 lpStatusPtr
->lpDisplayName
=
933 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
939 if (dwError
!= ERROR_SUCCESS
)
941 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
942 SetLastError(dwError
);
946 TRACE("EnumServiceGroupW() done\n");
952 /**********************************************************************
953 * EnumServicesStatusA
958 EnumServicesStatusA(SC_HANDLE hSCManager
,
960 DWORD dwServiceState
,
961 LPENUM_SERVICE_STATUSA lpServices
,
963 LPDWORD pcbBytesNeeded
,
964 LPDWORD lpServicesReturned
,
965 LPDWORD lpResumeHandle
)
967 LPENUM_SERVICE_STATUSA lpStatusPtr
;
971 TRACE("EnumServicesStatusA() called\n");
975 SetLastError(ERROR_INVALID_HANDLE
);
979 if (dwServiceType
!= SERVICE_DRIVER
&& dwServiceType
!= SERVICE_WIN32
)
981 if (pcbBytesNeeded
&& lpServicesReturned
)
984 *lpServicesReturned
= 0;
987 SetLastError(ERROR_INVALID_PARAMETER
);
991 if (dwServiceState
!= SERVICE_ACTIVE
&& dwServiceState
!= SERVICE_INACTIVE
&& dwServiceState
!= SERVICE_STATE_ALL
)
996 if (lpServicesReturned
)
997 *lpServicesReturned
= 0;
999 SetLastError(ERROR_INVALID_PARAMETER
);
1003 if (!pcbBytesNeeded
|| !lpServicesReturned
)
1005 SetLastError(ERROR_INVALID_ADDRESS
);
1009 if (!lpServices
&& cbBufSize
!= 0)
1011 SetLastError(ERROR_INVALID_ADDRESS
);
1017 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1026 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1028 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1032 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1034 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
1035 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1037 if (lpStatusPtr
->lpServiceName
)
1038 lpStatusPtr
->lpServiceName
=
1039 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1041 if (lpStatusPtr
->lpDisplayName
)
1042 lpStatusPtr
->lpDisplayName
=
1043 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1049 if (dwError
!= ERROR_SUCCESS
)
1051 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1052 SetLastError(dwError
);
1056 TRACE("EnumServicesStatusA() done\n");
1062 /**********************************************************************
1063 * EnumServicesStatusW
1068 EnumServicesStatusW(SC_HANDLE hSCManager
,
1069 DWORD dwServiceType
,
1070 DWORD dwServiceState
,
1071 LPENUM_SERVICE_STATUSW lpServices
,
1073 LPDWORD pcbBytesNeeded
,
1074 LPDWORD lpServicesReturned
,
1075 LPDWORD lpResumeHandle
)
1077 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1081 TRACE("EnumServicesStatusW() called\n");
1085 SetLastError(ERROR_INVALID_HANDLE
);
1091 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1100 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1102 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1106 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1108 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1109 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1111 if (lpStatusPtr
->lpServiceName
)
1112 lpStatusPtr
->lpServiceName
=
1113 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1115 if (lpStatusPtr
->lpDisplayName
)
1116 lpStatusPtr
->lpDisplayName
=
1117 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1123 if (dwError
!= ERROR_SUCCESS
)
1125 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1126 SetLastError(dwError
);
1130 TRACE("EnumServicesStatusW() done\n");
1136 /**********************************************************************
1137 * EnumServicesStatusExA
1142 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1143 SC_ENUM_TYPE InfoLevel
,
1144 DWORD dwServiceType
,
1145 DWORD dwServiceState
,
1148 LPDWORD pcbBytesNeeded
,
1149 LPDWORD lpServicesReturned
,
1150 LPDWORD lpResumeHandle
,
1151 LPCSTR pszGroupName
)
1153 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1157 TRACE("EnumServicesStatusExA() called\n");
1159 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1161 SetLastError(ERROR_INVALID_LEVEL
);
1167 SetLastError(ERROR_INVALID_HANDLE
);
1173 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1182 (LPSTR
)pszGroupName
);
1184 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1186 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1190 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1192 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1193 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1195 if (lpStatusPtr
->lpServiceName
)
1196 lpStatusPtr
->lpServiceName
=
1197 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1199 if (lpStatusPtr
->lpDisplayName
)
1200 lpStatusPtr
->lpDisplayName
=
1201 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1207 if (dwError
!= ERROR_SUCCESS
)
1209 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1210 SetLastError(dwError
);
1214 TRACE("EnumServicesStatusExA() done\n");
1220 /**********************************************************************
1221 * EnumServicesStatusExW
1226 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1227 SC_ENUM_TYPE InfoLevel
,
1228 DWORD dwServiceType
,
1229 DWORD dwServiceState
,
1232 LPDWORD pcbBytesNeeded
,
1233 LPDWORD lpServicesReturned
,
1234 LPDWORD lpResumeHandle
,
1235 LPCWSTR pszGroupName
)
1237 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1241 TRACE("EnumServicesStatusExW() called\n");
1245 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1254 (LPWSTR
)pszGroupName
);
1256 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1258 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1262 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1264 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1265 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1267 if (lpStatusPtr
->lpServiceName
)
1268 lpStatusPtr
->lpServiceName
=
1269 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1271 if (lpStatusPtr
->lpDisplayName
)
1272 lpStatusPtr
->lpDisplayName
=
1273 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1279 if (dwError
!= ERROR_SUCCESS
)
1281 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1282 SetLastError(dwError
);
1286 TRACE("EnumServicesStatusExW() done\n");
1292 /**********************************************************************
1293 * GetServiceDisplayNameA
1298 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1299 LPCSTR lpServiceName
,
1300 LPSTR lpDisplayName
,
1301 LPDWORD lpcchBuffer
)
1305 CHAR szEmptyName
[] = "";
1307 TRACE("GetServiceDisplayNameA() called\n");
1308 TRACE("%p %s %p %p\n", hSCManager
,
1309 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1313 SetLastError(ERROR_INVALID_HANDLE
);
1317 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1319 lpNameBuffer
= szEmptyName
;
1320 *lpcchBuffer
= sizeof(CHAR
);
1324 lpNameBuffer
= lpDisplayName
;
1329 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1334 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1336 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1337 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1341 if (dwError
!= ERROR_SUCCESS
)
1343 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1344 SetLastError(dwError
);
1352 /**********************************************************************
1353 * GetServiceDisplayNameW
1358 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1359 LPCWSTR lpServiceName
,
1360 LPWSTR lpDisplayName
,
1361 LPDWORD lpcchBuffer
)
1364 LPWSTR lpNameBuffer
;
1365 WCHAR szEmptyName
[] = L
"";
1367 TRACE("GetServiceDisplayNameW() called\n");
1371 SetLastError(ERROR_INVALID_HANDLE
);
1375 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1377 lpNameBuffer
= szEmptyName
;
1378 *lpcchBuffer
= sizeof(WCHAR
);
1382 lpNameBuffer
= lpDisplayName
;
1387 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1392 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1394 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1398 if (dwError
!= ERROR_SUCCESS
)
1400 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1401 SetLastError(dwError
);
1409 /**********************************************************************
1410 * GetServiceKeyNameA
1415 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1416 LPCSTR lpDisplayName
,
1417 LPSTR lpServiceName
,
1418 LPDWORD lpcchBuffer
)
1422 CHAR szEmptyName
[] = "";
1424 TRACE("GetServiceKeyNameA() called\n");
1428 SetLastError(ERROR_INVALID_HANDLE
);
1432 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1434 lpNameBuffer
= szEmptyName
;
1435 *lpcchBuffer
= sizeof(CHAR
);
1439 lpNameBuffer
= lpServiceName
;
1444 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1449 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1451 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1455 if (dwError
!= ERROR_SUCCESS
)
1457 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1458 SetLastError(dwError
);
1466 /**********************************************************************
1467 * GetServiceKeyNameW
1472 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1473 LPCWSTR lpDisplayName
,
1474 LPWSTR lpServiceName
,
1475 LPDWORD lpcchBuffer
)
1478 LPWSTR lpNameBuffer
;
1479 WCHAR szEmptyName
[] = L
"";
1481 TRACE("GetServiceKeyNameW() called\n");
1485 SetLastError(ERROR_INVALID_HANDLE
);
1489 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1491 lpNameBuffer
= szEmptyName
;
1492 *lpcchBuffer
= sizeof(WCHAR
);
1496 lpNameBuffer
= lpServiceName
;
1501 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1506 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1508 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1512 if (dwError
!= ERROR_SUCCESS
)
1514 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1515 SetLastError(dwError
);
1523 /**********************************************************************
1524 * LockServiceDatabase
1529 LockServiceDatabase(SC_HANDLE hSCManager
)
1534 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1538 /* Call to services.exe using RPC */
1539 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1540 (SC_RPC_LOCK
*)&hLock
);
1542 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1544 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1548 if (dwError
!= ERROR_SUCCESS
)
1550 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1551 SetLastError(dwError
);
1555 TRACE("hLock = %p\n", hLock
);
1562 WaitForSCManager(VOID
)
1566 TRACE("WaitForSCManager() called\n");
1568 /* Try to open the existing event */
1569 hEvent
= OpenEventW(SYNCHRONIZE
,
1571 L
"SvcctrlStartEvent_A3752DX");
1574 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1577 /* Try to create a new event */
1578 hEvent
= CreateEventW(NULL
,
1581 L
"SvcctrlStartEvent_A3752DX");
1584 /* Try to open the existing event again */
1585 hEvent
= OpenEventW(SYNCHRONIZE
,
1587 L
"SvcctrlStartEvent_A3752DX");
1593 /* Wait for 3 minutes */
1594 WaitForSingleObject(hEvent
, 180000);
1595 CloseHandle(hEvent
);
1597 TRACE("ScmWaitForSCManager() done\n");
1601 /**********************************************************************
1607 OpenSCManagerA(LPCSTR lpMachineName
,
1608 LPCSTR lpDatabaseName
,
1609 DWORD dwDesiredAccess
)
1611 SC_HANDLE hScm
= NULL
;
1614 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1615 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1621 /* Call to services.exe using RPC */
1622 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1623 (LPSTR
)lpDatabaseName
,
1625 (SC_RPC_HANDLE
*)&hScm
);
1627 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1629 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1633 if (dwError
!= ERROR_SUCCESS
)
1635 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1636 SetLastError(dwError
);
1640 TRACE("hScm = %p\n", hScm
);
1646 /**********************************************************************
1652 OpenSCManagerW(LPCWSTR lpMachineName
,
1653 LPCWSTR lpDatabaseName
,
1654 DWORD dwDesiredAccess
)
1656 SC_HANDLE hScm
= NULL
;
1659 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1660 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1666 /* Call to services.exe using RPC */
1667 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1668 (LPWSTR
)lpDatabaseName
,
1670 (SC_RPC_HANDLE
*)&hScm
);
1672 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1674 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1678 if (dwError
!= ERROR_SUCCESS
)
1680 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1681 SetLastError(dwError
);
1685 TRACE("hScm = %p\n", hScm
);
1691 /**********************************************************************
1697 OpenServiceA(SC_HANDLE hSCManager
,
1698 LPCSTR lpServiceName
,
1699 DWORD dwDesiredAccess
)
1701 SC_HANDLE hService
= NULL
;
1704 TRACE("OpenServiceA(%p, %s, %lx)\n",
1705 hSCManager
, lpServiceName
, dwDesiredAccess
);
1709 SetLastError(ERROR_INVALID_HANDLE
);
1715 /* Call to services.exe using RPC */
1716 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1717 (LPSTR
)lpServiceName
,
1719 (SC_RPC_HANDLE
*)&hService
);
1721 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1723 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1727 if (dwError
!= ERROR_SUCCESS
)
1729 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1730 SetLastError(dwError
);
1734 TRACE("hService = %p\n", hService
);
1740 /**********************************************************************
1746 OpenServiceW(SC_HANDLE hSCManager
,
1747 LPCWSTR lpServiceName
,
1748 DWORD dwDesiredAccess
)
1750 SC_HANDLE hService
= NULL
;
1753 TRACE("OpenServiceW(%p, %S, %lx)\n",
1754 hSCManager
, lpServiceName
, dwDesiredAccess
);
1758 SetLastError(ERROR_INVALID_HANDLE
);
1764 /* Call to services.exe using RPC */
1765 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1766 (LPWSTR
)lpServiceName
,
1768 (SC_RPC_HANDLE
*)&hService
);
1770 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1772 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1776 if (dwError
!= ERROR_SUCCESS
)
1778 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1779 SetLastError(dwError
);
1783 TRACE("hService = %p\n", hService
);
1789 /**********************************************************************
1790 * QueryServiceConfigA
1795 QueryServiceConfigA(SC_HANDLE hService
,
1796 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1798 LPDWORD pcbBytesNeeded
)
1802 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1803 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1807 /* Call to services.exe using RPC */
1808 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1809 (LPBYTE
)lpServiceConfig
,
1813 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1815 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1819 if (dwError
!= ERROR_SUCCESS
)
1821 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1822 SetLastError(dwError
);
1826 /* Adjust the pointers */
1827 if (lpServiceConfig
->lpBinaryPathName
)
1828 lpServiceConfig
->lpBinaryPathName
=
1829 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1830 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1832 if (lpServiceConfig
->lpLoadOrderGroup
)
1833 lpServiceConfig
->lpLoadOrderGroup
=
1834 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1835 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1837 if (lpServiceConfig
->lpDependencies
)
1838 lpServiceConfig
->lpDependencies
=
1839 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1840 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1842 if (lpServiceConfig
->lpServiceStartName
)
1843 lpServiceConfig
->lpServiceStartName
=
1844 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1845 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1847 if (lpServiceConfig
->lpDisplayName
)
1848 lpServiceConfig
->lpDisplayName
=
1849 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1850 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1852 TRACE("QueryServiceConfigA() done\n");
1858 /**********************************************************************
1859 * QueryServiceConfigW
1864 QueryServiceConfigW(SC_HANDLE hService
,
1865 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1867 LPDWORD pcbBytesNeeded
)
1871 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1872 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1875 *pcbBytesNeeded
= 0;
1879 /* Call to services.exe using RPC */
1880 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1881 (LPBYTE
)lpServiceConfig
,
1885 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1887 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1891 if (dwError
!= ERROR_SUCCESS
)
1893 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1894 SetLastError(dwError
);
1898 /* Adjust the pointers */
1899 if (lpServiceConfig
->lpBinaryPathName
)
1900 lpServiceConfig
->lpBinaryPathName
=
1901 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1902 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1904 if (lpServiceConfig
->lpLoadOrderGroup
)
1905 lpServiceConfig
->lpLoadOrderGroup
=
1906 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1907 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1909 if (lpServiceConfig
->lpDependencies
)
1910 lpServiceConfig
->lpDependencies
=
1911 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1912 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1914 if (lpServiceConfig
->lpServiceStartName
)
1915 lpServiceConfig
->lpServiceStartName
=
1916 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1917 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1919 if (lpServiceConfig
->lpDisplayName
)
1920 lpServiceConfig
->lpDisplayName
=
1921 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1922 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1924 TRACE("QueryServiceConfigW() done\n");
1930 /**********************************************************************
1931 * QueryServiceConfig2A
1936 QueryServiceConfig2A(SC_HANDLE hService
,
1940 LPDWORD pcbBytesNeeded
)
1944 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
1945 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
1947 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
1948 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
1950 SetLastError(ERROR_INVALID_LEVEL
);
1954 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
1955 pcbBytesNeeded
== NULL
)
1957 SetLastError(ERROR_INVALID_ADDRESS
);
1963 /* Call to services.exe using RPC */
1964 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
1970 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1972 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1976 if (dwError
!= ERROR_SUCCESS
)
1978 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
1979 SetLastError(dwError
);
1983 switch (dwInfoLevel
)
1985 case SERVICE_CONFIG_DESCRIPTION
:
1987 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
1989 if (lpPtr
->lpDescription
!= NULL
)
1990 lpPtr
->lpDescription
=
1991 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
1995 case SERVICE_CONFIG_FAILURE_ACTIONS
:
1997 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
1999 if (lpPtr
->lpRebootMsg
!= NULL
)
2000 lpPtr
->lpRebootMsg
=
2001 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2003 if (lpPtr
->lpCommand
!= NULL
)
2005 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2007 if (lpPtr
->lpsaActions
!= NULL
)
2008 lpPtr
->lpsaActions
=
2009 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2014 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2015 SetLastError(ERROR_INVALID_PARAMETER
);
2019 TRACE("QueryServiceConfig2A() done\n");
2025 /**********************************************************************
2026 * QueryServiceConfig2W
2031 QueryServiceConfig2W(SC_HANDLE hService
,
2035 LPDWORD pcbBytesNeeded
)
2039 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2040 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2042 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2043 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2045 SetLastError(ERROR_INVALID_LEVEL
);
2049 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2050 pcbBytesNeeded
== NULL
)
2052 SetLastError(ERROR_INVALID_ADDRESS
);
2058 /* Call to services.exe using RPC */
2059 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2065 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2067 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2071 if (dwError
!= ERROR_SUCCESS
)
2073 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2074 SetLastError(dwError
);
2078 switch (dwInfoLevel
)
2080 case SERVICE_CONFIG_DESCRIPTION
:
2082 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2084 if (lpPtr
->lpDescription
!= NULL
)
2085 lpPtr
->lpDescription
=
2086 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2090 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2092 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2094 if (lpPtr
->lpRebootMsg
!= NULL
)
2095 lpPtr
->lpRebootMsg
=
2096 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2098 if (lpPtr
->lpCommand
!= NULL
)
2100 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2102 if (lpPtr
->lpsaActions
!= NULL
)
2103 lpPtr
->lpsaActions
=
2104 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2109 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2110 SetLastError(ERROR_INVALID_PARAMETER
);
2114 TRACE("QueryServiceConfig2W() done\n");
2120 /**********************************************************************
2121 * QueryServiceLockStatusA
2126 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2127 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2129 LPDWORD pcbBytesNeeded
)
2133 TRACE("QueryServiceLockStatusA() called\n");
2137 /* Call to services.exe using RPC */
2138 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2143 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2145 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2149 if (dwError
!= ERROR_SUCCESS
)
2151 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2152 SetLastError(dwError
);
2156 if (lpLockStatus
->lpLockOwner
!= NULL
)
2158 lpLockStatus
->lpLockOwner
=
2159 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2162 TRACE("QueryServiceLockStatusA() done\n");
2168 /**********************************************************************
2169 * QueryServiceLockStatusW
2174 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2175 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2177 LPDWORD pcbBytesNeeded
)
2181 TRACE("QueryServiceLockStatusW() called\n");
2185 /* Call to services.exe using RPC */
2186 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2191 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2193 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2197 if (dwError
!= ERROR_SUCCESS
)
2199 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2200 SetLastError(dwError
);
2204 if (lpLockStatus
->lpLockOwner
!= NULL
)
2206 lpLockStatus
->lpLockOwner
=
2207 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2210 TRACE("QueryServiceLockStatusW() done\n");
2216 /**********************************************************************
2217 * QueryServiceObjectSecurity
2222 QueryServiceObjectSecurity(SC_HANDLE hService
,
2223 SECURITY_INFORMATION dwSecurityInformation
,
2224 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2226 LPDWORD pcbBytesNeeded
)
2230 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2231 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2235 /* Call to services.exe using RPC */
2236 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2237 dwSecurityInformation
,
2238 (LPBYTE
)lpSecurityDescriptor
,
2242 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2244 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2248 if (dwError
!= ERROR_SUCCESS
)
2250 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2251 SetLastError(dwError
);
2258 /**********************************************************************
2259 * SetServiceObjectSecurity
2264 SetServiceObjectSecurity(SC_HANDLE hService
,
2265 SECURITY_INFORMATION dwSecurityInformation
,
2266 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2268 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2274 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2277 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2279 SetLastError(ERROR_INVALID_PARAMETER
);
2283 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2284 if (SelfRelativeSD
== NULL
)
2286 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2290 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2293 if (!NT_SUCCESS(Status
))
2295 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2296 SetLastError(RtlNtStatusToDosError(Status
));
2302 /* Call to services.exe using RPC */
2303 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2304 dwSecurityInformation
,
2305 (LPBYTE
)SelfRelativeSD
,
2308 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2310 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2314 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2316 if (dwError
!= ERROR_SUCCESS
)
2318 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2319 SetLastError(dwError
);
2327 /**********************************************************************
2328 * QueryServiceStatus
2333 QueryServiceStatus(SC_HANDLE hService
,
2334 LPSERVICE_STATUS lpServiceStatus
)
2338 TRACE("QueryServiceStatus(%p, %p)\n",
2339 hService
, lpServiceStatus
);
2343 SetLastError(ERROR_INVALID_HANDLE
);
2349 /* Call to services.exe using RPC */
2350 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2353 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2355 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2359 if (dwError
!= ERROR_SUCCESS
)
2361 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2362 SetLastError(dwError
);
2370 /**********************************************************************
2371 * QueryServiceStatusEx
2376 QueryServiceStatusEx(SC_HANDLE hService
,
2377 SC_STATUS_TYPE InfoLevel
,
2380 LPDWORD pcbBytesNeeded
)
2384 TRACE("QueryServiceStatusEx() called\n");
2386 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2388 SetLastError(ERROR_INVALID_LEVEL
);
2394 /* Call to services.exe using RPC */
2395 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2401 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2403 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2407 if (dwError
!= ERROR_SUCCESS
)
2409 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2410 SetLastError(dwError
);
2418 /**********************************************************************
2424 StartServiceA(SC_HANDLE hService
,
2425 DWORD dwNumServiceArgs
,
2426 LPCSTR
*lpServiceArgVectors
)
2432 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2434 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2436 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2438 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2442 if (dwError
!= ERROR_SUCCESS
)
2444 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2445 SetLastError(dwError
);
2453 /**********************************************************************
2459 StartServiceW(SC_HANDLE hService
,
2460 DWORD dwNumServiceArgs
,
2461 LPCWSTR
*lpServiceArgVectors
)
2467 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2469 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2471 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2473 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2477 if (dwError
!= ERROR_SUCCESS
)
2479 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2480 SetLastError(dwError
);
2488 /**********************************************************************
2489 * UnlockServiceDatabase
2494 UnlockServiceDatabase(SC_LOCK ScLock
)
2498 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2502 /* Call to services.exe using RPC */
2503 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2505 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2507 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2511 if (dwError
!= ERROR_SUCCESS
)
2513 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2514 SetLastError(dwError
);
2522 /**********************************************************************
2523 * NotifyBootConfigStatus
2528 NotifyBootConfigStatus(BOOL BootAcceptable
)
2532 TRACE("NotifyBootConfigStatus()\n");
2536 /* Call to services.exe using RPC */
2537 dwError
= RNotifyBootConfigStatus(NULL
,
2540 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2542 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2546 if (dwError
!= ERROR_SUCCESS
)
2548 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2549 SetLastError(dwError
);