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 *****************************************************************/
24 handle_t BindingHandle
= NULL
;
29 LPWSTR pszStringBinding
;
32 if (BindingHandle
!= NULL
)
35 status
= RpcStringBindingComposeW(NULL
,
43 TRACE("RpcStringBindingCompose returned 0x%x\n", status
);
47 /* Set the binding handle that will be used to bind to the server. */
48 status
= RpcBindingFromStringBindingW(pszStringBinding
,
52 TRACE("RpcBindingFromStringBinding returned 0x%x\n", status
);
55 status
= RpcStringFreeW(&pszStringBinding
);
58 TRACE("RpcStringFree returned 0x%x\n", status
);
69 if (BindingHandle
== NULL
)
72 status
= RpcBindingFree(&BindingHandle
);
75 TRACE("RpcBindingFree returned 0x%x\n", status
);
81 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName
)
83 handle_t hBinding
= NULL
;
84 UCHAR
*pszStringBinding
;
87 ERR("SVCCTL_HANDLEA_bind() called\n");
89 status
= RpcStringBindingComposeA((UCHAR
*)szMachineName
,
92 (UCHAR
*)"\\pipe\\ntsvcs",
94 (UCHAR
**)&pszStringBinding
);
97 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
101 /* Set the binding handle that will be used to bind to the server. */
102 status
= RpcBindingFromStringBindingA(pszStringBinding
,
106 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
109 status
= RpcStringFreeA(&pszStringBinding
);
112 ERR("RpcStringFree returned 0x%x\n", status
);
120 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName
,
125 ERR("SVCCTL_HANDLEA_unbind() called\n");
127 status
= RpcBindingFree(&hBinding
);
130 ERR("RpcBindingFree returned 0x%x\n", status
);
136 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName
)
138 handle_t hBinding
= NULL
;
139 LPWSTR pszStringBinding
;
142 ERR("SVCCTL_HANDLEW_bind() called\n");
145 status
= RpcStringBindingComposeW(szMachineName
,
153 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
157 /* Set the binding handle that will be used to bind to the server. */
158 status
= RpcBindingFromStringBindingW(pszStringBinding
,
162 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
165 status
= RpcStringFreeW(&pszStringBinding
);
168 ERR("RpcStringFree returned 0x%x\n", status
);
176 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName
,
181 ERR("SVCCTL_HANDLEW_unbind() called\n");
183 status
= RpcBindingFree(&hBinding
);
186 ERR("RpcBindingFree returned 0x%x\n", status
);
192 RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus
)
194 handle_t hBinding
= NULL
;
195 LPWSTR pszStringBinding
;
198 ERR("RPC_SERVICE_STATUS_HANDLE_bind() called\n");
201 status
= RpcStringBindingComposeW(NULL
,
209 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
213 /* Set the binding handle that will be used to bind to the server. */
214 status
= RpcBindingFromStringBindingW(pszStringBinding
,
218 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
221 status
= RpcStringFreeW(&pszStringBinding
);
224 ERR("RpcStringFree returned 0x%x\n", status
);
232 RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus
,
237 ERR("RPC_SERVICE_STATUS_HANDLE_unbind() called\n");
239 status
= RpcBindingFree(&hBinding
);
242 ERR("RpcBindingFree returned 0x%x\n", status
);
248 ScmRpcStatusToWinError(RPC_STATUS Status
)
252 case RPC_X_SS_IN_NULL_CONTEXT
:
253 return ERROR_INVALID_HANDLE
;
255 case RPC_X_NULL_REF_POINTER
:
256 return ERROR_INVALID_PARAMETER
;
258 case STATUS_ACCESS_VIOLATION
:
259 return ERROR_INVALID_ADDRESS
;
262 return (DWORD
)Status
;
267 /**********************************************************************
268 * ChangeServiceConfig2A
273 ChangeServiceConfig2A(SC_HANDLE hService
,
277 SC_RPC_CONFIG_INFOA Info
;
280 TRACE("ChangeServiceConfig2A() called\n");
282 /* Fill relevent field of the Info structure */
283 Info
.dwInfoLevel
= dwInfoLevel
;
286 case SERVICE_CONFIG_DESCRIPTION
:
287 Info
.psd
= (LPSERVICE_DESCRIPTIONA
)&lpInfo
;
290 case SERVICE_CONFIG_FAILURE_ACTIONS
:
291 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSA
)&lpInfo
;
295 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
296 SetLastError(ERROR_INVALID_PARAMETER
);
307 dwError
= RChangeServiceConfig2A(BindingHandle
,
308 (SC_RPC_HANDLE
)hService
,
313 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
317 if (dwError
!= ERROR_SUCCESS
)
319 ERR("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
320 SetLastError(dwError
);
328 /**********************************************************************
329 * ChangeServiceConfig2W
334 ChangeServiceConfig2W(SC_HANDLE hService
,
338 SC_RPC_CONFIG_INFOW Info
;
341 TRACE("ChangeServiceConfig2W() called\n");
343 /* Fill relevent field of the Info structure */
344 Info
.dwInfoLevel
= dwInfoLevel
;
347 case SERVICE_CONFIG_DESCRIPTION
:
349 Info
.psd
= (LPSERVICE_DESCRIPTIONW
)&lpInfo
;
353 case SERVICE_CONFIG_FAILURE_ACTIONS
:
354 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSW
)&lpInfo
;
358 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
359 SetLastError(ERROR_INVALID_PARAMETER
);
370 dwError
= RChangeServiceConfig2W(BindingHandle
,
371 (SC_RPC_HANDLE
)hService
,
376 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
380 if (dwError
!= ERROR_SUCCESS
)
382 ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
383 SetLastError(dwError
);
391 /**********************************************************************
392 * ChangeServiceConfigA
397 ChangeServiceConfigA(SC_HANDLE hService
,
400 DWORD dwErrorControl
,
401 LPCSTR lpBinaryPathName
,
402 LPCSTR lpLoadOrderGroup
,
404 LPCSTR lpDependencies
,
405 LPCSTR lpServiceStartName
,
407 LPCSTR lpDisplayName
)
410 DWORD dwDependenciesLength
= 0;
414 TRACE("ChangeServiceConfigA() called\n");
416 /* Calculate the Dependencies length*/
417 if (lpDependencies
!= NULL
)
419 lpStr
= (LPSTR
)lpDependencies
;
422 dwLength
= strlen(lpStr
) + 1;
423 dwDependenciesLength
+= dwLength
;
424 lpStr
= lpStr
+ dwLength
;
426 dwDependenciesLength
++;
429 /* FIXME: Encrypt the password */
435 /* Call to services.exe using RPC */
436 dwError
= RChangeServiceConfigA(BindingHandle
,
437 (SC_RPC_HANDLE
)hService
,
441 (LPSTR
)lpBinaryPathName
,
442 (LPSTR
)lpLoadOrderGroup
,
444 (LPSTR
)lpDependencies
,
445 dwDependenciesLength
,
446 (LPSTR
)lpServiceStartName
,
447 NULL
, /* FIXME: lpPassword */
448 0, /* FIXME: dwPasswordLength */
449 (LPSTR
)lpDisplayName
);
453 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
457 if (dwError
!= ERROR_SUCCESS
)
459 ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
460 SetLastError(dwError
);
468 /**********************************************************************
469 * ChangeServiceConfigW
474 ChangeServiceConfigW(SC_HANDLE hService
,
477 DWORD dwErrorControl
,
478 LPCWSTR lpBinaryPathName
,
479 LPCWSTR lpLoadOrderGroup
,
481 LPCWSTR lpDependencies
,
482 LPCWSTR lpServiceStartName
,
484 LPCWSTR lpDisplayName
)
487 DWORD dwDependenciesLength
= 0;
491 TRACE("ChangeServiceConfigW() called\n");
493 /* Calculate the Dependencies length*/
494 if (lpDependencies
!= NULL
)
496 lpStr
= (LPWSTR
)lpDependencies
;
499 dwLength
= wcslen(lpStr
) + 1;
500 dwDependenciesLength
+= dwLength
;
501 lpStr
= lpStr
+ dwLength
;
503 dwDependenciesLength
++;
506 /* FIXME: Encrypt the password */
512 /* Call to services.exe using RPC */
513 dwError
= RChangeServiceConfigW(BindingHandle
,
514 (SC_RPC_HANDLE
)hService
,
518 (LPWSTR
)lpBinaryPathName
,
519 (LPWSTR
)lpLoadOrderGroup
,
521 (LPBYTE
)lpDependencies
,
522 dwDependenciesLength
,
523 (LPWSTR
)lpServiceStartName
,
524 NULL
, /* FIXME: lpPassword */
525 0, /* FIXME: dwPasswordLength */
526 (LPWSTR
)lpDisplayName
);
530 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
534 if (dwError
!= ERROR_SUCCESS
)
536 ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
537 SetLastError(dwError
);
545 /**********************************************************************
551 CloseServiceHandle(SC_HANDLE hSCObject
)
555 TRACE("CloseServiceHandle() called\n");
561 /* Call to services.exe using RPC */
562 dwError
= RCloseServiceHandle(BindingHandle
,
563 (LPSC_RPC_HANDLE
)&hSCObject
);
567 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
573 ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
574 SetLastError(dwError
);
578 TRACE("CloseServiceHandle() done\n");
584 /**********************************************************************
590 ControlService(SC_HANDLE hService
,
592 LPSERVICE_STATUS lpServiceStatus
)
596 TRACE("ControlService(%x, %x, %p)\n",
597 hService
, dwControl
, lpServiceStatus
);
603 /* Call to services.exe using RPC */
604 dwError
= RControlService(BindingHandle
,
605 (SC_RPC_HANDLE
)hService
,
611 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
615 if (dwError
!= ERROR_SUCCESS
)
617 ERR("RControlService() failed (Error %lu)\n", dwError
);
618 SetLastError(dwError
);
622 TRACE("ControlService() done\n");
628 /**********************************************************************
634 ControlServiceEx(IN SC_HANDLE hService
,
636 IN DWORD dwInfoLevel
,
637 IN OUT PVOID pControlParams
)
639 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
640 hService
, dwControl
, dwInfoLevel
, pControlParams
);
641 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
646 /**********************************************************************
652 CreateServiceA(SC_HANDLE hSCManager
,
653 LPCSTR lpServiceName
,
654 LPCSTR lpDisplayName
,
655 DWORD dwDesiredAccess
,
658 DWORD dwErrorControl
,
659 LPCSTR lpBinaryPathName
,
660 LPCSTR lpLoadOrderGroup
,
662 LPCSTR lpDependencies
,
663 LPCSTR lpServiceStartName
,
666 SC_HANDLE RetVal
= NULL
;
667 LPWSTR lpServiceNameW
= NULL
;
668 LPWSTR lpDisplayNameW
= NULL
;
669 LPWSTR lpBinaryPathNameW
= NULL
;
670 LPWSTR lpLoadOrderGroupW
= NULL
;
671 LPWSTR lpDependenciesW
= NULL
;
672 LPWSTR lpServiceStartNameW
= NULL
;
673 LPWSTR lpPasswordW
= NULL
;
674 DWORD dwDependenciesLength
= 0;
681 len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, NULL
, 0);
682 lpServiceNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
685 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
688 MultiByteToWideChar(CP_ACP
, 0, lpServiceName
, -1, lpServiceNameW
, len
);
693 len
= MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, NULL
, 0);
694 lpDisplayNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
697 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
700 MultiByteToWideChar(CP_ACP
, 0, lpDisplayName
, -1, lpDisplayNameW
, len
);
703 if (lpBinaryPathName
)
705 len
= MultiByteToWideChar(CP_ACP
, 0, lpBinaryPathName
, -1, NULL
, 0);
706 lpBinaryPathNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
707 if (!lpBinaryPathNameW
)
709 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
712 MultiByteToWideChar(CP_ACP
, 0, lpBinaryPathName
, -1, lpBinaryPathNameW
, len
);
715 if (lpLoadOrderGroup
)
717 len
= MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, NULL
, 0);
718 lpLoadOrderGroupW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
719 if (!lpLoadOrderGroupW
)
721 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
724 MultiByteToWideChar(CP_ACP
, 0, lpLoadOrderGroup
, -1, lpLoadOrderGroupW
, len
);
729 lpStr
= (LPSTR
)lpDependencies
;
732 dwLength
= strlen(lpStr
) + 1;
733 dwDependenciesLength
+= dwLength
;
734 lpStr
= lpStr
+ dwLength
;
736 dwDependenciesLength
++;
738 lpDependenciesW
= HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength
* sizeof(WCHAR
));
739 if (!lpDependenciesW
)
741 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
744 MultiByteToWideChar(CP_ACP
, 0, lpDependencies
, dwDependenciesLength
, lpDependenciesW
, dwDependenciesLength
);
747 if (lpServiceStartName
)
749 len
= MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, NULL
, 0);
750 lpServiceStartNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
751 if (!lpServiceStartNameW
)
753 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
756 MultiByteToWideChar(CP_ACP
, 0, lpServiceStartName
, -1, lpServiceStartNameW
, len
);
761 len
= MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, NULL
, 0);
762 lpPasswordW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
765 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
768 MultiByteToWideChar(CP_ACP
, 0, lpPassword
, -1, lpPasswordW
, len
);
771 RetVal
= CreateServiceW(hSCManager
,
786 if (lpServiceNameW
!=NULL
)
787 HeapFree(GetProcessHeap(), 0, lpServiceNameW
);
789 if (lpDisplayNameW
!= NULL
)
790 HeapFree(GetProcessHeap(), 0, lpDisplayNameW
);
792 if (lpBinaryPathNameW
!= NULL
)
793 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW
);
795 if (lpLoadOrderGroupW
!= NULL
)
796 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW
);
798 if (lpDependenciesW
!= NULL
)
799 HeapFree(GetProcessHeap(), 0, lpDependenciesW
);
801 if (lpServiceStartNameW
!= NULL
)
802 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW
);
804 if (lpPasswordW
!= NULL
)
805 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
811 /**********************************************************************
817 CreateServiceW(SC_HANDLE hSCManager
,
818 LPCWSTR lpServiceName
,
819 LPCWSTR lpDisplayName
,
820 DWORD dwDesiredAccess
,
823 DWORD dwErrorControl
,
824 LPCWSTR lpBinaryPathName
,
825 LPCWSTR lpLoadOrderGroup
,
827 LPCWSTR lpDependencies
,
828 LPCWSTR lpServiceStartName
,
831 SC_HANDLE hService
= NULL
;
832 DWORD dwDependenciesLength
= 0;
837 TRACE("CreateServiceW() called\n");
839 /* Calculate the Dependencies length*/
840 if (lpDependencies
!= NULL
)
842 lpStr
= (LPWSTR
)lpDependencies
;
845 dwLength
= wcslen(lpStr
) + 1;
846 dwDependenciesLength
+= dwLength
;
847 lpStr
= lpStr
+ dwLength
;
849 dwDependenciesLength
++;
851 dwDependenciesLength
*= sizeof(WCHAR
);
854 /* FIXME: Encrypt the password */
860 /* Call to services.exe using RPC */
861 dwError
= RCreateServiceW(BindingHandle
,
862 (SC_RPC_HANDLE
)hSCManager
,
863 (LPWSTR
)lpServiceName
,
864 (LPWSTR
)lpDisplayName
,
869 (LPWSTR
)lpBinaryPathName
,
870 (LPWSTR
)lpLoadOrderGroup
,
872 (LPBYTE
)lpDependencies
,
873 dwDependenciesLength
,
874 (LPWSTR
)lpServiceStartName
,
875 NULL
, /* FIXME: lpPassword */
876 0, /* FIXME: dwPasswordLength */
877 (SC_RPC_HANDLE
*)&hService
);
881 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
885 if (dwError
!= ERROR_SUCCESS
)
887 ERR("RCreateServiceW() failed (Error %lu)\n", dwError
);
888 SetLastError(dwError
);
896 /**********************************************************************
902 DeleteService(SC_HANDLE hService
)
906 TRACE("DeleteService(%x)\n", hService
);
912 /* Call to services.exe using RPC */
913 dwError
= RDeleteService(BindingHandle
,
914 (SC_RPC_HANDLE
)hService
);
918 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
922 if (dwError
!= ERROR_SUCCESS
)
924 ERR("RDeleteService() failed (Error %lu)\n", dwError
);
925 SetLastError(dwError
);
933 /**********************************************************************
934 * EnumDependentServicesA
939 EnumDependentServicesA(SC_HANDLE hService
,
940 DWORD dwServiceState
,
941 LPENUM_SERVICE_STATUSA lpServices
,
943 LPDWORD pcbBytesNeeded
,
944 LPDWORD lpServicesReturned
)
946 LPENUM_SERVICE_STATUSA lpStatusPtr
;
950 TRACE("EnumServicesStatusA() called\n");
956 dwError
= REnumDependentServicesA(BindingHandle
,
957 (SC_RPC_HANDLE
)hService
,
966 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
970 if (dwError
!= ERROR_SUCCESS
)
972 ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
973 SetLastError(dwError
);
977 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
978 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
980 if (lpStatusPtr
->lpServiceName
)
981 lpStatusPtr
->lpServiceName
=
982 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
984 if (lpStatusPtr
->lpDisplayName
)
985 lpStatusPtr
->lpDisplayName
=
986 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
991 TRACE("EnumDependentServicesA() done\n");
997 /**********************************************************************
998 * EnumDependentServicesW
1003 EnumDependentServicesW(SC_HANDLE hService
,
1004 DWORD dwServiceState
,
1005 LPENUM_SERVICE_STATUSW lpServices
,
1007 LPDWORD pcbBytesNeeded
,
1008 LPDWORD lpServicesReturned
)
1010 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1014 TRACE("EnumServicesStatusW() called\n");
1020 dwError
= REnumDependentServicesW(BindingHandle
,
1021 (SC_RPC_HANDLE
)hService
,
1026 lpServicesReturned
);
1030 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1034 if (dwError
!= ERROR_SUCCESS
)
1036 ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
1037 SetLastError(dwError
);
1041 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1042 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1044 if (lpStatusPtr
->lpServiceName
)
1045 lpStatusPtr
->lpServiceName
=
1046 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1048 if (lpStatusPtr
->lpDisplayName
)
1049 lpStatusPtr
->lpDisplayName
=
1050 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1055 TRACE("EnumDependentServicesW() done\n");
1061 /**********************************************************************
1069 SC_HANDLE hSCManager
,
1070 DWORD dwServiceType
,
1071 DWORD dwServiceState
,
1072 LPENUM_SERVICE_STATUSW lpServices
,
1074 LPDWORD pcbBytesNeeded
,
1075 LPDWORD lpServicesReturned
,
1076 LPDWORD lpResumeHandle
,
1079 FIXME("EnumServiceGroupW is unimplemented\n");
1080 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1085 /**********************************************************************
1086 * EnumServicesStatusA
1091 EnumServicesStatusA(SC_HANDLE hSCManager
,
1092 DWORD dwServiceType
,
1093 DWORD dwServiceState
,
1094 LPENUM_SERVICE_STATUSA lpServices
,
1096 LPDWORD pcbBytesNeeded
,
1097 LPDWORD lpServicesReturned
,
1098 LPDWORD lpResumeHandle
)
1100 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1104 TRACE("EnumServicesStatusA() called\n");
1110 dwError
= REnumServicesStatusA(BindingHandle
,
1111 (SC_RPC_HANDLE
)hSCManager
,
1122 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1126 if (dwError
!= ERROR_SUCCESS
)
1128 ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1129 SetLastError(dwError
);
1133 lpStatusPtr
= (LPENUM_SERVICE_STATUSA
)lpServices
;
1134 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1136 if (lpStatusPtr
->lpServiceName
)
1137 lpStatusPtr
->lpServiceName
=
1138 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1140 if (lpStatusPtr
->lpDisplayName
)
1141 lpStatusPtr
->lpDisplayName
=
1142 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1147 TRACE("EnumServicesStatusA() done\n");
1153 /**********************************************************************
1154 * EnumServicesStatusW
1159 EnumServicesStatusW(SC_HANDLE hSCManager
,
1160 DWORD dwServiceType
,
1161 DWORD dwServiceState
,
1162 LPENUM_SERVICE_STATUSW lpServices
,
1164 LPDWORD pcbBytesNeeded
,
1165 LPDWORD lpServicesReturned
,
1166 LPDWORD lpResumeHandle
)
1168 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1172 TRACE("EnumServicesStatusW() called\n");
1178 dwError
= REnumServicesStatusW(BindingHandle
,
1179 (SC_RPC_HANDLE
)hSCManager
,
1190 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1194 if (dwError
!= ERROR_SUCCESS
)
1196 ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1197 SetLastError(dwError
);
1201 lpStatusPtr
= (LPENUM_SERVICE_STATUSW
)lpServices
;
1202 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1204 if (lpStatusPtr
->lpServiceName
)
1205 lpStatusPtr
->lpServiceName
=
1206 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1208 if (lpStatusPtr
->lpDisplayName
)
1209 lpStatusPtr
->lpDisplayName
=
1210 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1215 TRACE("EnumServicesStatusW() done\n");
1221 /**********************************************************************
1222 * EnumServicesStatusExA
1227 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1228 SC_ENUM_TYPE InfoLevel
,
1229 DWORD dwServiceType
,
1230 DWORD dwServiceState
,
1233 LPDWORD pcbBytesNeeded
,
1234 LPDWORD lpServicesReturned
,
1235 LPDWORD lpResumeHandle
,
1236 LPCSTR pszGroupName
)
1238 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1242 TRACE("EnumServicesStatusExA() called\n");
1248 dwError
= REnumServicesStatusExA(BindingHandle
,
1249 (SC_RPC_HANDLE
)hSCManager
,
1258 (LPSTR
)pszGroupName
);
1262 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1266 if (dwError
== ERROR_MORE_DATA
)
1268 WARN("Required buffer size %ul\n", *pcbBytesNeeded
);
1269 SetLastError(dwError
);
1272 else if (dwError
== ERROR_SUCCESS
)
1274 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1275 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1277 if (lpStatusPtr
->lpServiceName
)
1278 lpStatusPtr
->lpServiceName
=
1279 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1281 if (lpStatusPtr
->lpDisplayName
)
1282 lpStatusPtr
->lpDisplayName
=
1283 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1290 ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1291 SetLastError(dwError
);
1295 TRACE("EnumServicesStatusExA() done\n");
1301 /**********************************************************************
1302 * EnumServicesStatusExW
1307 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1308 SC_ENUM_TYPE InfoLevel
,
1309 DWORD dwServiceType
,
1310 DWORD dwServiceState
,
1313 LPDWORD pcbBytesNeeded
,
1314 LPDWORD lpServicesReturned
,
1315 LPDWORD lpResumeHandle
,
1316 LPCWSTR pszGroupName
)
1318 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1322 TRACE("EnumServicesStatusExW() called\n");
1328 dwError
= REnumServicesStatusExW(BindingHandle
,
1329 (SC_RPC_HANDLE
)hSCManager
,
1338 (LPWSTR
)pszGroupName
);
1342 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1346 if (dwError
== ERROR_MORE_DATA
)
1348 WARN("Required buffer size %ul\n", *pcbBytesNeeded
);
1349 SetLastError(dwError
);
1352 else if (dwError
== ERROR_SUCCESS
)
1354 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1355 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1357 if (lpStatusPtr
->lpServiceName
)
1358 lpStatusPtr
->lpServiceName
=
1359 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1361 if (lpStatusPtr
->lpDisplayName
)
1362 lpStatusPtr
->lpDisplayName
=
1363 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1370 ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1371 SetLastError(dwError
);
1375 TRACE("EnumServicesStatusExW() done\n");
1381 /**********************************************************************
1382 * GetServiceDisplayNameA
1387 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1388 LPCSTR lpServiceName
,
1389 LPSTR lpDisplayName
,
1390 LPDWORD lpcchBuffer
)
1394 TRACE("GetServiceDisplayNameA() called\n");
1403 dwError
= RGetServiceDisplayNameA(BindingHandle
,
1404 (SC_RPC_HANDLE
)hSCManager
,
1405 (LPSTR
)lpServiceName
,
1411 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1412 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1418 if (dwError
!= ERROR_SUCCESS
)
1420 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1421 SetLastError(dwError
);
1429 /**********************************************************************
1430 * GetServiceDisplayNameW
1435 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1436 LPCWSTR lpServiceName
,
1437 LPWSTR lpDisplayName
,
1438 LPDWORD lpcchBuffer
)
1442 TRACE("GetServiceDisplayNameW() called\n");
1451 dwError
= RGetServiceDisplayNameW(BindingHandle
,
1452 (SC_RPC_HANDLE
)hSCManager
,
1453 (LPWSTR
)lpServiceName
,
1459 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1463 if (dwError
!= ERROR_SUCCESS
)
1465 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1466 SetLastError(dwError
);
1474 /**********************************************************************
1475 * GetServiceKeyNameA
1480 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1481 LPCSTR lpDisplayName
,
1482 LPSTR lpServiceName
,
1483 LPDWORD lpcchBuffer
)
1487 TRACE("GetServiceKeyNameA() called\n");
1496 dwError
= RGetServiceKeyNameA(BindingHandle
,
1497 (SC_RPC_HANDLE
)hSCManager
,
1498 (LPSTR
)lpDisplayName
,
1504 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1508 if (dwError
!= ERROR_SUCCESS
)
1510 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1511 SetLastError(dwError
);
1519 /**********************************************************************
1520 * GetServiceKeyNameW
1525 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1526 LPCWSTR lpDisplayName
,
1527 LPWSTR lpServiceName
,
1528 LPDWORD lpcchBuffer
)
1532 TRACE("GetServiceKeyNameW() called\n");
1541 dwError
= RGetServiceKeyNameW(BindingHandle
,
1542 (SC_RPC_HANDLE
)hSCManager
,
1543 (LPWSTR
)lpDisplayName
,
1549 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1553 if (dwError
!= ERROR_SUCCESS
)
1555 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1556 SetLastError(dwError
);
1564 /**********************************************************************
1565 * LockServiceDatabase
1570 LockServiceDatabase(SC_HANDLE hSCManager
)
1575 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1581 /* Call to services.exe using RPC */
1582 dwError
= RLockServiceDatabase(BindingHandle
,
1583 (SC_RPC_HANDLE
)hSCManager
,
1584 (SC_RPC_LOCK
*)&hLock
);
1588 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1592 if (dwError
!= ERROR_SUCCESS
)
1594 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1595 SetLastError(dwError
);
1599 TRACE("hLock = %p\n", hLock
);
1606 WaitForSCManager(VOID
)
1610 TRACE("WaitForSCManager() called\n");
1612 /* Try to open the existing event */
1613 hEvent
= OpenEventW(SYNCHRONIZE
,
1615 L
"SvcctrlStartEvent_A3752DX");
1618 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1621 /* Try to create a new event */
1622 hEvent
= CreateEventW(NULL
,
1625 L
"SvcctrlStartEvent_A3752DX");
1628 /* Try to open the existing event again */
1629 hEvent
= OpenEventW(SYNCHRONIZE
,
1631 L
"SvcctrlStartEvent_A3752DX");
1637 /* Wait for 3 minutes */
1638 WaitForSingleObject(hEvent
, 180000);
1639 CloseHandle(hEvent
);
1641 TRACE("ScmWaitForSCManager() done\n");
1645 /**********************************************************************
1651 OpenSCManagerA(LPCSTR lpMachineName
,
1652 LPCSTR lpDatabaseName
,
1653 DWORD dwDesiredAccess
)
1655 SC_HANDLE hScm
= NULL
;
1658 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1659 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1667 /* Call to services.exe using RPC */
1668 dwError
= ROpenSCManagerA(//BindingHandle,
1669 (LPSTR
)lpMachineName
,
1670 (LPSTR
)lpDatabaseName
,
1672 (SC_RPC_HANDLE
*)&hScm
);
1676 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1680 if (dwError
!= ERROR_SUCCESS
)
1682 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1683 SetLastError(dwError
);
1687 TRACE("hScm = %p\n", hScm
);
1693 /**********************************************************************
1699 OpenSCManagerW(LPCWSTR lpMachineName
,
1700 LPCWSTR lpDatabaseName
,
1701 DWORD dwDesiredAccess
)
1703 SC_HANDLE hScm
= NULL
;
1706 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1707 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1715 /* Call to services.exe using RPC */
1716 dwError
= ROpenSCManagerW(//BindingHandle,
1717 (LPWSTR
)lpMachineName
,
1718 (LPWSTR
)lpDatabaseName
,
1720 (SC_RPC_HANDLE
*)&hScm
);
1724 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1728 if (dwError
!= ERROR_SUCCESS
)
1730 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1731 SetLastError(dwError
);
1735 TRACE("hScm = %p\n", hScm
);
1741 /**********************************************************************
1747 OpenServiceA(SC_HANDLE hSCManager
,
1748 LPCSTR lpServiceName
,
1749 DWORD dwDesiredAccess
)
1751 SC_HANDLE hService
= NULL
;
1754 TRACE("OpenServiceA(%p, %s, %lx)\n",
1755 hSCManager
, lpServiceName
, dwDesiredAccess
);
1761 /* Call to services.exe using RPC */
1762 dwError
= ROpenServiceA(BindingHandle
,
1763 (SC_RPC_HANDLE
)hSCManager
,
1764 (LPSTR
)lpServiceName
,
1766 (SC_RPC_HANDLE
*)&hService
);
1770 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1774 if (dwError
!= ERROR_SUCCESS
)
1776 ERR("ROpenServiceA() failed (Error %lu)\n", dwError
);
1777 SetLastError(dwError
);
1781 TRACE("hService = %p\n", hService
);
1787 /**********************************************************************
1793 OpenServiceW(SC_HANDLE hSCManager
,
1794 LPCWSTR lpServiceName
,
1795 DWORD dwDesiredAccess
)
1797 SC_HANDLE hService
= NULL
;
1800 TRACE("OpenServiceW(%p, %S, %lx)\n",
1801 hSCManager
, lpServiceName
, dwDesiredAccess
);
1807 /* Call to services.exe using RPC */
1808 dwError
= ROpenServiceW(BindingHandle
,
1809 (SC_RPC_HANDLE
)hSCManager
,
1810 (LPWSTR
)lpServiceName
,
1812 (SC_RPC_HANDLE
*)&hService
);
1816 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1820 if (dwError
!= ERROR_SUCCESS
)
1822 if (dwError
== ERROR_SERVICE_DOES_NOT_EXIST
)
1823 WARN("ROpenServiceW() failed (Error %lu)\n", dwError
);
1825 ERR("ROpenServiceW() failed (Error %lu)\n", dwError
);
1826 SetLastError(dwError
);
1830 TRACE("hService = %p\n", hService
);
1836 /**********************************************************************
1837 * QueryServiceConfigA
1842 QueryServiceConfigA(SC_HANDLE hService
,
1843 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1845 LPDWORD pcbBytesNeeded
)
1849 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1850 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1856 /* Call to services.exe using RPC */
1857 dwError
= RQueryServiceConfigA(BindingHandle
,
1858 (SC_RPC_HANDLE
)hService
,
1859 (LPBYTE
)lpServiceConfig
,
1865 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1869 if (dwError
!= ERROR_SUCCESS
)
1871 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1872 SetLastError(dwError
);
1876 /* Adjust the pointers */
1877 if (lpServiceConfig
->lpBinaryPathName
)
1878 lpServiceConfig
->lpBinaryPathName
=
1879 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1880 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1882 if (lpServiceConfig
->lpLoadOrderGroup
)
1883 lpServiceConfig
->lpLoadOrderGroup
=
1884 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1885 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1887 if (lpServiceConfig
->lpDependencies
)
1888 lpServiceConfig
->lpDependencies
=
1889 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1890 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1892 if (lpServiceConfig
->lpServiceStartName
)
1893 lpServiceConfig
->lpServiceStartName
=
1894 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1895 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1897 if (lpServiceConfig
->lpDisplayName
)
1898 lpServiceConfig
->lpDisplayName
=
1899 (LPSTR
)((ULONG_PTR
)lpServiceConfig
+
1900 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1902 TRACE("QueryServiceConfigA() done\n");
1908 /**********************************************************************
1909 * QueryServiceConfigW
1914 QueryServiceConfigW(SC_HANDLE hService
,
1915 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1917 LPDWORD pcbBytesNeeded
)
1921 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1922 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1928 /* Call to services.exe using RPC */
1929 dwError
= RQueryServiceConfigW(BindingHandle
,
1930 (SC_RPC_HANDLE
)hService
,
1931 (LPBYTE
)lpServiceConfig
,
1937 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1941 if (dwError
!= ERROR_SUCCESS
)
1943 if (dwError
== ERROR_INSUFFICIENT_BUFFER
)
1944 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1946 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
1947 SetLastError(dwError
);
1951 /* Adjust the pointers */
1952 if (lpServiceConfig
->lpBinaryPathName
)
1953 lpServiceConfig
->lpBinaryPathName
=
1954 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1955 (ULONG_PTR
)lpServiceConfig
->lpBinaryPathName
);
1957 if (lpServiceConfig
->lpLoadOrderGroup
)
1958 lpServiceConfig
->lpLoadOrderGroup
=
1959 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1960 (ULONG_PTR
)lpServiceConfig
->lpLoadOrderGroup
);
1962 if (lpServiceConfig
->lpDependencies
)
1963 lpServiceConfig
->lpDependencies
=
1964 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1965 (ULONG_PTR
)lpServiceConfig
->lpDependencies
);
1967 if (lpServiceConfig
->lpServiceStartName
)
1968 lpServiceConfig
->lpServiceStartName
=
1969 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1970 (ULONG_PTR
)lpServiceConfig
->lpServiceStartName
);
1972 if (lpServiceConfig
->lpDisplayName
)
1973 lpServiceConfig
->lpDisplayName
=
1974 (LPWSTR
)((ULONG_PTR
)lpServiceConfig
+
1975 (ULONG_PTR
)lpServiceConfig
->lpDisplayName
);
1977 TRACE("QueryServiceConfigW() done\n");
1983 /**********************************************************************
1984 * QueryServiceConfig2A
1989 QueryServiceConfig2A(SC_HANDLE hService
,
1993 LPDWORD pcbBytesNeeded
)
1997 TRACE("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
1998 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2000 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2001 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2003 SetLastError(ERROR_INVALID_LEVEL
);
2007 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2008 pcbBytesNeeded
== NULL
)
2010 SetLastError(ERROR_INVALID_ADDRESS
);
2018 /* Call to services.exe using RPC */
2019 dwError
= RQueryServiceConfig2A(BindingHandle
,
2020 (SC_RPC_HANDLE
)hService
,
2028 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2032 if (dwError
!= ERROR_SUCCESS
)
2034 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2035 SetLastError(dwError
);
2039 switch (dwInfoLevel
)
2041 case SERVICE_CONFIG_DESCRIPTION
:
2043 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpBuffer
;
2045 if (lpPtr
->lpDescription
!= NULL
)
2046 lpPtr
->lpDescription
=
2047 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2051 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2053 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpBuffer
;
2055 if (lpPtr
->lpRebootMsg
!= NULL
)
2056 lpPtr
->lpRebootMsg
=
2057 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2059 if (lpPtr
->lpCommand
!= NULL
)
2061 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2063 if (lpPtr
->lpsaActions
!= NULL
)
2064 lpPtr
->lpsaActions
=
2065 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2070 ERR("Unknown info level 0x%lx\n", dwInfoLevel
);
2071 SetLastError(ERROR_INVALID_PARAMETER
);
2075 TRACE("QueryServiceConfig2A() done\n");
2081 /**********************************************************************
2082 * QueryServiceConfig2W
2087 QueryServiceConfig2W(SC_HANDLE hService
,
2091 LPDWORD pcbBytesNeeded
)
2095 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2096 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2098 if (dwInfoLevel
!= SERVICE_CONFIG_DESCRIPTION
&&
2099 dwInfoLevel
!= SERVICE_CONFIG_FAILURE_ACTIONS
)
2101 SetLastError(ERROR_INVALID_LEVEL
);
2105 if ((lpBuffer
== NULL
&& cbBufSize
!= 0) ||
2106 pcbBytesNeeded
== NULL
)
2108 SetLastError(ERROR_INVALID_ADDRESS
);
2116 /* Call to services.exe using RPC */
2117 dwError
= RQueryServiceConfig2W(BindingHandle
,
2118 (SC_RPC_HANDLE
)hService
,
2126 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2130 if (dwError
!= ERROR_SUCCESS
)
2132 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2133 SetLastError(dwError
);
2137 switch (dwInfoLevel
)
2139 case SERVICE_CONFIG_DESCRIPTION
:
2141 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpBuffer
;
2143 if (lpPtr
->lpDescription
!= NULL
)
2144 lpPtr
->lpDescription
=
2145 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2149 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2151 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpBuffer
;
2153 if (lpPtr
->lpRebootMsg
!= NULL
)
2154 lpPtr
->lpRebootMsg
=
2155 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2157 if (lpPtr
->lpCommand
!= NULL
)
2159 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2161 if (lpPtr
->lpsaActions
!= NULL
)
2162 lpPtr
->lpsaActions
=
2163 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2168 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2169 SetLastError(ERROR_INVALID_PARAMETER
);
2173 TRACE("QueryServiceConfig2W() done\n");
2179 /**********************************************************************
2180 * QueryServiceLockStatusA
2185 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2186 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2188 LPDWORD pcbBytesNeeded
)
2192 TRACE("QueryServiceLockStatusA() called\n");
2198 /* Call to services.exe using RPC */
2199 dwError
= RQueryServiceLockStatusA(BindingHandle
,
2200 (SC_RPC_HANDLE
)hSCManager
,
2207 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2211 if (dwError
!= ERROR_SUCCESS
)
2213 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2214 SetLastError(dwError
);
2218 if (lpLockStatus
->lpLockOwner
!= NULL
)
2220 lpLockStatus
->lpLockOwner
=
2221 (LPSTR
)((UINT_PTR
)lpLockStatus
+ (UINT_PTR
)lpLockStatus
->lpLockOwner
);
2224 TRACE("QueryServiceLockStatusA() done\n");
2230 /**********************************************************************
2231 * QueryServiceLockStatusW
2236 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2237 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2239 LPDWORD pcbBytesNeeded
)
2243 TRACE("QueryServiceLockStatusW() called\n");
2249 /* Call to services.exe using RPC */
2250 dwError
= RQueryServiceLockStatusW(BindingHandle
,
2251 (SC_RPC_HANDLE
)hSCManager
,
2258 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2262 if (dwError
!= ERROR_SUCCESS
)
2264 ERR("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
);
2302 /* Call to services.exe using RPC */
2303 dwError
= RQueryServiceObjectSecurity(BindingHandle
,
2304 (SC_RPC_HANDLE
)hService
,
2305 dwSecurityInformation
,
2306 (LPBYTE
)lpSecurityDescriptor
,
2312 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2316 if (dwError
!= ERROR_SUCCESS
)
2318 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2319 SetLastError(dwError
);
2326 /**********************************************************************
2327 * SetServiceObjectSecurity
2332 SetServiceObjectSecurity(SC_HANDLE hService
,
2333 SECURITY_INFORMATION dwSecurityInformation
,
2334 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2336 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2342 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2345 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2347 SetLastError(ERROR_INVALID_PARAMETER
);
2351 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2352 if (SelfRelativeSD
== NULL
)
2354 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2358 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2361 if (!NT_SUCCESS(Status
))
2363 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2364 SetLastError(RtlNtStatusToDosError(Status
));
2372 /* Call to services.exe using RPC */
2373 dwError
= RSetServiceObjectSecurity(BindingHandle
,
2374 (SC_RPC_HANDLE
)hService
,
2375 dwSecurityInformation
,
2376 (LPBYTE
)SelfRelativeSD
,
2381 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2385 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2387 if (dwError
!= ERROR_SUCCESS
)
2389 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2390 SetLastError(dwError
);
2398 /**********************************************************************
2399 * QueryServiceStatus
2404 QueryServiceStatus(SC_HANDLE hService
,
2405 LPSERVICE_STATUS lpServiceStatus
)
2409 TRACE("QueryServiceStatus(%p, %p)\n",
2410 hService
, lpServiceStatus
);
2416 /* Call to services.exe using RPC */
2417 dwError
= RQueryServiceStatus(BindingHandle
,
2418 (SC_RPC_HANDLE
)hService
,
2423 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2427 if (dwError
!= ERROR_SUCCESS
)
2429 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2430 SetLastError(dwError
);
2438 /**********************************************************************
2439 * QueryServiceStatusEx
2444 QueryServiceStatusEx(SC_HANDLE hService
,
2445 SC_STATUS_TYPE InfoLevel
,
2448 LPDWORD pcbBytesNeeded
)
2452 TRACE("QueryServiceStatusEx() called\n");
2458 /* Call to services.exe using RPC */
2459 dwError
= RQueryServiceStatusEx(BindingHandle
,
2460 (SC_RPC_HANDLE
)hService
,
2468 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2472 if (dwError
!= ERROR_SUCCESS
)
2474 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2475 SetLastError(dwError
);
2483 /**********************************************************************
2489 StartServiceA(SC_HANDLE hService
,
2490 DWORD dwNumServiceArgs
,
2491 LPCSTR
*lpServiceArgVectors
)
2499 dwError
= RStartServiceA(BindingHandle
,
2500 (SC_RPC_HANDLE
)hService
,
2502 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2506 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2510 if (dwError
!= ERROR_SUCCESS
)
2512 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2513 SetLastError(dwError
);
2521 /**********************************************************************
2527 StartServiceW(SC_HANDLE hService
,
2528 DWORD dwNumServiceArgs
,
2529 LPCWSTR
*lpServiceArgVectors
)
2537 dwError
= RStartServiceW(BindingHandle
,
2538 (SC_RPC_HANDLE
)hService
,
2540 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2544 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2548 if (dwError
!= ERROR_SUCCESS
)
2550 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2551 SetLastError(dwError
);
2559 /**********************************************************************
2560 * UnlockServiceDatabase
2565 UnlockServiceDatabase(SC_LOCK ScLock
)
2569 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2575 /* Call to services.exe using RPC */
2576 dwError
= RUnlockServiceDatabase(BindingHandle
,
2577 (LPSC_RPC_LOCK
)&ScLock
);
2581 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2585 if (dwError
!= ERROR_SUCCESS
)
2587 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2588 SetLastError(dwError
);
2596 /**********************************************************************
2597 * NotifyBootConfigStatus
2602 NotifyBootConfigStatus(BOOL BootAcceptable
)
2606 TRACE("NotifyBootConfigStatus()\n");
2612 /* Call to services.exe using RPC */
2613 dwError
= RNotifyBootConfigStatus(BindingHandle
,
2619 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2623 if (dwError
!= ERROR_SUCCESS
)
2625 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2626 SetLastError(dwError
);