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 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1154 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1159 TRACE("EnumServicesStatusExA() called\n");
1161 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1163 SetLastError(ERROR_INVALID_LEVEL
);
1169 SetLastError(ERROR_INVALID_HANDLE
);
1173 if (lpServices
== NULL
||
1174 cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1176 lpStatusPtr
= &ServiceStatus
;
1177 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1181 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1182 dwBufferSize
= cbBufSize
;
1187 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1191 (LPBYTE
)lpStatusPtr
,
1196 (LPSTR
)pszGroupName
);
1198 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1200 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1204 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1206 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1208 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1210 if (lpStatusPtr
->lpServiceName
)
1211 lpStatusPtr
->lpServiceName
=
1212 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1214 if (lpStatusPtr
->lpDisplayName
)
1215 lpStatusPtr
->lpDisplayName
=
1216 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1223 if (dwError
!= ERROR_SUCCESS
)
1225 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1226 SetLastError(dwError
);
1230 TRACE("EnumServicesStatusExA() done\n");
1236 /**********************************************************************
1237 * EnumServicesStatusExW
1242 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1243 SC_ENUM_TYPE InfoLevel
,
1244 DWORD dwServiceType
,
1245 DWORD dwServiceState
,
1248 LPDWORD pcbBytesNeeded
,
1249 LPDWORD lpServicesReturned
,
1250 LPDWORD lpResumeHandle
,
1251 LPCWSTR pszGroupName
)
1253 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1254 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1259 TRACE("EnumServicesStatusExW() called\n");
1261 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1263 SetLastError(ERROR_INVALID_LEVEL
);
1267 if (lpServices
== NULL
||
1268 cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1270 lpStatusPtr
= &ServiceStatus
;
1271 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1275 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1276 dwBufferSize
= cbBufSize
;
1281 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1285 (LPBYTE
)lpStatusPtr
,
1290 (LPWSTR
)pszGroupName
);
1292 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1294 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1298 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1300 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1302 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1304 if (lpStatusPtr
->lpServiceName
)
1305 lpStatusPtr
->lpServiceName
=
1306 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1308 if (lpStatusPtr
->lpDisplayName
)
1309 lpStatusPtr
->lpDisplayName
=
1310 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1317 if (dwError
!= ERROR_SUCCESS
)
1319 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1320 SetLastError(dwError
);
1324 TRACE("EnumServicesStatusExW() done\n");
1330 /**********************************************************************
1331 * GetServiceDisplayNameA
1336 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1337 LPCSTR lpServiceName
,
1338 LPSTR lpDisplayName
,
1339 LPDWORD lpcchBuffer
)
1343 CHAR szEmptyName
[] = "";
1345 TRACE("GetServiceDisplayNameA() called\n");
1346 TRACE("%p %s %p %p\n", hSCManager
,
1347 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1351 SetLastError(ERROR_INVALID_HANDLE
);
1355 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1357 lpNameBuffer
= szEmptyName
;
1358 *lpcchBuffer
= sizeof(CHAR
);
1362 lpNameBuffer
= lpDisplayName
;
1367 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1372 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1374 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1375 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1379 if (dwError
!= ERROR_SUCCESS
)
1381 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1382 SetLastError(dwError
);
1390 /**********************************************************************
1391 * GetServiceDisplayNameW
1396 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1397 LPCWSTR lpServiceName
,
1398 LPWSTR lpDisplayName
,
1399 LPDWORD lpcchBuffer
)
1402 LPWSTR lpNameBuffer
;
1403 WCHAR szEmptyName
[] = L
"";
1405 TRACE("GetServiceDisplayNameW() called\n");
1409 SetLastError(ERROR_INVALID_HANDLE
);
1413 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1415 lpNameBuffer
= szEmptyName
;
1416 *lpcchBuffer
= sizeof(WCHAR
);
1420 lpNameBuffer
= lpDisplayName
;
1425 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1430 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1432 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1436 if (dwError
!= ERROR_SUCCESS
)
1438 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1439 SetLastError(dwError
);
1447 /**********************************************************************
1448 * GetServiceKeyNameA
1453 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1454 LPCSTR lpDisplayName
,
1455 LPSTR lpServiceName
,
1456 LPDWORD lpcchBuffer
)
1460 CHAR szEmptyName
[] = "";
1462 TRACE("GetServiceKeyNameA() called\n");
1466 SetLastError(ERROR_INVALID_HANDLE
);
1470 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1472 lpNameBuffer
= szEmptyName
;
1473 *lpcchBuffer
= sizeof(CHAR
);
1477 lpNameBuffer
= lpServiceName
;
1482 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1487 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1489 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1493 if (dwError
!= ERROR_SUCCESS
)
1495 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1496 SetLastError(dwError
);
1504 /**********************************************************************
1505 * GetServiceKeyNameW
1510 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1511 LPCWSTR lpDisplayName
,
1512 LPWSTR lpServiceName
,
1513 LPDWORD lpcchBuffer
)
1516 LPWSTR lpNameBuffer
;
1517 WCHAR szEmptyName
[] = L
"";
1519 TRACE("GetServiceKeyNameW() called\n");
1523 SetLastError(ERROR_INVALID_HANDLE
);
1527 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1529 lpNameBuffer
= szEmptyName
;
1530 *lpcchBuffer
= sizeof(WCHAR
);
1534 lpNameBuffer
= lpServiceName
;
1539 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1544 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1546 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1550 if (dwError
!= ERROR_SUCCESS
)
1552 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1553 SetLastError(dwError
);
1561 /**********************************************************************
1562 * LockServiceDatabase
1567 LockServiceDatabase(SC_HANDLE hSCManager
)
1572 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1576 /* Call to services.exe using RPC */
1577 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1578 (SC_RPC_LOCK
*)&hLock
);
1580 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1582 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1586 if (dwError
!= ERROR_SUCCESS
)
1588 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1589 SetLastError(dwError
);
1593 TRACE("hLock = %p\n", hLock
);
1600 WaitForSCManager(VOID
)
1604 TRACE("WaitForSCManager() called\n");
1606 /* Try to open the existing event */
1607 hEvent
= OpenEventW(SYNCHRONIZE
,
1609 L
"SvcctrlStartEvent_A3752DX");
1612 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1615 /* Try to create a new event */
1616 hEvent
= CreateEventW(NULL
,
1619 L
"SvcctrlStartEvent_A3752DX");
1622 /* Try to open the existing event again */
1623 hEvent
= OpenEventW(SYNCHRONIZE
,
1625 L
"SvcctrlStartEvent_A3752DX");
1631 /* Wait for 3 minutes */
1632 WaitForSingleObject(hEvent
, 180000);
1633 CloseHandle(hEvent
);
1635 TRACE("ScmWaitForSCManager() done\n");
1639 /**********************************************************************
1645 OpenSCManagerA(LPCSTR lpMachineName
,
1646 LPCSTR lpDatabaseName
,
1647 DWORD dwDesiredAccess
)
1649 SC_HANDLE hScm
= NULL
;
1652 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1653 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1659 /* Call to services.exe using RPC */
1660 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1661 (LPSTR
)lpDatabaseName
,
1663 (SC_RPC_HANDLE
*)&hScm
);
1665 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1667 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1671 if (dwError
!= ERROR_SUCCESS
)
1673 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1674 SetLastError(dwError
);
1678 TRACE("hScm = %p\n", hScm
);
1684 /**********************************************************************
1690 OpenSCManagerW(LPCWSTR lpMachineName
,
1691 LPCWSTR lpDatabaseName
,
1692 DWORD dwDesiredAccess
)
1694 SC_HANDLE hScm
= NULL
;
1697 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1698 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1704 /* Call to services.exe using RPC */
1705 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1706 (LPWSTR
)lpDatabaseName
,
1708 (SC_RPC_HANDLE
*)&hScm
);
1710 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1712 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1716 if (dwError
!= ERROR_SUCCESS
)
1718 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1719 SetLastError(dwError
);
1723 TRACE("hScm = %p\n", hScm
);
1729 /**********************************************************************
1735 OpenServiceA(SC_HANDLE hSCManager
,
1736 LPCSTR lpServiceName
,
1737 DWORD dwDesiredAccess
)
1739 SC_HANDLE hService
= NULL
;
1742 TRACE("OpenServiceA(%p, %s, %lx)\n",
1743 hSCManager
, lpServiceName
, dwDesiredAccess
);
1747 SetLastError(ERROR_INVALID_HANDLE
);
1753 /* Call to services.exe using RPC */
1754 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1755 (LPSTR
)lpServiceName
,
1757 (SC_RPC_HANDLE
*)&hService
);
1759 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1761 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1765 if (dwError
!= ERROR_SUCCESS
)
1767 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1768 SetLastError(dwError
);
1772 TRACE("hService = %p\n", hService
);
1778 /**********************************************************************
1784 OpenServiceW(SC_HANDLE hSCManager
,
1785 LPCWSTR lpServiceName
,
1786 DWORD dwDesiredAccess
)
1788 SC_HANDLE hService
= NULL
;
1791 TRACE("OpenServiceW(%p, %S, %lx)\n",
1792 hSCManager
, lpServiceName
, dwDesiredAccess
);
1796 SetLastError(ERROR_INVALID_HANDLE
);
1802 /* Call to services.exe using RPC */
1803 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1804 (LPWSTR
)lpServiceName
,
1806 (SC_RPC_HANDLE
*)&hService
);
1808 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1810 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1814 if (dwError
!= ERROR_SUCCESS
)
1816 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1817 SetLastError(dwError
);
1821 TRACE("hService = %p\n", hService
);
1827 /**********************************************************************
1828 * QueryServiceConfigA
1833 QueryServiceConfigA(SC_HANDLE hService
,
1834 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1836 LPDWORD pcbBytesNeeded
)
1838 QUERY_SERVICE_CONFIGA ServiceConfig
;
1839 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1843 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1844 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1846 if (lpServiceConfig
== NULL
||
1847 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1849 lpConfigPtr
= &ServiceConfig
;
1850 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1854 lpConfigPtr
= lpServiceConfig
;
1855 dwBufferSize
= cbBufSize
;
1860 /* Call to services.exe using RPC */
1861 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1862 (LPBYTE
)lpConfigPtr
,
1866 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1868 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1872 if (dwError
!= ERROR_SUCCESS
)
1874 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1875 SetLastError(dwError
);
1879 /* Adjust the pointers */
1880 if (lpConfigPtr
->lpBinaryPathName
)
1881 lpConfigPtr
->lpBinaryPathName
=
1882 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1883 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
1885 if (lpConfigPtr
->lpLoadOrderGroup
)
1886 lpConfigPtr
->lpLoadOrderGroup
=
1887 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1888 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
1890 if (lpConfigPtr
->lpDependencies
)
1891 lpConfigPtr
->lpDependencies
=
1892 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1893 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
1895 if (lpConfigPtr
->lpServiceStartName
)
1896 lpConfigPtr
->lpServiceStartName
=
1897 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1898 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
1900 if (lpConfigPtr
->lpDisplayName
)
1901 lpConfigPtr
->lpDisplayName
=
1902 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1903 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
1905 TRACE("QueryServiceConfigA() done\n");
1911 /**********************************************************************
1912 * QueryServiceConfigW
1917 QueryServiceConfigW(SC_HANDLE hService
,
1918 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1920 LPDWORD pcbBytesNeeded
)
1922 QUERY_SERVICE_CONFIGW ServiceConfig
;
1923 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
1927 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1928 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1930 if (lpServiceConfig
== NULL
||
1931 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
1933 lpConfigPtr
= &ServiceConfig
;
1934 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1938 lpConfigPtr
= lpServiceConfig
;
1939 dwBufferSize
= cbBufSize
;
1944 /* Call to services.exe using RPC */
1945 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1946 (LPBYTE
)lpConfigPtr
,
1950 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1952 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1956 if (dwError
!= ERROR_SUCCESS
)
1958 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1959 SetLastError(dwError
);
1963 /* Adjust the pointers */
1964 if (lpConfigPtr
->lpBinaryPathName
)
1965 lpConfigPtr
->lpBinaryPathName
=
1966 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
1967 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
1969 if (lpConfigPtr
->lpLoadOrderGroup
)
1970 lpConfigPtr
->lpLoadOrderGroup
=
1971 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
1972 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
1974 if (lpConfigPtr
->lpDependencies
)
1975 lpConfigPtr
->lpDependencies
=
1976 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
1977 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
1979 if (lpConfigPtr
->lpServiceStartName
)
1980 lpConfigPtr
->lpServiceStartName
=
1981 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
1982 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
1984 if (lpConfigPtr
->lpDisplayName
)
1985 lpConfigPtr
->lpDisplayName
=
1986 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
1987 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
1989 TRACE("QueryServiceConfigW() done\n");
1995 /**********************************************************************
1996 * QueryServiceConfig2A
2001 QueryServiceConfig2A(SC_HANDLE hService
,
2005 LPDWORD pcbBytesNeeded
)
2009 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2010 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2012 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2013 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2015 SetLastError(ERROR_INVALID_LEVEL
);
2019 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2020 pcbBytesNeeded
== NULL
)
2022 SetLastError(ERROR_INVALID_ADDRESS
);
2028 /* Call to services.exe using RPC */
2029 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2035 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2037 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2041 if (dwError
!= ERROR_SUCCESS
)
2043 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2044 SetLastError(dwError
);
2048 switch (dwInfoLevel
)
2050 case SERVICE_CONFIG_DESCRIPTION
:
2052 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
2054 if (lpPtr
->lpDescription
!= NULL
)
2055 lpPtr
->lpDescription
=
2056 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2060 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2062 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
2064 if (lpPtr
->lpRebootMsg
!= NULL
)
2065 lpPtr
->lpRebootMsg
=
2066 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2068 if (lpPtr
->lpCommand
!= NULL
)
2070 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2072 if (lpPtr
->lpsaActions
!= NULL
)
2073 lpPtr
->lpsaActions
=
2074 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2079 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2080 SetLastError(ERROR_INVALID_PARAMETER
);
2084 TRACE("QueryServiceConfig2A() done\n");
2090 /**********************************************************************
2091 * QueryServiceConfig2W
2096 QueryServiceConfig2W(SC_HANDLE hService
,
2100 LPDWORD pcbBytesNeeded
)
2104 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2105 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2107 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2108 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2110 SetLastError(ERROR_INVALID_LEVEL
);
2114 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2115 pcbBytesNeeded
== NULL
)
2117 SetLastError(ERROR_INVALID_ADDRESS
);
2123 /* Call to services.exe using RPC */
2124 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2130 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2132 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2136 if (dwError
!= ERROR_SUCCESS
)
2138 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2139 SetLastError(dwError
);
2143 switch (dwInfoLevel
)
2145 case SERVICE_CONFIG_DESCRIPTION
:
2147 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2149 if (lpPtr
->lpDescription
!= NULL
)
2150 lpPtr
->lpDescription
=
2151 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2155 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2157 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2159 if (lpPtr
->lpRebootMsg
!= NULL
)
2160 lpPtr
->lpRebootMsg
=
2161 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2163 if (lpPtr
->lpCommand
!= NULL
)
2165 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2167 if (lpPtr
->lpsaActions
!= NULL
)
2168 lpPtr
->lpsaActions
=
2169 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2174 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2175 SetLastError(ERROR_INVALID_PARAMETER
);
2179 TRACE("QueryServiceConfig2W() done\n");
2185 /**********************************************************************
2186 * QueryServiceLockStatusA
2191 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2192 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2194 LPDWORD pcbBytesNeeded
)
2198 TRACE("QueryServiceLockStatusA() called\n");
2202 /* Call to services.exe using RPC */
2203 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2208 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2210 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2214 if (dwError
!= ERROR_SUCCESS
)
2216 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2217 SetLastError(dwError
);
2221 if (lpLockStatus
->lpLockOwner
!= NULL
)
2223 lpLockStatus
->lpLockOwner
=
2224 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2227 TRACE("QueryServiceLockStatusA() done\n");
2233 /**********************************************************************
2234 * QueryServiceLockStatusW
2239 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2240 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2242 LPDWORD pcbBytesNeeded
)
2246 TRACE("QueryServiceLockStatusW() called\n");
2250 /* Call to services.exe using RPC */
2251 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2256 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2258 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2262 if (dwError
!= ERROR_SUCCESS
)
2264 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2265 SetLastError(dwError
);
2269 if (lpLockStatus
->lpLockOwner
!= NULL
)
2271 lpLockStatus
->lpLockOwner
=
2272 (LPWSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2275 TRACE("QueryServiceLockStatusW() done\n");
2281 /**********************************************************************
2282 * QueryServiceObjectSecurity
2287 QueryServiceObjectSecurity(SC_HANDLE hService
,
2288 SECURITY_INFORMATION dwSecurityInformation
,
2289 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2291 LPDWORD pcbBytesNeeded
)
2295 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2296 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2300 /* Call to services.exe using RPC */
2301 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2302 dwSecurityInformation
,
2303 (LPBYTE
)lpSecurityDescriptor
,
2307 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2309 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2313 if (dwError
!= ERROR_SUCCESS
)
2315 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2316 SetLastError(dwError
);
2323 /**********************************************************************
2324 * SetServiceObjectSecurity
2329 SetServiceObjectSecurity(SC_HANDLE hService
,
2330 SECURITY_INFORMATION dwSecurityInformation
,
2331 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2333 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2339 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2342 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2344 SetLastError(ERROR_INVALID_PARAMETER
);
2348 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2349 if (SelfRelativeSD
== NULL
)
2351 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2355 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2358 if (!NT_SUCCESS(Status
))
2360 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2361 SetLastError(RtlNtStatusToDosError(Status
));
2367 /* Call to services.exe using RPC */
2368 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2369 dwSecurityInformation
,
2370 (LPBYTE
)SelfRelativeSD
,
2373 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2375 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2379 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2381 if (dwError
!= ERROR_SUCCESS
)
2383 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2384 SetLastError(dwError
);
2392 /**********************************************************************
2393 * QueryServiceStatus
2398 QueryServiceStatus(SC_HANDLE hService
,
2399 LPSERVICE_STATUS lpServiceStatus
)
2403 TRACE("QueryServiceStatus(%p, %p)\n",
2404 hService
, lpServiceStatus
);
2408 SetLastError(ERROR_INVALID_HANDLE
);
2414 /* Call to services.exe using RPC */
2415 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2418 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2420 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2424 if (dwError
!= ERROR_SUCCESS
)
2426 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2427 SetLastError(dwError
);
2435 /**********************************************************************
2436 * QueryServiceStatusEx
2441 QueryServiceStatusEx(SC_HANDLE hService
,
2442 SC_STATUS_TYPE InfoLevel
,
2445 LPDWORD pcbBytesNeeded
)
2449 TRACE("QueryServiceStatusEx() called\n");
2451 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2453 SetLastError(ERROR_INVALID_LEVEL
);
2459 /* Call to services.exe using RPC */
2460 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2466 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2468 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2472 if (dwError
!= ERROR_SUCCESS
)
2474 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2475 SetLastError(dwError
);
2483 /**********************************************************************
2489 StartServiceA(SC_HANDLE hService
,
2490 DWORD dwNumServiceArgs
,
2491 LPCSTR
*lpServiceArgVectors
)
2497 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2499 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2501 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2503 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2507 if (dwError
!= ERROR_SUCCESS
)
2509 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2510 SetLastError(dwError
);
2518 /**********************************************************************
2524 StartServiceW(SC_HANDLE hService
,
2525 DWORD dwNumServiceArgs
,
2526 LPCWSTR
*lpServiceArgVectors
)
2532 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2534 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2536 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2538 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2542 if (dwError
!= ERROR_SUCCESS
)
2544 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2545 SetLastError(dwError
);
2553 /**********************************************************************
2554 * UnlockServiceDatabase
2559 UnlockServiceDatabase(SC_LOCK ScLock
)
2563 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2567 /* Call to services.exe using RPC */
2568 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2570 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2572 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2576 if (dwError
!= ERROR_SUCCESS
)
2578 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2579 SetLastError(dwError
);
2587 /**********************************************************************
2588 * NotifyBootConfigStatus
2593 NotifyBootConfigStatus(BOOL BootAcceptable
)
2597 TRACE("NotifyBootConfigStatus()\n");
2601 /* Call to services.exe using RPC */
2602 dwError
= RNotifyBootConfigStatus(NULL
,
2605 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2607 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2611 if (dwError
!= ERROR_SUCCESS
)
2613 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2614 SetLastError(dwError
);