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;
292 DWORD dwPasswordLength
= 0;
293 LPBYTE lpEncryptedPassword
= NULL
;
295 TRACE("ChangeServiceConfigA() called\n");
297 /* Calculate the Dependencies length*/
298 if (lpDependencies
!= NULL
)
300 lpStr
= lpDependencies
;
303 cchLength
= strlen(lpStr
) + 1;
304 dwDependenciesLength
+= (DWORD
)cchLength
;
305 lpStr
= lpStr
+ cchLength
;
307 dwDependenciesLength
++;
310 /* FIXME: Encrypt the password */
311 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
312 dwPasswordLength
= (DWORD
)(lpPassword
? (strlen(lpPassword
) + 1) * sizeof(CHAR
) : 0);
316 /* Call to services.exe using RPC */
317 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
321 (LPSTR
)lpBinaryPathName
,
322 (LPSTR
)lpLoadOrderGroup
,
324 (LPBYTE
)lpDependencies
,
325 dwDependenciesLength
,
326 (LPSTR
)lpServiceStartName
,
329 (LPSTR
)lpDisplayName
);
331 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
333 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
337 if (dwError
!= ERROR_SUCCESS
)
339 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
340 SetLastError(dwError
);
348 /**********************************************************************
349 * ChangeServiceConfigW
354 ChangeServiceConfigW(SC_HANDLE hService
,
357 DWORD dwErrorControl
,
358 LPCWSTR lpBinaryPathName
,
359 LPCWSTR lpLoadOrderGroup
,
361 LPCWSTR lpDependencies
,
362 LPCWSTR lpServiceStartName
,
364 LPCWSTR lpDisplayName
)
367 DWORD dwDependenciesLength
= 0;
370 DWORD dwPasswordLength
= 0;
371 LPBYTE lpEncryptedPassword
= NULL
;
373 TRACE("ChangeServiceConfigW() called\n");
375 /* Calculate the Dependencies length*/
376 if (lpDependencies
!= NULL
)
378 lpStr
= lpDependencies
;
381 cchLength
= wcslen(lpStr
) + 1;
382 dwDependenciesLength
+= (DWORD
)cchLength
;
383 lpStr
= lpStr
+ cchLength
;
385 dwDependenciesLength
++;
386 dwDependenciesLength
*= sizeof(WCHAR
);
389 /* FIXME: Encrypt the password */
390 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
391 dwPasswordLength
= (lpPassword
? (wcslen(lpPassword
) + 1) * sizeof(WCHAR
) : 0);
395 /* Call to services.exe using RPC */
396 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
400 (LPWSTR
)lpBinaryPathName
,
401 (LPWSTR
)lpLoadOrderGroup
,
403 (LPBYTE
)lpDependencies
,
404 dwDependenciesLength
,
405 (LPWSTR
)lpServiceStartName
,
408 (LPWSTR
)lpDisplayName
);
410 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
412 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
416 if (dwError
!= ERROR_SUCCESS
)
418 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
419 SetLastError(dwError
);
427 /**********************************************************************
433 CloseServiceHandle(SC_HANDLE hSCObject
)
437 TRACE("CloseServiceHandle() called\n");
441 SetLastError(ERROR_INVALID_HANDLE
);
447 /* Call to services.exe using RPC */
448 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
450 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
452 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
458 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
459 SetLastError(dwError
);
463 TRACE("CloseServiceHandle() done\n");
469 /**********************************************************************
475 ControlService(SC_HANDLE hService
,
477 LPSERVICE_STATUS lpServiceStatus
)
481 TRACE("ControlService(%x, %x, %p)\n",
482 hService
, dwControl
, lpServiceStatus
);
486 /* Call to services.exe using RPC */
487 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
491 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
493 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
497 if (dwError
!= ERROR_SUCCESS
)
499 TRACE("RControlService() failed (Error %lu)\n", dwError
);
500 SetLastError(dwError
);
504 TRACE("ControlService() done\n");
510 /**********************************************************************
516 ControlServiceEx(IN SC_HANDLE hService
,
518 IN DWORD dwInfoLevel
,
519 IN OUT PVOID pControlParams
)
521 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
522 hService
, dwControl
, dwInfoLevel
, pControlParams
);
523 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
528 /**********************************************************************
534 CreateServiceA(SC_HANDLE hSCManager
,
535 LPCSTR lpServiceName
,
536 LPCSTR lpDisplayName
,
537 DWORD dwDesiredAccess
,
540 DWORD dwErrorControl
,
541 LPCSTR lpBinaryPathName
,
542 LPCSTR lpLoadOrderGroup
,
544 LPCSTR lpDependencies
,
545 LPCSTR lpServiceStartName
,
548 SC_HANDLE hService
= NULL
;
549 DWORD dwDependenciesLength
= 0;
553 DWORD dwPasswordLength
= 0;
554 LPBYTE lpEncryptedPassword
= NULL
;
556 TRACE("CreateServiceA() called\n");
557 TRACE("%p %s %s\n", hSCManager
,
558 lpServiceName
, lpDisplayName
);
562 SetLastError(ERROR_INVALID_HANDLE
);
566 /* Calculate the Dependencies length */
567 if (lpDependencies
!= NULL
)
569 lpStr
= lpDependencies
;
572 cchLength
= strlen(lpStr
) + 1;
573 dwDependenciesLength
+= (DWORD
)cchLength
;
574 lpStr
= lpStr
+ cchLength
;
576 dwDependenciesLength
++;
579 /* FIXME: Encrypt the password */
580 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
581 dwPasswordLength
= (DWORD
)(lpPassword
? (strlen(lpPassword
) + 1) * sizeof(CHAR
) : 0);
585 /* Call to services.exe using RPC */
586 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
587 (LPSTR
)lpServiceName
,
588 (LPSTR
)lpDisplayName
,
593 (LPSTR
)lpBinaryPathName
,
594 (LPSTR
)lpLoadOrderGroup
,
596 (LPBYTE
)lpDependencies
,
597 dwDependenciesLength
,
598 (LPSTR
)lpServiceStartName
,
601 (SC_RPC_HANDLE
*)&hService
);
603 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
605 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
609 if (dwError
!= ERROR_SUCCESS
)
611 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
612 SetLastError(dwError
);
620 /**********************************************************************
626 CreateServiceW(SC_HANDLE hSCManager
,
627 LPCWSTR lpServiceName
,
628 LPCWSTR lpDisplayName
,
629 DWORD dwDesiredAccess
,
632 DWORD dwErrorControl
,
633 LPCWSTR lpBinaryPathName
,
634 LPCWSTR lpLoadOrderGroup
,
636 LPCWSTR lpDependencies
,
637 LPCWSTR lpServiceStartName
,
640 SC_HANDLE hService
= NULL
;
641 DWORD dwDependenciesLength
= 0;
645 DWORD dwPasswordLength
= 0;
646 LPBYTE lpEncryptedPassword
= NULL
;
648 TRACE("CreateServiceW() called\n");
649 TRACE("%p %S %S\n", hSCManager
,
650 lpServiceName
, lpDisplayName
);
654 SetLastError(ERROR_INVALID_HANDLE
);
658 /* Calculate the Dependencies length */
659 if (lpDependencies
!= NULL
)
661 lpStr
= lpDependencies
;
664 cchLength
= wcslen(lpStr
) + 1;
665 dwDependenciesLength
+= (DWORD
)cchLength
;
666 lpStr
= lpStr
+ cchLength
;
668 dwDependenciesLength
++;
669 dwDependenciesLength
*= sizeof(WCHAR
);
672 /* FIXME: Encrypt the password */
673 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
674 dwPasswordLength
= (DWORD
)(lpPassword
? (wcslen(lpPassword
) + 1) * sizeof(WCHAR
) : 0);
678 /* Call to services.exe using RPC */
679 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
689 (LPBYTE
)lpDependencies
,
690 dwDependenciesLength
,
694 (SC_RPC_HANDLE
*)&hService
);
696 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
698 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
702 if (dwError
!= ERROR_SUCCESS
)
704 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
705 SetLastError(dwError
);
713 /**********************************************************************
719 DeleteService(SC_HANDLE hService
)
723 TRACE("DeleteService(%x)\n", hService
);
727 /* Call to services.exe using RPC */
728 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
730 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
732 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
736 if (dwError
!= ERROR_SUCCESS
)
738 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
739 SetLastError(dwError
);
747 /**********************************************************************
748 * EnumDependentServicesA
753 EnumDependentServicesA(SC_HANDLE hService
,
754 DWORD dwServiceState
,
755 LPENUM_SERVICE_STATUSA lpServices
,
757 LPDWORD pcbBytesNeeded
,
758 LPDWORD lpServicesReturned
)
760 ENUM_SERVICE_STATUSA ServiceStatus
;
761 LPENUM_SERVICE_STATUSA lpStatusPtr
;
766 TRACE("EnumDependentServicesA() called\n");
768 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
770 lpStatusPtr
= &ServiceStatus
;
771 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
775 lpStatusPtr
= lpServices
;
776 dwBufferSize
= cbBufSize
;
781 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
788 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
790 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
794 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
796 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
798 if (lpStatusPtr
->lpServiceName
)
799 lpStatusPtr
->lpServiceName
=
800 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
802 if (lpStatusPtr
->lpDisplayName
)
803 lpStatusPtr
->lpDisplayName
=
804 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
810 if (dwError
!= ERROR_SUCCESS
)
812 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
813 SetLastError(dwError
);
817 TRACE("EnumDependentServicesA() done\n");
823 /**********************************************************************
824 * EnumDependentServicesW
829 EnumDependentServicesW(SC_HANDLE hService
,
830 DWORD dwServiceState
,
831 LPENUM_SERVICE_STATUSW lpServices
,
833 LPDWORD pcbBytesNeeded
,
834 LPDWORD lpServicesReturned
)
836 ENUM_SERVICE_STATUSW ServiceStatus
;
837 LPENUM_SERVICE_STATUSW lpStatusPtr
;
842 TRACE("EnumDependentServicesW() called\n");
844 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
846 lpStatusPtr
= &ServiceStatus
;
847 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
851 lpStatusPtr
= lpServices
;
852 dwBufferSize
= cbBufSize
;
857 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
864 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
866 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
870 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
872 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
874 if (lpStatusPtr
->lpServiceName
)
875 lpStatusPtr
->lpServiceName
=
876 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
878 if (lpStatusPtr
->lpDisplayName
)
879 lpStatusPtr
->lpDisplayName
=
880 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
886 if (dwError
!= ERROR_SUCCESS
)
888 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
889 SetLastError(dwError
);
893 TRACE("EnumDependentServicesW() done\n");
899 /**********************************************************************
905 EnumServiceGroupW(SC_HANDLE hSCManager
,
907 DWORD dwServiceState
,
908 LPENUM_SERVICE_STATUSW lpServices
,
910 LPDWORD pcbBytesNeeded
,
911 LPDWORD lpServicesReturned
,
912 LPDWORD lpResumeHandle
,
915 ENUM_SERVICE_STATUSW ServiceStatus
;
916 LPENUM_SERVICE_STATUSW lpStatusPtr
;
921 TRACE("EnumServiceGroupW() called\n");
925 SetLastError(ERROR_INVALID_HANDLE
);
929 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
931 lpStatusPtr
= &ServiceStatus
;
932 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
936 lpStatusPtr
= lpServices
;
937 dwBufferSize
= cbBufSize
;
944 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
955 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
966 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
968 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
972 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
974 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
976 if (lpStatusPtr
->lpServiceName
)
977 lpStatusPtr
->lpServiceName
=
978 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
980 if (lpStatusPtr
->lpDisplayName
)
981 lpStatusPtr
->lpDisplayName
=
982 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
988 if (dwError
!= ERROR_SUCCESS
)
990 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
991 SetLastError(dwError
);
995 TRACE("EnumServiceGroupW() done\n");
1001 /**********************************************************************
1002 * EnumServicesStatusA
1007 EnumServicesStatusA(SC_HANDLE hSCManager
,
1008 DWORD dwServiceType
,
1009 DWORD dwServiceState
,
1010 LPENUM_SERVICE_STATUSA lpServices
,
1012 LPDWORD pcbBytesNeeded
,
1013 LPDWORD lpServicesReturned
,
1014 LPDWORD lpResumeHandle
)
1016 ENUM_SERVICE_STATUSA ServiceStatus
;
1017 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1022 TRACE("EnumServicesStatusA() called\n");
1026 SetLastError(ERROR_INVALID_HANDLE
);
1030 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1032 lpStatusPtr
= &ServiceStatus
;
1033 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1037 lpStatusPtr
= lpServices
;
1038 dwBufferSize
= cbBufSize
;
1043 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1046 (LPBYTE
)lpStatusPtr
,
1052 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1054 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1058 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1060 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1062 if (lpStatusPtr
->lpServiceName
)
1063 lpStatusPtr
->lpServiceName
=
1064 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1066 if (lpStatusPtr
->lpDisplayName
)
1067 lpStatusPtr
->lpDisplayName
=
1068 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1074 if (dwError
!= ERROR_SUCCESS
)
1076 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1077 SetLastError(dwError
);
1081 TRACE("EnumServicesStatusA() done\n");
1087 /**********************************************************************
1088 * EnumServicesStatusW
1093 EnumServicesStatusW(SC_HANDLE hSCManager
,
1094 DWORD dwServiceType
,
1095 DWORD dwServiceState
,
1096 LPENUM_SERVICE_STATUSW lpServices
,
1098 LPDWORD pcbBytesNeeded
,
1099 LPDWORD lpServicesReturned
,
1100 LPDWORD lpResumeHandle
)
1102 ENUM_SERVICE_STATUSW ServiceStatus
;
1103 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1108 TRACE("EnumServicesStatusW() called\n");
1112 SetLastError(ERROR_INVALID_HANDLE
);
1116 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1118 lpStatusPtr
= &ServiceStatus
;
1119 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1123 lpStatusPtr
= lpServices
;
1124 dwBufferSize
= cbBufSize
;
1129 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1132 (LPBYTE
)lpStatusPtr
,
1138 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1140 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1144 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1146 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1148 if (lpStatusPtr
->lpServiceName
)
1149 lpStatusPtr
->lpServiceName
=
1150 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1152 if (lpStatusPtr
->lpDisplayName
)
1153 lpStatusPtr
->lpDisplayName
=
1154 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1160 if (dwError
!= ERROR_SUCCESS
)
1162 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1163 SetLastError(dwError
);
1167 TRACE("EnumServicesStatusW() done\n");
1173 /**********************************************************************
1174 * EnumServicesStatusExA
1179 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1180 SC_ENUM_TYPE InfoLevel
,
1181 DWORD dwServiceType
,
1182 DWORD dwServiceState
,
1185 LPDWORD pcbBytesNeeded
,
1186 LPDWORD lpServicesReturned
,
1187 LPDWORD lpResumeHandle
,
1188 LPCSTR pszGroupName
)
1190 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1191 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1196 TRACE("EnumServicesStatusExA() called\n");
1198 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1200 SetLastError(ERROR_INVALID_LEVEL
);
1206 SetLastError(ERROR_INVALID_HANDLE
);
1210 if (lpServices
== NULL
||
1211 cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1213 lpStatusPtr
= &ServiceStatus
;
1214 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1218 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1219 dwBufferSize
= cbBufSize
;
1224 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1228 (LPBYTE
)lpStatusPtr
,
1233 (LPSTR
)pszGroupName
);
1235 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1237 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1241 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1243 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1245 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1247 if (lpStatusPtr
->lpServiceName
)
1248 lpStatusPtr
->lpServiceName
=
1249 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1251 if (lpStatusPtr
->lpDisplayName
)
1252 lpStatusPtr
->lpDisplayName
=
1253 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1260 if (dwError
!= ERROR_SUCCESS
)
1262 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1263 SetLastError(dwError
);
1267 TRACE("EnumServicesStatusExA() done\n");
1273 /**********************************************************************
1274 * EnumServicesStatusExW
1279 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1280 SC_ENUM_TYPE InfoLevel
,
1281 DWORD dwServiceType
,
1282 DWORD dwServiceState
,
1285 LPDWORD pcbBytesNeeded
,
1286 LPDWORD lpServicesReturned
,
1287 LPDWORD lpResumeHandle
,
1288 LPCWSTR pszGroupName
)
1290 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1291 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1296 TRACE("EnumServicesStatusExW() called\n");
1298 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1300 SetLastError(ERROR_INVALID_LEVEL
);
1306 SetLastError(ERROR_INVALID_HANDLE
);
1310 if (lpServices
== NULL
||
1311 cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1313 lpStatusPtr
= &ServiceStatus
;
1314 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1318 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1319 dwBufferSize
= cbBufSize
;
1324 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1328 (LPBYTE
)lpStatusPtr
,
1333 (LPWSTR
)pszGroupName
);
1335 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1337 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1341 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1343 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1345 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1347 if (lpStatusPtr
->lpServiceName
)
1348 lpStatusPtr
->lpServiceName
=
1349 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1351 if (lpStatusPtr
->lpDisplayName
)
1352 lpStatusPtr
->lpDisplayName
=
1353 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1360 if (dwError
!= ERROR_SUCCESS
)
1362 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1363 SetLastError(dwError
);
1367 TRACE("EnumServicesStatusExW() done\n");
1373 /**********************************************************************
1374 * GetServiceDisplayNameA
1379 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1380 LPCSTR lpServiceName
,
1381 LPSTR lpDisplayName
,
1382 LPDWORD lpcchBuffer
)
1386 CHAR szEmptyName
[] = "";
1388 TRACE("GetServiceDisplayNameA() called\n");
1389 TRACE("%p %s %p %p\n", hSCManager
,
1390 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1394 SetLastError(ERROR_INVALID_HANDLE
);
1398 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1400 lpNameBuffer
= szEmptyName
;
1401 *lpcchBuffer
= sizeof(CHAR
);
1405 lpNameBuffer
= lpDisplayName
;
1410 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1415 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1417 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1418 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1422 if (dwError
!= ERROR_SUCCESS
)
1424 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1425 SetLastError(dwError
);
1433 /**********************************************************************
1434 * GetServiceDisplayNameW
1439 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1440 LPCWSTR lpServiceName
,
1441 LPWSTR lpDisplayName
,
1442 LPDWORD lpcchBuffer
)
1445 LPWSTR lpNameBuffer
;
1446 WCHAR szEmptyName
[] = L
"";
1448 TRACE("GetServiceDisplayNameW() called\n");
1452 SetLastError(ERROR_INVALID_HANDLE
);
1456 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1458 lpNameBuffer
= szEmptyName
;
1459 *lpcchBuffer
= sizeof(WCHAR
);
1463 lpNameBuffer
= lpDisplayName
;
1468 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1473 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1475 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1479 if (dwError
!= ERROR_SUCCESS
)
1481 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1482 SetLastError(dwError
);
1490 /**********************************************************************
1491 * GetServiceKeyNameA
1496 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1497 LPCSTR lpDisplayName
,
1498 LPSTR lpServiceName
,
1499 LPDWORD lpcchBuffer
)
1503 CHAR szEmptyName
[] = "";
1505 TRACE("GetServiceKeyNameA() called\n");
1509 SetLastError(ERROR_INVALID_HANDLE
);
1513 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1515 lpNameBuffer
= szEmptyName
;
1516 *lpcchBuffer
= sizeof(CHAR
);
1520 lpNameBuffer
= lpServiceName
;
1525 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1530 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1532 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1536 if (dwError
!= ERROR_SUCCESS
)
1538 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1539 SetLastError(dwError
);
1547 /**********************************************************************
1548 * GetServiceKeyNameW
1553 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1554 LPCWSTR lpDisplayName
,
1555 LPWSTR lpServiceName
,
1556 LPDWORD lpcchBuffer
)
1559 LPWSTR lpNameBuffer
;
1560 WCHAR szEmptyName
[] = L
"";
1562 TRACE("GetServiceKeyNameW() called\n");
1566 SetLastError(ERROR_INVALID_HANDLE
);
1570 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1572 lpNameBuffer
= szEmptyName
;
1573 *lpcchBuffer
= sizeof(WCHAR
);
1577 lpNameBuffer
= lpServiceName
;
1582 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1587 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1589 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1593 if (dwError
!= ERROR_SUCCESS
)
1595 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1596 SetLastError(dwError
);
1604 /**********************************************************************
1605 * LockServiceDatabase
1610 LockServiceDatabase(SC_HANDLE hSCManager
)
1615 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1619 /* Call to services.exe using RPC */
1620 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1621 (SC_RPC_LOCK
*)&hLock
);
1623 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1625 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1629 if (dwError
!= ERROR_SUCCESS
)
1631 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1632 SetLastError(dwError
);
1636 TRACE("hLock = %p\n", hLock
);
1643 WaitForSCManager(VOID
)
1647 TRACE("WaitForSCManager() called\n");
1649 /* Try to open the existing event */
1650 hEvent
= OpenEventW(SYNCHRONIZE
,
1652 L
"SvcctrlStartEvent_A3752DX");
1655 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1658 /* Try to create a new event */
1659 hEvent
= CreateEventW(NULL
,
1662 L
"SvcctrlStartEvent_A3752DX");
1665 /* Try to open the existing event again */
1666 hEvent
= OpenEventW(SYNCHRONIZE
,
1668 L
"SvcctrlStartEvent_A3752DX");
1674 /* Wait for 3 minutes */
1675 WaitForSingleObject(hEvent
, 180000);
1676 CloseHandle(hEvent
);
1678 TRACE("ScmWaitForSCManager() done\n");
1682 /**********************************************************************
1688 OpenSCManagerA(LPCSTR lpMachineName
,
1689 LPCSTR lpDatabaseName
,
1690 DWORD dwDesiredAccess
)
1692 SC_HANDLE hScm
= NULL
;
1695 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1696 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1702 /* Call to services.exe using RPC */
1703 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1704 (LPSTR
)lpDatabaseName
,
1706 (SC_RPC_HANDLE
*)&hScm
);
1708 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1710 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1714 if (dwError
!= ERROR_SUCCESS
)
1716 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1717 SetLastError(dwError
);
1721 TRACE("hScm = %p\n", hScm
);
1727 /**********************************************************************
1733 OpenSCManagerW(LPCWSTR lpMachineName
,
1734 LPCWSTR lpDatabaseName
,
1735 DWORD dwDesiredAccess
)
1737 SC_HANDLE hScm
= NULL
;
1740 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1741 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1747 /* Call to services.exe using RPC */
1748 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1749 (LPWSTR
)lpDatabaseName
,
1751 (SC_RPC_HANDLE
*)&hScm
);
1753 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1755 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1759 if (dwError
!= ERROR_SUCCESS
)
1761 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1762 SetLastError(dwError
);
1766 TRACE("hScm = %p\n", hScm
);
1772 /**********************************************************************
1778 OpenServiceA(SC_HANDLE hSCManager
,
1779 LPCSTR lpServiceName
,
1780 DWORD dwDesiredAccess
)
1782 SC_HANDLE hService
= NULL
;
1785 TRACE("OpenServiceA(%p, %s, %lx)\n",
1786 hSCManager
, lpServiceName
, dwDesiredAccess
);
1790 SetLastError(ERROR_INVALID_HANDLE
);
1796 /* Call to services.exe using RPC */
1797 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1798 (LPSTR
)lpServiceName
,
1800 (SC_RPC_HANDLE
*)&hService
);
1802 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1804 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1808 if (dwError
!= ERROR_SUCCESS
)
1810 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1811 SetLastError(dwError
);
1815 TRACE("hService = %p\n", hService
);
1821 /**********************************************************************
1827 OpenServiceW(SC_HANDLE hSCManager
,
1828 LPCWSTR lpServiceName
,
1829 DWORD dwDesiredAccess
)
1831 SC_HANDLE hService
= NULL
;
1834 TRACE("OpenServiceW(%p, %S, %lx)\n",
1835 hSCManager
, lpServiceName
, dwDesiredAccess
);
1839 SetLastError(ERROR_INVALID_HANDLE
);
1845 /* Call to services.exe using RPC */
1846 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1847 (LPWSTR
)lpServiceName
,
1849 (SC_RPC_HANDLE
*)&hService
);
1851 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1853 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1857 if (dwError
!= ERROR_SUCCESS
)
1859 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1860 SetLastError(dwError
);
1864 TRACE("hService = %p\n", hService
);
1870 /**********************************************************************
1871 * QueryServiceConfigA
1876 QueryServiceConfigA(SC_HANDLE hService
,
1877 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1879 LPDWORD pcbBytesNeeded
)
1881 QUERY_SERVICE_CONFIGA ServiceConfig
;
1882 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1886 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1887 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1889 if (lpServiceConfig
== NULL
||
1890 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1892 lpConfigPtr
= &ServiceConfig
;
1893 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1897 lpConfigPtr
= lpServiceConfig
;
1898 dwBufferSize
= cbBufSize
;
1903 /* Call to services.exe using RPC */
1904 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1905 (LPBYTE
)lpConfigPtr
,
1909 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1911 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1915 if (dwError
!= ERROR_SUCCESS
)
1917 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1918 SetLastError(dwError
);
1922 /* Adjust the pointers */
1923 if (lpConfigPtr
->lpBinaryPathName
)
1924 lpConfigPtr
->lpBinaryPathName
=
1925 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1926 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
1928 if (lpConfigPtr
->lpLoadOrderGroup
)
1929 lpConfigPtr
->lpLoadOrderGroup
=
1930 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1931 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
1933 if (lpConfigPtr
->lpDependencies
)
1934 lpConfigPtr
->lpDependencies
=
1935 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1936 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
1938 if (lpConfigPtr
->lpServiceStartName
)
1939 lpConfigPtr
->lpServiceStartName
=
1940 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1941 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
1943 if (lpConfigPtr
->lpDisplayName
)
1944 lpConfigPtr
->lpDisplayName
=
1945 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1946 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
1948 TRACE("QueryServiceConfigA() done\n");
1954 /**********************************************************************
1955 * QueryServiceConfigW
1960 QueryServiceConfigW(SC_HANDLE hService
,
1961 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1963 LPDWORD pcbBytesNeeded
)
1965 QUERY_SERVICE_CONFIGW ServiceConfig
;
1966 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
1970 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1971 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1973 if (lpServiceConfig
== NULL
||
1974 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
1976 lpConfigPtr
= &ServiceConfig
;
1977 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1981 lpConfigPtr
= lpServiceConfig
;
1982 dwBufferSize
= cbBufSize
;
1987 /* Call to services.exe using RPC */
1988 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
1989 (LPBYTE
)lpConfigPtr
,
1993 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1995 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1999 if (dwError
!= ERROR_SUCCESS
)
2001 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2002 SetLastError(dwError
);
2006 /* Adjust the pointers */
2007 if (lpConfigPtr
->lpBinaryPathName
)
2008 lpConfigPtr
->lpBinaryPathName
=
2009 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2010 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2012 if (lpConfigPtr
->lpLoadOrderGroup
)
2013 lpConfigPtr
->lpLoadOrderGroup
=
2014 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2015 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2017 if (lpConfigPtr
->lpDependencies
)
2018 lpConfigPtr
->lpDependencies
=
2019 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2020 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2022 if (lpConfigPtr
->lpServiceStartName
)
2023 lpConfigPtr
->lpServiceStartName
=
2024 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2025 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2027 if (lpConfigPtr
->lpDisplayName
)
2028 lpConfigPtr
->lpDisplayName
=
2029 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2030 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2032 TRACE("QueryServiceConfigW() done\n");
2038 /**********************************************************************
2039 * QueryServiceConfig2A
2044 QueryServiceConfig2A(SC_HANDLE hService
,
2048 LPDWORD pcbBytesNeeded
)
2050 SERVICE_DESCRIPTIONA ServiceDescription
;
2051 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2052 LPBYTE lpTempBuffer
;
2053 BOOL bUseTempBuffer
= FALSE
;
2057 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2058 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2060 lpTempBuffer
= lpBuffer
;
2061 dwBufferSize
= cbBufSize
;
2063 switch (dwInfoLevel
)
2065 case SERVICE_CONFIG_DESCRIPTION
:
2066 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2068 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2069 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2070 bUseTempBuffer
= TRUE
;
2074 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2075 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2077 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2078 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2079 bUseTempBuffer
= TRUE
;
2084 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2085 SetLastError(ERROR_INVALID_LEVEL
);
2091 /* Call to services.exe using RPC */
2092 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2098 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2100 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2104 if (dwError
!= ERROR_SUCCESS
)
2106 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2107 SetLastError(dwError
);
2111 if (bUseTempBuffer
== TRUE
)
2113 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2114 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2118 switch (dwInfoLevel
)
2120 case SERVICE_CONFIG_DESCRIPTION
:
2122 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2124 if (lpPtr
->lpDescription
!= NULL
)
2125 lpPtr
->lpDescription
=
2126 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2130 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2132 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2134 if (lpPtr
->lpRebootMsg
!= NULL
)
2135 lpPtr
->lpRebootMsg
=
2136 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2138 if (lpPtr
->lpCommand
!= NULL
)
2140 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2142 if (lpPtr
->lpsaActions
!= NULL
)
2143 lpPtr
->lpsaActions
=
2144 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2149 TRACE("QueryServiceConfig2A() done\n");
2155 /**********************************************************************
2156 * QueryServiceConfig2W
2161 QueryServiceConfig2W(SC_HANDLE hService
,
2165 LPDWORD pcbBytesNeeded
)
2167 SERVICE_DESCRIPTIONW ServiceDescription
;
2168 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2169 LPBYTE lpTempBuffer
;
2170 BOOL bUseTempBuffer
= FALSE
;
2174 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2175 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2177 lpTempBuffer
= lpBuffer
;
2178 dwBufferSize
= cbBufSize
;
2180 switch (dwInfoLevel
)
2182 case SERVICE_CONFIG_DESCRIPTION
:
2183 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2185 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2186 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2187 bUseTempBuffer
= TRUE
;
2191 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2192 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2194 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2195 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2196 bUseTempBuffer
= TRUE
;
2201 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2202 SetLastError(ERROR_INVALID_LEVEL
);
2208 /* Call to services.exe using RPC */
2209 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2215 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2217 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2221 if (dwError
!= ERROR_SUCCESS
)
2223 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2224 SetLastError(dwError
);
2228 if (bUseTempBuffer
== TRUE
)
2230 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2231 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2235 switch (dwInfoLevel
)
2237 case SERVICE_CONFIG_DESCRIPTION
:
2239 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2241 if (lpPtr
->lpDescription
!= NULL
)
2242 lpPtr
->lpDescription
=
2243 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2247 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2249 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2251 if (lpPtr
->lpRebootMsg
!= NULL
)
2252 lpPtr
->lpRebootMsg
=
2253 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2255 if (lpPtr
->lpCommand
!= NULL
)
2257 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2259 if (lpPtr
->lpsaActions
!= NULL
)
2260 lpPtr
->lpsaActions
=
2261 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2266 TRACE("QueryServiceConfig2W() done\n");
2272 /**********************************************************************
2273 * QueryServiceLockStatusA
2278 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2279 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2281 LPDWORD pcbBytesNeeded
)
2283 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2284 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2288 TRACE("QueryServiceLockStatusA() called\n");
2290 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2292 lpStatusPtr
= &LockStatus
;
2293 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2297 lpStatusPtr
= lpLockStatus
;
2298 dwBufferSize
= cbBufSize
;
2303 /* Call to services.exe using RPC */
2304 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2305 (LPBYTE
)lpStatusPtr
,
2309 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2311 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2315 if (dwError
!= ERROR_SUCCESS
)
2317 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2318 SetLastError(dwError
);
2322 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2324 lpStatusPtr
->lpLockOwner
=
2325 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2328 TRACE("QueryServiceLockStatusA() done\n");
2334 /**********************************************************************
2335 * QueryServiceLockStatusW
2340 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2341 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2343 LPDWORD pcbBytesNeeded
)
2345 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2346 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2350 TRACE("QueryServiceLockStatusW() called\n");
2352 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2354 lpStatusPtr
= &LockStatus
;
2355 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2359 lpStatusPtr
= lpLockStatus
;
2360 dwBufferSize
= cbBufSize
;
2365 /* Call to services.exe using RPC */
2366 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2367 (LPBYTE
)lpStatusPtr
,
2371 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2373 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2377 if (dwError
!= ERROR_SUCCESS
)
2379 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2380 SetLastError(dwError
);
2384 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2386 lpStatusPtr
->lpLockOwner
=
2387 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2390 TRACE("QueryServiceLockStatusW() done\n");
2396 /**********************************************************************
2397 * QueryServiceObjectSecurity
2402 QueryServiceObjectSecurity(SC_HANDLE hService
,
2403 SECURITY_INFORMATION dwSecurityInformation
,
2404 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2406 LPDWORD pcbBytesNeeded
)
2410 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2411 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2415 /* Call to services.exe using RPC */
2416 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2417 dwSecurityInformation
,
2418 (LPBYTE
)lpSecurityDescriptor
,
2422 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2424 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2428 if (dwError
!= ERROR_SUCCESS
)
2430 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2431 SetLastError(dwError
);
2438 /**********************************************************************
2439 * SetServiceObjectSecurity
2444 SetServiceObjectSecurity(SC_HANDLE hService
,
2445 SECURITY_INFORMATION dwSecurityInformation
,
2446 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2448 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2454 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2457 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2459 SetLastError(ERROR_INVALID_PARAMETER
);
2463 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2464 if (SelfRelativeSD
== NULL
)
2466 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2470 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2473 if (!NT_SUCCESS(Status
))
2475 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2476 SetLastError(RtlNtStatusToDosError(Status
));
2482 /* Call to services.exe using RPC */
2483 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2484 dwSecurityInformation
,
2485 (LPBYTE
)SelfRelativeSD
,
2488 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2490 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2494 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2496 if (dwError
!= ERROR_SUCCESS
)
2498 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2499 SetLastError(dwError
);
2507 /**********************************************************************
2508 * QueryServiceStatus
2513 QueryServiceStatus(SC_HANDLE hService
,
2514 LPSERVICE_STATUS lpServiceStatus
)
2518 TRACE("QueryServiceStatus(%p, %p)\n",
2519 hService
, lpServiceStatus
);
2523 SetLastError(ERROR_INVALID_HANDLE
);
2529 /* Call to services.exe using RPC */
2530 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2533 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2535 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2539 if (dwError
!= ERROR_SUCCESS
)
2541 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2542 SetLastError(dwError
);
2550 /**********************************************************************
2551 * QueryServiceStatusEx
2556 QueryServiceStatusEx(SC_HANDLE hService
,
2557 SC_STATUS_TYPE InfoLevel
,
2560 LPDWORD pcbBytesNeeded
)
2564 TRACE("QueryServiceStatusEx() called\n");
2566 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2568 SetLastError(ERROR_INVALID_LEVEL
);
2572 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2574 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2575 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2581 /* Call to services.exe using RPC */
2582 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2588 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2590 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2594 if (dwError
!= ERROR_SUCCESS
)
2596 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2597 SetLastError(dwError
);
2605 /**********************************************************************
2611 StartServiceA(SC_HANDLE hService
,
2612 DWORD dwNumServiceArgs
,
2613 LPCSTR
*lpServiceArgVectors
)
2619 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2621 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2623 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2625 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2629 if (dwError
!= ERROR_SUCCESS
)
2631 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2632 SetLastError(dwError
);
2640 /**********************************************************************
2646 StartServiceW(SC_HANDLE hService
,
2647 DWORD dwNumServiceArgs
,
2648 LPCWSTR
*lpServiceArgVectors
)
2654 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2656 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2658 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2660 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2664 if (dwError
!= ERROR_SUCCESS
)
2666 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2667 SetLastError(dwError
);
2675 /**********************************************************************
2676 * UnlockServiceDatabase
2681 UnlockServiceDatabase(SC_LOCK ScLock
)
2685 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2689 /* Call to services.exe using RPC */
2690 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2692 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2694 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2698 if (dwError
!= ERROR_SUCCESS
)
2700 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2701 SetLastError(dwError
);
2709 /**********************************************************************
2710 * NotifyBootConfigStatus
2715 NotifyBootConfigStatus(BOOL BootAcceptable
)
2719 TRACE("NotifyBootConfigStatus()\n");
2723 /* Call to services.exe using RPC */
2724 dwError
= RNotifyBootConfigStatus(NULL
,
2727 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2729 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2733 if (dwError
!= ERROR_SUCCESS
)
2735 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2736 SetLastError(dwError
);