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
10 /* INCLUDES ******************************************************************/
13 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
16 /* FUNCTIONS *****************************************************************/
19 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName
)
21 handle_t hBinding
= NULL
;
22 RPC_CSTR pszStringBinding
;
25 TRACE("SVCCTL_HANDLEA_bind() called\n");
27 Status
= RpcStringBindingComposeA(NULL
,
29 (RPC_CSTR
)szMachineName
,
30 (RPC_CSTR
)"\\pipe\\ntsvcs",
33 if (Status
!= RPC_S_OK
)
35 ERR("RpcStringBindingCompose returned 0x%x\n", Status
);
39 /* Set the binding handle that will be used to bind to the server. */
40 Status
= RpcBindingFromStringBindingA(pszStringBinding
,
42 if (Status
!= RPC_S_OK
)
44 ERR("RpcBindingFromStringBinding returned 0x%x\n", Status
);
47 Status
= RpcStringFreeA(&pszStringBinding
);
48 if (Status
!= RPC_S_OK
)
50 ERR("RpcStringFree returned 0x%x\n", Status
);
58 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName
,
63 TRACE("SVCCTL_HANDLEA_unbind() called\n");
65 Status
= RpcBindingFree(&hBinding
);
66 if (Status
!= RPC_S_OK
)
68 ERR("RpcBindingFree returned 0x%x\n", Status
);
74 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName
)
76 handle_t hBinding
= NULL
;
77 RPC_WSTR pszStringBinding
;
80 TRACE("SVCCTL_HANDLEW_bind() called\n");
82 Status
= RpcStringBindingComposeW(NULL
,
88 if (Status
!= RPC_S_OK
)
90 ERR("RpcStringBindingCompose returned 0x%x\n", Status
);
94 /* Set the binding handle that will be used to bind to the server. */
95 Status
= RpcBindingFromStringBindingW(pszStringBinding
,
97 if (Status
!= RPC_S_OK
)
99 ERR("RpcBindingFromStringBinding returned 0x%x\n", Status
);
102 Status
= RpcStringFreeW(&pszStringBinding
);
103 if (Status
!= RPC_S_OK
)
105 ERR("RpcStringFree returned 0x%x\n", Status
);
113 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName
,
118 TRACE("SVCCTL_HANDLEW_unbind() called\n");
120 Status
= RpcBindingFree(&hBinding
);
121 if (Status
!= RPC_S_OK
)
123 ERR("RpcBindingFree returned 0x%x\n", Status
);
128 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
130 ScmRpcStatusToWinError(RPC_STATUS Status
)
134 case STATUS_ACCESS_VIOLATION
:
135 case RPC_S_INVALID_BINDING
:
136 case RPC_X_SS_IN_NULL_CONTEXT
:
137 return ERROR_INVALID_HANDLE
;
139 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
140 case RPC_X_BYTE_COUNT_TOO_SMALL
:
141 return ERROR_INVALID_PARAMETER
;
143 case RPC_X_NULL_REF_POINTER
:
144 return ERROR_INVALID_ADDRESS
;
147 return (DWORD
)Status
;
152 /**********************************************************************
153 * ChangeServiceConfig2A
158 ChangeServiceConfig2A(SC_HANDLE hService
,
162 SC_RPC_CONFIG_INFOA Info
;
165 TRACE("ChangeServiceConfig2A() called\n");
167 if (lpInfo
== NULL
) return TRUE
;
169 /* Fill relevant field of the Info structure */
170 Info
.dwInfoLevel
= dwInfoLevel
;
173 case SERVICE_CONFIG_DESCRIPTION
:
177 case SERVICE_CONFIG_FAILURE_ACTIONS
:
182 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
183 SetLastError(ERROR_INVALID_PARAMETER
);
189 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
192 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
194 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
198 if (dwError
!= ERROR_SUCCESS
)
200 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
201 SetLastError(dwError
);
209 /**********************************************************************
210 * ChangeServiceConfig2W
215 ChangeServiceConfig2W(SC_HANDLE hService
,
219 SC_RPC_CONFIG_INFOW Info
;
222 TRACE("ChangeServiceConfig2W() called\n");
224 if (lpInfo
== NULL
) return TRUE
;
226 /* Fill relevant field of the Info structure */
227 Info
.dwInfoLevel
= dwInfoLevel
;
230 case SERVICE_CONFIG_DESCRIPTION
:
234 case SERVICE_CONFIG_FAILURE_ACTIONS
:
239 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
240 SetLastError(ERROR_INVALID_PARAMETER
);
246 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
249 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
251 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
255 if (dwError
!= ERROR_SUCCESS
)
257 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
258 SetLastError(dwError
);
266 /**********************************************************************
267 * ChangeServiceConfigA
272 ChangeServiceConfigA(SC_HANDLE hService
,
275 DWORD dwErrorControl
,
276 LPCSTR lpBinaryPathName
,
277 LPCSTR lpLoadOrderGroup
,
279 LPCSTR lpDependencies
,
280 LPCSTR lpServiceStartName
,
282 LPCSTR lpDisplayName
)
285 DWORD dwDependenciesLength
= 0;
288 DWORD dwPasswordLength
= 0;
289 LPWSTR lpPasswordW
= NULL
;
290 LPBYTE lpEncryptedPassword
= NULL
;
292 TRACE("ChangeServiceConfigA() called\n");
294 /* Calculate the Dependencies length*/
295 if (lpDependencies
!= NULL
)
297 lpStr
= lpDependencies
;
300 cchLength
= strlen(lpStr
) + 1;
301 dwDependenciesLength
+= (DWORD
)cchLength
;
302 lpStr
= lpStr
+ cchLength
;
304 dwDependenciesLength
++;
307 if (lpPassword
!= NULL
)
309 /* Convert the password to unicode */
310 lpPasswordW
= HeapAlloc(GetProcessHeap(),
312 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
313 if (lpPasswordW
== NULL
)
315 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
319 MultiByteToWideChar(CP_ACP
,
324 (int)(strlen(lpPassword
) + 1));
326 /* FIXME: Encrypt the password */
327 lpEncryptedPassword
= (LPBYTE
)lpPasswordW
;
328 dwPasswordLength
= (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
);
333 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
337 (LPSTR
)lpBinaryPathName
,
338 (LPSTR
)lpLoadOrderGroup
,
340 (LPBYTE
)lpDependencies
,
341 dwDependenciesLength
,
342 (LPSTR
)lpServiceStartName
,
345 (LPSTR
)lpDisplayName
);
347 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
349 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
353 if (lpPasswordW
!= NULL
)
354 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
356 if (dwError
!= ERROR_SUCCESS
)
358 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
359 SetLastError(dwError
);
367 /**********************************************************************
368 * ChangeServiceConfigW
373 ChangeServiceConfigW(SC_HANDLE hService
,
376 DWORD dwErrorControl
,
377 LPCWSTR lpBinaryPathName
,
378 LPCWSTR lpLoadOrderGroup
,
380 LPCWSTR lpDependencies
,
381 LPCWSTR lpServiceStartName
,
383 LPCWSTR lpDisplayName
)
386 DWORD dwDependenciesLength
= 0;
389 DWORD dwPasswordLength
= 0;
390 LPBYTE lpEncryptedPassword
= NULL
;
392 TRACE("ChangeServiceConfigW() called\n");
394 /* Calculate the Dependencies length*/
395 if (lpDependencies
!= NULL
)
397 lpStr
= lpDependencies
;
400 cchLength
= wcslen(lpStr
) + 1;
401 dwDependenciesLength
+= (DWORD
)cchLength
;
402 lpStr
= lpStr
+ cchLength
;
404 dwDependenciesLength
++;
405 dwDependenciesLength
*= sizeof(WCHAR
);
408 if (lpPassword
!= NULL
)
410 /* FIXME: Encrypt the password */
411 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
412 dwPasswordLength
= (wcslen(lpPassword
) + 1) * sizeof(WCHAR
);
417 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
421 (LPWSTR
)lpBinaryPathName
,
422 (LPWSTR
)lpLoadOrderGroup
,
424 (LPBYTE
)lpDependencies
,
425 dwDependenciesLength
,
426 (LPWSTR
)lpServiceStartName
,
429 (LPWSTR
)lpDisplayName
);
431 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
433 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
437 if (dwError
!= ERROR_SUCCESS
)
439 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
440 SetLastError(dwError
);
448 /**********************************************************************
454 CloseServiceHandle(SC_HANDLE hSCObject
)
458 TRACE("CloseServiceHandle() called\n");
462 SetLastError(ERROR_INVALID_HANDLE
);
468 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
470 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
472 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
478 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
479 SetLastError(dwError
);
483 TRACE("CloseServiceHandle() done\n");
489 /**********************************************************************
495 ControlService(SC_HANDLE hService
,
497 LPSERVICE_STATUS lpServiceStatus
)
501 TRACE("ControlService(%x, %x, %p)\n",
502 hService
, dwControl
, lpServiceStatus
);
506 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
510 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
512 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
516 if (dwError
!= ERROR_SUCCESS
)
518 TRACE("RControlService() failed (Error %lu)\n", dwError
);
519 SetLastError(dwError
);
523 TRACE("ControlService() done\n");
529 /**********************************************************************
535 ControlServiceEx(IN SC_HANDLE hService
,
537 IN DWORD dwInfoLevel
,
538 IN OUT PVOID pControlParams
)
540 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
541 hService
, dwControl
, dwInfoLevel
, pControlParams
);
542 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
547 /**********************************************************************
553 CreateServiceA(SC_HANDLE hSCManager
,
554 LPCSTR lpServiceName
,
555 LPCSTR lpDisplayName
,
556 DWORD dwDesiredAccess
,
559 DWORD dwErrorControl
,
560 LPCSTR lpBinaryPathName
,
561 LPCSTR lpLoadOrderGroup
,
563 LPCSTR lpDependencies
,
564 LPCSTR lpServiceStartName
,
567 SC_HANDLE hService
= NULL
;
568 DWORD dwDependenciesLength
= 0;
572 DWORD dwPasswordLength
= 0;
573 LPWSTR lpPasswordW
= NULL
;
574 LPBYTE lpEncryptedPassword
= NULL
;
576 TRACE("CreateServiceA() called\n");
577 TRACE("%p %s %s\n", hSCManager
,
578 lpServiceName
, lpDisplayName
);
582 SetLastError(ERROR_INVALID_HANDLE
);
586 /* Calculate the Dependencies length */
587 if (lpDependencies
!= NULL
)
589 lpStr
= lpDependencies
;
592 cchLength
= strlen(lpStr
) + 1;
593 dwDependenciesLength
+= (DWORD
)cchLength
;
594 lpStr
= lpStr
+ cchLength
;
596 dwDependenciesLength
++;
599 if (lpPassword
!= NULL
)
601 /* Convert the password to unicode */
602 lpPasswordW
= HeapAlloc(GetProcessHeap(),
604 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
605 if (lpPasswordW
== NULL
)
607 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
611 MultiByteToWideChar(CP_ACP
,
616 (int)(strlen(lpPassword
) + 1));
618 /* FIXME: Encrypt the password */
619 lpEncryptedPassword
= (LPBYTE
)lpPasswordW
;
620 dwPasswordLength
= (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
);
625 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
626 (LPSTR
)lpServiceName
,
627 (LPSTR
)lpDisplayName
,
632 (LPSTR
)lpBinaryPathName
,
633 (LPSTR
)lpLoadOrderGroup
,
635 (LPBYTE
)lpDependencies
,
636 dwDependenciesLength
,
637 (LPSTR
)lpServiceStartName
,
640 (SC_RPC_HANDLE
*)&hService
);
642 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
644 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
648 if (lpPasswordW
!= NULL
)
649 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
651 SetLastError(dwError
);
652 if (dwError
!= ERROR_SUCCESS
)
654 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
662 /**********************************************************************
668 CreateServiceW(SC_HANDLE hSCManager
,
669 LPCWSTR lpServiceName
,
670 LPCWSTR lpDisplayName
,
671 DWORD dwDesiredAccess
,
674 DWORD dwErrorControl
,
675 LPCWSTR lpBinaryPathName
,
676 LPCWSTR lpLoadOrderGroup
,
678 LPCWSTR lpDependencies
,
679 LPCWSTR lpServiceStartName
,
682 SC_HANDLE hService
= NULL
;
683 DWORD dwDependenciesLength
= 0;
687 DWORD dwPasswordLength
= 0;
688 LPBYTE lpEncryptedPassword
= NULL
;
690 TRACE("CreateServiceW() called\n");
691 TRACE("%p %S %S\n", hSCManager
,
692 lpServiceName
, lpDisplayName
);
696 SetLastError(ERROR_INVALID_HANDLE
);
700 /* Calculate the Dependencies length */
701 if (lpDependencies
!= NULL
)
703 lpStr
= lpDependencies
;
706 cchLength
= wcslen(lpStr
) + 1;
707 dwDependenciesLength
+= (DWORD
)cchLength
;
708 lpStr
= lpStr
+ cchLength
;
710 dwDependenciesLength
++;
711 dwDependenciesLength
*= sizeof(WCHAR
);
714 if (lpPassword
!= NULL
)
716 /* FIXME: Encrypt the password */
717 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
718 dwPasswordLength
= (wcslen(lpPassword
) + 1) * sizeof(WCHAR
);
723 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
733 (LPBYTE
)lpDependencies
,
734 dwDependenciesLength
,
738 (SC_RPC_HANDLE
*)&hService
);
740 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
742 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
746 SetLastError(dwError
);
747 if (dwError
!= ERROR_SUCCESS
)
749 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
757 /**********************************************************************
763 DeleteService(SC_HANDLE hService
)
767 TRACE("DeleteService(%x)\n", hService
);
771 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
773 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
775 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
779 if (dwError
!= ERROR_SUCCESS
)
781 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
782 SetLastError(dwError
);
790 /**********************************************************************
791 * EnumDependentServicesA
796 EnumDependentServicesA(SC_HANDLE hService
,
797 DWORD dwServiceState
,
798 LPENUM_SERVICE_STATUSA lpServices
,
800 LPDWORD pcbBytesNeeded
,
801 LPDWORD lpServicesReturned
)
803 ENUM_SERVICE_STATUSA ServiceStatus
;
804 LPENUM_SERVICE_STATUSA lpStatusPtr
;
809 TRACE("EnumDependentServicesA() called\n");
811 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
813 lpStatusPtr
= &ServiceStatus
;
814 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
818 lpStatusPtr
= lpServices
;
819 dwBufferSize
= cbBufSize
;
824 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
831 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
833 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
837 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
839 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
841 if (lpStatusPtr
->lpServiceName
)
842 lpStatusPtr
->lpServiceName
=
843 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
845 if (lpStatusPtr
->lpDisplayName
)
846 lpStatusPtr
->lpDisplayName
=
847 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
853 if (dwError
!= ERROR_SUCCESS
)
855 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
856 SetLastError(dwError
);
860 TRACE("EnumDependentServicesA() done\n");
866 /**********************************************************************
867 * EnumDependentServicesW
872 EnumDependentServicesW(SC_HANDLE hService
,
873 DWORD dwServiceState
,
874 LPENUM_SERVICE_STATUSW lpServices
,
876 LPDWORD pcbBytesNeeded
,
877 LPDWORD lpServicesReturned
)
879 ENUM_SERVICE_STATUSW ServiceStatus
;
880 LPENUM_SERVICE_STATUSW lpStatusPtr
;
885 TRACE("EnumDependentServicesW() called\n");
887 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
889 lpStatusPtr
= &ServiceStatus
;
890 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
894 lpStatusPtr
= lpServices
;
895 dwBufferSize
= cbBufSize
;
900 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
907 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
909 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
913 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
915 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
917 if (lpStatusPtr
->lpServiceName
)
918 lpStatusPtr
->lpServiceName
=
919 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
921 if (lpStatusPtr
->lpDisplayName
)
922 lpStatusPtr
->lpDisplayName
=
923 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
929 if (dwError
!= ERROR_SUCCESS
)
931 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
932 SetLastError(dwError
);
936 TRACE("EnumDependentServicesW() done\n");
942 /**********************************************************************
948 EnumServiceGroupW(SC_HANDLE hSCManager
,
950 DWORD dwServiceState
,
951 LPENUM_SERVICE_STATUSW lpServices
,
953 LPDWORD pcbBytesNeeded
,
954 LPDWORD lpServicesReturned
,
955 LPDWORD lpResumeHandle
,
958 ENUM_SERVICE_STATUSW ServiceStatus
;
959 LPENUM_SERVICE_STATUSW lpStatusPtr
;
964 TRACE("EnumServiceGroupW() called\n");
968 SetLastError(ERROR_INVALID_HANDLE
);
972 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
974 SetLastError(ERROR_INVALID_ADDRESS
);
978 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
980 lpStatusPtr
= &ServiceStatus
;
981 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
985 lpStatusPtr
= lpServices
;
986 dwBufferSize
= cbBufSize
;
993 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1004 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
1007 (LPBYTE
)lpStatusPtr
,
1015 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1017 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1021 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1023 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1025 if (lpStatusPtr
->lpServiceName
)
1026 lpStatusPtr
->lpServiceName
=
1027 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1029 if (lpStatusPtr
->lpDisplayName
)
1030 lpStatusPtr
->lpDisplayName
=
1031 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1037 if (dwError
!= ERROR_SUCCESS
)
1039 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
1040 SetLastError(dwError
);
1044 TRACE("EnumServiceGroupW() done\n");
1050 /**********************************************************************
1051 * EnumServicesStatusA
1056 EnumServicesStatusA(SC_HANDLE hSCManager
,
1057 DWORD dwServiceType
,
1058 DWORD dwServiceState
,
1059 LPENUM_SERVICE_STATUSA lpServices
,
1061 LPDWORD pcbBytesNeeded
,
1062 LPDWORD lpServicesReturned
,
1063 LPDWORD lpResumeHandle
)
1065 ENUM_SERVICE_STATUSA ServiceStatus
;
1066 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1071 TRACE("EnumServicesStatusA() called\n");
1075 SetLastError(ERROR_INVALID_HANDLE
);
1079 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1081 SetLastError(ERROR_INVALID_ADDRESS
);
1085 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1087 lpStatusPtr
= &ServiceStatus
;
1088 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1092 lpStatusPtr
= lpServices
;
1093 dwBufferSize
= cbBufSize
;
1098 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1101 (LPBYTE
)lpStatusPtr
,
1107 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1109 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1113 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1115 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1117 if (lpStatusPtr
->lpServiceName
)
1118 lpStatusPtr
->lpServiceName
=
1119 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1121 if (lpStatusPtr
->lpDisplayName
)
1122 lpStatusPtr
->lpDisplayName
=
1123 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1129 if (dwError
!= ERROR_SUCCESS
)
1131 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1132 SetLastError(dwError
);
1136 TRACE("EnumServicesStatusA() done\n");
1142 /**********************************************************************
1143 * EnumServicesStatusW
1148 EnumServicesStatusW(SC_HANDLE hSCManager
,
1149 DWORD dwServiceType
,
1150 DWORD dwServiceState
,
1151 LPENUM_SERVICE_STATUSW lpServices
,
1153 LPDWORD pcbBytesNeeded
,
1154 LPDWORD lpServicesReturned
,
1155 LPDWORD lpResumeHandle
)
1157 ENUM_SERVICE_STATUSW ServiceStatus
;
1158 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1163 TRACE("EnumServicesStatusW() called\n");
1167 SetLastError(ERROR_INVALID_HANDLE
);
1171 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1173 SetLastError(ERROR_INVALID_ADDRESS
);
1177 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1179 lpStatusPtr
= &ServiceStatus
;
1180 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1184 lpStatusPtr
= lpServices
;
1185 dwBufferSize
= cbBufSize
;
1190 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1193 (LPBYTE
)lpStatusPtr
,
1199 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1201 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1205 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1207 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1209 if (lpStatusPtr
->lpServiceName
)
1210 lpStatusPtr
->lpServiceName
=
1211 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1213 if (lpStatusPtr
->lpDisplayName
)
1214 lpStatusPtr
->lpDisplayName
=
1215 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1221 if (dwError
!= ERROR_SUCCESS
)
1223 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1224 SetLastError(dwError
);
1228 TRACE("EnumServicesStatusW() done\n");
1234 /**********************************************************************
1235 * EnumServicesStatusExA
1240 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1241 SC_ENUM_TYPE InfoLevel
,
1242 DWORD dwServiceType
,
1243 DWORD dwServiceState
,
1246 LPDWORD pcbBytesNeeded
,
1247 LPDWORD lpServicesReturned
,
1248 LPDWORD lpResumeHandle
,
1249 LPCSTR pszGroupName
)
1251 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1252 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1257 TRACE("EnumServicesStatusExA() called\n");
1259 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1261 SetLastError(ERROR_INVALID_LEVEL
);
1267 SetLastError(ERROR_INVALID_HANDLE
);
1271 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1273 SetLastError(ERROR_INVALID_ADDRESS
);
1277 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1279 lpStatusPtr
= &ServiceStatus
;
1280 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1284 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1285 dwBufferSize
= cbBufSize
;
1290 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1294 (LPBYTE
)lpStatusPtr
,
1299 (LPSTR
)pszGroupName
);
1301 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1303 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1307 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1309 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1311 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1313 if (lpStatusPtr
->lpServiceName
)
1314 lpStatusPtr
->lpServiceName
=
1315 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1317 if (lpStatusPtr
->lpDisplayName
)
1318 lpStatusPtr
->lpDisplayName
=
1319 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1326 if (dwError
!= ERROR_SUCCESS
)
1328 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1329 SetLastError(dwError
);
1333 TRACE("EnumServicesStatusExA() done\n");
1339 /**********************************************************************
1340 * EnumServicesStatusExW
1345 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1346 SC_ENUM_TYPE InfoLevel
,
1347 DWORD dwServiceType
,
1348 DWORD dwServiceState
,
1351 LPDWORD pcbBytesNeeded
,
1352 LPDWORD lpServicesReturned
,
1353 LPDWORD lpResumeHandle
,
1354 LPCWSTR pszGroupName
)
1356 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1357 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1362 TRACE("EnumServicesStatusExW() called\n");
1364 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1366 SetLastError(ERROR_INVALID_LEVEL
);
1372 SetLastError(ERROR_INVALID_HANDLE
);
1376 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1378 SetLastError(ERROR_INVALID_ADDRESS
);
1382 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1384 lpStatusPtr
= &ServiceStatus
;
1385 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1389 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1390 dwBufferSize
= cbBufSize
;
1395 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1399 (LPBYTE
)lpStatusPtr
,
1404 (LPWSTR
)pszGroupName
);
1406 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1408 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1412 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1414 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1416 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1418 if (lpStatusPtr
->lpServiceName
)
1419 lpStatusPtr
->lpServiceName
=
1420 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1422 if (lpStatusPtr
->lpDisplayName
)
1423 lpStatusPtr
->lpDisplayName
=
1424 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1431 if (dwError
!= ERROR_SUCCESS
)
1433 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1434 SetLastError(dwError
);
1438 TRACE("EnumServicesStatusExW() done\n");
1444 /**********************************************************************
1445 * GetServiceDisplayNameA
1450 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1451 LPCSTR lpServiceName
,
1452 LPSTR lpDisplayName
,
1453 LPDWORD lpcchBuffer
)
1457 CHAR szEmptyName
[] = "";
1459 TRACE("GetServiceDisplayNameA() called\n");
1460 TRACE("%p %s %p %p\n", hSCManager
,
1461 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1465 SetLastError(ERROR_INVALID_HANDLE
);
1469 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1471 lpNameBuffer
= szEmptyName
;
1472 *lpcchBuffer
= sizeof(CHAR
);
1476 lpNameBuffer
= lpDisplayName
;
1481 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1486 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1488 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1492 if (dwError
!= ERROR_SUCCESS
)
1494 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1495 SetLastError(dwError
);
1503 /**********************************************************************
1504 * GetServiceDisplayNameW
1509 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1510 LPCWSTR lpServiceName
,
1511 LPWSTR lpDisplayName
,
1512 LPDWORD lpcchBuffer
)
1515 LPWSTR lpNameBuffer
;
1516 WCHAR szEmptyName
[] = L
"";
1518 TRACE("GetServiceDisplayNameW() called\n");
1522 SetLastError(ERROR_INVALID_HANDLE
);
1526 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1528 lpNameBuffer
= szEmptyName
;
1529 *lpcchBuffer
= sizeof(WCHAR
);
1533 lpNameBuffer
= lpDisplayName
;
1538 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1543 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1545 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1549 if (dwError
!= ERROR_SUCCESS
)
1551 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1552 SetLastError(dwError
);
1560 /**********************************************************************
1561 * GetServiceKeyNameA
1566 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1567 LPCSTR lpDisplayName
,
1568 LPSTR lpServiceName
,
1569 LPDWORD lpcchBuffer
)
1573 CHAR szEmptyName
[] = "";
1575 TRACE("GetServiceKeyNameA() called\n");
1579 SetLastError(ERROR_INVALID_HANDLE
);
1583 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1585 lpNameBuffer
= szEmptyName
;
1586 *lpcchBuffer
= sizeof(CHAR
);
1590 lpNameBuffer
= lpServiceName
;
1595 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1600 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1602 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1606 if (dwError
!= ERROR_SUCCESS
)
1608 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1609 SetLastError(dwError
);
1617 /**********************************************************************
1618 * GetServiceKeyNameW
1623 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1624 LPCWSTR lpDisplayName
,
1625 LPWSTR lpServiceName
,
1626 LPDWORD lpcchBuffer
)
1629 LPWSTR lpNameBuffer
;
1630 WCHAR szEmptyName
[] = L
"";
1632 TRACE("GetServiceKeyNameW() called\n");
1636 SetLastError(ERROR_INVALID_HANDLE
);
1640 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1642 lpNameBuffer
= szEmptyName
;
1643 *lpcchBuffer
= sizeof(WCHAR
);
1647 lpNameBuffer
= lpServiceName
;
1652 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1657 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1659 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1663 if (dwError
!= ERROR_SUCCESS
)
1665 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1666 SetLastError(dwError
);
1674 /**********************************************************************
1675 * I_ScGetCurrentGroupStateW
1680 I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager
,
1681 LPWSTR pszGroupName
,
1682 LPDWORD pdwGroupState
)
1686 TRACE("I_ScGetCurrentGroupStateW() called\n");
1690 dwError
= RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE
)hSCManager
,
1694 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1696 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1700 if (dwError
!= ERROR_SUCCESS
)
1702 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError
);
1703 SetLastError(dwError
);
1710 /**********************************************************************
1711 * LockServiceDatabase
1716 LockServiceDatabase(SC_HANDLE hSCManager
)
1721 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1725 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1726 (SC_RPC_LOCK
*)&hLock
);
1728 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1730 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1734 if (dwError
!= ERROR_SUCCESS
)
1736 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1737 SetLastError(dwError
);
1741 TRACE("hLock = %p\n", hLock
);
1748 WaitForSCManager(VOID
)
1752 TRACE("WaitForSCManager() called\n");
1754 /* Try to open the existing event */
1755 hEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, SCM_START_EVENT
);
1758 if (GetLastError() != ERROR_FILE_NOT_FOUND
) return;
1760 /* Try to create a new event */
1761 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
1762 if (hEvent
== NULL
) return;
1765 /* Wait for 3 minutes */
1766 WaitForSingleObject(hEvent
, 180000);
1767 CloseHandle(hEvent
);
1769 TRACE("ScmWaitForSCManager() done\n");
1773 /**********************************************************************
1779 OpenSCManagerA(LPCSTR lpMachineName
,
1780 LPCSTR lpDatabaseName
,
1781 DWORD dwDesiredAccess
)
1783 SC_HANDLE hScm
= NULL
;
1786 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1787 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1793 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1794 (LPSTR
)lpDatabaseName
,
1796 (SC_RPC_HANDLE
*)&hScm
);
1798 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1800 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1804 if (dwError
!= ERROR_SUCCESS
)
1806 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1807 SetLastError(dwError
);
1811 TRACE("hScm = %p\n", hScm
);
1817 /**********************************************************************
1823 OpenSCManagerW(LPCWSTR lpMachineName
,
1824 LPCWSTR lpDatabaseName
,
1825 DWORD dwDesiredAccess
)
1827 SC_HANDLE hScm
= NULL
;
1830 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1831 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1837 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1838 (LPWSTR
)lpDatabaseName
,
1840 (SC_RPC_HANDLE
*)&hScm
);
1842 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1844 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1848 if (dwError
!= ERROR_SUCCESS
)
1850 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1851 SetLastError(dwError
);
1855 TRACE("hScm = %p\n", hScm
);
1861 /**********************************************************************
1867 OpenServiceA(SC_HANDLE hSCManager
,
1868 LPCSTR lpServiceName
,
1869 DWORD dwDesiredAccess
)
1871 SC_HANDLE hService
= NULL
;
1874 TRACE("OpenServiceA(%p, %s, %lx)\n",
1875 hSCManager
, lpServiceName
, dwDesiredAccess
);
1879 SetLastError(ERROR_INVALID_HANDLE
);
1885 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1886 (LPSTR
)lpServiceName
,
1888 (SC_RPC_HANDLE
*)&hService
);
1890 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1892 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1896 SetLastError(dwError
);
1897 if (dwError
!= ERROR_SUCCESS
)
1899 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1903 TRACE("hService = %p\n", hService
);
1909 /**********************************************************************
1915 OpenServiceW(SC_HANDLE hSCManager
,
1916 LPCWSTR lpServiceName
,
1917 DWORD dwDesiredAccess
)
1919 SC_HANDLE hService
= NULL
;
1922 TRACE("OpenServiceW(%p, %S, %lx)\n",
1923 hSCManager
, lpServiceName
, dwDesiredAccess
);
1927 SetLastError(ERROR_INVALID_HANDLE
);
1933 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1934 (LPWSTR
)lpServiceName
,
1936 (SC_RPC_HANDLE
*)&hService
);
1938 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1940 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1944 SetLastError(dwError
);
1945 if (dwError
!= ERROR_SUCCESS
)
1947 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1951 TRACE("hService = %p\n", hService
);
1957 /**********************************************************************
1958 * QueryServiceConfigA
1963 QueryServiceConfigA(SC_HANDLE hService
,
1964 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1966 LPDWORD pcbBytesNeeded
)
1968 QUERY_SERVICE_CONFIGA ServiceConfig
;
1969 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1973 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1974 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1976 if (lpServiceConfig
== NULL
||
1977 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1979 lpConfigPtr
= &ServiceConfig
;
1980 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1984 lpConfigPtr
= lpServiceConfig
;
1985 dwBufferSize
= cbBufSize
;
1990 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1991 (LPBYTE
)lpConfigPtr
,
1995 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1997 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2001 if (dwError
!= ERROR_SUCCESS
)
2003 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
2004 SetLastError(dwError
);
2008 /* Adjust the pointers */
2009 if (lpConfigPtr
->lpBinaryPathName
)
2010 lpConfigPtr
->lpBinaryPathName
=
2011 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2012 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2014 if (lpConfigPtr
->lpLoadOrderGroup
)
2015 lpConfigPtr
->lpLoadOrderGroup
=
2016 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2017 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2019 if (lpConfigPtr
->lpDependencies
)
2020 lpConfigPtr
->lpDependencies
=
2021 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2022 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2024 if (lpConfigPtr
->lpServiceStartName
)
2025 lpConfigPtr
->lpServiceStartName
=
2026 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2027 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2029 if (lpConfigPtr
->lpDisplayName
)
2030 lpConfigPtr
->lpDisplayName
=
2031 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2032 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2034 TRACE("QueryServiceConfigA() done\n");
2040 /**********************************************************************
2041 * QueryServiceConfigW
2046 QueryServiceConfigW(SC_HANDLE hService
,
2047 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
2049 LPDWORD pcbBytesNeeded
)
2051 QUERY_SERVICE_CONFIGW ServiceConfig
;
2052 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
2056 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
2057 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2059 if (lpServiceConfig
== NULL
||
2060 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2062 lpConfigPtr
= &ServiceConfig
;
2063 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2067 lpConfigPtr
= lpServiceConfig
;
2068 dwBufferSize
= cbBufSize
;
2073 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2074 (LPBYTE
)lpConfigPtr
,
2078 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2080 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2084 if (dwError
!= ERROR_SUCCESS
)
2086 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2087 SetLastError(dwError
);
2091 /* Adjust the pointers */
2092 if (lpConfigPtr
->lpBinaryPathName
)
2093 lpConfigPtr
->lpBinaryPathName
=
2094 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2095 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2097 if (lpConfigPtr
->lpLoadOrderGroup
)
2098 lpConfigPtr
->lpLoadOrderGroup
=
2099 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2100 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2102 if (lpConfigPtr
->lpDependencies
)
2103 lpConfigPtr
->lpDependencies
=
2104 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2105 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2107 if (lpConfigPtr
->lpServiceStartName
)
2108 lpConfigPtr
->lpServiceStartName
=
2109 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2110 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2112 if (lpConfigPtr
->lpDisplayName
)
2113 lpConfigPtr
->lpDisplayName
=
2114 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2115 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2117 TRACE("QueryServiceConfigW() done\n");
2123 /**********************************************************************
2124 * QueryServiceConfig2A
2129 QueryServiceConfig2A(SC_HANDLE hService
,
2133 LPDWORD pcbBytesNeeded
)
2135 SERVICE_DESCRIPTIONA ServiceDescription
;
2136 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2137 LPBYTE lpTempBuffer
;
2138 BOOL bUseTempBuffer
= FALSE
;
2142 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2143 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2145 lpTempBuffer
= lpBuffer
;
2146 dwBufferSize
= cbBufSize
;
2148 switch (dwInfoLevel
)
2150 case SERVICE_CONFIG_DESCRIPTION
:
2151 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2153 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2154 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2155 bUseTempBuffer
= TRUE
;
2159 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2160 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2162 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2163 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2164 bUseTempBuffer
= TRUE
;
2169 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2170 SetLastError(ERROR_INVALID_LEVEL
);
2176 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2182 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2184 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2188 if (dwError
!= ERROR_SUCCESS
)
2190 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2191 SetLastError(dwError
);
2195 if (bUseTempBuffer
!= FALSE
)
2197 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2198 *pcbBytesNeeded
= dwBufferSize
;
2199 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2203 switch (dwInfoLevel
)
2205 case SERVICE_CONFIG_DESCRIPTION
:
2207 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2209 if (lpPtr
->lpDescription
!= NULL
)
2210 lpPtr
->lpDescription
=
2211 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2215 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2217 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2219 if (lpPtr
->lpRebootMsg
!= NULL
)
2220 lpPtr
->lpRebootMsg
=
2221 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2223 if (lpPtr
->lpCommand
!= NULL
)
2225 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2227 if (lpPtr
->lpsaActions
!= NULL
)
2228 lpPtr
->lpsaActions
=
2229 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2234 TRACE("QueryServiceConfig2A() done\n");
2240 /**********************************************************************
2241 * QueryServiceConfig2W
2246 QueryServiceConfig2W(SC_HANDLE hService
,
2250 LPDWORD pcbBytesNeeded
)
2252 SERVICE_DESCRIPTIONW ServiceDescription
;
2253 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2254 LPBYTE lpTempBuffer
;
2255 BOOL bUseTempBuffer
= FALSE
;
2259 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2260 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2262 lpTempBuffer
= lpBuffer
;
2263 dwBufferSize
= cbBufSize
;
2265 switch (dwInfoLevel
)
2267 case SERVICE_CONFIG_DESCRIPTION
:
2268 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2270 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2271 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2272 bUseTempBuffer
= TRUE
;
2276 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2277 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2279 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2280 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2281 bUseTempBuffer
= TRUE
;
2286 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2287 SetLastError(ERROR_INVALID_LEVEL
);
2293 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2299 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2301 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2305 if (dwError
!= ERROR_SUCCESS
)
2307 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2308 SetLastError(dwError
);
2312 if (bUseTempBuffer
!= FALSE
)
2314 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2315 *pcbBytesNeeded
= dwBufferSize
;
2316 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2320 switch (dwInfoLevel
)
2322 case SERVICE_CONFIG_DESCRIPTION
:
2324 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2326 if (lpPtr
->lpDescription
!= NULL
)
2327 lpPtr
->lpDescription
=
2328 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2332 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2334 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2336 if (lpPtr
->lpRebootMsg
!= NULL
)
2337 lpPtr
->lpRebootMsg
=
2338 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2340 if (lpPtr
->lpCommand
!= NULL
)
2342 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2344 if (lpPtr
->lpsaActions
!= NULL
)
2345 lpPtr
->lpsaActions
=
2346 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2351 TRACE("QueryServiceConfig2W() done\n");
2357 /**********************************************************************
2358 * QueryServiceLockStatusA
2363 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2364 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2366 LPDWORD pcbBytesNeeded
)
2368 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2369 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2373 TRACE("QueryServiceLockStatusA() called\n");
2375 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2377 lpStatusPtr
= &LockStatus
;
2378 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2382 lpStatusPtr
= lpLockStatus
;
2383 dwBufferSize
= cbBufSize
;
2388 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2389 (LPBYTE
)lpStatusPtr
,
2393 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2395 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2399 if (dwError
!= ERROR_SUCCESS
)
2401 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2402 SetLastError(dwError
);
2406 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2408 lpStatusPtr
->lpLockOwner
=
2409 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2412 TRACE("QueryServiceLockStatusA() done\n");
2418 /**********************************************************************
2419 * QueryServiceLockStatusW
2424 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2425 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2427 LPDWORD pcbBytesNeeded
)
2429 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2430 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2434 TRACE("QueryServiceLockStatusW() called\n");
2436 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2438 lpStatusPtr
= &LockStatus
;
2439 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2443 lpStatusPtr
= lpLockStatus
;
2444 dwBufferSize
= cbBufSize
;
2449 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2450 (LPBYTE
)lpStatusPtr
,
2454 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2456 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2460 if (dwError
!= ERROR_SUCCESS
)
2462 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2463 SetLastError(dwError
);
2467 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2469 lpStatusPtr
->lpLockOwner
=
2470 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2473 TRACE("QueryServiceLockStatusW() done\n");
2479 /**********************************************************************
2480 * QueryServiceObjectSecurity
2485 QueryServiceObjectSecurity(SC_HANDLE hService
,
2486 SECURITY_INFORMATION dwSecurityInformation
,
2487 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2489 LPDWORD pcbBytesNeeded
)
2493 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2494 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2498 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2499 dwSecurityInformation
,
2500 (LPBYTE
)lpSecurityDescriptor
,
2504 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2506 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2510 if (dwError
!= ERROR_SUCCESS
)
2512 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2513 SetLastError(dwError
);
2520 /**********************************************************************
2521 * SetServiceObjectSecurity
2526 SetServiceObjectSecurity(SC_HANDLE hService
,
2527 SECURITY_INFORMATION dwSecurityInformation
,
2528 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2530 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2536 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2539 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2541 SetLastError(ERROR_INVALID_PARAMETER
);
2545 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2546 if (SelfRelativeSD
== NULL
)
2548 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2552 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2555 if (!NT_SUCCESS(Status
))
2557 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2558 SetLastError(RtlNtStatusToDosError(Status
));
2564 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2565 dwSecurityInformation
,
2566 (LPBYTE
)SelfRelativeSD
,
2569 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2571 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2575 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2577 if (dwError
!= ERROR_SUCCESS
)
2579 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2580 SetLastError(dwError
);
2588 /**********************************************************************
2589 * QueryServiceStatus
2594 QueryServiceStatus(SC_HANDLE hService
,
2595 LPSERVICE_STATUS lpServiceStatus
)
2599 TRACE("QueryServiceStatus(%p, %p)\n",
2600 hService
, lpServiceStatus
);
2604 SetLastError(ERROR_INVALID_HANDLE
);
2610 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2613 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2615 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2619 if (dwError
!= ERROR_SUCCESS
)
2621 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2622 SetLastError(dwError
);
2630 /**********************************************************************
2631 * QueryServiceStatusEx
2636 QueryServiceStatusEx(SC_HANDLE hService
,
2637 SC_STATUS_TYPE InfoLevel
,
2640 LPDWORD pcbBytesNeeded
)
2644 TRACE("QueryServiceStatusEx() called\n");
2646 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2648 SetLastError(ERROR_INVALID_LEVEL
);
2652 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2654 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2655 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2661 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2667 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2669 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2673 if (dwError
!= ERROR_SUCCESS
)
2675 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2676 SetLastError(dwError
);
2684 /**********************************************************************
2690 StartServiceA(SC_HANDLE hService
,
2691 DWORD dwNumServiceArgs
,
2692 LPCSTR
*lpServiceArgVectors
)
2698 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2700 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2702 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2704 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2708 if (dwError
!= ERROR_SUCCESS
)
2710 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2711 SetLastError(dwError
);
2719 /**********************************************************************
2725 StartServiceW(SC_HANDLE hService
,
2726 DWORD dwNumServiceArgs
,
2727 LPCWSTR
*lpServiceArgVectors
)
2733 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2735 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2737 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2739 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2743 if (dwError
!= ERROR_SUCCESS
)
2745 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2746 SetLastError(dwError
);
2754 /**********************************************************************
2755 * UnlockServiceDatabase
2760 UnlockServiceDatabase(SC_LOCK ScLock
)
2764 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2768 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2770 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2772 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2776 if (dwError
== ERROR_INVALID_HANDLE
)
2777 dwError
= ERROR_INVALID_SERVICE_LOCK
;
2779 if (dwError
!= ERROR_SUCCESS
)
2781 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2782 SetLastError(dwError
);
2790 /**********************************************************************
2791 * NotifyBootConfigStatus
2796 NotifyBootConfigStatus(BOOL BootAcceptable
)
2800 TRACE("NotifyBootConfigStatus()\n");
2804 dwError
= RNotifyBootConfigStatus(NULL
,
2807 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2809 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2813 if (dwError
!= ERROR_SUCCESS
)
2815 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2816 SetLastError(dwError
);