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
11 /* INCLUDES ******************************************************************/
14 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
19 const struct ustring
*in
,
20 const struct ustring
*key
,
26 IN PVOID ContextHandle
,
27 OUT LPBYTE SessionKey
);
29 /* FUNCTIONS *****************************************************************/
32 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName
)
34 handle_t hBinding
= NULL
;
35 RPC_CSTR pszStringBinding
;
38 TRACE("SVCCTL_HANDLEA_bind(%s)\n",
39 debugstr_a(szMachineName
));
41 status
= RpcStringBindingComposeA(NULL
,
43 (RPC_CSTR
)szMachineName
,
44 (RPC_CSTR
)"\\pipe\\ntsvcs",
47 if (status
!= RPC_S_OK
)
49 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
53 /* Set the binding handle that will be used to bind to the server. */
54 status
= RpcBindingFromStringBindingA(pszStringBinding
,
56 if (status
!= RPC_S_OK
)
58 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
61 status
= RpcStringFreeA(&pszStringBinding
);
62 if (status
!= RPC_S_OK
)
64 ERR("RpcStringFree returned 0x%x\n", status
);
72 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName
,
77 TRACE("SVCCTL_HANDLEA_unbind(%s %p)\n",
78 debugstr_a(szMachineName
), hBinding
);
80 status
= RpcBindingFree(&hBinding
);
81 if (status
!= RPC_S_OK
)
83 ERR("RpcBindingFree returned 0x%x\n", status
);
89 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName
)
91 handle_t hBinding
= NULL
;
92 RPC_WSTR pszStringBinding
;
95 TRACE("SVCCTL_HANDLEW_bind(%s)\n",
96 debugstr_w(szMachineName
));
98 status
= RpcStringBindingComposeW(NULL
,
104 if (status
!= RPC_S_OK
)
106 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
110 /* Set the binding handle that will be used to bind to the server. */
111 status
= RpcBindingFromStringBindingW(pszStringBinding
,
113 if (status
!= RPC_S_OK
)
115 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
118 status
= RpcStringFreeW(&pszStringBinding
);
119 if (status
!= RPC_S_OK
)
121 ERR("RpcStringFree returned 0x%x\n", status
);
129 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName
,
134 TRACE("SVCCTL_HANDLEW_unbind(%s %p)\n",
135 debugstr_w(szMachineName
), hBinding
);
137 status
= RpcBindingFree(&hBinding
);
138 if (status
!= RPC_S_OK
)
140 ERR("RpcBindingFree returned 0x%x\n", status
);
146 ScmRpcStatusToWinError(RPC_STATUS Status
)
148 TRACE("ScmRpcStatusToWinError(%lx)\n",
153 case STATUS_ACCESS_VIOLATION
:
154 case RPC_S_INVALID_BINDING
:
155 case RPC_X_SS_IN_NULL_CONTEXT
:
156 return ERROR_INVALID_HANDLE
;
158 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
159 case RPC_X_BYTE_COUNT_TOO_SMALL
:
160 return ERROR_INVALID_PARAMETER
;
162 case RPC_X_NULL_REF_POINTER
:
163 return ERROR_INVALID_ADDRESS
;
166 return (DWORD
)Status
;
174 _In_ PVOID ContextHandle
,
175 _In_ PCWSTR pClearTextPassword
,
176 _Out_ PBYTE
*pEncryptedPassword
,
177 _Out_ PDWORD pEncryptedPasswordSize
)
179 struct ustring inData
, keyData
, outData
;
184 /* Get the session key */
185 Status
= SystemFunction028(ContextHandle
,
187 if (!NT_SUCCESS(Status
))
189 ERR("SystemFunction028 failed (Status 0x%08lx)\n", Status
);
190 return RtlNtStatusToDosError(Status
);
193 inData
.Length
= (wcslen(pClearTextPassword
) + 1) * sizeof(WCHAR
);
194 inData
.MaximumLength
= inData
.Length
;
195 inData
.Buffer
= (unsigned char *)pClearTextPassword
;
197 keyData
.Length
= sizeof(SessionKey
);
198 keyData
.MaximumLength
= keyData
.Length
;
199 keyData
.Buffer
= SessionKey
;
202 outData
.MaximumLength
= 0;
203 outData
.Buffer
= NULL
;
205 /* Get the required buffer size */
206 Status
= SystemFunction004(&inData
,
209 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
211 ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status
);
212 return RtlNtStatusToDosError(Status
);
215 /* Allocate a buffer for the encrypted password */
216 pBuffer
= HeapAlloc(GetProcessHeap(), 0, outData
.Length
);
218 return ERROR_OUTOFMEMORY
;
220 outData
.MaximumLength
= outData
.Length
;
221 outData
.Buffer
= pBuffer
;
223 /* Encrypt the password */
224 Status
= SystemFunction004(&inData
,
227 if (!NT_SUCCESS(Status
))
229 ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status
);
230 HeapFree(GetProcessHeap(), 0, pBuffer
);
231 return RtlNtStatusToDosError(Status
);
234 *pEncryptedPassword
= outData
.Buffer
;
235 *pEncryptedPasswordSize
= outData
.Length
;
237 return ERROR_SUCCESS
;
241 /**********************************************************************
242 * ChangeServiceConfig2A
247 ChangeServiceConfig2A(SC_HANDLE hService
,
251 SC_RPC_CONFIG_INFOA Info
;
254 TRACE("ChangeServiceConfig2A(%p %lu %p)\n",
255 hService
, dwInfoLevel
, lpInfo
);
257 if (lpInfo
== NULL
) return TRUE
;
259 /* Fill relevant field of the Info structure */
260 Info
.dwInfoLevel
= dwInfoLevel
;
263 case SERVICE_CONFIG_DESCRIPTION
:
267 case SERVICE_CONFIG_FAILURE_ACTIONS
:
272 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
273 SetLastError(ERROR_INVALID_PARAMETER
);
279 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
282 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
284 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
288 if (dwError
!= ERROR_SUCCESS
)
290 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
291 SetLastError(dwError
);
299 /**********************************************************************
300 * ChangeServiceConfig2W
305 ChangeServiceConfig2W(SC_HANDLE hService
,
309 SC_RPC_CONFIG_INFOW Info
;
312 TRACE("ChangeServiceConfig2W(%p %lu %p)\n",
313 hService
, dwInfoLevel
, lpInfo
);
315 if (lpInfo
== NULL
) return TRUE
;
317 /* Fill relevant field of the Info structure */
318 Info
.dwInfoLevel
= dwInfoLevel
;
321 case SERVICE_CONFIG_DESCRIPTION
:
325 case SERVICE_CONFIG_FAILURE_ACTIONS
:
330 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
331 SetLastError(ERROR_INVALID_PARAMETER
);
337 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
340 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
342 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
346 if (dwError
!= ERROR_SUCCESS
)
348 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
349 SetLastError(dwError
);
357 /**********************************************************************
358 * ChangeServiceConfigA
363 ChangeServiceConfigA(SC_HANDLE hService
,
366 DWORD dwErrorControl
,
367 LPCSTR lpBinaryPathName
,
368 LPCSTR lpLoadOrderGroup
,
370 LPCSTR lpDependencies
,
371 LPCSTR lpServiceStartName
,
373 LPCSTR lpDisplayName
)
376 DWORD dwDependenciesLength
= 0;
379 DWORD dwPasswordSize
= 0;
380 LPWSTR lpPasswordW
= NULL
;
381 LPBYTE lpEncryptedPassword
= NULL
;
383 TRACE("ChangeServiceConfigA(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
384 hService
, dwServiceType
, dwStartType
, dwErrorControl
, debugstr_a(lpBinaryPathName
),
385 debugstr_a(lpLoadOrderGroup
), lpdwTagId
, debugstr_a(lpDependencies
),
386 debugstr_a(lpServiceStartName
), debugstr_a(lpPassword
), debugstr_a(lpDisplayName
));
388 /* Calculate the Dependencies length*/
389 if (lpDependencies
!= NULL
)
391 lpStr
= lpDependencies
;
394 cchLength
= strlen(lpStr
) + 1;
395 dwDependenciesLength
+= (DWORD
)cchLength
;
396 lpStr
= lpStr
+ cchLength
;
398 dwDependenciesLength
++;
401 if (lpPassword
!= NULL
)
403 /* Convert the password to unicode */
404 lpPasswordW
= HeapAlloc(GetProcessHeap(),
406 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
407 if (lpPasswordW
== NULL
)
409 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
413 MultiByteToWideChar(CP_ACP
,
418 (int)(strlen(lpPassword
) + 1));
420 /* Encrypt the unicode password */
421 dwError
= ScmEncryptPassword(hService
,
423 &lpEncryptedPassword
,
425 if (dwError
!= ERROR_SUCCESS
)
431 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
435 (LPSTR
)lpBinaryPathName
,
436 (LPSTR
)lpLoadOrderGroup
,
438 (LPBYTE
)lpDependencies
,
439 dwDependenciesLength
,
440 (LPSTR
)lpServiceStartName
,
443 (LPSTR
)lpDisplayName
);
445 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
447 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
452 if (lpPasswordW
!= NULL
)
454 /* Wipe and release the password buffers */
455 SecureZeroMemory(lpPasswordW
, (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
));
456 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
458 if (lpEncryptedPassword
!= NULL
)
460 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
461 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
465 if (dwError
!= ERROR_SUCCESS
)
467 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
468 SetLastError(dwError
);
476 /**********************************************************************
477 * ChangeServiceConfigW
482 ChangeServiceConfigW(SC_HANDLE hService
,
485 DWORD dwErrorControl
,
486 LPCWSTR lpBinaryPathName
,
487 LPCWSTR lpLoadOrderGroup
,
489 LPCWSTR lpDependencies
,
490 LPCWSTR lpServiceStartName
,
492 LPCWSTR lpDisplayName
)
495 DWORD dwDependenciesLength
= 0;
498 DWORD dwPasswordSize
= 0;
499 LPBYTE lpEncryptedPassword
= NULL
;
501 TRACE("ChangeServiceConfigW(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
502 hService
, dwServiceType
, dwStartType
, dwErrorControl
, debugstr_w(lpBinaryPathName
),
503 debugstr_w(lpLoadOrderGroup
), lpdwTagId
, debugstr_w(lpDependencies
),
504 debugstr_w(lpServiceStartName
), debugstr_w(lpPassword
), debugstr_w(lpDisplayName
));
506 /* Calculate the Dependencies length*/
507 if (lpDependencies
!= NULL
)
509 lpStr
= lpDependencies
;
512 cchLength
= wcslen(lpStr
) + 1;
513 dwDependenciesLength
+= (DWORD
)cchLength
;
514 lpStr
= lpStr
+ cchLength
;
516 dwDependenciesLength
++;
517 dwDependenciesLength
*= sizeof(WCHAR
);
520 if (lpPassword
!= NULL
)
522 dwError
= ScmEncryptPassword(hService
,
524 &lpEncryptedPassword
,
526 if (dwError
!= ERROR_SUCCESS
)
528 ERR("ScmEncryptPassword failed (Error %lu)\n", dwError
);
535 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
539 (LPWSTR
)lpBinaryPathName
,
540 (LPWSTR
)lpLoadOrderGroup
,
542 (LPBYTE
)lpDependencies
,
543 dwDependenciesLength
,
544 (LPWSTR
)lpServiceStartName
,
547 (LPWSTR
)lpDisplayName
);
549 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
551 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
556 if (lpEncryptedPassword
!= NULL
)
558 /* Wipe and release the password buffer */
559 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
560 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
563 if (dwError
!= ERROR_SUCCESS
)
565 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
566 SetLastError(dwError
);
574 /**********************************************************************
580 CloseServiceHandle(SC_HANDLE hSCObject
)
584 TRACE("CloseServiceHandle(%p)\n",
589 SetLastError(ERROR_INVALID_HANDLE
);
595 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
597 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
599 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
605 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
606 SetLastError(dwError
);
610 TRACE("CloseServiceHandle() done\n");
616 /**********************************************************************
622 ControlService(SC_HANDLE hService
,
624 LPSERVICE_STATUS lpServiceStatus
)
628 TRACE("ControlService(%p %lu %p)\n",
629 hService
, dwControl
, lpServiceStatus
);
633 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
637 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
639 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
643 if (dwError
!= ERROR_SUCCESS
)
645 TRACE("RControlService() failed (Error %lu)\n", dwError
);
646 SetLastError(dwError
);
650 TRACE("ControlService() done\n");
656 /**********************************************************************
662 ControlServiceEx(IN SC_HANDLE hService
,
664 IN DWORD dwInfoLevel
,
665 IN OUT PVOID pControlParams
)
667 FIXME("ControlServiceEx(%p %lu %lu %p)\n",
668 hService
, dwControl
, dwInfoLevel
, pControlParams
);
669 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
674 /**********************************************************************
680 CreateServiceA(SC_HANDLE hSCManager
,
681 LPCSTR lpServiceName
,
682 LPCSTR lpDisplayName
,
683 DWORD dwDesiredAccess
,
686 DWORD dwErrorControl
,
687 LPCSTR lpBinaryPathName
,
688 LPCSTR lpLoadOrderGroup
,
690 LPCSTR lpDependencies
,
691 LPCSTR lpServiceStartName
,
694 SC_HANDLE hService
= NULL
;
695 DWORD dwDependenciesLength
= 0;
699 DWORD dwPasswordSize
= 0;
700 LPWSTR lpPasswordW
= NULL
;
701 LPBYTE lpEncryptedPassword
= NULL
;
703 TRACE("CreateServiceA(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
704 hSCManager
, debugstr_a(lpServiceName
), debugstr_a(lpDisplayName
),
705 dwDesiredAccess
, dwServiceType
, dwStartType
, dwErrorControl
,
706 debugstr_a(lpBinaryPathName
), debugstr_a(lpLoadOrderGroup
), lpdwTagId
,
707 debugstr_a(lpDependencies
), debugstr_a(lpServiceStartName
), debugstr_a(lpPassword
));
711 SetLastError(ERROR_INVALID_HANDLE
);
715 /* Calculate the Dependencies length */
716 if (lpDependencies
!= NULL
)
718 lpStr
= lpDependencies
;
721 cchLength
= strlen(lpStr
) + 1;
722 dwDependenciesLength
+= (DWORD
)cchLength
;
723 lpStr
= lpStr
+ cchLength
;
725 dwDependenciesLength
++;
728 if (lpPassword
!= NULL
)
730 /* Convert the password to unicode */
731 lpPasswordW
= HeapAlloc(GetProcessHeap(),
733 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
734 if (lpPasswordW
== NULL
)
736 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
740 MultiByteToWideChar(CP_ACP
,
745 (int)(strlen(lpPassword
) + 1));
747 /* Encrypt the password */
748 dwError
= ScmEncryptPassword(hSCManager
,
750 &lpEncryptedPassword
,
752 if (dwError
!= ERROR_SUCCESS
)
758 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
759 (LPSTR
)lpServiceName
,
760 (LPSTR
)lpDisplayName
,
765 (LPSTR
)lpBinaryPathName
,
766 (LPSTR
)lpLoadOrderGroup
,
768 (LPBYTE
)lpDependencies
,
769 dwDependenciesLength
,
770 (LPSTR
)lpServiceStartName
,
773 (SC_RPC_HANDLE
*)&hService
);
775 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
777 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
782 if (lpPasswordW
!= NULL
)
784 /* Wipe and release the password buffers */
785 SecureZeroMemory(lpPasswordW
, (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
));
786 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
788 if (lpEncryptedPassword
!= NULL
)
790 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
791 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
795 SetLastError(dwError
);
796 if (dwError
!= ERROR_SUCCESS
)
798 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
806 /**********************************************************************
812 CreateServiceW(SC_HANDLE hSCManager
,
813 LPCWSTR lpServiceName
,
814 LPCWSTR lpDisplayName
,
815 DWORD dwDesiredAccess
,
818 DWORD dwErrorControl
,
819 LPCWSTR lpBinaryPathName
,
820 LPCWSTR lpLoadOrderGroup
,
822 LPCWSTR lpDependencies
,
823 LPCWSTR lpServiceStartName
,
826 SC_HANDLE hService
= NULL
;
827 DWORD dwDependenciesLength
= 0;
831 DWORD dwPasswordSize
= 0;
832 LPBYTE lpEncryptedPassword
= NULL
;
834 TRACE("CreateServiceW(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
835 hSCManager
, debugstr_w(lpServiceName
), debugstr_w(lpDisplayName
),
836 dwDesiredAccess
, dwServiceType
, dwStartType
, dwErrorControl
,
837 debugstr_w(lpBinaryPathName
), debugstr_w(lpLoadOrderGroup
), lpdwTagId
,
838 debugstr_w(lpDependencies
), debugstr_w(lpServiceStartName
), debugstr_w(lpPassword
));
842 SetLastError(ERROR_INVALID_HANDLE
);
846 /* Calculate the Dependencies length */
847 if (lpDependencies
!= NULL
)
849 lpStr
= lpDependencies
;
852 cchLength
= wcslen(lpStr
) + 1;
853 dwDependenciesLength
+= (DWORD
)cchLength
;
854 lpStr
= lpStr
+ cchLength
;
856 dwDependenciesLength
++;
857 dwDependenciesLength
*= sizeof(WCHAR
);
860 if (lpPassword
!= NULL
)
862 /* Encrypt the password */
863 dwError
= ScmEncryptPassword(hSCManager
,
865 &lpEncryptedPassword
,
867 if (dwError
!= ERROR_SUCCESS
)
873 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
883 (LPBYTE
)lpDependencies
,
884 dwDependenciesLength
,
888 (SC_RPC_HANDLE
*)&hService
);
890 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
892 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
897 if (lpEncryptedPassword
!= NULL
)
899 /* Wipe and release the password buffers */
900 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
901 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
904 SetLastError(dwError
);
905 if (dwError
!= ERROR_SUCCESS
)
907 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
915 /**********************************************************************
921 DeleteService(SC_HANDLE hService
)
925 TRACE("DeleteService(%p)\n",
930 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
932 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
934 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
938 if (dwError
!= ERROR_SUCCESS
)
940 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
941 SetLastError(dwError
);
949 /**********************************************************************
950 * EnumDependentServicesA
955 EnumDependentServicesA(SC_HANDLE hService
,
956 DWORD dwServiceState
,
957 LPENUM_SERVICE_STATUSA lpServices
,
959 LPDWORD pcbBytesNeeded
,
960 LPDWORD lpServicesReturned
)
962 ENUM_SERVICE_STATUSA ServiceStatus
;
963 LPENUM_SERVICE_STATUSA lpStatusPtr
;
968 TRACE("EnumDependentServicesA(%p %lu %p %lu %p %p)\n",
969 hService
, dwServiceState
, lpServices
, cbBufSize
,
970 pcbBytesNeeded
, lpServicesReturned
);
972 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
974 lpStatusPtr
= &ServiceStatus
;
975 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
979 lpStatusPtr
= lpServices
;
980 dwBufferSize
= cbBufSize
;
985 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
992 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
994 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
998 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1000 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1002 if (lpStatusPtr
->lpServiceName
)
1003 lpStatusPtr
->lpServiceName
=
1004 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1006 if (lpStatusPtr
->lpDisplayName
)
1007 lpStatusPtr
->lpDisplayName
=
1008 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1014 if (dwError
!= ERROR_SUCCESS
)
1016 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
1017 SetLastError(dwError
);
1021 TRACE("EnumDependentServicesA() done\n");
1027 /**********************************************************************
1028 * EnumDependentServicesW
1033 EnumDependentServicesW(SC_HANDLE hService
,
1034 DWORD dwServiceState
,
1035 LPENUM_SERVICE_STATUSW lpServices
,
1037 LPDWORD pcbBytesNeeded
,
1038 LPDWORD lpServicesReturned
)
1040 ENUM_SERVICE_STATUSW ServiceStatus
;
1041 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1046 TRACE("EnumDependentServicesW(%p %lu %p %lu %p %p)\n",
1047 hService
, dwServiceState
, lpServices
, cbBufSize
,
1048 pcbBytesNeeded
, lpServicesReturned
);
1050 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1052 lpStatusPtr
= &ServiceStatus
;
1053 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1057 lpStatusPtr
= lpServices
;
1058 dwBufferSize
= cbBufSize
;
1063 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
1065 (LPBYTE
)lpStatusPtr
,
1068 lpServicesReturned
);
1070 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1072 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1076 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1078 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1080 if (lpStatusPtr
->lpServiceName
)
1081 lpStatusPtr
->lpServiceName
=
1082 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1084 if (lpStatusPtr
->lpDisplayName
)
1085 lpStatusPtr
->lpDisplayName
=
1086 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1092 if (dwError
!= ERROR_SUCCESS
)
1094 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
1095 SetLastError(dwError
);
1099 TRACE("EnumDependentServicesW() done\n");
1105 /**********************************************************************
1111 EnumServiceGroupW(SC_HANDLE hSCManager
,
1112 DWORD dwServiceType
,
1113 DWORD dwServiceState
,
1114 LPENUM_SERVICE_STATUSW lpServices
,
1116 LPDWORD pcbBytesNeeded
,
1117 LPDWORD lpServicesReturned
,
1118 LPDWORD lpResumeHandle
,
1121 ENUM_SERVICE_STATUSW ServiceStatus
;
1122 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1127 TRACE("EnumServiceGroupW(%p %lu %lu %p %lu %p %p %p %s)\n",
1128 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1129 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
,
1130 lpResumeHandle
, debugstr_w(lpGroup
));
1134 SetLastError(ERROR_INVALID_HANDLE
);
1138 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1140 SetLastError(ERROR_INVALID_ADDRESS
);
1144 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1146 lpStatusPtr
= &ServiceStatus
;
1147 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1151 lpStatusPtr
= lpServices
;
1152 dwBufferSize
= cbBufSize
;
1157 if (lpGroup
== NULL
)
1159 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1162 (LPBYTE
)lpStatusPtr
,
1170 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
1173 (LPBYTE
)lpStatusPtr
,
1181 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1183 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1187 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1189 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1191 if (lpStatusPtr
->lpServiceName
)
1192 lpStatusPtr
->lpServiceName
=
1193 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1195 if (lpStatusPtr
->lpDisplayName
)
1196 lpStatusPtr
->lpDisplayName
=
1197 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1203 if (dwError
!= ERROR_SUCCESS
)
1205 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
1206 SetLastError(dwError
);
1210 TRACE("EnumServiceGroupW() done\n");
1216 /**********************************************************************
1217 * EnumServicesStatusA
1222 EnumServicesStatusA(SC_HANDLE hSCManager
,
1223 DWORD dwServiceType
,
1224 DWORD dwServiceState
,
1225 LPENUM_SERVICE_STATUSA lpServices
,
1227 LPDWORD pcbBytesNeeded
,
1228 LPDWORD lpServicesReturned
,
1229 LPDWORD lpResumeHandle
)
1231 ENUM_SERVICE_STATUSA ServiceStatus
;
1232 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1237 TRACE("EnumServicesStatusA(%p %lu %lu %p %lu %p %p %p)\n",
1238 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1239 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
);
1243 SetLastError(ERROR_INVALID_HANDLE
);
1247 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1249 SetLastError(ERROR_INVALID_ADDRESS
);
1253 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1255 lpStatusPtr
= &ServiceStatus
;
1256 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1260 lpStatusPtr
= lpServices
;
1261 dwBufferSize
= cbBufSize
;
1266 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1269 (LPBYTE
)lpStatusPtr
,
1275 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1277 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1281 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1283 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1285 if (lpStatusPtr
->lpServiceName
)
1286 lpStatusPtr
->lpServiceName
=
1287 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1289 if (lpStatusPtr
->lpDisplayName
)
1290 lpStatusPtr
->lpDisplayName
=
1291 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1297 if (dwError
!= ERROR_SUCCESS
)
1299 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1300 SetLastError(dwError
);
1304 TRACE("EnumServicesStatusA() done\n");
1310 /**********************************************************************
1311 * EnumServicesStatusW
1316 EnumServicesStatusW(SC_HANDLE hSCManager
,
1317 DWORD dwServiceType
,
1318 DWORD dwServiceState
,
1319 LPENUM_SERVICE_STATUSW lpServices
,
1321 LPDWORD pcbBytesNeeded
,
1322 LPDWORD lpServicesReturned
,
1323 LPDWORD lpResumeHandle
)
1325 ENUM_SERVICE_STATUSW ServiceStatus
;
1326 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1331 TRACE("EnumServicesStatusW(%p %lu %lu %p %lu %p %p %p)\n",
1332 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1333 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
);
1337 SetLastError(ERROR_INVALID_HANDLE
);
1341 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1343 SetLastError(ERROR_INVALID_ADDRESS
);
1347 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1349 lpStatusPtr
= &ServiceStatus
;
1350 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1354 lpStatusPtr
= lpServices
;
1355 dwBufferSize
= cbBufSize
;
1360 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1363 (LPBYTE
)lpStatusPtr
,
1369 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1371 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1375 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1377 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1379 if (lpStatusPtr
->lpServiceName
)
1380 lpStatusPtr
->lpServiceName
=
1381 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1383 if (lpStatusPtr
->lpDisplayName
)
1384 lpStatusPtr
->lpDisplayName
=
1385 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1391 if (dwError
!= ERROR_SUCCESS
)
1393 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1394 SetLastError(dwError
);
1398 TRACE("EnumServicesStatusW() done\n");
1404 /**********************************************************************
1405 * EnumServicesStatusExA
1410 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1411 SC_ENUM_TYPE InfoLevel
,
1412 DWORD dwServiceType
,
1413 DWORD dwServiceState
,
1416 LPDWORD pcbBytesNeeded
,
1417 LPDWORD lpServicesReturned
,
1418 LPDWORD lpResumeHandle
,
1419 LPCSTR pszGroupName
)
1421 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1422 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1427 TRACE("EnumServicesStatusExA(%p %lu %lu %p %lu %p %p %p %s)\n",
1428 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1429 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
,
1430 debugstr_a(pszGroupName
));
1432 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1434 SetLastError(ERROR_INVALID_LEVEL
);
1440 SetLastError(ERROR_INVALID_HANDLE
);
1444 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1446 SetLastError(ERROR_INVALID_ADDRESS
);
1450 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1452 lpStatusPtr
= &ServiceStatus
;
1453 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1457 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1458 dwBufferSize
= cbBufSize
;
1463 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1467 (LPBYTE
)lpStatusPtr
,
1472 (LPSTR
)pszGroupName
);
1474 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1476 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1480 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1482 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1484 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1486 if (lpStatusPtr
->lpServiceName
)
1487 lpStatusPtr
->lpServiceName
=
1488 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1490 if (lpStatusPtr
->lpDisplayName
)
1491 lpStatusPtr
->lpDisplayName
=
1492 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1499 if (dwError
!= ERROR_SUCCESS
)
1501 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1502 SetLastError(dwError
);
1506 TRACE("EnumServicesStatusExA() done\n");
1512 /**********************************************************************
1513 * EnumServicesStatusExW
1518 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1519 SC_ENUM_TYPE InfoLevel
,
1520 DWORD dwServiceType
,
1521 DWORD dwServiceState
,
1524 LPDWORD pcbBytesNeeded
,
1525 LPDWORD lpServicesReturned
,
1526 LPDWORD lpResumeHandle
,
1527 LPCWSTR pszGroupName
)
1529 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1530 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1535 TRACE("EnumServicesStatusExW(%p %lu %lu %p %lu %p %p %p %s)\n",
1536 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1537 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
,
1538 debugstr_w(pszGroupName
));
1540 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1542 SetLastError(ERROR_INVALID_LEVEL
);
1548 SetLastError(ERROR_INVALID_HANDLE
);
1552 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1554 SetLastError(ERROR_INVALID_ADDRESS
);
1558 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1560 lpStatusPtr
= &ServiceStatus
;
1561 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1565 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1566 dwBufferSize
= cbBufSize
;
1571 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1575 (LPBYTE
)lpStatusPtr
,
1580 (LPWSTR
)pszGroupName
);
1582 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1584 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1588 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1590 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1592 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1594 if (lpStatusPtr
->lpServiceName
)
1595 lpStatusPtr
->lpServiceName
=
1596 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1598 if (lpStatusPtr
->lpDisplayName
)
1599 lpStatusPtr
->lpDisplayName
=
1600 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1607 if (dwError
!= ERROR_SUCCESS
)
1609 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1610 SetLastError(dwError
);
1614 TRACE("EnumServicesStatusExW() done\n");
1620 /**********************************************************************
1621 * GetServiceDisplayNameA
1626 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1627 LPCSTR lpServiceName
,
1628 LPSTR lpDisplayName
,
1629 LPDWORD lpcchBuffer
)
1633 CHAR szEmptyName
[] = "";
1635 TRACE("GetServiceDisplayNameA(%p %s %p %p)\n",
1636 hSCManager
, debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1640 SetLastError(ERROR_INVALID_HANDLE
);
1644 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1646 lpNameBuffer
= szEmptyName
;
1647 *lpcchBuffer
= sizeof(CHAR
);
1651 lpNameBuffer
= lpDisplayName
;
1656 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1661 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1663 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1667 if (dwError
!= ERROR_SUCCESS
)
1669 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1670 SetLastError(dwError
);
1678 /**********************************************************************
1679 * GetServiceDisplayNameW
1684 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1685 LPCWSTR lpServiceName
,
1686 LPWSTR lpDisplayName
,
1687 LPDWORD lpcchBuffer
)
1690 LPWSTR lpNameBuffer
;
1691 WCHAR szEmptyName
[] = L
"";
1693 TRACE("GetServiceDisplayNameW(%p %s %p %p)\n",
1694 hSCManager
, debugstr_w(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1698 SetLastError(ERROR_INVALID_HANDLE
);
1703 * NOTE: A size of 1 character would be enough, but tests show that
1704 * Windows returns 2 characters instead, certainly due to a WCHAR/bytes
1705 * mismatch in their code.
1707 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1709 lpNameBuffer
= szEmptyName
;
1710 *lpcchBuffer
= sizeof(WCHAR
);
1714 lpNameBuffer
= lpDisplayName
;
1719 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1724 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1726 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1730 if (dwError
!= ERROR_SUCCESS
)
1732 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1733 SetLastError(dwError
);
1741 /**********************************************************************
1742 * GetServiceKeyNameA
1747 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1748 LPCSTR lpDisplayName
,
1749 LPSTR lpServiceName
,
1750 LPDWORD lpcchBuffer
)
1754 CHAR szEmptyName
[] = "";
1756 TRACE("GetServiceKeyNameA(%p %s %p %p)\n",
1757 hSCManager
, debugstr_a(lpDisplayName
), lpServiceName
, lpcchBuffer
);
1761 SetLastError(ERROR_INVALID_HANDLE
);
1765 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1767 lpNameBuffer
= szEmptyName
;
1768 *lpcchBuffer
= sizeof(CHAR
);
1772 lpNameBuffer
= lpServiceName
;
1777 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1782 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1784 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1785 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1789 if (dwError
!= ERROR_SUCCESS
)
1791 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1792 SetLastError(dwError
);
1800 /**********************************************************************
1801 * GetServiceKeyNameW
1806 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1807 LPCWSTR lpDisplayName
,
1808 LPWSTR lpServiceName
,
1809 LPDWORD lpcchBuffer
)
1812 LPWSTR lpNameBuffer
;
1813 WCHAR szEmptyName
[] = L
"";
1815 TRACE("GetServiceKeyNameW(%p %s %p %p)\n",
1816 hSCManager
, debugstr_w(lpDisplayName
), lpServiceName
, lpcchBuffer
);
1820 SetLastError(ERROR_INVALID_HANDLE
);
1825 * NOTE: A size of 1 character would be enough, but tests show that
1826 * Windows returns 2 characters instead, certainly due to a WCHAR/bytes
1827 * mismatch in their code.
1829 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1831 lpNameBuffer
= szEmptyName
;
1832 *lpcchBuffer
= sizeof(WCHAR
);
1836 lpNameBuffer
= lpServiceName
;
1841 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1846 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1848 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1852 if (dwError
!= ERROR_SUCCESS
)
1854 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1855 SetLastError(dwError
);
1863 /**********************************************************************
1864 * I_ScGetCurrentGroupStateW
1869 I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager
,
1870 LPWSTR pszGroupName
,
1871 LPDWORD pdwGroupState
)
1875 TRACE("I_ScGetCurrentGroupStateW(%p %s %p)\n",
1876 hSCManager
, debugstr_w(pszGroupName
), pdwGroupState
);
1880 dwError
= RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE
)hSCManager
,
1884 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1886 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1890 if (dwError
!= ERROR_SUCCESS
)
1892 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError
);
1893 SetLastError(dwError
);
1900 /**********************************************************************
1901 * I_ScValidatePnpService
1909 I_ScValidatePnpService(
1910 _In_ LPCWSTR pszMachineName
,
1911 _In_ LPCWSTR pszServiceName
,
1912 _Out_ SERVICE_STATUS_HANDLE
*phServiceStatus
)
1914 SC_RPC_HANDLE hSCManager
= NULL
;
1915 SERVICE_STATUS_HANDLE hServiceStatus
= NULL
;
1918 TRACE("I_ScValidatePnpService(%S %S %p)\n",
1919 pszMachineName
, pszServiceName
, phServiceStatus
);
1921 hSCManager
= OpenSCManagerW(pszMachineName
,
1922 SERVICES_ACTIVE_DATABASEW
,
1923 SC_MANAGER_CONNECT
);
1924 if (hSCManager
== NULL
)
1926 dwError
= GetLastError();
1932 dwError
= RI_ScValidatePnPService(hSCManager
,
1933 (LPWSTR
)pszServiceName
,
1934 (RPC_SERVICE_STATUS_HANDLE
*)&hServiceStatus
);
1936 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1938 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1942 *phServiceStatus
= hServiceStatus
;
1945 if (hSCManager
!= NULL
)
1946 CloseServiceHandle(hSCManager
);
1952 /**********************************************************************
1953 * LockServiceDatabase
1958 LockServiceDatabase(SC_HANDLE hSCManager
)
1963 TRACE("LockServiceDatabase(%p)\n",
1968 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1969 (SC_RPC_LOCK
*)&hLock
);
1971 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1973 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1977 if (dwError
!= ERROR_SUCCESS
)
1979 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1980 SetLastError(dwError
);
1984 TRACE("hLock = %p\n", hLock
);
1991 WaitForSCManager(VOID
)
1995 TRACE("WaitForSCManager()\n");
1997 /* Try to open the existing event */
1998 hEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, SCM_START_EVENT
);
2001 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
2004 /* Try to create a new event */
2005 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
2010 /* Wait for 3 minutes */
2011 WaitForSingleObject(hEvent
, 180000);
2012 CloseHandle(hEvent
);
2014 TRACE("ScmWaitForSCManager() done\n");
2018 /**********************************************************************
2024 OpenSCManagerA(LPCSTR lpMachineName
,
2025 LPCSTR lpDatabaseName
,
2026 DWORD dwDesiredAccess
)
2028 SC_HANDLE hScm
= NULL
;
2031 TRACE("OpenSCManagerA(%s %s %lx)\n",
2032 debugstr_a(lpMachineName
), debugstr_a(lpDatabaseName
), dwDesiredAccess
);
2038 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
2039 (LPSTR
)lpDatabaseName
,
2041 (SC_RPC_HANDLE
*)&hScm
);
2043 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2045 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2049 SetLastError(dwError
);
2050 if (dwError
!= ERROR_SUCCESS
)
2052 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
2056 TRACE("hScm = %p\n", hScm
);
2062 /**********************************************************************
2068 OpenSCManagerW(LPCWSTR lpMachineName
,
2069 LPCWSTR lpDatabaseName
,
2070 DWORD dwDesiredAccess
)
2072 SC_HANDLE hScm
= NULL
;
2075 TRACE("OpenSCManagerW(%s %s %lx)\n",
2076 debugstr_w(lpMachineName
), debugstr_w(lpDatabaseName
), dwDesiredAccess
);
2082 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
2083 (LPWSTR
)lpDatabaseName
,
2085 (SC_RPC_HANDLE
*)&hScm
);
2087 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2089 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2093 SetLastError(dwError
);
2094 if (dwError
!= ERROR_SUCCESS
)
2096 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
2100 TRACE("hScm = %p\n", hScm
);
2106 /**********************************************************************
2112 OpenServiceA(SC_HANDLE hSCManager
,
2113 LPCSTR lpServiceName
,
2114 DWORD dwDesiredAccess
)
2116 SC_HANDLE hService
= NULL
;
2119 TRACE("OpenServiceA(%p %s %lx)\n",
2120 hSCManager
, debugstr_a(lpServiceName
), dwDesiredAccess
);
2124 SetLastError(ERROR_INVALID_HANDLE
);
2130 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
2131 (LPSTR
)lpServiceName
,
2133 (SC_RPC_HANDLE
*)&hService
);
2135 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2137 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2141 SetLastError(dwError
);
2142 if (dwError
!= ERROR_SUCCESS
)
2144 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
2148 TRACE("hService = %p\n", hService
);
2154 /**********************************************************************
2160 OpenServiceW(SC_HANDLE hSCManager
,
2161 LPCWSTR lpServiceName
,
2162 DWORD dwDesiredAccess
)
2164 SC_HANDLE hService
= NULL
;
2167 TRACE("OpenServiceW(%p %s %lx)\n",
2168 hSCManager
, debugstr_w(lpServiceName
), dwDesiredAccess
);
2172 SetLastError(ERROR_INVALID_HANDLE
);
2178 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
2179 (LPWSTR
)lpServiceName
,
2181 (SC_RPC_HANDLE
*)&hService
);
2183 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2185 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2189 SetLastError(dwError
);
2190 if (dwError
!= ERROR_SUCCESS
)
2192 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
2196 TRACE("hService = %p\n", hService
);
2202 /**********************************************************************
2203 * QueryServiceConfigA
2208 QueryServiceConfigA(SC_HANDLE hService
,
2209 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
2211 LPDWORD pcbBytesNeeded
)
2213 QUERY_SERVICE_CONFIGA ServiceConfig
;
2214 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
2218 TRACE("QueryServiceConfigA(%p %p %lu %p)\n",
2219 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2221 if (lpServiceConfig
== NULL
||
2222 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
2224 lpConfigPtr
= &ServiceConfig
;
2225 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
2229 lpConfigPtr
= lpServiceConfig
;
2230 dwBufferSize
= cbBufSize
;
2235 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
2236 (LPBYTE
)lpConfigPtr
,
2240 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2242 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2246 if (dwError
!= ERROR_SUCCESS
)
2248 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
2249 SetLastError(dwError
);
2253 /* Adjust the pointers */
2254 if (lpConfigPtr
->lpBinaryPathName
)
2255 lpConfigPtr
->lpBinaryPathName
=
2256 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2257 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2259 if (lpConfigPtr
->lpLoadOrderGroup
)
2260 lpConfigPtr
->lpLoadOrderGroup
=
2261 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2262 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2264 if (lpConfigPtr
->lpDependencies
)
2265 lpConfigPtr
->lpDependencies
=
2266 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2267 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2269 if (lpConfigPtr
->lpServiceStartName
)
2270 lpConfigPtr
->lpServiceStartName
=
2271 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2272 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2274 if (lpConfigPtr
->lpDisplayName
)
2275 lpConfigPtr
->lpDisplayName
=
2276 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2277 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2279 TRACE("QueryServiceConfigA() done\n");
2285 /**********************************************************************
2286 * QueryServiceConfigW
2291 QueryServiceConfigW(SC_HANDLE hService
,
2292 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
2294 LPDWORD pcbBytesNeeded
)
2296 QUERY_SERVICE_CONFIGW ServiceConfig
;
2297 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
2301 TRACE("QueryServiceConfigW(%p %p %lu %p)\n",
2302 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2304 if (lpServiceConfig
== NULL
||
2305 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2307 lpConfigPtr
= &ServiceConfig
;
2308 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2312 lpConfigPtr
= lpServiceConfig
;
2313 dwBufferSize
= cbBufSize
;
2318 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2319 (LPBYTE
)lpConfigPtr
,
2323 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2325 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2329 if (dwError
!= ERROR_SUCCESS
)
2331 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2332 SetLastError(dwError
);
2336 /* Adjust the pointers */
2337 if (lpConfigPtr
->lpBinaryPathName
)
2338 lpConfigPtr
->lpBinaryPathName
=
2339 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2340 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2342 if (lpConfigPtr
->lpLoadOrderGroup
)
2343 lpConfigPtr
->lpLoadOrderGroup
=
2344 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2345 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2347 if (lpConfigPtr
->lpDependencies
)
2348 lpConfigPtr
->lpDependencies
=
2349 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2350 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2352 if (lpConfigPtr
->lpServiceStartName
)
2353 lpConfigPtr
->lpServiceStartName
=
2354 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2355 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2357 if (lpConfigPtr
->lpDisplayName
)
2358 lpConfigPtr
->lpDisplayName
=
2359 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2360 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2362 TRACE("QueryServiceConfigW() done\n");
2368 /**********************************************************************
2369 * QueryServiceConfig2A
2374 QueryServiceConfig2A(SC_HANDLE hService
,
2378 LPDWORD pcbBytesNeeded
)
2380 SERVICE_DESCRIPTIONA ServiceDescription
;
2381 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2382 LPBYTE lpTempBuffer
;
2383 BOOL bUseTempBuffer
= FALSE
;
2387 TRACE("QueryServiceConfig2A(%p %lu %p %lu %p)\n",
2388 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2390 lpTempBuffer
= lpBuffer
;
2391 dwBufferSize
= cbBufSize
;
2393 switch (dwInfoLevel
)
2395 case SERVICE_CONFIG_DESCRIPTION
:
2396 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2398 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2399 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2400 bUseTempBuffer
= TRUE
;
2404 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2405 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2407 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2408 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2409 bUseTempBuffer
= TRUE
;
2414 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2415 SetLastError(ERROR_INVALID_LEVEL
);
2421 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2427 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2429 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2433 if (dwError
!= ERROR_SUCCESS
)
2435 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2436 SetLastError(dwError
);
2440 if (bUseTempBuffer
!= FALSE
)
2442 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2443 *pcbBytesNeeded
= dwBufferSize
;
2444 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2448 switch (dwInfoLevel
)
2450 case SERVICE_CONFIG_DESCRIPTION
:
2452 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2454 if (lpPtr
->lpDescription
!= NULL
)
2455 lpPtr
->lpDescription
=
2456 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2460 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2462 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2464 if (lpPtr
->lpRebootMsg
!= NULL
)
2465 lpPtr
->lpRebootMsg
=
2466 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2468 if (lpPtr
->lpCommand
!= NULL
)
2470 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2472 if (lpPtr
->lpsaActions
!= NULL
)
2473 lpPtr
->lpsaActions
=
2474 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2479 TRACE("QueryServiceConfig2A() done\n");
2485 /**********************************************************************
2486 * QueryServiceConfig2W
2491 QueryServiceConfig2W(SC_HANDLE hService
,
2495 LPDWORD pcbBytesNeeded
)
2497 SERVICE_DESCRIPTIONW ServiceDescription
;
2498 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2499 LPBYTE lpTempBuffer
;
2500 BOOL bUseTempBuffer
= FALSE
;
2504 TRACE("QueryServiceConfig2W(%p %lu %p %lu %p)\n",
2505 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2507 lpTempBuffer
= lpBuffer
;
2508 dwBufferSize
= cbBufSize
;
2510 switch (dwInfoLevel
)
2512 case SERVICE_CONFIG_DESCRIPTION
:
2513 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2515 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2516 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2517 bUseTempBuffer
= TRUE
;
2521 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2522 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2524 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2525 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2526 bUseTempBuffer
= TRUE
;
2531 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2532 SetLastError(ERROR_INVALID_LEVEL
);
2538 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2544 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2546 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2550 if (dwError
!= ERROR_SUCCESS
)
2552 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2553 SetLastError(dwError
);
2557 if (bUseTempBuffer
!= FALSE
)
2559 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2560 *pcbBytesNeeded
= dwBufferSize
;
2561 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2565 switch (dwInfoLevel
)
2567 case SERVICE_CONFIG_DESCRIPTION
:
2569 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2571 if (lpPtr
->lpDescription
!= NULL
)
2572 lpPtr
->lpDescription
=
2573 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2577 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2579 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2581 if (lpPtr
->lpRebootMsg
!= NULL
)
2582 lpPtr
->lpRebootMsg
=
2583 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2585 if (lpPtr
->lpCommand
!= NULL
)
2587 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2589 if (lpPtr
->lpsaActions
!= NULL
)
2590 lpPtr
->lpsaActions
=
2591 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2596 TRACE("QueryServiceConfig2W() done\n");
2602 /**********************************************************************
2603 * QueryServiceLockStatusA
2608 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2609 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2611 LPDWORD pcbBytesNeeded
)
2613 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2614 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2618 TRACE("QueryServiceLockStatusA(%p %p %lu %p)\n",
2619 hSCManager
, lpLockStatus
, cbBufSize
, pcbBytesNeeded
);
2621 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2623 lpStatusPtr
= &LockStatus
;
2624 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2628 lpStatusPtr
= lpLockStatus
;
2629 dwBufferSize
= cbBufSize
;
2634 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2635 (LPBYTE
)lpStatusPtr
,
2639 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2641 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2645 if (dwError
!= ERROR_SUCCESS
)
2647 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2648 SetLastError(dwError
);
2652 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2654 lpStatusPtr
->lpLockOwner
=
2655 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2658 TRACE("QueryServiceLockStatusA() done\n");
2664 /**********************************************************************
2665 * QueryServiceLockStatusW
2670 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2671 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2673 LPDWORD pcbBytesNeeded
)
2675 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2676 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2680 TRACE("QueryServiceLockStatusW(%p %p %lu %p)\n",
2681 hSCManager
, lpLockStatus
, cbBufSize
, pcbBytesNeeded
);
2683 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2685 lpStatusPtr
= &LockStatus
;
2686 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2690 lpStatusPtr
= lpLockStatus
;
2691 dwBufferSize
= cbBufSize
;
2696 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2697 (LPBYTE
)lpStatusPtr
,
2701 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2703 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2707 if (dwError
!= ERROR_SUCCESS
)
2709 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2710 SetLastError(dwError
);
2714 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2716 lpStatusPtr
->lpLockOwner
=
2717 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2720 TRACE("QueryServiceLockStatusW() done\n");
2726 /**********************************************************************
2727 * QueryServiceObjectSecurity
2732 QueryServiceObjectSecurity(SC_HANDLE hService
,
2733 SECURITY_INFORMATION dwSecurityInformation
,
2734 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2736 LPDWORD pcbBytesNeeded
)
2740 TRACE("QueryServiceObjectSecurity(%p %lu %p)\n",
2741 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2745 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2746 dwSecurityInformation
,
2747 (LPBYTE
)lpSecurityDescriptor
,
2751 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2753 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2757 if (dwError
!= ERROR_SUCCESS
)
2759 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2760 SetLastError(dwError
);
2768 /**********************************************************************
2769 * SetServiceObjectSecurity
2774 SetServiceObjectSecurity(SC_HANDLE hService
,
2775 SECURITY_INFORMATION dwSecurityInformation
,
2776 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2778 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2783 TRACE("SetServiceObjectSecurity(%p %lu %p)\n",
2784 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2787 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2790 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2792 SetLastError(ERROR_INVALID_PARAMETER
);
2796 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2797 if (SelfRelativeSD
== NULL
)
2799 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2803 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2806 if (!NT_SUCCESS(Status
))
2808 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2809 SetLastError(RtlNtStatusToDosError(Status
));
2815 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2816 dwSecurityInformation
,
2817 (LPBYTE
)SelfRelativeSD
,
2820 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2822 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2826 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2828 if (dwError
!= ERROR_SUCCESS
)
2830 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2831 SetLastError(dwError
);
2839 /**********************************************************************
2840 * QueryServiceStatus
2845 QueryServiceStatus(SC_HANDLE hService
,
2846 LPSERVICE_STATUS lpServiceStatus
)
2850 TRACE("QueryServiceStatus(%p %p)\n",
2851 hService
, lpServiceStatus
);
2855 SetLastError(ERROR_INVALID_HANDLE
);
2861 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2864 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2866 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2870 if (dwError
!= ERROR_SUCCESS
)
2872 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2873 SetLastError(dwError
);
2881 /**********************************************************************
2882 * QueryServiceStatusEx
2887 QueryServiceStatusEx(SC_HANDLE hService
,
2888 SC_STATUS_TYPE InfoLevel
,
2891 LPDWORD pcbBytesNeeded
)
2895 TRACE("QueryServiceStatusEx(%p %lu %p %lu %p)\n",
2896 hService
, InfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2898 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2900 SetLastError(ERROR_INVALID_LEVEL
);
2904 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2906 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2907 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2913 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2919 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2921 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2925 if (dwError
!= ERROR_SUCCESS
)
2927 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2928 SetLastError(dwError
);
2936 /**********************************************************************
2942 StartServiceA(SC_HANDLE hService
,
2943 DWORD dwNumServiceArgs
,
2944 LPCSTR
*lpServiceArgVectors
)
2948 TRACE("StartServiceA(%p %lu %p)\n",
2949 hService
, dwNumServiceArgs
, lpServiceArgVectors
);
2953 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2955 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2957 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2959 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2963 if (dwError
!= ERROR_SUCCESS
)
2965 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2966 SetLastError(dwError
);
2974 /**********************************************************************
2980 StartServiceW(SC_HANDLE hService
,
2981 DWORD dwNumServiceArgs
,
2982 LPCWSTR
*lpServiceArgVectors
)
2986 TRACE("StartServiceW(%p %lu %p)\n",
2987 hService
, dwNumServiceArgs
, lpServiceArgVectors
);
2991 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2993 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2995 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2997 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
3001 if (dwError
!= ERROR_SUCCESS
)
3003 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
3004 SetLastError(dwError
);
3012 /**********************************************************************
3013 * UnlockServiceDatabase
3018 UnlockServiceDatabase(SC_LOCK ScLock
)
3022 TRACE("UnlockServiceDatabase(%x)\n",
3027 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
3029 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
3031 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
3035 if (dwError
== ERROR_INVALID_HANDLE
)
3036 dwError
= ERROR_INVALID_SERVICE_LOCK
;
3038 if (dwError
!= ERROR_SUCCESS
)
3040 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
3041 SetLastError(dwError
);
3049 /**********************************************************************
3050 * NotifyBootConfigStatus
3055 NotifyBootConfigStatus(BOOL BootAcceptable
)
3059 TRACE("NotifyBootConfigStatus(%u)\n",
3064 dwError
= RNotifyBootConfigStatus(NULL
,
3067 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
3069 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
3073 if (dwError
!= ERROR_SUCCESS
)
3075 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
3076 SetLastError(dwError
);
3084 I_ScQueryServiceTagInfo(PVOID Unused
,
3085 TAG_INFO_LEVEL dwInfoLevel
,
3086 PTAG_INFO_NAME_FROM_TAG InOutParams
)
3090 PTAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams
;
3091 PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS OutParams
;
3094 /* We only support one class */
3095 if (dwInfoLevel
!= TagInfoLevelNameFromTag
)
3100 /* Validate input structure */
3101 if (InOutParams
->InParams
.dwPid
== 0 || InOutParams
->InParams
.dwTag
== 0)
3103 return ERROR_INVALID_PARAMETER
;
3106 /* Validate output structure */
3107 if (InOutParams
->OutParams
.pszName
!= NULL
)
3109 return ERROR_INVALID_PARAMETER
;
3112 /* Open service manager */
3113 hScm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
3116 return GetLastError();
3119 /* Setup call parameters */
3120 InParams
= &InOutParams
->InParams
;
3123 /* Call SCM to query tag information */
3126 dwError
= RI_ScQueryServiceTagInfo(hScm
, TagInfoLevelNameFromTag
, &InParams
, &OutParams
);
3128 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
3130 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
3134 /* Quit if not a success */
3135 if (dwError
!= ERROR_SUCCESS
)
3140 /* OutParams must be set now and we must have a name */
3141 if (OutParams
== NULL
||
3142 OutParams
->pszName
== NULL
)
3144 dwError
= ERROR_INVALID_DATA
;
3148 /* Copy back what SCM returned */
3149 lpszName
= LocalAlloc(LPTR
,
3150 sizeof(WCHAR
) * wcslen(OutParams
->pszName
) + sizeof(UNICODE_NULL
));
3151 if (lpszName
== NULL
)
3153 dwError
= GetLastError();
3157 wcscpy(lpszName
, OutParams
->pszName
);
3158 InOutParams
->OutParams
.pszName
= lpszName
;
3159 InOutParams
->OutParams
.TagType
= OutParams
->TagType
;
3162 CloseServiceHandle(hScm
);
3164 /* Free memory allocated by SCM */
3165 if (OutParams
!= NULL
)
3167 if (OutParams
->pszName
!= NULL
)
3169 midl_user_free(OutParams
->pszName
);
3172 midl_user_free(OutParams
);
3178 /**********************************************************************
3179 * I_QueryTagInformation
3184 I_QueryTagInformation(PVOID Unused
,
3185 TAG_INFO_LEVEL dwInfoLevel
,
3186 PTAG_INFO_NAME_FROM_TAG InOutParams
)
3189 * We only support one information class and it
3192 if (dwInfoLevel
!= TagInfoLevelNameFromTag
||
3193 InOutParams
== NULL
)
3195 return ERROR_INVALID_PARAMETER
;
3198 /* Validate input structure */
3199 if (InOutParams
->InParams
.dwPid
== 0 || InOutParams
->InParams
.dwTag
== 0)
3201 return ERROR_INVALID_PARAMETER
;
3204 /* Validate output structure */
3205 if (InOutParams
->OutParams
.pszName
!= NULL
)
3207 return ERROR_INVALID_PARAMETER
;
3210 /* Call internal function for the RPC call */
3211 return I_ScQueryServiceTagInfo(Unused
, TagInfoLevelNameFromTag
, InOutParams
);