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 ******************************************************************/
16 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
19 /* FUNCTIONS *****************************************************************/
22 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName
)
24 handle_t hBinding
= NULL
;
25 UCHAR
*pszStringBinding
;
28 TRACE("SVCCTL_HANDLEA_bind() called\n");
30 status
= RpcStringBindingComposeA(NULL
,
32 (UCHAR
*)szMachineName
,
33 (UCHAR
*)"\\pipe\\ntsvcs",
35 (UCHAR
**)&pszStringBinding
);
36 if (status
!= RPC_S_OK
)
38 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
42 /* Set the binding handle that will be used to bind to the server. */
43 status
= RpcBindingFromStringBindingA(pszStringBinding
,
45 if (status
!= RPC_S_OK
)
47 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
50 status
= RpcStringFreeA(&pszStringBinding
);
51 if (status
!= RPC_S_OK
)
53 ERR("RpcStringFree returned 0x%x\n", status
);
61 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName
,
66 TRACE("SVCCTL_HANDLEA_unbind() called\n");
68 status
= RpcBindingFree(&hBinding
);
69 if (status
!= RPC_S_OK
)
71 ERR("RpcBindingFree returned 0x%x\n", status
);
77 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName
)
79 handle_t hBinding
= NULL
;
80 LPWSTR pszStringBinding
;
83 TRACE("SVCCTL_HANDLEW_bind() called\n");
85 status
= RpcStringBindingComposeW(NULL
,
91 if (status
!= RPC_S_OK
)
93 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
97 /* Set the binding handle that will be used to bind to the server. */
98 status
= RpcBindingFromStringBindingW(pszStringBinding
,
100 if (status
!= RPC_S_OK
)
102 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
105 status
= RpcStringFreeW(&pszStringBinding
);
106 if (status
!= RPC_S_OK
)
108 ERR("RpcStringFree returned 0x%x\n", status
);
116 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName
,
121 TRACE("SVCCTL_HANDLEW_unbind() called\n");
123 status
= RpcBindingFree(&hBinding
);
124 if (status
!= RPC_S_OK
)
126 ERR("RpcBindingFree returned 0x%x\n", status
);
132 ScmRpcStatusToWinError(RPC_STATUS Status
)
136 case RPC_S_INVALID_BINDING
:
137 case RPC_X_SS_IN_NULL_CONTEXT
:
138 return ERROR_INVALID_HANDLE
;
140 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
141 case RPC_X_BYTE_COUNT_TOO_SMALL
:
142 return ERROR_INVALID_PARAMETER
;
144 case RPC_X_NULL_REF_POINTER
:
145 return ERROR_INVALID_ADDRESS
;
148 return (DWORD
)Status
;
153 /**********************************************************************
154 * ChangeServiceConfig2A
159 ChangeServiceConfig2A(SC_HANDLE hService
,
163 SC_RPC_CONFIG_INFOA Info
;
166 TRACE("ChangeServiceConfig2A() called\n");
168 /* Fill relevent field of the Info structure */
169 Info
.dwInfoLevel
= dwInfoLevel
;
172 case SERVICE_CONFIG_DESCRIPTION
:
173 Info
.psd
= (LPSERVICE_DESCRIPTIONA
)&lpInfo
;
174 Info
.lpDescription
= ((LPSERVICE_DESCRIPTIONA
)lpInfo
)->lpDescription
; //HACK
177 case SERVICE_CONFIG_FAILURE_ACTIONS
:
178 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSA
)lpInfo
;
182 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
183 SetLastError(ERROR_INVALID_PARAMETER
);
192 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
195 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
197 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
201 if (dwError
!= ERROR_SUCCESS
)
203 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
204 SetLastError(dwError
);
212 /**********************************************************************
213 * ChangeServiceConfig2W
218 ChangeServiceConfig2W(SC_HANDLE hService
,
222 SC_RPC_CONFIG_INFOW Info
;
225 TRACE("ChangeServiceConfig2W() called\n");
227 /* Fill relevent field of the Info structure */
228 Info
.dwInfoLevel
= dwInfoLevel
;
231 case SERVICE_CONFIG_DESCRIPTION
:
232 Info
.psd
= (LPSERVICE_DESCRIPTIONW
)&lpInfo
;
235 case SERVICE_CONFIG_FAILURE_ACTIONS
:
236 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSW
)&lpInfo
;
240 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
241 SetLastError(ERROR_INVALID_PARAMETER
);
250 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
253 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
255 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
259 if (dwError
!= ERROR_SUCCESS
)
261 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
262 SetLastError(dwError
);
270 /**********************************************************************
271 * ChangeServiceConfigA
276 ChangeServiceConfigA(SC_HANDLE hService
,
279 DWORD dwErrorControl
,
280 LPCSTR lpBinaryPathName
,
281 LPCSTR lpLoadOrderGroup
,
283 LPCSTR lpDependencies
,
284 LPCSTR lpServiceStartName
,
286 LPCSTR lpDisplayName
)
289 DWORD dwDependenciesLength
= 0;
293 TRACE("ChangeServiceConfigA() called\n");
295 /* Calculate the Dependencies length*/
296 if (lpDependencies
!= NULL
)
298 lpStr
= (LPSTR
)lpDependencies
;
301 dwLength
= strlen(lpStr
) + 1;
302 dwDependenciesLength
+= dwLength
;
303 lpStr
= lpStr
+ dwLength
;
305 dwDependenciesLength
++;
308 /* FIXME: Encrypt the password */
312 /* Call to services.exe using RPC */
313 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
317 (LPSTR
)lpBinaryPathName
,
318 (LPSTR
)lpLoadOrderGroup
,
320 (LPSTR
)lpDependencies
,
321 dwDependenciesLength
,
322 (LPSTR
)lpServiceStartName
,
323 NULL
, /* FIXME: lpPassword */
324 0, /* FIXME: dwPasswordLength */
325 (LPSTR
)lpDisplayName
);
327 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
329 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
333 if (dwError
!= ERROR_SUCCESS
)
335 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
336 SetLastError(dwError
);
344 /**********************************************************************
345 * ChangeServiceConfigW
350 ChangeServiceConfigW(SC_HANDLE hService
,
353 DWORD dwErrorControl
,
354 LPCWSTR lpBinaryPathName
,
355 LPCWSTR lpLoadOrderGroup
,
357 LPCWSTR lpDependencies
,
358 LPCWSTR lpServiceStartName
,
360 LPCWSTR lpDisplayName
)
363 DWORD dwDependenciesLength
= 0;
367 TRACE("ChangeServiceConfigW() called\n");
369 /* Calculate the Dependencies length*/
370 if (lpDependencies
!= NULL
)
372 lpStr
= (LPWSTR
)lpDependencies
;
375 dwLength
= wcslen(lpStr
) + 1;
376 dwDependenciesLength
+= dwLength
;
377 lpStr
= lpStr
+ dwLength
;
379 dwDependenciesLength
++;
382 /* FIXME: Encrypt the password */
386 /* Call to services.exe using RPC */
387 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
391 (LPWSTR
)lpBinaryPathName
,
392 (LPWSTR
)lpLoadOrderGroup
,
394 (LPBYTE
)lpDependencies
,
395 dwDependenciesLength
,
396 (LPWSTR
)lpServiceStartName
,
397 NULL
, /* FIXME: lpPassword */
398 0, /* FIXME: dwPasswordLength */
399 (LPWSTR
)lpDisplayName
);
401 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
403 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
407 if (dwError
!= ERROR_SUCCESS
)
409 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
410 SetLastError(dwError
);
418 /**********************************************************************
424 CloseServiceHandle(SC_HANDLE hSCObject
)
428 TRACE("CloseServiceHandle() called\n");
432 SetLastError(ERROR_INVALID_HANDLE
);
438 /* Call to services.exe using RPC */
439 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
441 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
443 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
449 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
450 SetLastError(dwError
);
454 TRACE("CloseServiceHandle() done\n");
460 /**********************************************************************
466 ControlService(SC_HANDLE hService
,
468 LPSERVICE_STATUS lpServiceStatus
)
472 TRACE("ControlService(%x, %x, %p)\n",
473 hService
, dwControl
, lpServiceStatus
);
477 /* Call to services.exe using RPC */
478 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
482 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
484 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
488 if (dwError
!= ERROR_SUCCESS
)
490 TRACE("RControlService() failed (Error %lu)\n", dwError
);
491 SetLastError(dwError
);
495 TRACE("ControlService() done\n");
501 /**********************************************************************
507 ControlServiceEx(IN SC_HANDLE hService
,
509 IN DWORD dwInfoLevel
,
510 IN OUT PVOID pControlParams
)
512 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
513 hService
, dwControl
, dwInfoLevel
, pControlParams
);
514 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
519 /**********************************************************************
525 CreateServiceA(SC_HANDLE hSCManager
,
526 LPCSTR lpServiceName
,
527 LPCSTR lpDisplayName
,
528 DWORD dwDesiredAccess
,
531 DWORD dwErrorControl
,
532 LPCSTR lpBinaryPathName
,
533 LPCSTR lpLoadOrderGroup
,
535 LPCSTR lpDependencies
,
536 LPCSTR lpServiceStartName
,
539 SC_HANDLE hService
= NULL
;
540 DWORD dwDependenciesLength
= 0;
545 TRACE("CreateServiceA() called\n");
546 TRACE("%p %s %s\n", hSCManager
,
547 lpServiceName
, lpDisplayName
);
551 SetLastError(ERROR_INVALID_HANDLE
);
555 /* Calculate the Dependencies length*/
556 if (lpDependencies
!= NULL
)
558 lpStr
= (LPSTR
)lpDependencies
;
561 dwLength
= strlen(lpStr
) + 1;
562 dwDependenciesLength
+= dwLength
;
563 lpStr
= lpStr
+ dwLength
;
565 dwDependenciesLength
++;
568 /* FIXME: Encrypt the password */
572 /* Call to services.exe using RPC */
573 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
574 (LPSTR
)lpServiceName
,
575 (LPSTR
)lpDisplayName
,
580 (LPSTR
)lpBinaryPathName
,
581 (LPSTR
)lpLoadOrderGroup
,
583 (LPBYTE
)lpDependencies
,
584 dwDependenciesLength
,
585 (LPSTR
)lpServiceStartName
,
586 NULL
, /* FIXME: lpPassword */
587 0, /* FIXME: dwPasswordLength */
588 (SC_RPC_HANDLE
*)&hService
);
590 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
592 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
596 if (dwError
!= ERROR_SUCCESS
)
598 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
599 SetLastError(dwError
);
607 /**********************************************************************
613 CreateServiceW(SC_HANDLE hSCManager
,
614 LPCWSTR lpServiceName
,
615 LPCWSTR lpDisplayName
,
616 DWORD dwDesiredAccess
,
619 DWORD dwErrorControl
,
620 LPCWSTR lpBinaryPathName
,
621 LPCWSTR lpLoadOrderGroup
,
623 LPCWSTR lpDependencies
,
624 LPCWSTR lpServiceStartName
,
627 SC_HANDLE hService
= NULL
;
628 DWORD dwDependenciesLength
= 0;
633 TRACE("CreateServiceW() called\n");
634 TRACE("%p %S %S\n", hSCManager
,
635 lpServiceName
, lpDisplayName
);
639 SetLastError(ERROR_INVALID_HANDLE
);
643 /* Calculate the Dependencies length*/
644 if (lpDependencies
!= NULL
)
646 lpStr
= (LPWSTR
)lpDependencies
;
649 dwLength
= wcslen(lpStr
) + 1;
650 dwDependenciesLength
+= dwLength
;
651 lpStr
= lpStr
+ dwLength
;
653 dwDependenciesLength
++;
655 dwDependenciesLength
*= sizeof(WCHAR
);
658 /* FIXME: Encrypt the password */
662 /* Call to services.exe using RPC */
663 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
673 (LPBYTE
)lpDependencies
,
674 dwDependenciesLength
,
676 NULL
, /* FIXME: lpPassword */
677 0, /* FIXME: dwPasswordLength */
678 (SC_RPC_HANDLE
*)&hService
);
680 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
682 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
686 if (dwError
!= ERROR_SUCCESS
)
688 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
689 SetLastError(dwError
);
697 /**********************************************************************
703 DeleteService(SC_HANDLE hService
)
707 TRACE("DeleteService(%x)\n", hService
);
711 /* Call to services.exe using RPC */
712 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
714 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
716 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
720 if (dwError
!= ERROR_SUCCESS
)
722 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
723 SetLastError(dwError
);
731 /**********************************************************************
732 * EnumDependentServicesA
737 EnumDependentServicesA(SC_HANDLE hService
,
738 DWORD dwServiceState
,
739 LPENUM_SERVICE_STATUSA lpServices
,
741 LPDWORD pcbBytesNeeded
,
742 LPDWORD lpServicesReturned
)
744 ENUM_SERVICE_STATUSA ServiceStatus
;
745 LPENUM_SERVICE_STATUSA lpStatusPtr
;
750 TRACE("EnumDependentServicesA() called\n");
752 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
754 lpStatusPtr
= &ServiceStatus
;
755 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
759 lpStatusPtr
= lpServices
;
760 dwBufferSize
= cbBufSize
;
765 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
772 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
774 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
778 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
780 if (*lpServicesReturned
> 0)
782 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
784 if (lpStatusPtr
->lpServiceName
)
785 lpStatusPtr
->lpServiceName
=
786 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
788 if (lpStatusPtr
->lpDisplayName
)
789 lpStatusPtr
->lpDisplayName
=
790 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
797 if (dwError
!= ERROR_SUCCESS
)
799 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
800 SetLastError(dwError
);
804 TRACE("EnumDependentServicesA() done\n");
810 /**********************************************************************
811 * EnumDependentServicesW
816 EnumDependentServicesW(SC_HANDLE hService
,
817 DWORD dwServiceState
,
818 LPENUM_SERVICE_STATUSW lpServices
,
820 LPDWORD pcbBytesNeeded
,
821 LPDWORD lpServicesReturned
)
823 ENUM_SERVICE_STATUSW ServiceStatus
;
824 LPENUM_SERVICE_STATUSW lpStatusPtr
;
829 TRACE("EnumDependentServicesW() called\n");
831 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
833 lpStatusPtr
= &ServiceStatus
;
834 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
838 lpStatusPtr
= lpServices
;
839 dwBufferSize
= cbBufSize
;
844 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
851 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
853 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
857 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
859 if (*lpServicesReturned
> 0)
861 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
863 if (lpStatusPtr
->lpServiceName
)
864 lpStatusPtr
->lpServiceName
=
865 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
867 if (lpStatusPtr
->lpDisplayName
)
868 lpStatusPtr
->lpDisplayName
=
869 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
876 if (dwError
!= ERROR_SUCCESS
)
878 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
879 SetLastError(dwError
);
883 TRACE("EnumDependentServicesW() done\n");
889 /**********************************************************************
895 EnumServiceGroupW(SC_HANDLE hSCManager
,
897 DWORD dwServiceState
,
898 LPENUM_SERVICE_STATUSW lpServices
,
900 LPDWORD pcbBytesNeeded
,
901 LPDWORD lpServicesReturned
,
902 LPDWORD lpResumeHandle
,
905 ENUM_SERVICE_STATUSW ServiceStatus
;
906 LPENUM_SERVICE_STATUSW lpStatusPtr
;
911 TRACE("EnumServiceGroupW() called\n");
915 SetLastError(ERROR_INVALID_HANDLE
);
919 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
921 lpStatusPtr
= &ServiceStatus
;
922 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
926 lpStatusPtr
= lpServices
;
927 dwBufferSize
= cbBufSize
;
934 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
945 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
956 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
958 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
962 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
964 if (*lpServicesReturned
> 0)
966 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
968 if (lpStatusPtr
->lpServiceName
)
969 lpStatusPtr
->lpServiceName
=
970 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
972 if (lpStatusPtr
->lpDisplayName
)
973 lpStatusPtr
->lpDisplayName
=
974 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
981 if (dwError
!= ERROR_SUCCESS
)
983 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
984 SetLastError(dwError
);
988 TRACE("EnumServiceGroupW() done\n");
994 /**********************************************************************
995 * EnumServicesStatusA
1000 EnumServicesStatusA(SC_HANDLE hSCManager
,
1001 DWORD dwServiceType
,
1002 DWORD dwServiceState
,
1003 LPENUM_SERVICE_STATUSA lpServices
,
1005 LPDWORD pcbBytesNeeded
,
1006 LPDWORD lpServicesReturned
,
1007 LPDWORD lpResumeHandle
)
1009 ENUM_SERVICE_STATUSA ServiceStatus
;
1010 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1015 TRACE("EnumServicesStatusA() called\n");
1019 SetLastError(ERROR_INVALID_HANDLE
);
1023 if (dwServiceType
!= SERVICE_DRIVER
&& dwServiceType
!= SERVICE_WIN32
)
1025 if (pcbBytesNeeded
&& lpServicesReturned
)
1027 *pcbBytesNeeded
= 0;
1028 *lpServicesReturned
= 0;
1031 SetLastError(ERROR_INVALID_PARAMETER
);
1035 if (dwServiceState
!= SERVICE_ACTIVE
&& dwServiceState
!= SERVICE_INACTIVE
&& dwServiceState
!= SERVICE_STATE_ALL
)
1038 *pcbBytesNeeded
= 0;
1040 if (lpServicesReturned
)
1041 *lpServicesReturned
= 0;
1043 SetLastError(ERROR_INVALID_PARAMETER
);
1047 if (!pcbBytesNeeded
|| !lpServicesReturned
)
1049 SetLastError(ERROR_INVALID_ADDRESS
);
1053 if (!lpServices
&& cbBufSize
!= 0)
1055 SetLastError(ERROR_INVALID_ADDRESS
);
1059 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1061 lpStatusPtr
= &ServiceStatus
;
1062 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1066 lpStatusPtr
= lpServices
;
1067 dwBufferSize
= cbBufSize
;
1072 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1075 (LPBYTE
)lpStatusPtr
,
1081 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1083 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1087 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1089 if (*lpServicesReturned
> 0)
1091 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1093 if (lpStatusPtr
->lpServiceName
)
1094 lpStatusPtr
->lpServiceName
=
1095 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1097 if (lpStatusPtr
->lpDisplayName
)
1098 lpStatusPtr
->lpDisplayName
=
1099 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1106 if (dwError
!= ERROR_SUCCESS
)
1108 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1109 SetLastError(dwError
);
1113 TRACE("EnumServicesStatusA() done\n");
1119 /**********************************************************************
1120 * EnumServicesStatusW
1125 EnumServicesStatusW(SC_HANDLE hSCManager
,
1126 DWORD dwServiceType
,
1127 DWORD dwServiceState
,
1128 LPENUM_SERVICE_STATUSW lpServices
,
1130 LPDWORD pcbBytesNeeded
,
1131 LPDWORD lpServicesReturned
,
1132 LPDWORD lpResumeHandle
)
1134 ENUM_SERVICE_STATUSW ServiceStatus
;
1135 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1140 TRACE("EnumServicesStatusW() called\n");
1144 SetLastError(ERROR_INVALID_HANDLE
);
1148 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1150 lpStatusPtr
= &ServiceStatus
;
1151 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1155 lpStatusPtr
= lpServices
;
1156 dwBufferSize
= cbBufSize
;
1161 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1164 (LPBYTE
)lpStatusPtr
,
1170 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1172 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1176 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1178 if (*lpServicesReturned
> 0)
1180 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1182 if (lpStatusPtr
->lpServiceName
)
1183 lpStatusPtr
->lpServiceName
=
1184 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1186 if (lpStatusPtr
->lpDisplayName
)
1187 lpStatusPtr
->lpDisplayName
=
1188 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1195 if (dwError
!= ERROR_SUCCESS
)
1197 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1198 SetLastError(dwError
);
1202 TRACE("EnumServicesStatusW() done\n");
1208 /**********************************************************************
1209 * EnumServicesStatusExA
1214 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1215 SC_ENUM_TYPE InfoLevel
,
1216 DWORD dwServiceType
,
1217 DWORD dwServiceState
,
1220 LPDWORD pcbBytesNeeded
,
1221 LPDWORD lpServicesReturned
,
1222 LPDWORD lpResumeHandle
,
1223 LPCSTR pszGroupName
)
1225 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1226 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1231 TRACE("EnumServicesStatusExA() called\n");
1233 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1235 SetLastError(ERROR_INVALID_LEVEL
);
1241 SetLastError(ERROR_INVALID_HANDLE
);
1245 if (lpServices
== NULL
||
1246 cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1248 lpStatusPtr
= &ServiceStatus
;
1249 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1253 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1254 dwBufferSize
= cbBufSize
;
1259 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1263 (LPBYTE
)lpStatusPtr
,
1268 (LPSTR
)pszGroupName
);
1270 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1272 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1276 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1278 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1280 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1282 if (lpStatusPtr
->lpServiceName
)
1283 lpStatusPtr
->lpServiceName
=
1284 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1286 if (lpStatusPtr
->lpDisplayName
)
1287 lpStatusPtr
->lpDisplayName
=
1288 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1295 if (dwError
!= ERROR_SUCCESS
)
1297 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1298 SetLastError(dwError
);
1302 TRACE("EnumServicesStatusExA() done\n");
1308 /**********************************************************************
1309 * EnumServicesStatusExW
1314 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1315 SC_ENUM_TYPE InfoLevel
,
1316 DWORD dwServiceType
,
1317 DWORD dwServiceState
,
1320 LPDWORD pcbBytesNeeded
,
1321 LPDWORD lpServicesReturned
,
1322 LPDWORD lpResumeHandle
,
1323 LPCWSTR pszGroupName
)
1325 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1326 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1331 TRACE("EnumServicesStatusExW() called\n");
1333 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1335 SetLastError(ERROR_INVALID_LEVEL
);
1339 if (lpServices
== NULL
||
1340 cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1342 lpStatusPtr
= &ServiceStatus
;
1343 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1347 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1348 dwBufferSize
= cbBufSize
;
1353 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1357 (LPBYTE
)lpStatusPtr
,
1362 (LPWSTR
)pszGroupName
);
1364 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1366 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1370 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1372 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1374 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1376 if (lpStatusPtr
->lpServiceName
)
1377 lpStatusPtr
->lpServiceName
=
1378 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1380 if (lpStatusPtr
->lpDisplayName
)
1381 lpStatusPtr
->lpDisplayName
=
1382 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1389 if (dwError
!= ERROR_SUCCESS
)
1391 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1392 SetLastError(dwError
);
1396 TRACE("EnumServicesStatusExW() done\n");
1402 /**********************************************************************
1403 * GetServiceDisplayNameA
1408 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1409 LPCSTR lpServiceName
,
1410 LPSTR lpDisplayName
,
1411 LPDWORD lpcchBuffer
)
1415 CHAR szEmptyName
[] = "";
1417 TRACE("GetServiceDisplayNameA() called\n");
1418 TRACE("%p %s %p %p\n", hSCManager
,
1419 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1423 SetLastError(ERROR_INVALID_HANDLE
);
1427 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1429 lpNameBuffer
= szEmptyName
;
1430 *lpcchBuffer
= sizeof(CHAR
);
1434 lpNameBuffer
= lpDisplayName
;
1439 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1444 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1446 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1447 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1451 if (dwError
!= ERROR_SUCCESS
)
1453 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1454 SetLastError(dwError
);
1462 /**********************************************************************
1463 * GetServiceDisplayNameW
1468 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1469 LPCWSTR lpServiceName
,
1470 LPWSTR lpDisplayName
,
1471 LPDWORD lpcchBuffer
)
1474 LPWSTR lpNameBuffer
;
1475 WCHAR szEmptyName
[] = L
"";
1477 TRACE("GetServiceDisplayNameW() called\n");
1481 SetLastError(ERROR_INVALID_HANDLE
);
1485 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1487 lpNameBuffer
= szEmptyName
;
1488 *lpcchBuffer
= sizeof(WCHAR
);
1492 lpNameBuffer
= lpDisplayName
;
1497 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1502 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1504 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1508 if (dwError
!= ERROR_SUCCESS
)
1510 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1511 SetLastError(dwError
);
1519 /**********************************************************************
1520 * GetServiceKeyNameA
1525 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1526 LPCSTR lpDisplayName
,
1527 LPSTR lpServiceName
,
1528 LPDWORD lpcchBuffer
)
1532 CHAR szEmptyName
[] = "";
1534 TRACE("GetServiceKeyNameA() called\n");
1538 SetLastError(ERROR_INVALID_HANDLE
);
1542 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1544 lpNameBuffer
= szEmptyName
;
1545 *lpcchBuffer
= sizeof(CHAR
);
1549 lpNameBuffer
= lpServiceName
;
1554 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1559 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1561 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1565 if (dwError
!= ERROR_SUCCESS
)
1567 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1568 SetLastError(dwError
);
1576 /**********************************************************************
1577 * GetServiceKeyNameW
1582 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1583 LPCWSTR lpDisplayName
,
1584 LPWSTR lpServiceName
,
1585 LPDWORD lpcchBuffer
)
1588 LPWSTR lpNameBuffer
;
1589 WCHAR szEmptyName
[] = L
"";
1591 TRACE("GetServiceKeyNameW() called\n");
1595 SetLastError(ERROR_INVALID_HANDLE
);
1599 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1601 lpNameBuffer
= szEmptyName
;
1602 *lpcchBuffer
= sizeof(WCHAR
);
1606 lpNameBuffer
= lpServiceName
;
1611 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1616 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1618 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1622 if (dwError
!= ERROR_SUCCESS
)
1624 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1625 SetLastError(dwError
);
1633 /**********************************************************************
1634 * LockServiceDatabase
1639 LockServiceDatabase(SC_HANDLE hSCManager
)
1644 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1648 /* Call to services.exe using RPC */
1649 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1650 (SC_RPC_LOCK
*)&hLock
);
1652 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1654 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1658 if (dwError
!= ERROR_SUCCESS
)
1660 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1661 SetLastError(dwError
);
1665 TRACE("hLock = %p\n", hLock
);
1672 WaitForSCManager(VOID
)
1676 TRACE("WaitForSCManager() called\n");
1678 /* Try to open the existing event */
1679 hEvent
= OpenEventW(SYNCHRONIZE
,
1681 L
"SvcctrlStartEvent_A3752DX");
1684 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1687 /* Try to create a new event */
1688 hEvent
= CreateEventW(NULL
,
1691 L
"SvcctrlStartEvent_A3752DX");
1694 /* Try to open the existing event again */
1695 hEvent
= OpenEventW(SYNCHRONIZE
,
1697 L
"SvcctrlStartEvent_A3752DX");
1703 /* Wait for 3 minutes */
1704 WaitForSingleObject(hEvent
, 180000);
1705 CloseHandle(hEvent
);
1707 TRACE("ScmWaitForSCManager() done\n");
1711 /**********************************************************************
1717 OpenSCManagerA(LPCSTR lpMachineName
,
1718 LPCSTR lpDatabaseName
,
1719 DWORD dwDesiredAccess
)
1721 SC_HANDLE hScm
= NULL
;
1724 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1725 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1731 /* Call to services.exe using RPC */
1732 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1733 (LPSTR
)lpDatabaseName
,
1735 (SC_RPC_HANDLE
*)&hScm
);
1737 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1739 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1743 if (dwError
!= ERROR_SUCCESS
)
1745 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1746 SetLastError(dwError
);
1750 TRACE("hScm = %p\n", hScm
);
1756 /**********************************************************************
1762 OpenSCManagerW(LPCWSTR lpMachineName
,
1763 LPCWSTR lpDatabaseName
,
1764 DWORD dwDesiredAccess
)
1766 SC_HANDLE hScm
= NULL
;
1769 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1770 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1776 /* Call to services.exe using RPC */
1777 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1778 (LPWSTR
)lpDatabaseName
,
1780 (SC_RPC_HANDLE
*)&hScm
);
1782 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1784 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1788 if (dwError
!= ERROR_SUCCESS
)
1790 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1791 SetLastError(dwError
);
1795 TRACE("hScm = %p\n", hScm
);
1801 /**********************************************************************
1807 OpenServiceA(SC_HANDLE hSCManager
,
1808 LPCSTR lpServiceName
,
1809 DWORD dwDesiredAccess
)
1811 SC_HANDLE hService
= NULL
;
1814 TRACE("OpenServiceA(%p, %s, %lx)\n",
1815 hSCManager
, lpServiceName
, dwDesiredAccess
);
1819 SetLastError(ERROR_INVALID_HANDLE
);
1825 /* Call to services.exe using RPC */
1826 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1827 (LPSTR
)lpServiceName
,
1829 (SC_RPC_HANDLE
*)&hService
);
1831 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1833 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1837 if (dwError
!= ERROR_SUCCESS
)
1839 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1840 SetLastError(dwError
);
1844 TRACE("hService = %p\n", hService
);
1850 /**********************************************************************
1856 OpenServiceW(SC_HANDLE hSCManager
,
1857 LPCWSTR lpServiceName
,
1858 DWORD dwDesiredAccess
)
1860 SC_HANDLE hService
= NULL
;
1863 TRACE("OpenServiceW(%p, %S, %lx)\n",
1864 hSCManager
, lpServiceName
, dwDesiredAccess
);
1868 SetLastError(ERROR_INVALID_HANDLE
);
1874 /* Call to services.exe using RPC */
1875 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1876 (LPWSTR
)lpServiceName
,
1878 (SC_RPC_HANDLE
*)&hService
);
1880 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1882 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1886 if (dwError
!= ERROR_SUCCESS
)
1888 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1889 SetLastError(dwError
);
1893 TRACE("hService = %p\n", hService
);
1899 /**********************************************************************
1900 * QueryServiceConfigA
1905 QueryServiceConfigA(SC_HANDLE hService
,
1906 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1908 LPDWORD pcbBytesNeeded
)
1910 QUERY_SERVICE_CONFIGA ServiceConfig
;
1911 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1915 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1916 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1918 if (lpServiceConfig
== NULL
||
1919 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1921 lpConfigPtr
= &ServiceConfig
;
1922 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1926 lpConfigPtr
= lpServiceConfig
;
1927 dwBufferSize
= cbBufSize
;
1932 /* Call to services.exe using RPC */
1933 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1934 (LPBYTE
)lpConfigPtr
,
1938 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1940 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1944 if (dwError
!= ERROR_SUCCESS
)
1946 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1947 SetLastError(dwError
);
1951 /* Adjust the pointers */
1952 if (lpConfigPtr
->lpBinaryPathName
)
1953 lpConfigPtr
->lpBinaryPathName
=
1954 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1955 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
1957 if (lpConfigPtr
->lpLoadOrderGroup
)
1958 lpConfigPtr
->lpLoadOrderGroup
=
1959 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1960 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
1962 if (lpConfigPtr
->lpDependencies
)
1963 lpConfigPtr
->lpDependencies
=
1964 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1965 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
1967 if (lpConfigPtr
->lpServiceStartName
)
1968 lpConfigPtr
->lpServiceStartName
=
1969 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1970 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
1972 if (lpConfigPtr
->lpDisplayName
)
1973 lpConfigPtr
->lpDisplayName
=
1974 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1975 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
1977 TRACE("QueryServiceConfigA() done\n");
1983 /**********************************************************************
1984 * QueryServiceConfigW
1989 QueryServiceConfigW(SC_HANDLE hService
,
1990 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1992 LPDWORD pcbBytesNeeded
)
1994 QUERY_SERVICE_CONFIGW ServiceConfig
;
1995 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
1999 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
2000 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2002 if (lpServiceConfig
== NULL
||
2003 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2005 lpConfigPtr
= &ServiceConfig
;
2006 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2010 lpConfigPtr
= lpServiceConfig
;
2011 dwBufferSize
= cbBufSize
;
2016 /* Call to services.exe using RPC */
2017 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2018 (LPBYTE
)lpConfigPtr
,
2022 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2024 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2028 if (dwError
!= ERROR_SUCCESS
)
2030 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2031 SetLastError(dwError
);
2035 /* Adjust the pointers */
2036 if (lpConfigPtr
->lpBinaryPathName
)
2037 lpConfigPtr
->lpBinaryPathName
=
2038 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2039 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2041 if (lpConfigPtr
->lpLoadOrderGroup
)
2042 lpConfigPtr
->lpLoadOrderGroup
=
2043 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2044 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2046 if (lpConfigPtr
->lpDependencies
)
2047 lpConfigPtr
->lpDependencies
=
2048 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2049 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2051 if (lpConfigPtr
->lpServiceStartName
)
2052 lpConfigPtr
->lpServiceStartName
=
2053 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2054 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2056 if (lpConfigPtr
->lpDisplayName
)
2057 lpConfigPtr
->lpDisplayName
=
2058 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2059 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2061 TRACE("QueryServiceConfigW() done\n");
2067 /**********************************************************************
2068 * QueryServiceConfig2A
2073 QueryServiceConfig2A(SC_HANDLE hService
,
2077 LPDWORD pcbBytesNeeded
)
2079 SERVICE_DESCRIPTIONA ServiceDescription
;
2080 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2081 LPBYTE lpTempBuffer
;
2082 BOOL bUseTempBuffer
= FALSE
;
2086 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2087 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2089 lpTempBuffer
= lpBuffer
;
2090 dwBufferSize
= cbBufSize
;
2092 switch (dwInfoLevel
)
2094 case SERVICE_CONFIG_DESCRIPTION
:
2095 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2097 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2098 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2099 bUseTempBuffer
= TRUE
;
2103 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2104 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2106 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2107 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2108 bUseTempBuffer
= TRUE
;
2113 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2114 SetLastError(ERROR_INVALID_LEVEL
);
2120 /* Call to services.exe using RPC */
2121 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2127 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2129 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2133 if (dwError
!= ERROR_SUCCESS
)
2135 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2136 SetLastError(dwError
);
2140 if (bUseTempBuffer
== TRUE
)
2142 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2143 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2147 switch (dwInfoLevel
)
2149 case SERVICE_CONFIG_DESCRIPTION
:
2151 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2153 if (lpPtr
->lpDescription
!= NULL
)
2154 lpPtr
->lpDescription
=
2155 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2159 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2161 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2163 if (lpPtr
->lpRebootMsg
!= NULL
)
2164 lpPtr
->lpRebootMsg
=
2165 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2167 if (lpPtr
->lpCommand
!= NULL
)
2169 (LPSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2171 if (lpPtr
->lpsaActions
!= NULL
)
2172 lpPtr
->lpsaActions
=
2173 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2178 TRACE("QueryServiceConfig2A() done\n");
2184 /**********************************************************************
2185 * QueryServiceConfig2W
2190 QueryServiceConfig2W(SC_HANDLE hService
,
2194 LPDWORD pcbBytesNeeded
)
2196 SERVICE_DESCRIPTIONW ServiceDescription
;
2197 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2198 LPBYTE lpTempBuffer
;
2199 BOOL bUseTempBuffer
= FALSE
;
2203 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2204 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2206 lpTempBuffer
= lpBuffer
;
2207 dwBufferSize
= cbBufSize
;
2209 switch (dwInfoLevel
)
2211 case SERVICE_CONFIG_DESCRIPTION
:
2212 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2214 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2215 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2216 bUseTempBuffer
= TRUE
;
2220 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2221 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2223 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2224 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2225 bUseTempBuffer
= TRUE
;
2230 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2231 SetLastError(ERROR_INVALID_LEVEL
);
2237 /* Call to services.exe using RPC */
2238 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2244 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2246 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2250 if (dwError
!= ERROR_SUCCESS
)
2252 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2253 SetLastError(dwError
);
2257 if (bUseTempBuffer
== TRUE
)
2259 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2260 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2264 switch (dwInfoLevel
)
2266 case SERVICE_CONFIG_DESCRIPTION
:
2268 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2270 if (lpPtr
->lpDescription
!= NULL
)
2271 lpPtr
->lpDescription
=
2272 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpDescription
);
2276 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2278 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2280 if (lpPtr
->lpRebootMsg
!= NULL
)
2281 lpPtr
->lpRebootMsg
=
2282 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpRebootMsg
);
2284 if (lpPtr
->lpCommand
!= NULL
)
2286 (LPWSTR
)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpCommand
);
2288 if (lpPtr
->lpsaActions
!= NULL
)
2289 lpPtr
->lpsaActions
=
2290 (SC_ACTION
*)((UINT_PTR
)lpPtr
+ (UINT_PTR
)lpPtr
->lpsaActions
);
2295 TRACE("QueryServiceConfig2W() done\n");
2301 /**********************************************************************
2302 * QueryServiceLockStatusA
2307 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2308 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2310 LPDWORD pcbBytesNeeded
)
2312 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2313 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2317 TRACE("QueryServiceLockStatusA() called\n");
2319 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2321 lpStatusPtr
= &LockStatus
;
2322 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2326 lpStatusPtr
= lpLockStatus
;
2327 dwBufferSize
= cbBufSize
;
2332 /* Call to services.exe using RPC */
2333 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2338 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2340 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2344 if (dwError
!= ERROR_SUCCESS
)
2346 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2347 SetLastError(dwError
);
2351 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2353 lpStatusPtr
->lpLockOwner
=
2354 (LPSTR
)((UINT_PTR
)lpStatusPtr
+ (UINT_PTR
)lpStatusPtr
->lpLockOwner
);
2357 TRACE("QueryServiceLockStatusA() done\n");
2363 /**********************************************************************
2364 * QueryServiceLockStatusW
2369 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2370 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2372 LPDWORD pcbBytesNeeded
)
2374 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2375 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2379 TRACE("QueryServiceLockStatusW() called\n");
2381 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2383 lpStatusPtr
= &LockStatus
;
2384 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2388 lpStatusPtr
= lpLockStatus
;
2389 dwBufferSize
= cbBufSize
;
2394 /* Call to services.exe using RPC */
2395 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2400 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2402 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2406 if (dwError
!= ERROR_SUCCESS
)
2408 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2409 SetLastError(dwError
);
2413 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2415 lpStatusPtr
->lpLockOwner
=
2416 (LPWSTR
)((UINT_PTR
)lpStatusPtr
+ (UINT_PTR
)lpStatusPtr
->lpLockOwner
);
2419 TRACE("QueryServiceLockStatusW() done\n");
2425 /**********************************************************************
2426 * QueryServiceObjectSecurity
2431 QueryServiceObjectSecurity(SC_HANDLE hService
,
2432 SECURITY_INFORMATION dwSecurityInformation
,
2433 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2435 LPDWORD pcbBytesNeeded
)
2439 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2440 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2444 /* Call to services.exe using RPC */
2445 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2446 dwSecurityInformation
,
2447 (LPBYTE
)lpSecurityDescriptor
,
2451 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2453 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2457 if (dwError
!= ERROR_SUCCESS
)
2459 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2460 SetLastError(dwError
);
2467 /**********************************************************************
2468 * SetServiceObjectSecurity
2473 SetServiceObjectSecurity(SC_HANDLE hService
,
2474 SECURITY_INFORMATION dwSecurityInformation
,
2475 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2477 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2483 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2486 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2488 SetLastError(ERROR_INVALID_PARAMETER
);
2492 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2493 if (SelfRelativeSD
== NULL
)
2495 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2499 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2502 if (!NT_SUCCESS(Status
))
2504 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2505 SetLastError(RtlNtStatusToDosError(Status
));
2511 /* Call to services.exe using RPC */
2512 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2513 dwSecurityInformation
,
2514 (LPBYTE
)SelfRelativeSD
,
2517 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2519 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2523 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2525 if (dwError
!= ERROR_SUCCESS
)
2527 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2528 SetLastError(dwError
);
2536 /**********************************************************************
2537 * QueryServiceStatus
2542 QueryServiceStatus(SC_HANDLE hService
,
2543 LPSERVICE_STATUS lpServiceStatus
)
2547 TRACE("QueryServiceStatus(%p, %p)\n",
2548 hService
, lpServiceStatus
);
2552 SetLastError(ERROR_INVALID_HANDLE
);
2558 /* Call to services.exe using RPC */
2559 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2562 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2564 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2568 if (dwError
!= ERROR_SUCCESS
)
2570 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2571 SetLastError(dwError
);
2579 /**********************************************************************
2580 * QueryServiceStatusEx
2585 QueryServiceStatusEx(SC_HANDLE hService
,
2586 SC_STATUS_TYPE InfoLevel
,
2589 LPDWORD pcbBytesNeeded
)
2593 TRACE("QueryServiceStatusEx() called\n");
2595 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2597 SetLastError(ERROR_INVALID_LEVEL
);
2601 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2603 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2604 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2610 /* Call to services.exe using RPC */
2611 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2617 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2619 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2623 if (dwError
!= ERROR_SUCCESS
)
2625 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2626 SetLastError(dwError
);
2634 /**********************************************************************
2640 StartServiceA(SC_HANDLE hService
,
2641 DWORD dwNumServiceArgs
,
2642 LPCSTR
*lpServiceArgVectors
)
2648 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2650 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2652 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2654 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2658 if (dwError
!= ERROR_SUCCESS
)
2660 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2661 SetLastError(dwError
);
2669 /**********************************************************************
2675 StartServiceW(SC_HANDLE hService
,
2676 DWORD dwNumServiceArgs
,
2677 LPCWSTR
*lpServiceArgVectors
)
2683 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2685 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2687 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2689 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2693 if (dwError
!= ERROR_SUCCESS
)
2695 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2696 SetLastError(dwError
);
2704 /**********************************************************************
2705 * UnlockServiceDatabase
2710 UnlockServiceDatabase(SC_LOCK ScLock
)
2714 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2718 /* Call to services.exe using RPC */
2719 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2721 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2723 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2727 if (dwError
!= ERROR_SUCCESS
)
2729 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2730 SetLastError(dwError
);
2738 /**********************************************************************
2739 * NotifyBootConfigStatus
2744 NotifyBootConfigStatus(BOOL BootAcceptable
)
2748 TRACE("NotifyBootConfigStatus()\n");
2752 /* Call to services.exe using RPC */
2753 dwError
= RNotifyBootConfigStatus(NULL
,
2756 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2758 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2762 if (dwError
!= ERROR_SUCCESS
)
2764 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2765 SetLastError(dwError
);