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 STATUS_ACCESS_VIOLATION
:
137 case RPC_S_INVALID_BINDING
:
138 case RPC_X_SS_IN_NULL_CONTEXT
:
139 return ERROR_INVALID_HANDLE
;
141 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
142 case RPC_X_BYTE_COUNT_TOO_SMALL
:
143 return ERROR_INVALID_PARAMETER
;
145 case RPC_X_NULL_REF_POINTER
:
146 return ERROR_INVALID_ADDRESS
;
149 return (DWORD
)Status
;
154 /**********************************************************************
155 * ChangeServiceConfig2A
160 ChangeServiceConfig2A(SC_HANDLE hService
,
164 SC_RPC_CONFIG_INFOA Info
;
167 TRACE("ChangeServiceConfig2A() called\n");
169 if (lpInfo
== NULL
) return TRUE
;
171 /* Fill relevant field of the Info structure */
172 Info
.dwInfoLevel
= dwInfoLevel
;
175 case SERVICE_CONFIG_DESCRIPTION
:
179 case SERVICE_CONFIG_FAILURE_ACTIONS
:
184 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
185 SetLastError(ERROR_INVALID_PARAMETER
);
191 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
194 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
196 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
200 if (dwError
!= ERROR_SUCCESS
)
202 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
203 SetLastError(dwError
);
211 /**********************************************************************
212 * ChangeServiceConfig2W
217 ChangeServiceConfig2W(SC_HANDLE hService
,
221 SC_RPC_CONFIG_INFOW Info
;
224 TRACE("ChangeServiceConfig2W() called\n");
226 if (lpInfo
== NULL
) return TRUE
;
228 /* Fill relevant field of the Info structure */
229 Info
.dwInfoLevel
= dwInfoLevel
;
232 case SERVICE_CONFIG_DESCRIPTION
:
236 case SERVICE_CONFIG_FAILURE_ACTIONS
:
241 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
242 SetLastError(ERROR_INVALID_PARAMETER
);
248 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
251 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
253 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
257 if (dwError
!= ERROR_SUCCESS
)
259 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
260 SetLastError(dwError
);
268 /**********************************************************************
269 * ChangeServiceConfigA
274 ChangeServiceConfigA(SC_HANDLE hService
,
277 DWORD dwErrorControl
,
278 LPCSTR lpBinaryPathName
,
279 LPCSTR lpLoadOrderGroup
,
281 LPCSTR lpDependencies
,
282 LPCSTR lpServiceStartName
,
284 LPCSTR lpDisplayName
)
287 DWORD dwDependenciesLength
= 0;
290 DWORD dwPasswordLength
= 0;
291 LPWSTR lpPasswordW
= NULL
;
292 LPBYTE lpEncryptedPassword
= NULL
;
294 TRACE("ChangeServiceConfigA() called\n");
296 /* Calculate the Dependencies length*/
297 if (lpDependencies
!= NULL
)
299 lpStr
= lpDependencies
;
302 cchLength
= strlen(lpStr
) + 1;
303 dwDependenciesLength
+= (DWORD
)cchLength
;
304 lpStr
= lpStr
+ cchLength
;
306 dwDependenciesLength
++;
309 if (lpPassword
!= NULL
)
311 /* Convert the password to unicode */
312 lpPasswordW
= HeapAlloc(GetProcessHeap(),
314 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
315 if (lpPasswordW
== NULL
)
317 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
321 MultiByteToWideChar(CP_ACP
,
326 (int)(strlen(lpPassword
) + 1));
328 /* FIXME: Encrypt the password */
329 lpEncryptedPassword
= (LPBYTE
)lpPasswordW
;
330 dwPasswordLength
= (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
);
335 /* Call to services.exe using RPC */
336 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
340 (LPSTR
)lpBinaryPathName
,
341 (LPSTR
)lpLoadOrderGroup
,
343 (LPBYTE
)lpDependencies
,
344 dwDependenciesLength
,
345 (LPSTR
)lpServiceStartName
,
348 (LPSTR
)lpDisplayName
);
350 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
352 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
356 if (lpPasswordW
!= NULL
)
357 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
359 if (dwError
!= ERROR_SUCCESS
)
361 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
362 SetLastError(dwError
);
370 /**********************************************************************
371 * ChangeServiceConfigW
376 ChangeServiceConfigW(SC_HANDLE hService
,
379 DWORD dwErrorControl
,
380 LPCWSTR lpBinaryPathName
,
381 LPCWSTR lpLoadOrderGroup
,
383 LPCWSTR lpDependencies
,
384 LPCWSTR lpServiceStartName
,
386 LPCWSTR lpDisplayName
)
389 DWORD dwDependenciesLength
= 0;
392 DWORD dwPasswordLength
= 0;
393 LPBYTE lpEncryptedPassword
= NULL
;
395 TRACE("ChangeServiceConfigW() called\n");
397 /* Calculate the Dependencies length*/
398 if (lpDependencies
!= NULL
)
400 lpStr
= lpDependencies
;
403 cchLength
= wcslen(lpStr
) + 1;
404 dwDependenciesLength
+= (DWORD
)cchLength
;
405 lpStr
= lpStr
+ cchLength
;
407 dwDependenciesLength
++;
408 dwDependenciesLength
*= sizeof(WCHAR
);
411 if (lpPassword
!= NULL
)
413 /* FIXME: Encrypt the password */
414 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
415 dwPasswordLength
= (wcslen(lpPassword
) + 1) * sizeof(WCHAR
);
420 /* Call to services.exe using RPC */
421 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
425 (LPWSTR
)lpBinaryPathName
,
426 (LPWSTR
)lpLoadOrderGroup
,
428 (LPBYTE
)lpDependencies
,
429 dwDependenciesLength
,
430 (LPWSTR
)lpServiceStartName
,
433 (LPWSTR
)lpDisplayName
);
435 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
437 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
441 if (dwError
!= ERROR_SUCCESS
)
443 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
444 SetLastError(dwError
);
452 /**********************************************************************
458 CloseServiceHandle(SC_HANDLE hSCObject
)
462 TRACE("CloseServiceHandle() called\n");
466 SetLastError(ERROR_INVALID_HANDLE
);
472 /* Call to services.exe using RPC */
473 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
475 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
477 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
483 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
484 SetLastError(dwError
);
488 TRACE("CloseServiceHandle() done\n");
494 /**********************************************************************
500 ControlService(SC_HANDLE hService
,
502 LPSERVICE_STATUS lpServiceStatus
)
506 TRACE("ControlService(%x, %x, %p)\n",
507 hService
, dwControl
, lpServiceStatus
);
511 /* Call to services.exe using RPC */
512 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
516 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
518 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
522 if (dwError
!= ERROR_SUCCESS
)
524 TRACE("RControlService() failed (Error %lu)\n", dwError
);
525 SetLastError(dwError
);
529 TRACE("ControlService() done\n");
535 /**********************************************************************
541 ControlServiceEx(IN SC_HANDLE hService
,
543 IN DWORD dwInfoLevel
,
544 IN OUT PVOID pControlParams
)
546 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
547 hService
, dwControl
, dwInfoLevel
, pControlParams
);
548 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
553 /**********************************************************************
559 CreateServiceA(SC_HANDLE hSCManager
,
560 LPCSTR lpServiceName
,
561 LPCSTR lpDisplayName
,
562 DWORD dwDesiredAccess
,
565 DWORD dwErrorControl
,
566 LPCSTR lpBinaryPathName
,
567 LPCSTR lpLoadOrderGroup
,
569 LPCSTR lpDependencies
,
570 LPCSTR lpServiceStartName
,
573 SC_HANDLE hService
= NULL
;
574 DWORD dwDependenciesLength
= 0;
578 DWORD dwPasswordLength
= 0;
579 LPWSTR lpPasswordW
= NULL
;
580 LPBYTE lpEncryptedPassword
= NULL
;
582 TRACE("CreateServiceA() called\n");
583 TRACE("%p %s %s\n", hSCManager
,
584 lpServiceName
, lpDisplayName
);
588 SetLastError(ERROR_INVALID_HANDLE
);
592 /* Calculate the Dependencies length */
593 if (lpDependencies
!= NULL
)
595 lpStr
= lpDependencies
;
598 cchLength
= strlen(lpStr
) + 1;
599 dwDependenciesLength
+= (DWORD
)cchLength
;
600 lpStr
= lpStr
+ cchLength
;
602 dwDependenciesLength
++;
605 if (lpPassword
!= NULL
)
607 /* Convert the password to unicode */
608 lpPasswordW
= HeapAlloc(GetProcessHeap(),
610 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
611 if (lpPasswordW
== NULL
)
613 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
617 MultiByteToWideChar(CP_ACP
,
622 (int)(strlen(lpPassword
) + 1));
624 /* FIXME: Encrypt the password */
625 lpEncryptedPassword
= (LPBYTE
)lpPasswordW
;
626 dwPasswordLength
= (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
);
631 /* Call to services.exe using RPC */
632 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
633 (LPSTR
)lpServiceName
,
634 (LPSTR
)lpDisplayName
,
639 (LPSTR
)lpBinaryPathName
,
640 (LPSTR
)lpLoadOrderGroup
,
642 (LPBYTE
)lpDependencies
,
643 dwDependenciesLength
,
644 (LPSTR
)lpServiceStartName
,
647 (SC_RPC_HANDLE
*)&hService
);
649 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
651 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
655 if (lpPasswordW
!= NULL
)
656 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
658 SetLastError(dwError
);
659 if (dwError
!= ERROR_SUCCESS
)
661 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
669 /**********************************************************************
675 CreateServiceW(SC_HANDLE hSCManager
,
676 LPCWSTR lpServiceName
,
677 LPCWSTR lpDisplayName
,
678 DWORD dwDesiredAccess
,
681 DWORD dwErrorControl
,
682 LPCWSTR lpBinaryPathName
,
683 LPCWSTR lpLoadOrderGroup
,
685 LPCWSTR lpDependencies
,
686 LPCWSTR lpServiceStartName
,
689 SC_HANDLE hService
= NULL
;
690 DWORD dwDependenciesLength
= 0;
694 DWORD dwPasswordLength
= 0;
695 LPBYTE lpEncryptedPassword
= NULL
;
697 TRACE("CreateServiceW() called\n");
698 TRACE("%p %S %S\n", hSCManager
,
699 lpServiceName
, lpDisplayName
);
703 SetLastError(ERROR_INVALID_HANDLE
);
707 /* Calculate the Dependencies length */
708 if (lpDependencies
!= NULL
)
710 lpStr
= lpDependencies
;
713 cchLength
= wcslen(lpStr
) + 1;
714 dwDependenciesLength
+= (DWORD
)cchLength
;
715 lpStr
= lpStr
+ cchLength
;
717 dwDependenciesLength
++;
718 dwDependenciesLength
*= sizeof(WCHAR
);
721 if (lpPassword
!= NULL
)
723 /* FIXME: Encrypt the password */
724 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
725 dwPasswordLength
= (wcslen(lpPassword
) + 1) * sizeof(WCHAR
);
730 /* Call to services.exe using RPC */
731 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
741 (LPBYTE
)lpDependencies
,
742 dwDependenciesLength
,
746 (SC_RPC_HANDLE
*)&hService
);
748 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
750 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
754 SetLastError(dwError
);
755 if (dwError
!= ERROR_SUCCESS
)
757 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
765 /**********************************************************************
771 DeleteService(SC_HANDLE hService
)
775 TRACE("DeleteService(%x)\n", hService
);
779 /* Call to services.exe using RPC */
780 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
782 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
784 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
788 if (dwError
!= ERROR_SUCCESS
)
790 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
791 SetLastError(dwError
);
799 /**********************************************************************
800 * EnumDependentServicesA
805 EnumDependentServicesA(SC_HANDLE hService
,
806 DWORD dwServiceState
,
807 LPENUM_SERVICE_STATUSA lpServices
,
809 LPDWORD pcbBytesNeeded
,
810 LPDWORD lpServicesReturned
)
812 ENUM_SERVICE_STATUSA ServiceStatus
;
813 LPENUM_SERVICE_STATUSA lpStatusPtr
;
818 TRACE("EnumDependentServicesA() called\n");
820 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
822 lpStatusPtr
= &ServiceStatus
;
823 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
827 lpStatusPtr
= lpServices
;
828 dwBufferSize
= cbBufSize
;
833 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
840 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
842 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
846 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
848 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
850 if (lpStatusPtr
->lpServiceName
)
851 lpStatusPtr
->lpServiceName
=
852 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
854 if (lpStatusPtr
->lpDisplayName
)
855 lpStatusPtr
->lpDisplayName
=
856 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
862 if (dwError
!= ERROR_SUCCESS
)
864 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
865 SetLastError(dwError
);
869 TRACE("EnumDependentServicesA() done\n");
875 /**********************************************************************
876 * EnumDependentServicesW
881 EnumDependentServicesW(SC_HANDLE hService
,
882 DWORD dwServiceState
,
883 LPENUM_SERVICE_STATUSW lpServices
,
885 LPDWORD pcbBytesNeeded
,
886 LPDWORD lpServicesReturned
)
888 ENUM_SERVICE_STATUSW ServiceStatus
;
889 LPENUM_SERVICE_STATUSW lpStatusPtr
;
894 TRACE("EnumDependentServicesW() called\n");
896 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
898 lpStatusPtr
= &ServiceStatus
;
899 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
903 lpStatusPtr
= lpServices
;
904 dwBufferSize
= cbBufSize
;
909 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
916 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
918 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
922 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
924 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
926 if (lpStatusPtr
->lpServiceName
)
927 lpStatusPtr
->lpServiceName
=
928 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
930 if (lpStatusPtr
->lpDisplayName
)
931 lpStatusPtr
->lpDisplayName
=
932 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
938 if (dwError
!= ERROR_SUCCESS
)
940 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
941 SetLastError(dwError
);
945 TRACE("EnumDependentServicesW() done\n");
951 /**********************************************************************
957 EnumServiceGroupW(SC_HANDLE hSCManager
,
959 DWORD dwServiceState
,
960 LPENUM_SERVICE_STATUSW lpServices
,
962 LPDWORD pcbBytesNeeded
,
963 LPDWORD lpServicesReturned
,
964 LPDWORD lpResumeHandle
,
967 ENUM_SERVICE_STATUSW ServiceStatus
;
968 LPENUM_SERVICE_STATUSW lpStatusPtr
;
973 TRACE("EnumServiceGroupW() called\n");
977 SetLastError(ERROR_INVALID_HANDLE
);
981 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
983 SetLastError(ERROR_INVALID_ADDRESS
);
987 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
989 lpStatusPtr
= &ServiceStatus
;
990 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
994 lpStatusPtr
= lpServices
;
995 dwBufferSize
= cbBufSize
;
1000 if (lpGroup
== NULL
)
1002 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1005 (LPBYTE
)lpStatusPtr
,
1013 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
1016 (LPBYTE
)lpStatusPtr
,
1024 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1026 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1030 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1032 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1034 if (lpStatusPtr
->lpServiceName
)
1035 lpStatusPtr
->lpServiceName
=
1036 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1038 if (lpStatusPtr
->lpDisplayName
)
1039 lpStatusPtr
->lpDisplayName
=
1040 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1046 if (dwError
!= ERROR_SUCCESS
)
1048 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
1049 SetLastError(dwError
);
1053 TRACE("EnumServiceGroupW() done\n");
1059 /**********************************************************************
1060 * EnumServicesStatusA
1065 EnumServicesStatusA(SC_HANDLE hSCManager
,
1066 DWORD dwServiceType
,
1067 DWORD dwServiceState
,
1068 LPENUM_SERVICE_STATUSA lpServices
,
1070 LPDWORD pcbBytesNeeded
,
1071 LPDWORD lpServicesReturned
,
1072 LPDWORD lpResumeHandle
)
1074 ENUM_SERVICE_STATUSA ServiceStatus
;
1075 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1080 TRACE("EnumServicesStatusA() called\n");
1084 SetLastError(ERROR_INVALID_HANDLE
);
1088 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1090 SetLastError(ERROR_INVALID_ADDRESS
);
1094 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1096 lpStatusPtr
= &ServiceStatus
;
1097 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1101 lpStatusPtr
= lpServices
;
1102 dwBufferSize
= cbBufSize
;
1107 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1110 (LPBYTE
)lpStatusPtr
,
1116 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1118 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1122 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1124 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1126 if (lpStatusPtr
->lpServiceName
)
1127 lpStatusPtr
->lpServiceName
=
1128 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1130 if (lpStatusPtr
->lpDisplayName
)
1131 lpStatusPtr
->lpDisplayName
=
1132 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1138 if (dwError
!= ERROR_SUCCESS
)
1140 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1141 SetLastError(dwError
);
1145 TRACE("EnumServicesStatusA() done\n");
1151 /**********************************************************************
1152 * EnumServicesStatusW
1157 EnumServicesStatusW(SC_HANDLE hSCManager
,
1158 DWORD dwServiceType
,
1159 DWORD dwServiceState
,
1160 LPENUM_SERVICE_STATUSW lpServices
,
1162 LPDWORD pcbBytesNeeded
,
1163 LPDWORD lpServicesReturned
,
1164 LPDWORD lpResumeHandle
)
1166 ENUM_SERVICE_STATUSW ServiceStatus
;
1167 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1172 TRACE("EnumServicesStatusW() called\n");
1176 SetLastError(ERROR_INVALID_HANDLE
);
1180 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1182 SetLastError(ERROR_INVALID_ADDRESS
);
1186 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1188 lpStatusPtr
= &ServiceStatus
;
1189 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1193 lpStatusPtr
= lpServices
;
1194 dwBufferSize
= cbBufSize
;
1199 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1202 (LPBYTE
)lpStatusPtr
,
1208 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1210 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1214 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1216 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1218 if (lpStatusPtr
->lpServiceName
)
1219 lpStatusPtr
->lpServiceName
=
1220 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1222 if (lpStatusPtr
->lpDisplayName
)
1223 lpStatusPtr
->lpDisplayName
=
1224 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1230 if (dwError
!= ERROR_SUCCESS
)
1232 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1233 SetLastError(dwError
);
1237 TRACE("EnumServicesStatusW() done\n");
1243 /**********************************************************************
1244 * EnumServicesStatusExA
1249 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1250 SC_ENUM_TYPE InfoLevel
,
1251 DWORD dwServiceType
,
1252 DWORD dwServiceState
,
1255 LPDWORD pcbBytesNeeded
,
1256 LPDWORD lpServicesReturned
,
1257 LPDWORD lpResumeHandle
,
1258 LPCSTR pszGroupName
)
1260 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1261 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1266 TRACE("EnumServicesStatusExA() called\n");
1268 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1270 SetLastError(ERROR_INVALID_LEVEL
);
1276 SetLastError(ERROR_INVALID_HANDLE
);
1280 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1282 SetLastError(ERROR_INVALID_ADDRESS
);
1286 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1288 lpStatusPtr
= &ServiceStatus
;
1289 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1293 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1294 dwBufferSize
= cbBufSize
;
1299 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1303 (LPBYTE
)lpStatusPtr
,
1308 (LPSTR
)pszGroupName
);
1310 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1312 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1316 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1318 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1320 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1322 if (lpStatusPtr
->lpServiceName
)
1323 lpStatusPtr
->lpServiceName
=
1324 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1326 if (lpStatusPtr
->lpDisplayName
)
1327 lpStatusPtr
->lpDisplayName
=
1328 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1335 if (dwError
!= ERROR_SUCCESS
)
1337 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1338 SetLastError(dwError
);
1342 TRACE("EnumServicesStatusExA() done\n");
1348 /**********************************************************************
1349 * EnumServicesStatusExW
1354 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1355 SC_ENUM_TYPE InfoLevel
,
1356 DWORD dwServiceType
,
1357 DWORD dwServiceState
,
1360 LPDWORD pcbBytesNeeded
,
1361 LPDWORD lpServicesReturned
,
1362 LPDWORD lpResumeHandle
,
1363 LPCWSTR pszGroupName
)
1365 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1366 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1371 TRACE("EnumServicesStatusExW() called\n");
1373 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1375 SetLastError(ERROR_INVALID_LEVEL
);
1381 SetLastError(ERROR_INVALID_HANDLE
);
1385 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1387 SetLastError(ERROR_INVALID_ADDRESS
);
1391 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1393 lpStatusPtr
= &ServiceStatus
;
1394 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1398 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1399 dwBufferSize
= cbBufSize
;
1404 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1408 (LPBYTE
)lpStatusPtr
,
1413 (LPWSTR
)pszGroupName
);
1415 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1417 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1421 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1423 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1425 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1427 if (lpStatusPtr
->lpServiceName
)
1428 lpStatusPtr
->lpServiceName
=
1429 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1431 if (lpStatusPtr
->lpDisplayName
)
1432 lpStatusPtr
->lpDisplayName
=
1433 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1440 if (dwError
!= ERROR_SUCCESS
)
1442 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1443 SetLastError(dwError
);
1447 TRACE("EnumServicesStatusExW() done\n");
1453 /**********************************************************************
1454 * GetServiceDisplayNameA
1459 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1460 LPCSTR lpServiceName
,
1461 LPSTR lpDisplayName
,
1462 LPDWORD lpcchBuffer
)
1466 CHAR szEmptyName
[] = "";
1468 TRACE("GetServiceDisplayNameA() called\n");
1469 TRACE("%p %s %p %p\n", hSCManager
,
1470 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1474 SetLastError(ERROR_INVALID_HANDLE
);
1478 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1480 lpNameBuffer
= szEmptyName
;
1481 *lpcchBuffer
= sizeof(CHAR
);
1485 lpNameBuffer
= lpDisplayName
;
1490 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1495 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1497 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1498 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1502 if (dwError
!= ERROR_SUCCESS
)
1504 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1505 SetLastError(dwError
);
1513 /**********************************************************************
1514 * GetServiceDisplayNameW
1519 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1520 LPCWSTR lpServiceName
,
1521 LPWSTR lpDisplayName
,
1522 LPDWORD lpcchBuffer
)
1525 LPWSTR lpNameBuffer
;
1526 WCHAR szEmptyName
[] = L
"";
1528 TRACE("GetServiceDisplayNameW() called\n");
1532 SetLastError(ERROR_INVALID_HANDLE
);
1536 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1538 lpNameBuffer
= szEmptyName
;
1539 *lpcchBuffer
= sizeof(WCHAR
);
1543 lpNameBuffer
= lpDisplayName
;
1548 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1553 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1555 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1559 if (dwError
!= ERROR_SUCCESS
)
1561 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1562 SetLastError(dwError
);
1570 /**********************************************************************
1571 * GetServiceKeyNameA
1576 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1577 LPCSTR lpDisplayName
,
1578 LPSTR lpServiceName
,
1579 LPDWORD lpcchBuffer
)
1583 CHAR szEmptyName
[] = "";
1585 TRACE("GetServiceKeyNameA() called\n");
1589 SetLastError(ERROR_INVALID_HANDLE
);
1593 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1595 lpNameBuffer
= szEmptyName
;
1596 *lpcchBuffer
= sizeof(CHAR
);
1600 lpNameBuffer
= lpServiceName
;
1605 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1610 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1612 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1616 if (dwError
!= ERROR_SUCCESS
)
1618 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1619 SetLastError(dwError
);
1627 /**********************************************************************
1628 * GetServiceKeyNameW
1633 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1634 LPCWSTR lpDisplayName
,
1635 LPWSTR lpServiceName
,
1636 LPDWORD lpcchBuffer
)
1639 LPWSTR lpNameBuffer
;
1640 WCHAR szEmptyName
[] = L
"";
1642 TRACE("GetServiceKeyNameW() called\n");
1646 SetLastError(ERROR_INVALID_HANDLE
);
1650 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1652 lpNameBuffer
= szEmptyName
;
1653 *lpcchBuffer
= sizeof(WCHAR
);
1657 lpNameBuffer
= lpServiceName
;
1662 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1667 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1669 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1673 if (dwError
!= ERROR_SUCCESS
)
1675 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1676 SetLastError(dwError
);
1684 /**********************************************************************
1685 * I_ScGetCurrentGroupStateW
1690 I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager
,
1691 LPWSTR pszGroupName
,
1692 LPDWORD pdwGroupState
)
1696 TRACE("I_ScGetCurrentGroupStateW() called\n");
1700 dwError
= RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE
)hSCManager
,
1704 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1706 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1710 if (dwError
!= ERROR_SUCCESS
)
1712 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError
);
1713 SetLastError(dwError
);
1720 /**********************************************************************
1721 * LockServiceDatabase
1726 LockServiceDatabase(SC_HANDLE hSCManager
)
1731 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1735 /* Call to services.exe using RPC */
1736 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1737 (SC_RPC_LOCK
*)&hLock
);
1739 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1741 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1745 if (dwError
!= ERROR_SUCCESS
)
1747 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1748 SetLastError(dwError
);
1752 TRACE("hLock = %p\n", hLock
);
1759 WaitForSCManager(VOID
)
1763 TRACE("WaitForSCManager() called\n");
1765 /* Try to open the existing event */
1766 hEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, SCM_START_EVENT
);
1769 if (GetLastError() != ERROR_FILE_NOT_FOUND
) return;
1771 /* Try to create a new event */
1772 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
1773 if (hEvent
== NULL
) return;
1776 /* Wait for 3 minutes */
1777 WaitForSingleObject(hEvent
, 180000);
1778 CloseHandle(hEvent
);
1780 TRACE("ScmWaitForSCManager() done\n");
1784 /**********************************************************************
1790 OpenSCManagerA(LPCSTR lpMachineName
,
1791 LPCSTR lpDatabaseName
,
1792 DWORD dwDesiredAccess
)
1794 SC_HANDLE hScm
= NULL
;
1797 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1798 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1804 /* Call to services.exe using RPC */
1805 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1806 (LPSTR
)lpDatabaseName
,
1808 (SC_RPC_HANDLE
*)&hScm
);
1810 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1812 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1816 if (dwError
!= ERROR_SUCCESS
)
1818 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1819 SetLastError(dwError
);
1823 TRACE("hScm = %p\n", hScm
);
1829 /**********************************************************************
1835 OpenSCManagerW(LPCWSTR lpMachineName
,
1836 LPCWSTR lpDatabaseName
,
1837 DWORD dwDesiredAccess
)
1839 SC_HANDLE hScm
= NULL
;
1842 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1843 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1849 /* Call to services.exe using RPC */
1850 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1851 (LPWSTR
)lpDatabaseName
,
1853 (SC_RPC_HANDLE
*)&hScm
);
1855 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1857 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1861 if (dwError
!= ERROR_SUCCESS
)
1863 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1864 SetLastError(dwError
);
1868 TRACE("hScm = %p\n", hScm
);
1874 /**********************************************************************
1880 OpenServiceA(SC_HANDLE hSCManager
,
1881 LPCSTR lpServiceName
,
1882 DWORD dwDesiredAccess
)
1884 SC_HANDLE hService
= NULL
;
1887 TRACE("OpenServiceA(%p, %s, %lx)\n",
1888 hSCManager
, lpServiceName
, dwDesiredAccess
);
1892 SetLastError(ERROR_INVALID_HANDLE
);
1898 /* Call to services.exe using RPC */
1899 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1900 (LPSTR
)lpServiceName
,
1902 (SC_RPC_HANDLE
*)&hService
);
1904 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1906 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1910 SetLastError(dwError
);
1911 if (dwError
!= ERROR_SUCCESS
)
1913 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1917 TRACE("hService = %p\n", hService
);
1923 /**********************************************************************
1929 OpenServiceW(SC_HANDLE hSCManager
,
1930 LPCWSTR lpServiceName
,
1931 DWORD dwDesiredAccess
)
1933 SC_HANDLE hService
= NULL
;
1936 TRACE("OpenServiceW(%p, %S, %lx)\n",
1937 hSCManager
, lpServiceName
, dwDesiredAccess
);
1941 SetLastError(ERROR_INVALID_HANDLE
);
1947 /* Call to services.exe using RPC */
1948 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1949 (LPWSTR
)lpServiceName
,
1951 (SC_RPC_HANDLE
*)&hService
);
1953 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1955 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1959 SetLastError(dwError
);
1960 if (dwError
!= ERROR_SUCCESS
)
1962 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1966 TRACE("hService = %p\n", hService
);
1972 /**********************************************************************
1973 * QueryServiceConfigA
1978 QueryServiceConfigA(SC_HANDLE hService
,
1979 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1981 LPDWORD pcbBytesNeeded
)
1983 QUERY_SERVICE_CONFIGA ServiceConfig
;
1984 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1988 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1989 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1991 if (lpServiceConfig
== NULL
||
1992 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1994 lpConfigPtr
= &ServiceConfig
;
1995 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1999 lpConfigPtr
= lpServiceConfig
;
2000 dwBufferSize
= cbBufSize
;
2005 /* Call to services.exe using RPC */
2006 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
2007 (LPBYTE
)lpConfigPtr
,
2011 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2013 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2017 if (dwError
!= ERROR_SUCCESS
)
2019 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
2020 SetLastError(dwError
);
2024 /* Adjust the pointers */
2025 if (lpConfigPtr
->lpBinaryPathName
)
2026 lpConfigPtr
->lpBinaryPathName
=
2027 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2028 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2030 if (lpConfigPtr
->lpLoadOrderGroup
)
2031 lpConfigPtr
->lpLoadOrderGroup
=
2032 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2033 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2035 if (lpConfigPtr
->lpDependencies
)
2036 lpConfigPtr
->lpDependencies
=
2037 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2038 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2040 if (lpConfigPtr
->lpServiceStartName
)
2041 lpConfigPtr
->lpServiceStartName
=
2042 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2043 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2045 if (lpConfigPtr
->lpDisplayName
)
2046 lpConfigPtr
->lpDisplayName
=
2047 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2048 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2050 TRACE("QueryServiceConfigA() done\n");
2056 /**********************************************************************
2057 * QueryServiceConfigW
2062 QueryServiceConfigW(SC_HANDLE hService
,
2063 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
2065 LPDWORD pcbBytesNeeded
)
2067 QUERY_SERVICE_CONFIGW ServiceConfig
;
2068 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
2072 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
2073 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2075 if (lpServiceConfig
== NULL
||
2076 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2078 lpConfigPtr
= &ServiceConfig
;
2079 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2083 lpConfigPtr
= lpServiceConfig
;
2084 dwBufferSize
= cbBufSize
;
2089 /* Call to services.exe using RPC */
2090 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2091 (LPBYTE
)lpConfigPtr
,
2095 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2097 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2101 if (dwError
!= ERROR_SUCCESS
)
2103 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2104 SetLastError(dwError
);
2108 /* Adjust the pointers */
2109 if (lpConfigPtr
->lpBinaryPathName
)
2110 lpConfigPtr
->lpBinaryPathName
=
2111 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2112 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2114 if (lpConfigPtr
->lpLoadOrderGroup
)
2115 lpConfigPtr
->lpLoadOrderGroup
=
2116 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2117 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2119 if (lpConfigPtr
->lpDependencies
)
2120 lpConfigPtr
->lpDependencies
=
2121 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2122 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2124 if (lpConfigPtr
->lpServiceStartName
)
2125 lpConfigPtr
->lpServiceStartName
=
2126 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2127 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2129 if (lpConfigPtr
->lpDisplayName
)
2130 lpConfigPtr
->lpDisplayName
=
2131 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2132 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2134 TRACE("QueryServiceConfigW() done\n");
2140 /**********************************************************************
2141 * QueryServiceConfig2A
2146 QueryServiceConfig2A(SC_HANDLE hService
,
2150 LPDWORD pcbBytesNeeded
)
2152 SERVICE_DESCRIPTIONA ServiceDescription
;
2153 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2154 LPBYTE lpTempBuffer
;
2155 BOOL bUseTempBuffer
= FALSE
;
2159 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2160 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2162 lpTempBuffer
= lpBuffer
;
2163 dwBufferSize
= cbBufSize
;
2165 switch (dwInfoLevel
)
2167 case SERVICE_CONFIG_DESCRIPTION
:
2168 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2170 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2171 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2172 bUseTempBuffer
= TRUE
;
2176 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2177 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2179 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2180 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2181 bUseTempBuffer
= TRUE
;
2186 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2187 SetLastError(ERROR_INVALID_LEVEL
);
2193 /* Call to services.exe using RPC */
2194 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2200 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2202 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2206 if (dwError
!= ERROR_SUCCESS
)
2208 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2209 SetLastError(dwError
);
2213 if (bUseTempBuffer
== TRUE
)
2215 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2216 *pcbBytesNeeded
= dwBufferSize
;
2217 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2221 switch (dwInfoLevel
)
2223 case SERVICE_CONFIG_DESCRIPTION
:
2225 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2227 if (lpPtr
->lpDescription
!= NULL
)
2228 lpPtr
->lpDescription
=
2229 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2233 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2235 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2237 if (lpPtr
->lpRebootMsg
!= NULL
)
2238 lpPtr
->lpRebootMsg
=
2239 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2241 if (lpPtr
->lpCommand
!= NULL
)
2243 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2245 if (lpPtr
->lpsaActions
!= NULL
)
2246 lpPtr
->lpsaActions
=
2247 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2252 TRACE("QueryServiceConfig2A() done\n");
2258 /**********************************************************************
2259 * QueryServiceConfig2W
2264 QueryServiceConfig2W(SC_HANDLE hService
,
2268 LPDWORD pcbBytesNeeded
)
2270 SERVICE_DESCRIPTIONW ServiceDescription
;
2271 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2272 LPBYTE lpTempBuffer
;
2273 BOOL bUseTempBuffer
= FALSE
;
2277 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2278 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2280 lpTempBuffer
= lpBuffer
;
2281 dwBufferSize
= cbBufSize
;
2283 switch (dwInfoLevel
)
2285 case SERVICE_CONFIG_DESCRIPTION
:
2286 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2288 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2289 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2290 bUseTempBuffer
= TRUE
;
2294 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2295 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2297 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2298 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2299 bUseTempBuffer
= TRUE
;
2304 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2305 SetLastError(ERROR_INVALID_LEVEL
);
2311 /* Call to services.exe using RPC */
2312 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2318 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2320 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2324 if (dwError
!= ERROR_SUCCESS
)
2326 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2327 SetLastError(dwError
);
2331 if (bUseTempBuffer
== TRUE
)
2333 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2334 *pcbBytesNeeded
= dwBufferSize
;
2335 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2339 switch (dwInfoLevel
)
2341 case SERVICE_CONFIG_DESCRIPTION
:
2343 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2345 if (lpPtr
->lpDescription
!= NULL
)
2346 lpPtr
->lpDescription
=
2347 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2351 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2353 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2355 if (lpPtr
->lpRebootMsg
!= NULL
)
2356 lpPtr
->lpRebootMsg
=
2357 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2359 if (lpPtr
->lpCommand
!= NULL
)
2361 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2363 if (lpPtr
->lpsaActions
!= NULL
)
2364 lpPtr
->lpsaActions
=
2365 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2370 TRACE("QueryServiceConfig2W() done\n");
2376 /**********************************************************************
2377 * QueryServiceLockStatusA
2382 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2383 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2385 LPDWORD pcbBytesNeeded
)
2387 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2388 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2392 TRACE("QueryServiceLockStatusA() called\n");
2394 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2396 lpStatusPtr
= &LockStatus
;
2397 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2401 lpStatusPtr
= lpLockStatus
;
2402 dwBufferSize
= cbBufSize
;
2407 /* Call to services.exe using RPC */
2408 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2409 (LPBYTE
)lpStatusPtr
,
2413 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2415 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2419 if (dwError
!= ERROR_SUCCESS
)
2421 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2422 SetLastError(dwError
);
2426 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2428 lpStatusPtr
->lpLockOwner
=
2429 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2432 TRACE("QueryServiceLockStatusA() done\n");
2438 /**********************************************************************
2439 * QueryServiceLockStatusW
2444 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2445 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2447 LPDWORD pcbBytesNeeded
)
2449 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2450 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2454 TRACE("QueryServiceLockStatusW() called\n");
2456 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2458 lpStatusPtr
= &LockStatus
;
2459 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2463 lpStatusPtr
= lpLockStatus
;
2464 dwBufferSize
= cbBufSize
;
2469 /* Call to services.exe using RPC */
2470 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2471 (LPBYTE
)lpStatusPtr
,
2475 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2477 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2481 if (dwError
!= ERROR_SUCCESS
)
2483 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2484 SetLastError(dwError
);
2488 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2490 lpStatusPtr
->lpLockOwner
=
2491 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2494 TRACE("QueryServiceLockStatusW() done\n");
2500 /**********************************************************************
2501 * QueryServiceObjectSecurity
2506 QueryServiceObjectSecurity(SC_HANDLE hService
,
2507 SECURITY_INFORMATION dwSecurityInformation
,
2508 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2510 LPDWORD pcbBytesNeeded
)
2514 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2515 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2519 /* Call to services.exe using RPC */
2520 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2521 dwSecurityInformation
,
2522 (LPBYTE
)lpSecurityDescriptor
,
2526 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2528 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2532 if (dwError
!= ERROR_SUCCESS
)
2534 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2535 SetLastError(dwError
);
2542 /**********************************************************************
2543 * SetServiceObjectSecurity
2548 SetServiceObjectSecurity(SC_HANDLE hService
,
2549 SECURITY_INFORMATION dwSecurityInformation
,
2550 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2552 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2558 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2561 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2563 SetLastError(ERROR_INVALID_PARAMETER
);
2567 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2568 if (SelfRelativeSD
== NULL
)
2570 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2574 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2577 if (!NT_SUCCESS(Status
))
2579 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2580 SetLastError(RtlNtStatusToDosError(Status
));
2586 /* Call to services.exe using RPC */
2587 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2588 dwSecurityInformation
,
2589 (LPBYTE
)SelfRelativeSD
,
2592 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2594 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2598 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2600 if (dwError
!= ERROR_SUCCESS
)
2602 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2603 SetLastError(dwError
);
2611 /**********************************************************************
2612 * QueryServiceStatus
2617 QueryServiceStatus(SC_HANDLE hService
,
2618 LPSERVICE_STATUS lpServiceStatus
)
2622 TRACE("QueryServiceStatus(%p, %p)\n",
2623 hService
, lpServiceStatus
);
2627 SetLastError(ERROR_INVALID_HANDLE
);
2633 /* Call to services.exe using RPC */
2634 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2637 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2639 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2643 if (dwError
!= ERROR_SUCCESS
)
2645 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2646 SetLastError(dwError
);
2654 /**********************************************************************
2655 * QueryServiceStatusEx
2660 QueryServiceStatusEx(SC_HANDLE hService
,
2661 SC_STATUS_TYPE InfoLevel
,
2664 LPDWORD pcbBytesNeeded
)
2668 TRACE("QueryServiceStatusEx() called\n");
2670 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2672 SetLastError(ERROR_INVALID_LEVEL
);
2676 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2678 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2679 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2685 /* Call to services.exe using RPC */
2686 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2692 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2694 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2698 if (dwError
!= ERROR_SUCCESS
)
2700 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2701 SetLastError(dwError
);
2709 /**********************************************************************
2715 StartServiceA(SC_HANDLE hService
,
2716 DWORD dwNumServiceArgs
,
2717 LPCSTR
*lpServiceArgVectors
)
2723 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2725 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2727 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2729 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2733 if (dwError
!= ERROR_SUCCESS
)
2735 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2736 SetLastError(dwError
);
2744 /**********************************************************************
2750 StartServiceW(SC_HANDLE hService
,
2751 DWORD dwNumServiceArgs
,
2752 LPCWSTR
*lpServiceArgVectors
)
2758 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2760 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2762 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2764 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2768 if (dwError
!= ERROR_SUCCESS
)
2770 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2771 SetLastError(dwError
);
2779 /**********************************************************************
2780 * UnlockServiceDatabase
2785 UnlockServiceDatabase(SC_LOCK ScLock
)
2789 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2793 /* Call to services.exe using RPC */
2794 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2796 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2798 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2802 if (dwError
== ERROR_INVALID_HANDLE
)
2803 dwError
= ERROR_INVALID_SERVICE_LOCK
;
2805 if (dwError
!= ERROR_SUCCESS
)
2807 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2808 SetLastError(dwError
);
2816 /**********************************************************************
2817 * NotifyBootConfigStatus
2822 NotifyBootConfigStatus(BOOL BootAcceptable
)
2826 TRACE("NotifyBootConfigStatus()\n");
2830 /* Call to services.exe using RPC */
2831 dwError
= RNotifyBootConfigStatus(NULL
,
2834 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2836 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2840 if (dwError
!= ERROR_SUCCESS
)
2842 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2843 SetLastError(dwError
);