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 if (lpInfo
== NULL
) return TRUE
;
170 /* Fill relevant field of the Info structure */
171 Info
.dwInfoLevel
= dwInfoLevel
;
174 case SERVICE_CONFIG_DESCRIPTION
:
178 case SERVICE_CONFIG_FAILURE_ACTIONS
:
183 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
184 SetLastError(ERROR_INVALID_PARAMETER
);
190 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
193 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
195 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
199 if (dwError
!= ERROR_SUCCESS
)
201 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
202 SetLastError(dwError
);
210 /**********************************************************************
211 * ChangeServiceConfig2W
216 ChangeServiceConfig2W(SC_HANDLE hService
,
220 SC_RPC_CONFIG_INFOW Info
;
223 TRACE("ChangeServiceConfig2W() called\n");
225 if (lpInfo
== NULL
) return TRUE
;
227 /* Fill relevant field of the Info structure */
228 Info
.dwInfoLevel
= dwInfoLevel
;
231 case SERVICE_CONFIG_DESCRIPTION
:
235 case SERVICE_CONFIG_FAILURE_ACTIONS
:
240 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
241 SetLastError(ERROR_INVALID_PARAMETER
);
247 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
250 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
252 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
256 if (dwError
!= ERROR_SUCCESS
)
258 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
259 SetLastError(dwError
);
267 /**********************************************************************
268 * ChangeServiceConfigA
273 ChangeServiceConfigA(SC_HANDLE hService
,
276 DWORD dwErrorControl
,
277 LPCSTR lpBinaryPathName
,
278 LPCSTR lpLoadOrderGroup
,
280 LPCSTR lpDependencies
,
281 LPCSTR lpServiceStartName
,
283 LPCSTR lpDisplayName
)
286 DWORD dwDependenciesLength
= 0;
289 DWORD dwPasswordLength
= 0;
290 LPWSTR lpPasswordW
= NULL
;
291 LPBYTE lpEncryptedPassword
= NULL
;
293 TRACE("ChangeServiceConfigA() called\n");
295 /* Calculate the Dependencies length*/
296 if (lpDependencies
!= NULL
)
298 lpStr
= lpDependencies
;
301 cchLength
= strlen(lpStr
) + 1;
302 dwDependenciesLength
+= (DWORD
)cchLength
;
303 lpStr
= lpStr
+ cchLength
;
305 dwDependenciesLength
++;
308 if (lpPassword
!= NULL
)
310 /* Convert the password to unicode */
311 lpPasswordW
= HeapAlloc(GetProcessHeap(),
313 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
314 if (lpPasswordW
== NULL
)
316 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
320 MultiByteToWideChar(CP_ACP
,
325 (int)(strlen(lpPassword
) + 1));
327 /* FIXME: Encrypt the password */
328 lpEncryptedPassword
= (LPBYTE
)lpPasswordW
;
329 dwPasswordLength
= (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
);
334 /* Call to services.exe using RPC */
335 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
339 (LPSTR
)lpBinaryPathName
,
340 (LPSTR
)lpLoadOrderGroup
,
342 (LPBYTE
)lpDependencies
,
343 dwDependenciesLength
,
344 (LPSTR
)lpServiceStartName
,
347 (LPSTR
)lpDisplayName
);
349 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
351 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
355 if (lpPasswordW
!= NULL
)
356 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
358 if (dwError
!= ERROR_SUCCESS
)
360 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
361 SetLastError(dwError
);
369 /**********************************************************************
370 * ChangeServiceConfigW
375 ChangeServiceConfigW(SC_HANDLE hService
,
378 DWORD dwErrorControl
,
379 LPCWSTR lpBinaryPathName
,
380 LPCWSTR lpLoadOrderGroup
,
382 LPCWSTR lpDependencies
,
383 LPCWSTR lpServiceStartName
,
385 LPCWSTR lpDisplayName
)
388 DWORD dwDependenciesLength
= 0;
391 DWORD dwPasswordLength
= 0;
392 LPBYTE lpEncryptedPassword
= NULL
;
394 TRACE("ChangeServiceConfigW() called\n");
396 /* Calculate the Dependencies length*/
397 if (lpDependencies
!= NULL
)
399 lpStr
= lpDependencies
;
402 cchLength
= wcslen(lpStr
) + 1;
403 dwDependenciesLength
+= (DWORD
)cchLength
;
404 lpStr
= lpStr
+ cchLength
;
406 dwDependenciesLength
++;
407 dwDependenciesLength
*= sizeof(WCHAR
);
410 if (lpPassword
!= NULL
)
412 /* FIXME: Encrypt the password */
413 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
414 dwPasswordLength
= (wcslen(lpPassword
) + 1) * sizeof(WCHAR
);
419 /* Call to services.exe using RPC */
420 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
424 (LPWSTR
)lpBinaryPathName
,
425 (LPWSTR
)lpLoadOrderGroup
,
427 (LPBYTE
)lpDependencies
,
428 dwDependenciesLength
,
429 (LPWSTR
)lpServiceStartName
,
432 (LPWSTR
)lpDisplayName
);
434 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
436 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
440 if (dwError
!= ERROR_SUCCESS
)
442 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
443 SetLastError(dwError
);
451 /**********************************************************************
457 CloseServiceHandle(SC_HANDLE hSCObject
)
461 TRACE("CloseServiceHandle() called\n");
465 SetLastError(ERROR_INVALID_HANDLE
);
471 /* Call to services.exe using RPC */
472 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
474 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
476 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
482 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
483 SetLastError(dwError
);
487 TRACE("CloseServiceHandle() done\n");
493 /**********************************************************************
499 ControlService(SC_HANDLE hService
,
501 LPSERVICE_STATUS lpServiceStatus
)
505 TRACE("ControlService(%x, %x, %p)\n",
506 hService
, dwControl
, lpServiceStatus
);
510 /* Call to services.exe using RPC */
511 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
515 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
517 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
521 if (dwError
!= ERROR_SUCCESS
)
523 TRACE("RControlService() failed (Error %lu)\n", dwError
);
524 SetLastError(dwError
);
528 TRACE("ControlService() done\n");
534 /**********************************************************************
540 ControlServiceEx(IN SC_HANDLE hService
,
542 IN DWORD dwInfoLevel
,
543 IN OUT PVOID pControlParams
)
545 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
546 hService
, dwControl
, dwInfoLevel
, pControlParams
);
547 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
552 /**********************************************************************
558 CreateServiceA(SC_HANDLE hSCManager
,
559 LPCSTR lpServiceName
,
560 LPCSTR lpDisplayName
,
561 DWORD dwDesiredAccess
,
564 DWORD dwErrorControl
,
565 LPCSTR lpBinaryPathName
,
566 LPCSTR lpLoadOrderGroup
,
568 LPCSTR lpDependencies
,
569 LPCSTR lpServiceStartName
,
572 SC_HANDLE hService
= NULL
;
573 DWORD dwDependenciesLength
= 0;
577 DWORD dwPasswordLength
= 0;
578 LPWSTR lpPasswordW
= NULL
;
579 LPBYTE lpEncryptedPassword
= NULL
;
581 TRACE("CreateServiceA() called\n");
582 TRACE("%p %s %s\n", hSCManager
,
583 lpServiceName
, lpDisplayName
);
587 SetLastError(ERROR_INVALID_HANDLE
);
591 /* Calculate the Dependencies length */
592 if (lpDependencies
!= NULL
)
594 lpStr
= lpDependencies
;
597 cchLength
= strlen(lpStr
) + 1;
598 dwDependenciesLength
+= (DWORD
)cchLength
;
599 lpStr
= lpStr
+ cchLength
;
601 dwDependenciesLength
++;
604 if (lpPassword
!= NULL
)
606 /* Convert the password to unicode */
607 lpPasswordW
= HeapAlloc(GetProcessHeap(),
609 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
610 if (lpPasswordW
== NULL
)
612 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
616 MultiByteToWideChar(CP_ACP
,
621 (int)(strlen(lpPassword
) + 1));
623 /* FIXME: Encrypt the password */
624 lpEncryptedPassword
= (LPBYTE
)lpPasswordW
;
625 dwPasswordLength
= (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
);
630 /* Call to services.exe using RPC */
631 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
632 (LPSTR
)lpServiceName
,
633 (LPSTR
)lpDisplayName
,
638 (LPSTR
)lpBinaryPathName
,
639 (LPSTR
)lpLoadOrderGroup
,
641 (LPBYTE
)lpDependencies
,
642 dwDependenciesLength
,
643 (LPSTR
)lpServiceStartName
,
646 (SC_RPC_HANDLE
*)&hService
);
648 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
650 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
654 if (lpPasswordW
!= NULL
)
655 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
657 SetLastError(dwError
);
658 if (dwError
!= ERROR_SUCCESS
)
660 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
668 /**********************************************************************
674 CreateServiceW(SC_HANDLE hSCManager
,
675 LPCWSTR lpServiceName
,
676 LPCWSTR lpDisplayName
,
677 DWORD dwDesiredAccess
,
680 DWORD dwErrorControl
,
681 LPCWSTR lpBinaryPathName
,
682 LPCWSTR lpLoadOrderGroup
,
684 LPCWSTR lpDependencies
,
685 LPCWSTR lpServiceStartName
,
688 SC_HANDLE hService
= NULL
;
689 DWORD dwDependenciesLength
= 0;
693 DWORD dwPasswordLength
= 0;
694 LPBYTE lpEncryptedPassword
= NULL
;
696 TRACE("CreateServiceW() called\n");
697 TRACE("%p %S %S\n", hSCManager
,
698 lpServiceName
, lpDisplayName
);
702 SetLastError(ERROR_INVALID_HANDLE
);
706 /* Calculate the Dependencies length */
707 if (lpDependencies
!= NULL
)
709 lpStr
= lpDependencies
;
712 cchLength
= wcslen(lpStr
) + 1;
713 dwDependenciesLength
+= (DWORD
)cchLength
;
714 lpStr
= lpStr
+ cchLength
;
716 dwDependenciesLength
++;
717 dwDependenciesLength
*= sizeof(WCHAR
);
720 if (lpPassword
!= NULL
)
722 /* FIXME: Encrypt the password */
723 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
724 dwPasswordLength
= (wcslen(lpPassword
) + 1) * sizeof(WCHAR
);
729 /* Call to services.exe using RPC */
730 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
740 (LPBYTE
)lpDependencies
,
741 dwDependenciesLength
,
745 (SC_RPC_HANDLE
*)&hService
);
747 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
749 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
753 SetLastError(dwError
);
754 if (dwError
!= ERROR_SUCCESS
)
756 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
764 /**********************************************************************
770 DeleteService(SC_HANDLE hService
)
774 TRACE("DeleteService(%x)\n", hService
);
778 /* Call to services.exe using RPC */
779 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
781 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
783 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
787 if (dwError
!= ERROR_SUCCESS
)
789 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
790 SetLastError(dwError
);
798 /**********************************************************************
799 * EnumDependentServicesA
804 EnumDependentServicesA(SC_HANDLE hService
,
805 DWORD dwServiceState
,
806 LPENUM_SERVICE_STATUSA lpServices
,
808 LPDWORD pcbBytesNeeded
,
809 LPDWORD lpServicesReturned
)
811 ENUM_SERVICE_STATUSA ServiceStatus
;
812 LPENUM_SERVICE_STATUSA lpStatusPtr
;
817 TRACE("EnumDependentServicesA() called\n");
819 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
821 lpStatusPtr
= &ServiceStatus
;
822 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
826 lpStatusPtr
= lpServices
;
827 dwBufferSize
= cbBufSize
;
832 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
839 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
841 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
845 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
847 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
849 if (lpStatusPtr
->lpServiceName
)
850 lpStatusPtr
->lpServiceName
=
851 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
853 if (lpStatusPtr
->lpDisplayName
)
854 lpStatusPtr
->lpDisplayName
=
855 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
861 if (dwError
!= ERROR_SUCCESS
)
863 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
864 SetLastError(dwError
);
868 TRACE("EnumDependentServicesA() done\n");
874 /**********************************************************************
875 * EnumDependentServicesW
880 EnumDependentServicesW(SC_HANDLE hService
,
881 DWORD dwServiceState
,
882 LPENUM_SERVICE_STATUSW lpServices
,
884 LPDWORD pcbBytesNeeded
,
885 LPDWORD lpServicesReturned
)
887 ENUM_SERVICE_STATUSW ServiceStatus
;
888 LPENUM_SERVICE_STATUSW lpStatusPtr
;
893 TRACE("EnumDependentServicesW() called\n");
895 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
897 lpStatusPtr
= &ServiceStatus
;
898 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
902 lpStatusPtr
= lpServices
;
903 dwBufferSize
= cbBufSize
;
908 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
915 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
917 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
921 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
923 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
925 if (lpStatusPtr
->lpServiceName
)
926 lpStatusPtr
->lpServiceName
=
927 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
929 if (lpStatusPtr
->lpDisplayName
)
930 lpStatusPtr
->lpDisplayName
=
931 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
937 if (dwError
!= ERROR_SUCCESS
)
939 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
940 SetLastError(dwError
);
944 TRACE("EnumDependentServicesW() done\n");
950 /**********************************************************************
956 EnumServiceGroupW(SC_HANDLE hSCManager
,
958 DWORD dwServiceState
,
959 LPENUM_SERVICE_STATUSW lpServices
,
961 LPDWORD pcbBytesNeeded
,
962 LPDWORD lpServicesReturned
,
963 LPDWORD lpResumeHandle
,
966 ENUM_SERVICE_STATUSW ServiceStatus
;
967 LPENUM_SERVICE_STATUSW lpStatusPtr
;
972 TRACE("EnumServiceGroupW() called\n");
976 SetLastError(ERROR_INVALID_HANDLE
);
980 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
982 SetLastError(ERROR_INVALID_ADDRESS
);
986 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
988 lpStatusPtr
= &ServiceStatus
;
989 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
993 lpStatusPtr
= lpServices
;
994 dwBufferSize
= cbBufSize
;
1001 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1004 (LPBYTE
)lpStatusPtr
,
1012 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
1015 (LPBYTE
)lpStatusPtr
,
1023 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1025 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1029 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1031 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1033 if (lpStatusPtr
->lpServiceName
)
1034 lpStatusPtr
->lpServiceName
=
1035 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1037 if (lpStatusPtr
->lpDisplayName
)
1038 lpStatusPtr
->lpDisplayName
=
1039 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1045 if (dwError
!= ERROR_SUCCESS
)
1047 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
1048 SetLastError(dwError
);
1052 TRACE("EnumServiceGroupW() done\n");
1058 /**********************************************************************
1059 * EnumServicesStatusA
1064 EnumServicesStatusA(SC_HANDLE hSCManager
,
1065 DWORD dwServiceType
,
1066 DWORD dwServiceState
,
1067 LPENUM_SERVICE_STATUSA lpServices
,
1069 LPDWORD pcbBytesNeeded
,
1070 LPDWORD lpServicesReturned
,
1071 LPDWORD lpResumeHandle
)
1073 ENUM_SERVICE_STATUSA ServiceStatus
;
1074 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1079 TRACE("EnumServicesStatusA() called\n");
1083 SetLastError(ERROR_INVALID_HANDLE
);
1087 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1089 SetLastError(ERROR_INVALID_ADDRESS
);
1093 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1095 lpStatusPtr
= &ServiceStatus
;
1096 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1100 lpStatusPtr
= lpServices
;
1101 dwBufferSize
= cbBufSize
;
1106 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1109 (LPBYTE
)lpStatusPtr
,
1115 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1117 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1121 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1123 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1125 if (lpStatusPtr
->lpServiceName
)
1126 lpStatusPtr
->lpServiceName
=
1127 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1129 if (lpStatusPtr
->lpDisplayName
)
1130 lpStatusPtr
->lpDisplayName
=
1131 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1137 if (dwError
!= ERROR_SUCCESS
)
1139 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1140 SetLastError(dwError
);
1144 TRACE("EnumServicesStatusA() done\n");
1150 /**********************************************************************
1151 * EnumServicesStatusW
1156 EnumServicesStatusW(SC_HANDLE hSCManager
,
1157 DWORD dwServiceType
,
1158 DWORD dwServiceState
,
1159 LPENUM_SERVICE_STATUSW lpServices
,
1161 LPDWORD pcbBytesNeeded
,
1162 LPDWORD lpServicesReturned
,
1163 LPDWORD lpResumeHandle
)
1165 ENUM_SERVICE_STATUSW ServiceStatus
;
1166 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1171 TRACE("EnumServicesStatusW() called\n");
1175 SetLastError(ERROR_INVALID_HANDLE
);
1179 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1181 SetLastError(ERROR_INVALID_ADDRESS
);
1185 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1187 lpStatusPtr
= &ServiceStatus
;
1188 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1192 lpStatusPtr
= lpServices
;
1193 dwBufferSize
= cbBufSize
;
1198 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1201 (LPBYTE
)lpStatusPtr
,
1207 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1209 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1213 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1215 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1217 if (lpStatusPtr
->lpServiceName
)
1218 lpStatusPtr
->lpServiceName
=
1219 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1221 if (lpStatusPtr
->lpDisplayName
)
1222 lpStatusPtr
->lpDisplayName
=
1223 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1229 if (dwError
!= ERROR_SUCCESS
)
1231 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1232 SetLastError(dwError
);
1236 TRACE("EnumServicesStatusW() done\n");
1242 /**********************************************************************
1243 * EnumServicesStatusExA
1248 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1249 SC_ENUM_TYPE InfoLevel
,
1250 DWORD dwServiceType
,
1251 DWORD dwServiceState
,
1254 LPDWORD pcbBytesNeeded
,
1255 LPDWORD lpServicesReturned
,
1256 LPDWORD lpResumeHandle
,
1257 LPCSTR pszGroupName
)
1259 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1260 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1265 TRACE("EnumServicesStatusExA() called\n");
1267 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1269 SetLastError(ERROR_INVALID_LEVEL
);
1275 SetLastError(ERROR_INVALID_HANDLE
);
1279 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1281 SetLastError(ERROR_INVALID_ADDRESS
);
1285 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1287 lpStatusPtr
= &ServiceStatus
;
1288 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1292 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1293 dwBufferSize
= cbBufSize
;
1298 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1302 (LPBYTE
)lpStatusPtr
,
1307 (LPSTR
)pszGroupName
);
1309 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1311 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1315 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1317 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1319 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1321 if (lpStatusPtr
->lpServiceName
)
1322 lpStatusPtr
->lpServiceName
=
1323 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1325 if (lpStatusPtr
->lpDisplayName
)
1326 lpStatusPtr
->lpDisplayName
=
1327 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1334 if (dwError
!= ERROR_SUCCESS
)
1336 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1337 SetLastError(dwError
);
1341 TRACE("EnumServicesStatusExA() done\n");
1347 /**********************************************************************
1348 * EnumServicesStatusExW
1353 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1354 SC_ENUM_TYPE InfoLevel
,
1355 DWORD dwServiceType
,
1356 DWORD dwServiceState
,
1359 LPDWORD pcbBytesNeeded
,
1360 LPDWORD lpServicesReturned
,
1361 LPDWORD lpResumeHandle
,
1362 LPCWSTR pszGroupName
)
1364 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1365 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1370 TRACE("EnumServicesStatusExW() called\n");
1372 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1374 SetLastError(ERROR_INVALID_LEVEL
);
1380 SetLastError(ERROR_INVALID_HANDLE
);
1384 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1386 SetLastError(ERROR_INVALID_ADDRESS
);
1390 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1392 lpStatusPtr
= &ServiceStatus
;
1393 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1397 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1398 dwBufferSize
= cbBufSize
;
1403 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1407 (LPBYTE
)lpStatusPtr
,
1412 (LPWSTR
)pszGroupName
);
1414 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1416 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1420 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1422 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1424 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1426 if (lpStatusPtr
->lpServiceName
)
1427 lpStatusPtr
->lpServiceName
=
1428 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1430 if (lpStatusPtr
->lpDisplayName
)
1431 lpStatusPtr
->lpDisplayName
=
1432 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1439 if (dwError
!= ERROR_SUCCESS
)
1441 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1442 SetLastError(dwError
);
1446 TRACE("EnumServicesStatusExW() done\n");
1452 /**********************************************************************
1453 * GetServiceDisplayNameA
1458 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1459 LPCSTR lpServiceName
,
1460 LPSTR lpDisplayName
,
1461 LPDWORD lpcchBuffer
)
1465 CHAR szEmptyName
[] = "";
1467 TRACE("GetServiceDisplayNameA() called\n");
1468 TRACE("%p %s %p %p\n", hSCManager
,
1469 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1473 SetLastError(ERROR_INVALID_HANDLE
);
1477 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1479 lpNameBuffer
= szEmptyName
;
1480 *lpcchBuffer
= sizeof(CHAR
);
1484 lpNameBuffer
= lpDisplayName
;
1489 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1494 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1496 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1497 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1501 if (dwError
!= ERROR_SUCCESS
)
1503 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1504 SetLastError(dwError
);
1512 /**********************************************************************
1513 * GetServiceDisplayNameW
1518 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1519 LPCWSTR lpServiceName
,
1520 LPWSTR lpDisplayName
,
1521 LPDWORD lpcchBuffer
)
1524 LPWSTR lpNameBuffer
;
1525 WCHAR szEmptyName
[] = L
"";
1527 TRACE("GetServiceDisplayNameW() called\n");
1531 SetLastError(ERROR_INVALID_HANDLE
);
1535 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1537 lpNameBuffer
= szEmptyName
;
1538 *lpcchBuffer
= sizeof(WCHAR
);
1542 lpNameBuffer
= lpDisplayName
;
1547 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1552 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1554 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1558 if (dwError
!= ERROR_SUCCESS
)
1560 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1561 SetLastError(dwError
);
1569 /**********************************************************************
1570 * GetServiceKeyNameA
1575 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1576 LPCSTR lpDisplayName
,
1577 LPSTR lpServiceName
,
1578 LPDWORD lpcchBuffer
)
1582 CHAR szEmptyName
[] = "";
1584 TRACE("GetServiceKeyNameA() called\n");
1588 SetLastError(ERROR_INVALID_HANDLE
);
1592 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1594 lpNameBuffer
= szEmptyName
;
1595 *lpcchBuffer
= sizeof(CHAR
);
1599 lpNameBuffer
= lpServiceName
;
1604 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1609 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1611 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1615 if (dwError
!= ERROR_SUCCESS
)
1617 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1618 SetLastError(dwError
);
1626 /**********************************************************************
1627 * GetServiceKeyNameW
1632 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1633 LPCWSTR lpDisplayName
,
1634 LPWSTR lpServiceName
,
1635 LPDWORD lpcchBuffer
)
1638 LPWSTR lpNameBuffer
;
1639 WCHAR szEmptyName
[] = L
"";
1641 TRACE("GetServiceKeyNameW() called\n");
1645 SetLastError(ERROR_INVALID_HANDLE
);
1649 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1651 lpNameBuffer
= szEmptyName
;
1652 *lpcchBuffer
= sizeof(WCHAR
);
1656 lpNameBuffer
= lpServiceName
;
1661 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1666 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1668 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1672 if (dwError
!= ERROR_SUCCESS
)
1674 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1675 SetLastError(dwError
);
1683 /**********************************************************************
1684 * I_ScGetCurrentGroupStateW
1689 I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager
,
1690 LPWSTR pszGroupName
,
1691 LPDWORD pdwGroupState
)
1695 TRACE("I_ScGetCurrentGroupStateW() called\n");
1699 dwError
= RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE
)hSCManager
,
1703 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1705 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1709 if (dwError
!= ERROR_SUCCESS
)
1711 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError
);
1712 SetLastError(dwError
);
1719 /**********************************************************************
1720 * LockServiceDatabase
1725 LockServiceDatabase(SC_HANDLE hSCManager
)
1730 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1734 /* Call to services.exe using RPC */
1735 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1736 (SC_RPC_LOCK
*)&hLock
);
1738 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1740 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1744 if (dwError
!= ERROR_SUCCESS
)
1746 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1747 SetLastError(dwError
);
1751 TRACE("hLock = %p\n", hLock
);
1758 WaitForSCManager(VOID
)
1762 TRACE("WaitForSCManager() called\n");
1764 /* Try to open the existing event */
1765 hEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, SCM_START_EVENT
);
1768 if (GetLastError() != ERROR_FILE_NOT_FOUND
) return;
1770 /* Try to create a new event */
1771 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
1772 if (hEvent
== NULL
) return;
1775 /* Wait for 3 minutes */
1776 WaitForSingleObject(hEvent
, 180000);
1777 CloseHandle(hEvent
);
1779 TRACE("ScmWaitForSCManager() done\n");
1783 /**********************************************************************
1789 OpenSCManagerA(LPCSTR lpMachineName
,
1790 LPCSTR lpDatabaseName
,
1791 DWORD dwDesiredAccess
)
1793 SC_HANDLE hScm
= NULL
;
1796 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1797 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1803 /* Call to services.exe using RPC */
1804 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1805 (LPSTR
)lpDatabaseName
,
1807 (SC_RPC_HANDLE
*)&hScm
);
1809 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1811 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1815 if (dwError
!= ERROR_SUCCESS
)
1817 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1818 SetLastError(dwError
);
1822 TRACE("hScm = %p\n", hScm
);
1828 /**********************************************************************
1834 OpenSCManagerW(LPCWSTR lpMachineName
,
1835 LPCWSTR lpDatabaseName
,
1836 DWORD dwDesiredAccess
)
1838 SC_HANDLE hScm
= NULL
;
1841 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1842 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1848 /* Call to services.exe using RPC */
1849 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1850 (LPWSTR
)lpDatabaseName
,
1852 (SC_RPC_HANDLE
*)&hScm
);
1854 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1856 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1860 if (dwError
!= ERROR_SUCCESS
)
1862 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1863 SetLastError(dwError
);
1867 TRACE("hScm = %p\n", hScm
);
1873 /**********************************************************************
1879 OpenServiceA(SC_HANDLE hSCManager
,
1880 LPCSTR lpServiceName
,
1881 DWORD dwDesiredAccess
)
1883 SC_HANDLE hService
= NULL
;
1886 TRACE("OpenServiceA(%p, %s, %lx)\n",
1887 hSCManager
, lpServiceName
, dwDesiredAccess
);
1891 SetLastError(ERROR_INVALID_HANDLE
);
1897 /* Call to services.exe using RPC */
1898 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1899 (LPSTR
)lpServiceName
,
1901 (SC_RPC_HANDLE
*)&hService
);
1903 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1905 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1909 SetLastError(dwError
);
1910 if (dwError
!= ERROR_SUCCESS
)
1912 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1916 TRACE("hService = %p\n", hService
);
1922 /**********************************************************************
1928 OpenServiceW(SC_HANDLE hSCManager
,
1929 LPCWSTR lpServiceName
,
1930 DWORD dwDesiredAccess
)
1932 SC_HANDLE hService
= NULL
;
1935 TRACE("OpenServiceW(%p, %S, %lx)\n",
1936 hSCManager
, lpServiceName
, dwDesiredAccess
);
1940 SetLastError(ERROR_INVALID_HANDLE
);
1946 /* Call to services.exe using RPC */
1947 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1948 (LPWSTR
)lpServiceName
,
1950 (SC_RPC_HANDLE
*)&hService
);
1952 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1954 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1958 SetLastError(dwError
);
1959 if (dwError
!= ERROR_SUCCESS
)
1961 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1965 TRACE("hService = %p\n", hService
);
1971 /**********************************************************************
1972 * QueryServiceConfigA
1977 QueryServiceConfigA(SC_HANDLE hService
,
1978 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1980 LPDWORD pcbBytesNeeded
)
1982 QUERY_SERVICE_CONFIGA ServiceConfig
;
1983 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1987 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1988 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1990 if (lpServiceConfig
== NULL
||
1991 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1993 lpConfigPtr
= &ServiceConfig
;
1994 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1998 lpConfigPtr
= lpServiceConfig
;
1999 dwBufferSize
= cbBufSize
;
2004 /* Call to services.exe using RPC */
2005 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
2006 (LPBYTE
)lpConfigPtr
,
2010 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2012 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2016 if (dwError
!= ERROR_SUCCESS
)
2018 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
2019 SetLastError(dwError
);
2023 /* Adjust the pointers */
2024 if (lpConfigPtr
->lpBinaryPathName
)
2025 lpConfigPtr
->lpBinaryPathName
=
2026 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2027 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2029 if (lpConfigPtr
->lpLoadOrderGroup
)
2030 lpConfigPtr
->lpLoadOrderGroup
=
2031 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2032 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2034 if (lpConfigPtr
->lpDependencies
)
2035 lpConfigPtr
->lpDependencies
=
2036 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2037 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2039 if (lpConfigPtr
->lpServiceStartName
)
2040 lpConfigPtr
->lpServiceStartName
=
2041 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2042 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2044 if (lpConfigPtr
->lpDisplayName
)
2045 lpConfigPtr
->lpDisplayName
=
2046 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2047 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2049 TRACE("QueryServiceConfigA() done\n");
2055 /**********************************************************************
2056 * QueryServiceConfigW
2061 QueryServiceConfigW(SC_HANDLE hService
,
2062 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
2064 LPDWORD pcbBytesNeeded
)
2066 QUERY_SERVICE_CONFIGW ServiceConfig
;
2067 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
2071 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
2072 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2074 if (lpServiceConfig
== NULL
||
2075 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2077 lpConfigPtr
= &ServiceConfig
;
2078 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2082 lpConfigPtr
= lpServiceConfig
;
2083 dwBufferSize
= cbBufSize
;
2088 /* Call to services.exe using RPC */
2089 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2090 (LPBYTE
)lpConfigPtr
,
2094 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2096 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2100 if (dwError
!= ERROR_SUCCESS
)
2102 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2103 SetLastError(dwError
);
2107 /* Adjust the pointers */
2108 if (lpConfigPtr
->lpBinaryPathName
)
2109 lpConfigPtr
->lpBinaryPathName
=
2110 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2111 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2113 if (lpConfigPtr
->lpLoadOrderGroup
)
2114 lpConfigPtr
->lpLoadOrderGroup
=
2115 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2116 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2118 if (lpConfigPtr
->lpDependencies
)
2119 lpConfigPtr
->lpDependencies
=
2120 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2121 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2123 if (lpConfigPtr
->lpServiceStartName
)
2124 lpConfigPtr
->lpServiceStartName
=
2125 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2126 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2128 if (lpConfigPtr
->lpDisplayName
)
2129 lpConfigPtr
->lpDisplayName
=
2130 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2131 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2133 TRACE("QueryServiceConfigW() done\n");
2139 /**********************************************************************
2140 * QueryServiceConfig2A
2145 QueryServiceConfig2A(SC_HANDLE hService
,
2149 LPDWORD pcbBytesNeeded
)
2151 SERVICE_DESCRIPTIONA ServiceDescription
;
2152 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2153 LPBYTE lpTempBuffer
;
2154 BOOL bUseTempBuffer
= FALSE
;
2158 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2159 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2161 lpTempBuffer
= lpBuffer
;
2162 dwBufferSize
= cbBufSize
;
2164 switch (dwInfoLevel
)
2166 case SERVICE_CONFIG_DESCRIPTION
:
2167 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2169 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2170 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2171 bUseTempBuffer
= TRUE
;
2175 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2176 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2178 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2179 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2180 bUseTempBuffer
= TRUE
;
2185 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2186 SetLastError(ERROR_INVALID_LEVEL
);
2192 /* Call to services.exe using RPC */
2193 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2199 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2201 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2205 if (dwError
!= ERROR_SUCCESS
)
2207 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2208 SetLastError(dwError
);
2212 if (bUseTempBuffer
== TRUE
)
2214 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2215 *pcbBytesNeeded
= dwBufferSize
;
2216 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2220 switch (dwInfoLevel
)
2222 case SERVICE_CONFIG_DESCRIPTION
:
2224 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2226 if (lpPtr
->lpDescription
!= NULL
)
2227 lpPtr
->lpDescription
=
2228 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2232 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2234 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2236 if (lpPtr
->lpRebootMsg
!= NULL
)
2237 lpPtr
->lpRebootMsg
=
2238 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2240 if (lpPtr
->lpCommand
!= NULL
)
2242 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2244 if (lpPtr
->lpsaActions
!= NULL
)
2245 lpPtr
->lpsaActions
=
2246 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2251 TRACE("QueryServiceConfig2A() done\n");
2257 /**********************************************************************
2258 * QueryServiceConfig2W
2263 QueryServiceConfig2W(SC_HANDLE hService
,
2267 LPDWORD pcbBytesNeeded
)
2269 SERVICE_DESCRIPTIONW ServiceDescription
;
2270 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2271 LPBYTE lpTempBuffer
;
2272 BOOL bUseTempBuffer
= FALSE
;
2276 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2277 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2279 lpTempBuffer
= lpBuffer
;
2280 dwBufferSize
= cbBufSize
;
2282 switch (dwInfoLevel
)
2284 case SERVICE_CONFIG_DESCRIPTION
:
2285 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2287 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2288 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2289 bUseTempBuffer
= TRUE
;
2293 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2294 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2296 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2297 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2298 bUseTempBuffer
= TRUE
;
2303 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2304 SetLastError(ERROR_INVALID_LEVEL
);
2310 /* Call to services.exe using RPC */
2311 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2317 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2319 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2323 if (dwError
!= ERROR_SUCCESS
)
2325 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2326 SetLastError(dwError
);
2330 if (bUseTempBuffer
== TRUE
)
2332 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2333 *pcbBytesNeeded
= dwBufferSize
;
2334 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2338 switch (dwInfoLevel
)
2340 case SERVICE_CONFIG_DESCRIPTION
:
2342 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2344 if (lpPtr
->lpDescription
!= NULL
)
2345 lpPtr
->lpDescription
=
2346 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2350 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2352 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2354 if (lpPtr
->lpRebootMsg
!= NULL
)
2355 lpPtr
->lpRebootMsg
=
2356 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2358 if (lpPtr
->lpCommand
!= NULL
)
2360 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2362 if (lpPtr
->lpsaActions
!= NULL
)
2363 lpPtr
->lpsaActions
=
2364 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2369 TRACE("QueryServiceConfig2W() done\n");
2375 /**********************************************************************
2376 * QueryServiceLockStatusA
2381 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2382 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2384 LPDWORD pcbBytesNeeded
)
2386 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2387 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2391 TRACE("QueryServiceLockStatusA() called\n");
2393 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2395 lpStatusPtr
= &LockStatus
;
2396 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2400 lpStatusPtr
= lpLockStatus
;
2401 dwBufferSize
= cbBufSize
;
2406 /* Call to services.exe using RPC */
2407 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2408 (LPBYTE
)lpStatusPtr
,
2412 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2414 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2418 if (dwError
!= ERROR_SUCCESS
)
2420 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2421 SetLastError(dwError
);
2425 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2427 lpStatusPtr
->lpLockOwner
=
2428 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2431 TRACE("QueryServiceLockStatusA() done\n");
2437 /**********************************************************************
2438 * QueryServiceLockStatusW
2443 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2444 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2446 LPDWORD pcbBytesNeeded
)
2448 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2449 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2453 TRACE("QueryServiceLockStatusW() called\n");
2455 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2457 lpStatusPtr
= &LockStatus
;
2458 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2462 lpStatusPtr
= lpLockStatus
;
2463 dwBufferSize
= cbBufSize
;
2468 /* Call to services.exe using RPC */
2469 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2470 (LPBYTE
)lpStatusPtr
,
2474 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2476 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2480 if (dwError
!= ERROR_SUCCESS
)
2482 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2483 SetLastError(dwError
);
2487 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2489 lpStatusPtr
->lpLockOwner
=
2490 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2493 TRACE("QueryServiceLockStatusW() done\n");
2499 /**********************************************************************
2500 * QueryServiceObjectSecurity
2505 QueryServiceObjectSecurity(SC_HANDLE hService
,
2506 SECURITY_INFORMATION dwSecurityInformation
,
2507 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2509 LPDWORD pcbBytesNeeded
)
2513 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2514 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2518 /* Call to services.exe using RPC */
2519 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2520 dwSecurityInformation
,
2521 (LPBYTE
)lpSecurityDescriptor
,
2525 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2527 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2531 if (dwError
!= ERROR_SUCCESS
)
2533 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2534 SetLastError(dwError
);
2541 /**********************************************************************
2542 * SetServiceObjectSecurity
2547 SetServiceObjectSecurity(SC_HANDLE hService
,
2548 SECURITY_INFORMATION dwSecurityInformation
,
2549 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2551 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2557 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2560 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2562 SetLastError(ERROR_INVALID_PARAMETER
);
2566 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2567 if (SelfRelativeSD
== NULL
)
2569 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2573 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2576 if (!NT_SUCCESS(Status
))
2578 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2579 SetLastError(RtlNtStatusToDosError(Status
));
2585 /* Call to services.exe using RPC */
2586 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2587 dwSecurityInformation
,
2588 (LPBYTE
)SelfRelativeSD
,
2591 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2593 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2597 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2599 if (dwError
!= ERROR_SUCCESS
)
2601 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2602 SetLastError(dwError
);
2610 /**********************************************************************
2611 * QueryServiceStatus
2616 QueryServiceStatus(SC_HANDLE hService
,
2617 LPSERVICE_STATUS lpServiceStatus
)
2621 TRACE("QueryServiceStatus(%p, %p)\n",
2622 hService
, lpServiceStatus
);
2626 SetLastError(ERROR_INVALID_HANDLE
);
2632 /* Call to services.exe using RPC */
2633 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2636 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2638 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2642 if (dwError
!= ERROR_SUCCESS
)
2644 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2645 SetLastError(dwError
);
2653 /**********************************************************************
2654 * QueryServiceStatusEx
2659 QueryServiceStatusEx(SC_HANDLE hService
,
2660 SC_STATUS_TYPE InfoLevel
,
2663 LPDWORD pcbBytesNeeded
)
2667 TRACE("QueryServiceStatusEx() called\n");
2669 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2671 SetLastError(ERROR_INVALID_LEVEL
);
2675 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2677 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2678 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2684 /* Call to services.exe using RPC */
2685 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2691 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2693 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2697 if (dwError
!= ERROR_SUCCESS
)
2699 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2700 SetLastError(dwError
);
2708 /**********************************************************************
2714 StartServiceA(SC_HANDLE hService
,
2715 DWORD dwNumServiceArgs
,
2716 LPCSTR
*lpServiceArgVectors
)
2722 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2724 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2726 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2728 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2732 if (dwError
!= ERROR_SUCCESS
)
2734 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2735 SetLastError(dwError
);
2743 /**********************************************************************
2749 StartServiceW(SC_HANDLE hService
,
2750 DWORD dwNumServiceArgs
,
2751 LPCWSTR
*lpServiceArgVectors
)
2757 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2759 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2761 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2763 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2767 if (dwError
!= ERROR_SUCCESS
)
2769 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2770 SetLastError(dwError
);
2778 /**********************************************************************
2779 * UnlockServiceDatabase
2784 UnlockServiceDatabase(SC_LOCK ScLock
)
2788 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2792 /* Call to services.exe using RPC */
2793 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2795 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2797 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2801 if (dwError
!= ERROR_SUCCESS
)
2803 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2804 SetLastError(dwError
);
2812 /**********************************************************************
2813 * NotifyBootConfigStatus
2818 NotifyBootConfigStatus(BOOL BootAcceptable
)
2822 TRACE("NotifyBootConfigStatus()\n");
2826 /* Call to services.exe using RPC */
2827 dwError
= RNotifyBootConfigStatus(NULL
,
2830 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2832 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2836 if (dwError
!= ERROR_SUCCESS
)
2838 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2839 SetLastError(dwError
);