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_ PCWSTR pClearTextPassword
,
175 _Out_ PBYTE
*pEncryptedPassword
,
176 _Out_ PDWORD pEncryptedPasswordSize
)
178 struct ustring inData
, keyData
, outData
;
183 /* Get the session key */
184 Status
= SystemFunction028(NULL
,
186 if (!NT_SUCCESS(Status
))
188 ERR("SystemFunction028 failed (Status 0x%08lx)\n", Status
);
189 return RtlNtStatusToDosError(Status
);
192 inData
.Length
= (wcslen(pClearTextPassword
) + 1) * sizeof(WCHAR
);
193 inData
.MaximumLength
= inData
.Length
;
194 inData
.Buffer
= (unsigned char *)pClearTextPassword
;
196 keyData
.Length
= sizeof(SessionKey
);
197 keyData
.MaximumLength
= keyData
.Length
;
198 keyData
.Buffer
= SessionKey
;
201 outData
.MaximumLength
= 0;
202 outData
.Buffer
= NULL
;
204 /* Get the required buffer size */
205 Status
= SystemFunction004(&inData
,
208 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
210 ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status
);
211 return RtlNtStatusToDosError(Status
);
214 /* Allocate a buffer for the encrypted password */
215 pBuffer
= HeapAlloc(GetProcessHeap(), 0, outData
.Length
);
217 return ERROR_OUTOFMEMORY
;
219 outData
.MaximumLength
= outData
.Length
;
220 outData
.Buffer
= pBuffer
;
222 /* Encrypt the password */
223 Status
= SystemFunction004(&inData
,
226 if (!NT_SUCCESS(Status
))
228 ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status
);
229 HeapFree(GetProcessHeap(), 0, pBuffer
);
230 return RtlNtStatusToDosError(Status
);
233 *pEncryptedPassword
= outData
.Buffer
;
234 *pEncryptedPasswordSize
= outData
.Length
;
236 return ERROR_SUCCESS
;
240 /**********************************************************************
241 * ChangeServiceConfig2A
246 ChangeServiceConfig2A(SC_HANDLE hService
,
250 SC_RPC_CONFIG_INFOA Info
;
253 TRACE("ChangeServiceConfig2A(%p %lu %p)\n",
254 hService
, dwInfoLevel
, lpInfo
);
256 if (lpInfo
== NULL
) return TRUE
;
258 /* Fill relevant field of the Info structure */
259 Info
.dwInfoLevel
= dwInfoLevel
;
262 case SERVICE_CONFIG_DESCRIPTION
:
266 case SERVICE_CONFIG_FAILURE_ACTIONS
:
271 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
272 SetLastError(ERROR_INVALID_PARAMETER
);
278 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
281 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
283 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
287 if (dwError
!= ERROR_SUCCESS
)
289 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
290 SetLastError(dwError
);
298 /**********************************************************************
299 * ChangeServiceConfig2W
304 ChangeServiceConfig2W(SC_HANDLE hService
,
308 SC_RPC_CONFIG_INFOW Info
;
311 TRACE("ChangeServiceConfig2W(%p %lu %p)\n",
312 hService
, dwInfoLevel
, lpInfo
);
314 if (lpInfo
== NULL
) return TRUE
;
316 /* Fill relevant field of the Info structure */
317 Info
.dwInfoLevel
= dwInfoLevel
;
320 case SERVICE_CONFIG_DESCRIPTION
:
324 case SERVICE_CONFIG_FAILURE_ACTIONS
:
329 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
330 SetLastError(ERROR_INVALID_PARAMETER
);
336 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
339 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
341 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
345 if (dwError
!= ERROR_SUCCESS
)
347 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
348 SetLastError(dwError
);
356 /**********************************************************************
357 * ChangeServiceConfigA
362 ChangeServiceConfigA(SC_HANDLE hService
,
365 DWORD dwErrorControl
,
366 LPCSTR lpBinaryPathName
,
367 LPCSTR lpLoadOrderGroup
,
369 LPCSTR lpDependencies
,
370 LPCSTR lpServiceStartName
,
372 LPCSTR lpDisplayName
)
375 DWORD dwDependenciesLength
= 0;
378 DWORD dwPasswordSize
= 0;
379 LPWSTR lpPasswordW
= NULL
;
380 LPBYTE lpEncryptedPassword
= NULL
;
382 TRACE("ChangeServiceConfigA(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
383 hService
, dwServiceType
, dwStartType
, dwErrorControl
, debugstr_a(lpBinaryPathName
),
384 debugstr_a(lpLoadOrderGroup
), lpdwTagId
, debugstr_a(lpDependencies
),
385 debugstr_a(lpServiceStartName
), debugstr_a(lpPassword
), debugstr_a(lpDisplayName
));
387 /* Calculate the Dependencies length*/
388 if (lpDependencies
!= NULL
)
390 lpStr
= lpDependencies
;
393 cchLength
= strlen(lpStr
) + 1;
394 dwDependenciesLength
+= (DWORD
)cchLength
;
395 lpStr
= lpStr
+ cchLength
;
397 dwDependenciesLength
++;
400 if (lpPassword
!= NULL
)
402 /* Convert the password to unicode */
403 lpPasswordW
= HeapAlloc(GetProcessHeap(),
405 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
406 if (lpPasswordW
== NULL
)
408 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
412 MultiByteToWideChar(CP_ACP
,
417 (int)(strlen(lpPassword
) + 1));
419 /* Encrypt the unicode password */
420 dwError
= ScmEncryptPassword(lpPasswordW
,
421 &lpEncryptedPassword
,
423 if (dwError
!= ERROR_SUCCESS
)
429 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
433 (LPSTR
)lpBinaryPathName
,
434 (LPSTR
)lpLoadOrderGroup
,
436 (LPBYTE
)lpDependencies
,
437 dwDependenciesLength
,
438 (LPSTR
)lpServiceStartName
,
441 (LPSTR
)lpDisplayName
);
443 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
445 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
450 if (lpPasswordW
!= NULL
)
452 /* Wipe and release the password buffers */
453 SecureZeroMemory(lpPasswordW
, (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
));
454 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
456 if (lpEncryptedPassword
!= NULL
)
458 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
459 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
463 if (dwError
!= ERROR_SUCCESS
)
465 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
466 SetLastError(dwError
);
474 /**********************************************************************
475 * ChangeServiceConfigW
480 ChangeServiceConfigW(SC_HANDLE hService
,
483 DWORD dwErrorControl
,
484 LPCWSTR lpBinaryPathName
,
485 LPCWSTR lpLoadOrderGroup
,
487 LPCWSTR lpDependencies
,
488 LPCWSTR lpServiceStartName
,
490 LPCWSTR lpDisplayName
)
493 DWORD dwDependenciesLength
= 0;
496 DWORD dwPasswordSize
= 0;
497 LPBYTE lpEncryptedPassword
= NULL
;
499 TRACE("ChangeServiceConfigW(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
500 hService
, dwServiceType
, dwStartType
, dwErrorControl
, debugstr_w(lpBinaryPathName
),
501 debugstr_w(lpLoadOrderGroup
), lpdwTagId
, debugstr_w(lpDependencies
),
502 debugstr_w(lpServiceStartName
), debugstr_w(lpPassword
), debugstr_w(lpDisplayName
));
504 /* Calculate the Dependencies length*/
505 if (lpDependencies
!= NULL
)
507 lpStr
= lpDependencies
;
510 cchLength
= wcslen(lpStr
) + 1;
511 dwDependenciesLength
+= (DWORD
)cchLength
;
512 lpStr
= lpStr
+ cchLength
;
514 dwDependenciesLength
++;
515 dwDependenciesLength
*= sizeof(WCHAR
);
518 if (lpPassword
!= NULL
)
520 dwError
= ScmEncryptPassword(lpPassword
,
521 &lpEncryptedPassword
,
523 if (dwError
!= ERROR_SUCCESS
)
525 ERR("ScmEncryptPassword failed (Error %lu)\n", dwError
);
532 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
536 (LPWSTR
)lpBinaryPathName
,
537 (LPWSTR
)lpLoadOrderGroup
,
539 (LPBYTE
)lpDependencies
,
540 dwDependenciesLength
,
541 (LPWSTR
)lpServiceStartName
,
544 (LPWSTR
)lpDisplayName
);
546 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
548 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
553 if (lpEncryptedPassword
!= NULL
)
555 /* Wipe and release the password buffer */
556 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
557 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
560 if (dwError
!= ERROR_SUCCESS
)
562 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
563 SetLastError(dwError
);
571 /**********************************************************************
577 CloseServiceHandle(SC_HANDLE hSCObject
)
581 TRACE("CloseServiceHandle(%p)\n",
586 SetLastError(ERROR_INVALID_HANDLE
);
592 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
594 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
596 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
602 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
603 SetLastError(dwError
);
607 TRACE("CloseServiceHandle() done\n");
613 /**********************************************************************
619 ControlService(SC_HANDLE hService
,
621 LPSERVICE_STATUS lpServiceStatus
)
625 TRACE("ControlService(%p %lu %p)\n",
626 hService
, dwControl
, lpServiceStatus
);
630 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
634 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
636 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
640 if (dwError
!= ERROR_SUCCESS
)
642 TRACE("RControlService() failed (Error %lu)\n", dwError
);
643 SetLastError(dwError
);
647 TRACE("ControlService() done\n");
653 /**********************************************************************
659 ControlServiceEx(IN SC_HANDLE hService
,
661 IN DWORD dwInfoLevel
,
662 IN OUT PVOID pControlParams
)
664 FIXME("ControlServiceEx(%p %lu %lu %p)\n",
665 hService
, dwControl
, dwInfoLevel
, pControlParams
);
666 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
671 /**********************************************************************
677 CreateServiceA(SC_HANDLE hSCManager
,
678 LPCSTR lpServiceName
,
679 LPCSTR lpDisplayName
,
680 DWORD dwDesiredAccess
,
683 DWORD dwErrorControl
,
684 LPCSTR lpBinaryPathName
,
685 LPCSTR lpLoadOrderGroup
,
687 LPCSTR lpDependencies
,
688 LPCSTR lpServiceStartName
,
691 SC_HANDLE hService
= NULL
;
692 DWORD dwDependenciesLength
= 0;
696 DWORD dwPasswordSize
= 0;
697 LPWSTR lpPasswordW
= NULL
;
698 LPBYTE lpEncryptedPassword
= NULL
;
700 TRACE("CreateServiceA(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
701 hSCManager
, debugstr_a(lpServiceName
), debugstr_a(lpDisplayName
),
702 dwDesiredAccess
, dwServiceType
, dwStartType
, dwErrorControl
,
703 debugstr_a(lpBinaryPathName
), debugstr_a(lpLoadOrderGroup
), lpdwTagId
,
704 debugstr_a(lpDependencies
), debugstr_a(lpServiceStartName
), debugstr_a(lpPassword
));
708 SetLastError(ERROR_INVALID_HANDLE
);
712 /* Calculate the Dependencies length */
713 if (lpDependencies
!= NULL
)
715 lpStr
= lpDependencies
;
718 cchLength
= strlen(lpStr
) + 1;
719 dwDependenciesLength
+= (DWORD
)cchLength
;
720 lpStr
= lpStr
+ cchLength
;
722 dwDependenciesLength
++;
725 if (lpPassword
!= NULL
)
727 /* Convert the password to unicode */
728 lpPasswordW
= HeapAlloc(GetProcessHeap(),
730 (strlen(lpPassword
) + 1) * sizeof(WCHAR
));
731 if (lpPasswordW
== NULL
)
733 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
737 MultiByteToWideChar(CP_ACP
,
742 (int)(strlen(lpPassword
) + 1));
744 /* Encrypt the password */
745 dwError
= ScmEncryptPassword(lpPasswordW
,
746 &lpEncryptedPassword
,
748 if (dwError
!= ERROR_SUCCESS
)
754 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
755 (LPSTR
)lpServiceName
,
756 (LPSTR
)lpDisplayName
,
761 (LPSTR
)lpBinaryPathName
,
762 (LPSTR
)lpLoadOrderGroup
,
764 (LPBYTE
)lpDependencies
,
765 dwDependenciesLength
,
766 (LPSTR
)lpServiceStartName
,
769 (SC_RPC_HANDLE
*)&hService
);
771 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
773 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
778 if (lpPasswordW
!= NULL
)
780 /* Wipe and release the password buffers */
781 SecureZeroMemory(lpPasswordW
, (wcslen(lpPasswordW
) + 1) * sizeof(WCHAR
));
782 HeapFree(GetProcessHeap(), 0, lpPasswordW
);
784 if (lpEncryptedPassword
!= NULL
)
786 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
787 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
791 SetLastError(dwError
);
792 if (dwError
!= ERROR_SUCCESS
)
794 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
802 /**********************************************************************
808 CreateServiceW(SC_HANDLE hSCManager
,
809 LPCWSTR lpServiceName
,
810 LPCWSTR lpDisplayName
,
811 DWORD dwDesiredAccess
,
814 DWORD dwErrorControl
,
815 LPCWSTR lpBinaryPathName
,
816 LPCWSTR lpLoadOrderGroup
,
818 LPCWSTR lpDependencies
,
819 LPCWSTR lpServiceStartName
,
822 SC_HANDLE hService
= NULL
;
823 DWORD dwDependenciesLength
= 0;
827 DWORD dwPasswordSize
= 0;
828 LPBYTE lpEncryptedPassword
= NULL
;
830 TRACE("CreateServiceW(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
831 hSCManager
, debugstr_w(lpServiceName
), debugstr_w(lpDisplayName
),
832 dwDesiredAccess
, dwServiceType
, dwStartType
, dwErrorControl
,
833 debugstr_w(lpBinaryPathName
), debugstr_w(lpLoadOrderGroup
), lpdwTagId
,
834 debugstr_w(lpDependencies
), debugstr_w(lpServiceStartName
), debugstr_w(lpPassword
));
838 SetLastError(ERROR_INVALID_HANDLE
);
842 /* Calculate the Dependencies length */
843 if (lpDependencies
!= NULL
)
845 lpStr
= lpDependencies
;
848 cchLength
= wcslen(lpStr
) + 1;
849 dwDependenciesLength
+= (DWORD
)cchLength
;
850 lpStr
= lpStr
+ cchLength
;
852 dwDependenciesLength
++;
853 dwDependenciesLength
*= sizeof(WCHAR
);
856 if (lpPassword
!= NULL
)
858 /* Encrypt the password */
859 dwError
= ScmEncryptPassword(lpPassword
,
860 &lpEncryptedPassword
,
862 if (dwError
!= ERROR_SUCCESS
)
868 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
878 (LPBYTE
)lpDependencies
,
879 dwDependenciesLength
,
883 (SC_RPC_HANDLE
*)&hService
);
885 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
887 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
892 if (lpEncryptedPassword
!= NULL
)
894 /* Wipe and release the password buffers */
895 SecureZeroMemory(lpEncryptedPassword
, dwPasswordSize
);
896 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword
);
899 SetLastError(dwError
);
900 if (dwError
!= ERROR_SUCCESS
)
902 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
910 /**********************************************************************
916 DeleteService(SC_HANDLE hService
)
920 TRACE("DeleteService(%p)\n",
925 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
927 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
929 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
933 if (dwError
!= ERROR_SUCCESS
)
935 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
936 SetLastError(dwError
);
944 /**********************************************************************
945 * EnumDependentServicesA
950 EnumDependentServicesA(SC_HANDLE hService
,
951 DWORD dwServiceState
,
952 LPENUM_SERVICE_STATUSA lpServices
,
954 LPDWORD pcbBytesNeeded
,
955 LPDWORD lpServicesReturned
)
957 ENUM_SERVICE_STATUSA ServiceStatus
;
958 LPENUM_SERVICE_STATUSA lpStatusPtr
;
963 TRACE("EnumDependentServicesA(%p %lu %p %lu %p %p)\n",
964 hService
, dwServiceState
, lpServices
, cbBufSize
,
965 pcbBytesNeeded
, lpServicesReturned
);
967 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
969 lpStatusPtr
= &ServiceStatus
;
970 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
974 lpStatusPtr
= lpServices
;
975 dwBufferSize
= cbBufSize
;
980 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
987 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
989 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
993 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
995 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
997 if (lpStatusPtr
->lpServiceName
)
998 lpStatusPtr
->lpServiceName
=
999 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1001 if (lpStatusPtr
->lpDisplayName
)
1002 lpStatusPtr
->lpDisplayName
=
1003 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1009 if (dwError
!= ERROR_SUCCESS
)
1011 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
1012 SetLastError(dwError
);
1016 TRACE("EnumDependentServicesA() done\n");
1022 /**********************************************************************
1023 * EnumDependentServicesW
1028 EnumDependentServicesW(SC_HANDLE hService
,
1029 DWORD dwServiceState
,
1030 LPENUM_SERVICE_STATUSW lpServices
,
1032 LPDWORD pcbBytesNeeded
,
1033 LPDWORD lpServicesReturned
)
1035 ENUM_SERVICE_STATUSW ServiceStatus
;
1036 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1041 TRACE("EnumDependentServicesW(%p %lu %p %lu %p %p)\n",
1042 hService
, dwServiceState
, lpServices
, cbBufSize
,
1043 pcbBytesNeeded
, lpServicesReturned
);
1045 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1047 lpStatusPtr
= &ServiceStatus
;
1048 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1052 lpStatusPtr
= lpServices
;
1053 dwBufferSize
= cbBufSize
;
1058 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
1060 (LPBYTE
)lpStatusPtr
,
1063 lpServicesReturned
);
1065 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1067 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1071 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1073 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1075 if (lpStatusPtr
->lpServiceName
)
1076 lpStatusPtr
->lpServiceName
=
1077 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1079 if (lpStatusPtr
->lpDisplayName
)
1080 lpStatusPtr
->lpDisplayName
=
1081 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1087 if (dwError
!= ERROR_SUCCESS
)
1089 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
1090 SetLastError(dwError
);
1094 TRACE("EnumDependentServicesW() done\n");
1100 /**********************************************************************
1106 EnumServiceGroupW(SC_HANDLE hSCManager
,
1107 DWORD dwServiceType
,
1108 DWORD dwServiceState
,
1109 LPENUM_SERVICE_STATUSW lpServices
,
1111 LPDWORD pcbBytesNeeded
,
1112 LPDWORD lpServicesReturned
,
1113 LPDWORD lpResumeHandle
,
1116 ENUM_SERVICE_STATUSW ServiceStatus
;
1117 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1122 TRACE("EnumServiceGroupW(%p %lu %lu %p %lu %p %p %p %s)\n",
1123 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1124 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
,
1125 lpResumeHandle
, debugstr_w(lpGroup
));
1129 SetLastError(ERROR_INVALID_HANDLE
);
1133 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1135 SetLastError(ERROR_INVALID_ADDRESS
);
1139 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1141 lpStatusPtr
= &ServiceStatus
;
1142 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1146 lpStatusPtr
= lpServices
;
1147 dwBufferSize
= cbBufSize
;
1152 if (lpGroup
== NULL
)
1154 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1157 (LPBYTE
)lpStatusPtr
,
1165 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
1168 (LPBYTE
)lpStatusPtr
,
1176 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1178 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1182 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1184 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1186 if (lpStatusPtr
->lpServiceName
)
1187 lpStatusPtr
->lpServiceName
=
1188 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1190 if (lpStatusPtr
->lpDisplayName
)
1191 lpStatusPtr
->lpDisplayName
=
1192 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1198 if (dwError
!= ERROR_SUCCESS
)
1200 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
1201 SetLastError(dwError
);
1205 TRACE("EnumServiceGroupW() done\n");
1211 /**********************************************************************
1212 * EnumServicesStatusA
1217 EnumServicesStatusA(SC_HANDLE hSCManager
,
1218 DWORD dwServiceType
,
1219 DWORD dwServiceState
,
1220 LPENUM_SERVICE_STATUSA lpServices
,
1222 LPDWORD pcbBytesNeeded
,
1223 LPDWORD lpServicesReturned
,
1224 LPDWORD lpResumeHandle
)
1226 ENUM_SERVICE_STATUSA ServiceStatus
;
1227 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1232 TRACE("EnumServicesStatusA(%p %lu %lu %p %lu %p %p %p)\n",
1233 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1234 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
);
1238 SetLastError(ERROR_INVALID_HANDLE
);
1242 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1244 SetLastError(ERROR_INVALID_ADDRESS
);
1248 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1250 lpStatusPtr
= &ServiceStatus
;
1251 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1255 lpStatusPtr
= lpServices
;
1256 dwBufferSize
= cbBufSize
;
1261 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1264 (LPBYTE
)lpStatusPtr
,
1270 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1272 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1276 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1278 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1280 if (lpStatusPtr
->lpServiceName
)
1281 lpStatusPtr
->lpServiceName
=
1282 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1284 if (lpStatusPtr
->lpDisplayName
)
1285 lpStatusPtr
->lpDisplayName
=
1286 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1292 if (dwError
!= ERROR_SUCCESS
)
1294 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1295 SetLastError(dwError
);
1299 TRACE("EnumServicesStatusA() done\n");
1305 /**********************************************************************
1306 * EnumServicesStatusW
1311 EnumServicesStatusW(SC_HANDLE hSCManager
,
1312 DWORD dwServiceType
,
1313 DWORD dwServiceState
,
1314 LPENUM_SERVICE_STATUSW lpServices
,
1316 LPDWORD pcbBytesNeeded
,
1317 LPDWORD lpServicesReturned
,
1318 LPDWORD lpResumeHandle
)
1320 ENUM_SERVICE_STATUSW ServiceStatus
;
1321 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1326 TRACE("EnumServicesStatusW(%p %lu %lu %p %lu %p %p %p)\n",
1327 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1328 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
);
1332 SetLastError(ERROR_INVALID_HANDLE
);
1336 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1338 SetLastError(ERROR_INVALID_ADDRESS
);
1342 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1344 lpStatusPtr
= &ServiceStatus
;
1345 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1349 lpStatusPtr
= lpServices
;
1350 dwBufferSize
= cbBufSize
;
1355 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1358 (LPBYTE
)lpStatusPtr
,
1364 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1366 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1370 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1372 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1374 if (lpStatusPtr
->lpServiceName
)
1375 lpStatusPtr
->lpServiceName
=
1376 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1378 if (lpStatusPtr
->lpDisplayName
)
1379 lpStatusPtr
->lpDisplayName
=
1380 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1386 if (dwError
!= ERROR_SUCCESS
)
1388 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1389 SetLastError(dwError
);
1393 TRACE("EnumServicesStatusW() done\n");
1399 /**********************************************************************
1400 * EnumServicesStatusExA
1405 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1406 SC_ENUM_TYPE InfoLevel
,
1407 DWORD dwServiceType
,
1408 DWORD dwServiceState
,
1411 LPDWORD pcbBytesNeeded
,
1412 LPDWORD lpServicesReturned
,
1413 LPDWORD lpResumeHandle
,
1414 LPCSTR pszGroupName
)
1416 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1417 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1422 TRACE("EnumServicesStatusExA(%p %lu %lu %p %lu %p %p %p %s)\n",
1423 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1424 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
,
1425 debugstr_a(pszGroupName
));
1427 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1429 SetLastError(ERROR_INVALID_LEVEL
);
1435 SetLastError(ERROR_INVALID_HANDLE
);
1439 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1441 SetLastError(ERROR_INVALID_ADDRESS
);
1445 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1447 lpStatusPtr
= &ServiceStatus
;
1448 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1452 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1453 dwBufferSize
= cbBufSize
;
1458 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1462 (LPBYTE
)lpStatusPtr
,
1467 (LPSTR
)pszGroupName
);
1469 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1471 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1475 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1477 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1479 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1481 if (lpStatusPtr
->lpServiceName
)
1482 lpStatusPtr
->lpServiceName
=
1483 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1485 if (lpStatusPtr
->lpDisplayName
)
1486 lpStatusPtr
->lpDisplayName
=
1487 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1494 if (dwError
!= ERROR_SUCCESS
)
1496 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1497 SetLastError(dwError
);
1501 TRACE("EnumServicesStatusExA() done\n");
1507 /**********************************************************************
1508 * EnumServicesStatusExW
1513 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1514 SC_ENUM_TYPE InfoLevel
,
1515 DWORD dwServiceType
,
1516 DWORD dwServiceState
,
1519 LPDWORD pcbBytesNeeded
,
1520 LPDWORD lpServicesReturned
,
1521 LPDWORD lpResumeHandle
,
1522 LPCWSTR pszGroupName
)
1524 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1525 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1530 TRACE("EnumServicesStatusExW(%p %lu %lu %p %lu %p %p %p %s)\n",
1531 hSCManager
, dwServiceType
, dwServiceState
, lpServices
,
1532 cbBufSize
, pcbBytesNeeded
, lpServicesReturned
, lpResumeHandle
,
1533 debugstr_w(pszGroupName
));
1535 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1537 SetLastError(ERROR_INVALID_LEVEL
);
1543 SetLastError(ERROR_INVALID_HANDLE
);
1547 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1549 SetLastError(ERROR_INVALID_ADDRESS
);
1553 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1555 lpStatusPtr
= &ServiceStatus
;
1556 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1560 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1561 dwBufferSize
= cbBufSize
;
1566 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1570 (LPBYTE
)lpStatusPtr
,
1575 (LPWSTR
)pszGroupName
);
1577 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1579 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1583 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1585 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1587 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1589 if (lpStatusPtr
->lpServiceName
)
1590 lpStatusPtr
->lpServiceName
=
1591 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1593 if (lpStatusPtr
->lpDisplayName
)
1594 lpStatusPtr
->lpDisplayName
=
1595 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1602 if (dwError
!= ERROR_SUCCESS
)
1604 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1605 SetLastError(dwError
);
1609 TRACE("EnumServicesStatusExW() done\n");
1615 /**********************************************************************
1616 * GetServiceDisplayNameA
1621 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1622 LPCSTR lpServiceName
,
1623 LPSTR lpDisplayName
,
1624 LPDWORD lpcchBuffer
)
1628 CHAR szEmptyName
[] = "";
1630 TRACE("GetServiceDisplayNameA(%p %s %p %p)\n",
1631 hSCManager
, debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1635 SetLastError(ERROR_INVALID_HANDLE
);
1639 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1641 lpNameBuffer
= szEmptyName
;
1642 *lpcchBuffer
= sizeof(CHAR
);
1646 lpNameBuffer
= lpDisplayName
;
1651 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1656 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1658 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1662 if (dwError
!= ERROR_SUCCESS
)
1664 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1665 SetLastError(dwError
);
1673 /**********************************************************************
1674 * GetServiceDisplayNameW
1679 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1680 LPCWSTR lpServiceName
,
1681 LPWSTR lpDisplayName
,
1682 LPDWORD lpcchBuffer
)
1685 LPWSTR lpNameBuffer
;
1686 WCHAR szEmptyName
[] = L
"";
1688 TRACE("GetServiceDisplayNameW(%p %s %p %p)\n",
1689 hSCManager
, debugstr_w(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1693 SetLastError(ERROR_INVALID_HANDLE
);
1698 * NOTE: A size of 1 character would be enough, but tests show that
1699 * Windows returns 2 characters instead, certainly due to a WCHAR/bytes
1700 * mismatch in their code.
1702 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1704 lpNameBuffer
= szEmptyName
;
1705 *lpcchBuffer
= sizeof(WCHAR
);
1709 lpNameBuffer
= lpDisplayName
;
1714 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1719 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1721 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1725 if (dwError
!= ERROR_SUCCESS
)
1727 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1728 SetLastError(dwError
);
1736 /**********************************************************************
1737 * GetServiceKeyNameA
1742 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1743 LPCSTR lpDisplayName
,
1744 LPSTR lpServiceName
,
1745 LPDWORD lpcchBuffer
)
1749 CHAR szEmptyName
[] = "";
1751 TRACE("GetServiceKeyNameA(%p %s %p %p)\n",
1752 hSCManager
, debugstr_a(lpDisplayName
), lpServiceName
, lpcchBuffer
);
1756 SetLastError(ERROR_INVALID_HANDLE
);
1760 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1762 lpNameBuffer
= szEmptyName
;
1763 *lpcchBuffer
= sizeof(CHAR
);
1767 lpNameBuffer
= lpServiceName
;
1772 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1777 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1779 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1780 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1784 if (dwError
!= ERROR_SUCCESS
)
1786 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1787 SetLastError(dwError
);
1795 /**********************************************************************
1796 * GetServiceKeyNameW
1801 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1802 LPCWSTR lpDisplayName
,
1803 LPWSTR lpServiceName
,
1804 LPDWORD lpcchBuffer
)
1807 LPWSTR lpNameBuffer
;
1808 WCHAR szEmptyName
[] = L
"";
1810 TRACE("GetServiceKeyNameW(%p %s %p %p)\n",
1811 hSCManager
, debugstr_w(lpDisplayName
), lpServiceName
, lpcchBuffer
);
1815 SetLastError(ERROR_INVALID_HANDLE
);
1820 * NOTE: A size of 1 character would be enough, but tests show that
1821 * Windows returns 2 characters instead, certainly due to a WCHAR/bytes
1822 * mismatch in their code.
1824 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1826 lpNameBuffer
= szEmptyName
;
1827 *lpcchBuffer
= sizeof(WCHAR
);
1831 lpNameBuffer
= lpServiceName
;
1836 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1841 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1843 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1847 if (dwError
!= ERROR_SUCCESS
)
1849 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1850 SetLastError(dwError
);
1858 /**********************************************************************
1859 * I_ScGetCurrentGroupStateW
1864 I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager
,
1865 LPWSTR pszGroupName
,
1866 LPDWORD pdwGroupState
)
1870 TRACE("I_ScGetCurrentGroupStateW(%p %s %p)\n",
1871 hSCManager
, debugstr_w(pszGroupName
), pdwGroupState
);
1875 dwError
= RI_ScGetCurrentGroupStateW((SC_RPC_HANDLE
)hSCManager
,
1879 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1881 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1885 if (dwError
!= ERROR_SUCCESS
)
1887 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError
);
1888 SetLastError(dwError
);
1895 /**********************************************************************
1896 * LockServiceDatabase
1901 LockServiceDatabase(SC_HANDLE hSCManager
)
1906 TRACE("LockServiceDatabase(%p)\n",
1911 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1912 (SC_RPC_LOCK
*)&hLock
);
1914 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1916 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1920 if (dwError
!= ERROR_SUCCESS
)
1922 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1923 SetLastError(dwError
);
1927 TRACE("hLock = %p\n", hLock
);
1934 WaitForSCManager(VOID
)
1938 TRACE("WaitForSCManager()\n");
1940 /* Try to open the existing event */
1941 hEvent
= OpenEventW(SYNCHRONIZE
, FALSE
, SCM_START_EVENT
);
1944 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1947 /* Try to create a new event */
1948 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
1953 /* Wait for 3 minutes */
1954 WaitForSingleObject(hEvent
, 180000);
1955 CloseHandle(hEvent
);
1957 TRACE("ScmWaitForSCManager() done\n");
1961 /**********************************************************************
1967 OpenSCManagerA(LPCSTR lpMachineName
,
1968 LPCSTR lpDatabaseName
,
1969 DWORD dwDesiredAccess
)
1971 SC_HANDLE hScm
= NULL
;
1974 TRACE("OpenSCManagerA(%s %s %lx)\n",
1975 debugstr_a(lpMachineName
), debugstr_a(lpDatabaseName
), dwDesiredAccess
);
1981 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1982 (LPSTR
)lpDatabaseName
,
1984 (SC_RPC_HANDLE
*)&hScm
);
1986 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1988 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1992 if (dwError
!= ERROR_SUCCESS
)
1994 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1995 SetLastError(dwError
);
1999 TRACE("hScm = %p\n", hScm
);
2005 /**********************************************************************
2011 OpenSCManagerW(LPCWSTR lpMachineName
,
2012 LPCWSTR lpDatabaseName
,
2013 DWORD dwDesiredAccess
)
2015 SC_HANDLE hScm
= NULL
;
2018 TRACE("OpenSCManagerW(%s %s %lx)\n",
2019 debugstr_w(lpMachineName
), debugstr_w(lpDatabaseName
), dwDesiredAccess
);
2025 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
2026 (LPWSTR
)lpDatabaseName
,
2028 (SC_RPC_HANDLE
*)&hScm
);
2030 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2032 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2036 if (dwError
!= ERROR_SUCCESS
)
2038 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
2039 SetLastError(dwError
);
2043 TRACE("hScm = %p\n", hScm
);
2049 /**********************************************************************
2055 OpenServiceA(SC_HANDLE hSCManager
,
2056 LPCSTR lpServiceName
,
2057 DWORD dwDesiredAccess
)
2059 SC_HANDLE hService
= NULL
;
2062 TRACE("OpenServiceA(%p %s %lx)\n",
2063 hSCManager
, debugstr_a(lpServiceName
), dwDesiredAccess
);
2067 SetLastError(ERROR_INVALID_HANDLE
);
2073 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
2074 (LPSTR
)lpServiceName
,
2076 (SC_RPC_HANDLE
*)&hService
);
2078 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2080 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2084 SetLastError(dwError
);
2085 if (dwError
!= ERROR_SUCCESS
)
2087 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
2091 TRACE("hService = %p\n", hService
);
2097 /**********************************************************************
2103 OpenServiceW(SC_HANDLE hSCManager
,
2104 LPCWSTR lpServiceName
,
2105 DWORD dwDesiredAccess
)
2107 SC_HANDLE hService
= NULL
;
2110 TRACE("OpenServiceW(%p %s %lx)\n",
2111 hSCManager
, debugstr_w(lpServiceName
), dwDesiredAccess
);
2115 SetLastError(ERROR_INVALID_HANDLE
);
2121 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
2122 (LPWSTR
)lpServiceName
,
2124 (SC_RPC_HANDLE
*)&hService
);
2126 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2128 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2132 SetLastError(dwError
);
2133 if (dwError
!= ERROR_SUCCESS
)
2135 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
2139 TRACE("hService = %p\n", hService
);
2145 /**********************************************************************
2146 * QueryServiceConfigA
2151 QueryServiceConfigA(SC_HANDLE hService
,
2152 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
2154 LPDWORD pcbBytesNeeded
)
2156 QUERY_SERVICE_CONFIGA ServiceConfig
;
2157 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
2161 TRACE("QueryServiceConfigA(%p %p %lu %p)\n",
2162 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2164 if (lpServiceConfig
== NULL
||
2165 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
2167 lpConfigPtr
= &ServiceConfig
;
2168 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
2172 lpConfigPtr
= lpServiceConfig
;
2173 dwBufferSize
= cbBufSize
;
2178 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
2179 (LPBYTE
)lpConfigPtr
,
2183 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2185 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2189 if (dwError
!= ERROR_SUCCESS
)
2191 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
2192 SetLastError(dwError
);
2196 /* Adjust the pointers */
2197 if (lpConfigPtr
->lpBinaryPathName
)
2198 lpConfigPtr
->lpBinaryPathName
=
2199 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2200 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2202 if (lpConfigPtr
->lpLoadOrderGroup
)
2203 lpConfigPtr
->lpLoadOrderGroup
=
2204 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2205 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2207 if (lpConfigPtr
->lpDependencies
)
2208 lpConfigPtr
->lpDependencies
=
2209 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2210 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2212 if (lpConfigPtr
->lpServiceStartName
)
2213 lpConfigPtr
->lpServiceStartName
=
2214 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2215 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2217 if (lpConfigPtr
->lpDisplayName
)
2218 lpConfigPtr
->lpDisplayName
=
2219 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
2220 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2222 TRACE("QueryServiceConfigA() done\n");
2228 /**********************************************************************
2229 * QueryServiceConfigW
2234 QueryServiceConfigW(SC_HANDLE hService
,
2235 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
2237 LPDWORD pcbBytesNeeded
)
2239 QUERY_SERVICE_CONFIGW ServiceConfig
;
2240 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
2244 TRACE("QueryServiceConfigW(%p %p %lu %p)\n",
2245 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
2247 if (lpServiceConfig
== NULL
||
2248 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2250 lpConfigPtr
= &ServiceConfig
;
2251 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2255 lpConfigPtr
= lpServiceConfig
;
2256 dwBufferSize
= cbBufSize
;
2261 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2262 (LPBYTE
)lpConfigPtr
,
2266 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2268 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2272 if (dwError
!= ERROR_SUCCESS
)
2274 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2275 SetLastError(dwError
);
2279 /* Adjust the pointers */
2280 if (lpConfigPtr
->lpBinaryPathName
)
2281 lpConfigPtr
->lpBinaryPathName
=
2282 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2283 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2285 if (lpConfigPtr
->lpLoadOrderGroup
)
2286 lpConfigPtr
->lpLoadOrderGroup
=
2287 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2288 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2290 if (lpConfigPtr
->lpDependencies
)
2291 lpConfigPtr
->lpDependencies
=
2292 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2293 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2295 if (lpConfigPtr
->lpServiceStartName
)
2296 lpConfigPtr
->lpServiceStartName
=
2297 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2298 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2300 if (lpConfigPtr
->lpDisplayName
)
2301 lpConfigPtr
->lpDisplayName
=
2302 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2303 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2305 TRACE("QueryServiceConfigW() done\n");
2311 /**********************************************************************
2312 * QueryServiceConfig2A
2317 QueryServiceConfig2A(SC_HANDLE hService
,
2321 LPDWORD pcbBytesNeeded
)
2323 SERVICE_DESCRIPTIONA ServiceDescription
;
2324 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2325 LPBYTE lpTempBuffer
;
2326 BOOL bUseTempBuffer
= FALSE
;
2330 TRACE("QueryServiceConfig2A(%p %lu %p %lu %p)\n",
2331 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2333 lpTempBuffer
= lpBuffer
;
2334 dwBufferSize
= cbBufSize
;
2336 switch (dwInfoLevel
)
2338 case SERVICE_CONFIG_DESCRIPTION
:
2339 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2341 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2342 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2343 bUseTempBuffer
= TRUE
;
2347 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2348 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2350 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2351 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2352 bUseTempBuffer
= TRUE
;
2357 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2358 SetLastError(ERROR_INVALID_LEVEL
);
2364 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2370 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2372 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2376 if (dwError
!= ERROR_SUCCESS
)
2378 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2379 SetLastError(dwError
);
2383 if (bUseTempBuffer
!= FALSE
)
2385 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2386 *pcbBytesNeeded
= dwBufferSize
;
2387 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2391 switch (dwInfoLevel
)
2393 case SERVICE_CONFIG_DESCRIPTION
:
2395 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2397 if (lpPtr
->lpDescription
!= NULL
)
2398 lpPtr
->lpDescription
=
2399 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2403 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2405 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2407 if (lpPtr
->lpRebootMsg
!= NULL
)
2408 lpPtr
->lpRebootMsg
=
2409 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2411 if (lpPtr
->lpCommand
!= NULL
)
2413 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2415 if (lpPtr
->lpsaActions
!= NULL
)
2416 lpPtr
->lpsaActions
=
2417 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2422 TRACE("QueryServiceConfig2A() done\n");
2428 /**********************************************************************
2429 * QueryServiceConfig2W
2434 QueryServiceConfig2W(SC_HANDLE hService
,
2438 LPDWORD pcbBytesNeeded
)
2440 SERVICE_DESCRIPTIONW ServiceDescription
;
2441 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2442 LPBYTE lpTempBuffer
;
2443 BOOL bUseTempBuffer
= FALSE
;
2447 TRACE("QueryServiceConfig2W(%p %lu %p %lu %p)\n",
2448 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2450 lpTempBuffer
= lpBuffer
;
2451 dwBufferSize
= cbBufSize
;
2453 switch (dwInfoLevel
)
2455 case SERVICE_CONFIG_DESCRIPTION
:
2456 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2458 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2459 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2460 bUseTempBuffer
= TRUE
;
2464 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2465 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2467 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2468 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2469 bUseTempBuffer
= TRUE
;
2474 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2475 SetLastError(ERROR_INVALID_LEVEL
);
2481 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2487 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2489 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2493 if (dwError
!= ERROR_SUCCESS
)
2495 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2496 SetLastError(dwError
);
2500 if (bUseTempBuffer
!= FALSE
)
2502 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2503 *pcbBytesNeeded
= dwBufferSize
;
2504 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2508 switch (dwInfoLevel
)
2510 case SERVICE_CONFIG_DESCRIPTION
:
2512 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2514 if (lpPtr
->lpDescription
!= NULL
)
2515 lpPtr
->lpDescription
=
2516 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2520 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2522 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2524 if (lpPtr
->lpRebootMsg
!= NULL
)
2525 lpPtr
->lpRebootMsg
=
2526 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2528 if (lpPtr
->lpCommand
!= NULL
)
2530 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2532 if (lpPtr
->lpsaActions
!= NULL
)
2533 lpPtr
->lpsaActions
=
2534 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2539 TRACE("QueryServiceConfig2W() done\n");
2545 /**********************************************************************
2546 * QueryServiceLockStatusA
2551 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2552 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2554 LPDWORD pcbBytesNeeded
)
2556 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2557 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2561 TRACE("QueryServiceLockStatusA(%p %p %lu %p)\n",
2562 hSCManager
, lpLockStatus
, cbBufSize
, pcbBytesNeeded
);
2564 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2566 lpStatusPtr
= &LockStatus
;
2567 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2571 lpStatusPtr
= lpLockStatus
;
2572 dwBufferSize
= cbBufSize
;
2577 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2578 (LPBYTE
)lpStatusPtr
,
2582 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2584 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2588 if (dwError
!= ERROR_SUCCESS
)
2590 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2591 SetLastError(dwError
);
2595 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2597 lpStatusPtr
->lpLockOwner
=
2598 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2601 TRACE("QueryServiceLockStatusA() done\n");
2607 /**********************************************************************
2608 * QueryServiceLockStatusW
2613 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2614 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2616 LPDWORD pcbBytesNeeded
)
2618 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2619 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2623 TRACE("QueryServiceLockStatusW(%p %p %lu %p)\n",
2624 hSCManager
, lpLockStatus
, cbBufSize
, pcbBytesNeeded
);
2626 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2628 lpStatusPtr
= &LockStatus
;
2629 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2633 lpStatusPtr
= lpLockStatus
;
2634 dwBufferSize
= cbBufSize
;
2639 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2640 (LPBYTE
)lpStatusPtr
,
2644 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2646 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2650 if (dwError
!= ERROR_SUCCESS
)
2652 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2653 SetLastError(dwError
);
2657 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2659 lpStatusPtr
->lpLockOwner
=
2660 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2663 TRACE("QueryServiceLockStatusW() done\n");
2669 /**********************************************************************
2670 * QueryServiceObjectSecurity
2675 QueryServiceObjectSecurity(SC_HANDLE hService
,
2676 SECURITY_INFORMATION dwSecurityInformation
,
2677 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2679 LPDWORD pcbBytesNeeded
)
2683 TRACE("QueryServiceObjectSecurity(%p %lu %p)\n",
2684 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2688 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2689 dwSecurityInformation
,
2690 (LPBYTE
)lpSecurityDescriptor
,
2694 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2696 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2700 if (dwError
!= ERROR_SUCCESS
)
2702 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2703 SetLastError(dwError
);
2711 /**********************************************************************
2712 * SetServiceObjectSecurity
2717 SetServiceObjectSecurity(SC_HANDLE hService
,
2718 SECURITY_INFORMATION dwSecurityInformation
,
2719 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2721 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2726 TRACE("SetServiceObjectSecurity(%p %lu %p)\n",
2727 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2730 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2733 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2735 SetLastError(ERROR_INVALID_PARAMETER
);
2739 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2740 if (SelfRelativeSD
== NULL
)
2742 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2746 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2749 if (!NT_SUCCESS(Status
))
2751 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2752 SetLastError(RtlNtStatusToDosError(Status
));
2758 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2759 dwSecurityInformation
,
2760 (LPBYTE
)SelfRelativeSD
,
2763 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2765 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2769 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2771 if (dwError
!= ERROR_SUCCESS
)
2773 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2774 SetLastError(dwError
);
2782 /**********************************************************************
2783 * QueryServiceStatus
2788 QueryServiceStatus(SC_HANDLE hService
,
2789 LPSERVICE_STATUS lpServiceStatus
)
2793 TRACE("QueryServiceStatus(%p %p)\n",
2794 hService
, lpServiceStatus
);
2798 SetLastError(ERROR_INVALID_HANDLE
);
2804 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2807 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2809 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2813 if (dwError
!= ERROR_SUCCESS
)
2815 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2816 SetLastError(dwError
);
2824 /**********************************************************************
2825 * QueryServiceStatusEx
2830 QueryServiceStatusEx(SC_HANDLE hService
,
2831 SC_STATUS_TYPE InfoLevel
,
2834 LPDWORD pcbBytesNeeded
)
2838 TRACE("QueryServiceStatusEx(%p %lu %p %lu %p)\n",
2839 hService
, InfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2841 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2843 SetLastError(ERROR_INVALID_LEVEL
);
2847 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2849 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2850 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2856 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2862 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2864 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2868 if (dwError
!= ERROR_SUCCESS
)
2870 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2871 SetLastError(dwError
);
2879 /**********************************************************************
2885 StartServiceA(SC_HANDLE hService
,
2886 DWORD dwNumServiceArgs
,
2887 LPCSTR
*lpServiceArgVectors
)
2891 TRACE("StartServiceA(%p %lu %p)\n",
2892 hService
, dwNumServiceArgs
, lpServiceArgVectors
);
2896 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2898 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2900 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2902 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2906 if (dwError
!= ERROR_SUCCESS
)
2908 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2909 SetLastError(dwError
);
2917 /**********************************************************************
2923 StartServiceW(SC_HANDLE hService
,
2924 DWORD dwNumServiceArgs
,
2925 LPCWSTR
*lpServiceArgVectors
)
2929 TRACE("StartServiceW(%p %lu %p)\n",
2930 hService
, dwNumServiceArgs
, lpServiceArgVectors
);
2934 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2936 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2938 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2940 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2944 if (dwError
!= ERROR_SUCCESS
)
2946 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2947 SetLastError(dwError
);
2955 /**********************************************************************
2956 * UnlockServiceDatabase
2961 UnlockServiceDatabase(SC_LOCK ScLock
)
2965 TRACE("UnlockServiceDatabase(%x)\n",
2970 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2972 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2974 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2978 if (dwError
== ERROR_INVALID_HANDLE
)
2979 dwError
= ERROR_INVALID_SERVICE_LOCK
;
2981 if (dwError
!= ERROR_SUCCESS
)
2983 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2984 SetLastError(dwError
);
2992 /**********************************************************************
2993 * NotifyBootConfigStatus
2998 NotifyBootConfigStatus(BOOL BootAcceptable
)
3002 TRACE("NotifyBootConfigStatus(%u)\n",
3007 dwError
= RNotifyBootConfigStatus(NULL
,
3010 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
3012 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
3016 if (dwError
!= ERROR_SUCCESS
)
3018 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
3019 SetLastError(dwError
);
3027 I_ScQueryServiceTagInfo(PVOID Unused
,
3028 TAG_INFO_LEVEL dwInfoLevel
,
3029 PTAG_INFO_NAME_FROM_TAG InOutParams
)
3033 PTAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams
;
3034 PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS OutParams
;
3037 /* We only support one class */
3038 if (dwInfoLevel
!= TagInfoLevelNameFromTag
)
3043 /* Validate input structure */
3044 if (InOutParams
->InParams
.dwPid
== 0 || InOutParams
->InParams
.dwTag
== 0)
3046 return ERROR_INVALID_PARAMETER
;
3049 /* Validate output structure */
3050 if (InOutParams
->OutParams
.pszName
!= NULL
)
3052 return ERROR_INVALID_PARAMETER
;
3055 /* Open service manager */
3056 hScm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
3059 return GetLastError();
3062 /* Setup call parameters */
3063 InParams
= &InOutParams
->InParams
;
3066 /* Call SCM to query tag information */
3069 dwError
= RI_ScQueryServiceTagInfo(hScm
, TagInfoLevelNameFromTag
, &InParams
, &OutParams
);
3071 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
3073 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
3077 /* Quit if not a success */
3078 if (dwError
!= ERROR_SUCCESS
)
3083 /* OutParams must be set now and we must have a name */
3084 if (OutParams
== NULL
||
3085 OutParams
->pszName
== NULL
)
3087 dwError
= ERROR_INVALID_DATA
;
3091 /* Copy back what SCM returned */
3092 lpszName
= LocalAlloc(LPTR
,
3093 sizeof(WCHAR
) * wcslen(OutParams
->pszName
) + sizeof(UNICODE_NULL
));
3094 if (lpszName
== NULL
)
3096 dwError
= GetLastError();
3100 wcscpy(lpszName
, OutParams
->pszName
);
3101 InOutParams
->OutParams
.pszName
= lpszName
;
3102 InOutParams
->OutParams
.TagType
= OutParams
->TagType
;
3105 CloseServiceHandle(hScm
);
3107 /* Free memory allocated by SCM */
3108 if (OutParams
!= NULL
)
3110 if (OutParams
->pszName
!= NULL
)
3112 midl_user_free(OutParams
->pszName
);
3115 midl_user_free(OutParams
);
3121 /**********************************************************************
3122 * I_QueryTagInformation
3127 I_QueryTagInformation(PVOID Unused
,
3128 TAG_INFO_LEVEL dwInfoLevel
,
3129 PTAG_INFO_NAME_FROM_TAG InOutParams
)
3132 * We only support one information class and it
3135 if (dwInfoLevel
!= TagInfoLevelNameFromTag
||
3136 InOutParams
== NULL
)
3138 return ERROR_INVALID_PARAMETER
;
3141 /* Validate input structure */
3142 if (InOutParams
->InParams
.dwPid
== 0 || InOutParams
->InParams
.dwTag
== 0)
3144 return ERROR_INVALID_PARAMETER
;
3147 /* Validate output structure */
3148 if (InOutParams
->OutParams
.pszName
!= NULL
)
3150 return ERROR_INVALID_PARAMETER
;
3153 /* Call internal function for the RPC call */
3154 return I_ScQueryServiceTagInfo(Unused
, TagInfoLevelNameFromTag
, InOutParams
);