2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/service/scm.c
5 * PURPOSE: Service control manager functions
6 * PROGRAMMER: Emanuele Aliberti
13 /* INCLUDES ******************************************************************/
16 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
19 /* FUNCTIONS *****************************************************************/
22 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName
)
24 handle_t hBinding
= NULL
;
25 UCHAR
*pszStringBinding
;
28 TRACE("SVCCTL_HANDLEA_bind() called\n");
30 status
= RpcStringBindingComposeA(NULL
,
32 (UCHAR
*)szMachineName
,
33 (UCHAR
*)"\\pipe\\ntsvcs",
35 (UCHAR
**)&pszStringBinding
);
36 if (status
!= RPC_S_OK
)
38 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
42 /* Set the binding handle that will be used to bind to the server. */
43 status
= RpcBindingFromStringBindingA(pszStringBinding
,
45 if (status
!= RPC_S_OK
)
47 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
50 status
= RpcStringFreeA(&pszStringBinding
);
51 if (status
!= RPC_S_OK
)
53 ERR("RpcStringFree returned 0x%x\n", status
);
61 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName
,
66 TRACE("SVCCTL_HANDLEA_unbind() called\n");
68 status
= RpcBindingFree(&hBinding
);
69 if (status
!= RPC_S_OK
)
71 ERR("RpcBindingFree returned 0x%x\n", status
);
77 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName
)
79 handle_t hBinding
= NULL
;
80 LPWSTR pszStringBinding
;
83 TRACE("SVCCTL_HANDLEW_bind() called\n");
85 status
= RpcStringBindingComposeW(NULL
,
91 if (status
!= RPC_S_OK
)
93 ERR("RpcStringBindingCompose returned 0x%x\n", status
);
97 /* Set the binding handle that will be used to bind to the server. */
98 status
= RpcBindingFromStringBindingW(pszStringBinding
,
100 if (status
!= RPC_S_OK
)
102 ERR("RpcBindingFromStringBinding returned 0x%x\n", status
);
105 status
= RpcStringFreeW(&pszStringBinding
);
106 if (status
!= RPC_S_OK
)
108 ERR("RpcStringFree returned 0x%x\n", status
);
116 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName
,
121 TRACE("SVCCTL_HANDLEW_unbind() called\n");
123 status
= RpcBindingFree(&hBinding
);
124 if (status
!= RPC_S_OK
)
126 ERR("RpcBindingFree returned 0x%x\n", status
);
132 ScmRpcStatusToWinError(RPC_STATUS Status
)
136 case RPC_S_INVALID_BINDING
:
137 case RPC_X_SS_IN_NULL_CONTEXT
:
138 return ERROR_INVALID_HANDLE
;
140 case RPC_X_ENUM_VALUE_OUT_OF_RANGE
:
141 case RPC_X_BYTE_COUNT_TOO_SMALL
:
142 return ERROR_INVALID_PARAMETER
;
144 case RPC_X_NULL_REF_POINTER
:
145 return ERROR_INVALID_ADDRESS
;
148 return (DWORD
)Status
;
153 /**********************************************************************
154 * ChangeServiceConfig2A
159 ChangeServiceConfig2A(SC_HANDLE hService
,
163 SC_RPC_CONFIG_INFOA Info
;
166 TRACE("ChangeServiceConfig2A() called\n");
168 if (lpInfo
== NULL
) return TRUE
;
170 /* Fill relevent field of the Info structure */
171 Info
.dwInfoLevel
= dwInfoLevel
;
174 case SERVICE_CONFIG_DESCRIPTION
:
175 Info
.psd
= (LPSERVICE_DESCRIPTIONA
)&lpInfo
;
176 Info
.lpDescription
= ((LPSERVICE_DESCRIPTIONA
)lpInfo
)->lpDescription
; //HACK
179 case SERVICE_CONFIG_FAILURE_ACTIONS
:
180 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSA
)lpInfo
;
184 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
185 SetLastError(ERROR_INVALID_PARAMETER
);
191 dwError
= RChangeServiceConfig2A((SC_RPC_HANDLE
)hService
,
194 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
196 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
200 if (dwError
!= ERROR_SUCCESS
)
202 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError
);
203 SetLastError(dwError
);
211 /**********************************************************************
212 * ChangeServiceConfig2W
217 ChangeServiceConfig2W(SC_HANDLE hService
,
221 SC_RPC_CONFIG_INFOW Info
;
224 TRACE("ChangeServiceConfig2W() called\n");
226 if (lpInfo
== NULL
) return TRUE
;
228 /* Fill relevent field of the Info structure */
229 Info
.dwInfoLevel
= dwInfoLevel
;
232 case SERVICE_CONFIG_DESCRIPTION
:
233 Info
.psd
= (LPSERVICE_DESCRIPTIONW
)lpInfo
;
236 case SERVICE_CONFIG_FAILURE_ACTIONS
:
237 Info
.psfa
= (LPSERVICE_FAILURE_ACTIONSW
)lpInfo
;
241 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
242 SetLastError(ERROR_INVALID_PARAMETER
);
248 dwError
= RChangeServiceConfig2W((SC_RPC_HANDLE
)hService
,
251 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
253 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
257 if (dwError
!= ERROR_SUCCESS
)
259 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError
);
260 SetLastError(dwError
);
268 /**********************************************************************
269 * ChangeServiceConfigA
274 ChangeServiceConfigA(SC_HANDLE hService
,
277 DWORD dwErrorControl
,
278 LPCSTR lpBinaryPathName
,
279 LPCSTR lpLoadOrderGroup
,
281 LPCSTR lpDependencies
,
282 LPCSTR lpServiceStartName
,
284 LPCSTR lpDisplayName
)
287 DWORD dwDependenciesLength
= 0;
290 DWORD dwPasswordLength
= 0;
291 LPBYTE lpEncryptedPassword
= NULL
;
293 TRACE("ChangeServiceConfigA() called\n");
295 /* Calculate the Dependencies length*/
296 if (lpDependencies
!= NULL
)
298 lpStr
= lpDependencies
;
301 cchLength
= strlen(lpStr
) + 1;
302 dwDependenciesLength
+= (DWORD
)cchLength
;
303 lpStr
= lpStr
+ cchLength
;
305 dwDependenciesLength
++;
308 /* FIXME: Encrypt the password */
309 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
310 dwPasswordLength
= (DWORD
)(lpPassword
? (strlen(lpPassword
) + 1) * sizeof(CHAR
) : 0);
314 /* Call to services.exe using RPC */
315 dwError
= RChangeServiceConfigA((SC_RPC_HANDLE
)hService
,
319 (LPSTR
)lpBinaryPathName
,
320 (LPSTR
)lpLoadOrderGroup
,
322 (LPBYTE
)lpDependencies
,
323 dwDependenciesLength
,
324 (LPSTR
)lpServiceStartName
,
327 (LPSTR
)lpDisplayName
);
329 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
331 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
335 if (dwError
!= ERROR_SUCCESS
)
337 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError
);
338 SetLastError(dwError
);
346 /**********************************************************************
347 * ChangeServiceConfigW
352 ChangeServiceConfigW(SC_HANDLE hService
,
355 DWORD dwErrorControl
,
356 LPCWSTR lpBinaryPathName
,
357 LPCWSTR lpLoadOrderGroup
,
359 LPCWSTR lpDependencies
,
360 LPCWSTR lpServiceStartName
,
362 LPCWSTR lpDisplayName
)
365 DWORD dwDependenciesLength
= 0;
368 DWORD dwPasswordLength
= 0;
369 LPBYTE lpEncryptedPassword
= NULL
;
371 TRACE("ChangeServiceConfigW() called\n");
373 /* Calculate the Dependencies length*/
374 if (lpDependencies
!= NULL
)
376 lpStr
= lpDependencies
;
379 cchLength
= wcslen(lpStr
) + 1;
380 dwDependenciesLength
+= (DWORD
)cchLength
;
381 lpStr
= lpStr
+ cchLength
;
383 dwDependenciesLength
++;
384 dwDependenciesLength
*= sizeof(WCHAR
);
387 /* FIXME: Encrypt the password */
388 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
389 dwPasswordLength
= (lpPassword
? (wcslen(lpPassword
) + 1) * sizeof(WCHAR
) : 0);
393 /* Call to services.exe using RPC */
394 dwError
= RChangeServiceConfigW((SC_RPC_HANDLE
)hService
,
398 (LPWSTR
)lpBinaryPathName
,
399 (LPWSTR
)lpLoadOrderGroup
,
401 (LPBYTE
)lpDependencies
,
402 dwDependenciesLength
,
403 (LPWSTR
)lpServiceStartName
,
406 (LPWSTR
)lpDisplayName
);
408 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
410 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
414 if (dwError
!= ERROR_SUCCESS
)
416 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError
);
417 SetLastError(dwError
);
425 /**********************************************************************
431 CloseServiceHandle(SC_HANDLE hSCObject
)
435 TRACE("CloseServiceHandle() called\n");
439 SetLastError(ERROR_INVALID_HANDLE
);
445 /* Call to services.exe using RPC */
446 dwError
= RCloseServiceHandle((LPSC_RPC_HANDLE
)&hSCObject
);
448 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
450 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
456 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError
);
457 SetLastError(dwError
);
461 TRACE("CloseServiceHandle() done\n");
467 /**********************************************************************
473 ControlService(SC_HANDLE hService
,
475 LPSERVICE_STATUS lpServiceStatus
)
479 TRACE("ControlService(%x, %x, %p)\n",
480 hService
, dwControl
, lpServiceStatus
);
484 /* Call to services.exe using RPC */
485 dwError
= RControlService((SC_RPC_HANDLE
)hService
,
489 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
491 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
495 if (dwError
!= ERROR_SUCCESS
)
497 TRACE("RControlService() failed (Error %lu)\n", dwError
);
498 SetLastError(dwError
);
502 TRACE("ControlService() done\n");
508 /**********************************************************************
514 ControlServiceEx(IN SC_HANDLE hService
,
516 IN DWORD dwInfoLevel
,
517 IN OUT PVOID pControlParams
)
519 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
520 hService
, dwControl
, dwInfoLevel
, pControlParams
);
521 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
526 /**********************************************************************
532 CreateServiceA(SC_HANDLE hSCManager
,
533 LPCSTR lpServiceName
,
534 LPCSTR lpDisplayName
,
535 DWORD dwDesiredAccess
,
538 DWORD dwErrorControl
,
539 LPCSTR lpBinaryPathName
,
540 LPCSTR lpLoadOrderGroup
,
542 LPCSTR lpDependencies
,
543 LPCSTR lpServiceStartName
,
546 SC_HANDLE hService
= NULL
;
547 DWORD dwDependenciesLength
= 0;
551 DWORD dwPasswordLength
= 0;
552 LPBYTE lpEncryptedPassword
= NULL
;
554 TRACE("CreateServiceA() called\n");
555 TRACE("%p %s %s\n", hSCManager
,
556 lpServiceName
, lpDisplayName
);
560 SetLastError(ERROR_INVALID_HANDLE
);
564 /* Calculate the Dependencies length */
565 if (lpDependencies
!= NULL
)
567 lpStr
= lpDependencies
;
570 cchLength
= strlen(lpStr
) + 1;
571 dwDependenciesLength
+= (DWORD
)cchLength
;
572 lpStr
= lpStr
+ cchLength
;
574 dwDependenciesLength
++;
577 /* FIXME: Encrypt the password */
578 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
579 dwPasswordLength
= (DWORD
)(lpPassword
? (strlen(lpPassword
) + 1) * sizeof(CHAR
) : 0);
583 /* Call to services.exe using RPC */
584 dwError
= RCreateServiceA((SC_RPC_HANDLE
)hSCManager
,
585 (LPSTR
)lpServiceName
,
586 (LPSTR
)lpDisplayName
,
591 (LPSTR
)lpBinaryPathName
,
592 (LPSTR
)lpLoadOrderGroup
,
594 (LPBYTE
)lpDependencies
,
595 dwDependenciesLength
,
596 (LPSTR
)lpServiceStartName
,
599 (SC_RPC_HANDLE
*)&hService
);
601 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
603 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
607 if (dwError
!= ERROR_SUCCESS
)
609 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError
);
610 SetLastError(dwError
);
618 /**********************************************************************
624 CreateServiceW(SC_HANDLE hSCManager
,
625 LPCWSTR lpServiceName
,
626 LPCWSTR lpDisplayName
,
627 DWORD dwDesiredAccess
,
630 DWORD dwErrorControl
,
631 LPCWSTR lpBinaryPathName
,
632 LPCWSTR lpLoadOrderGroup
,
634 LPCWSTR lpDependencies
,
635 LPCWSTR lpServiceStartName
,
638 SC_HANDLE hService
= NULL
;
639 DWORD dwDependenciesLength
= 0;
643 DWORD dwPasswordLength
= 0;
644 LPBYTE lpEncryptedPassword
= NULL
;
646 TRACE("CreateServiceW() called\n");
647 TRACE("%p %S %S\n", hSCManager
,
648 lpServiceName
, lpDisplayName
);
652 SetLastError(ERROR_INVALID_HANDLE
);
656 /* Calculate the Dependencies length */
657 if (lpDependencies
!= NULL
)
659 lpStr
= lpDependencies
;
662 cchLength
= wcslen(lpStr
) + 1;
663 dwDependenciesLength
+= (DWORD
)cchLength
;
664 lpStr
= lpStr
+ cchLength
;
666 dwDependenciesLength
++;
667 dwDependenciesLength
*= sizeof(WCHAR
);
670 /* FIXME: Encrypt the password */
671 lpEncryptedPassword
= (LPBYTE
)lpPassword
;
672 dwPasswordLength
= (DWORD
)(lpPassword
? (wcslen(lpPassword
) + 1) * sizeof(WCHAR
) : 0);
676 /* Call to services.exe using RPC */
677 dwError
= RCreateServiceW((SC_RPC_HANDLE
)hSCManager
,
687 (LPBYTE
)lpDependencies
,
688 dwDependenciesLength
,
692 (SC_RPC_HANDLE
*)&hService
);
694 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
696 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
700 if (dwError
!= ERROR_SUCCESS
)
702 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError
);
703 SetLastError(dwError
);
711 /**********************************************************************
717 DeleteService(SC_HANDLE hService
)
721 TRACE("DeleteService(%x)\n", hService
);
725 /* Call to services.exe using RPC */
726 dwError
= RDeleteService((SC_RPC_HANDLE
)hService
);
728 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
730 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
734 if (dwError
!= ERROR_SUCCESS
)
736 TRACE("RDeleteService() failed (Error %lu)\n", dwError
);
737 SetLastError(dwError
);
745 /**********************************************************************
746 * EnumDependentServicesA
751 EnumDependentServicesA(SC_HANDLE hService
,
752 DWORD dwServiceState
,
753 LPENUM_SERVICE_STATUSA lpServices
,
755 LPDWORD pcbBytesNeeded
,
756 LPDWORD lpServicesReturned
)
758 ENUM_SERVICE_STATUSA ServiceStatus
;
759 LPENUM_SERVICE_STATUSA lpStatusPtr
;
764 TRACE("EnumDependentServicesA() called\n");
766 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
768 lpStatusPtr
= &ServiceStatus
;
769 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
773 lpStatusPtr
= lpServices
;
774 dwBufferSize
= cbBufSize
;
779 dwError
= REnumDependentServicesA((SC_RPC_HANDLE
)hService
,
786 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
788 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
792 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
794 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
796 if (lpStatusPtr
->lpServiceName
)
797 lpStatusPtr
->lpServiceName
=
798 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
800 if (lpStatusPtr
->lpDisplayName
)
801 lpStatusPtr
->lpDisplayName
=
802 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
808 if (dwError
!= ERROR_SUCCESS
)
810 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError
);
811 SetLastError(dwError
);
815 TRACE("EnumDependentServicesA() done\n");
821 /**********************************************************************
822 * EnumDependentServicesW
827 EnumDependentServicesW(SC_HANDLE hService
,
828 DWORD dwServiceState
,
829 LPENUM_SERVICE_STATUSW lpServices
,
831 LPDWORD pcbBytesNeeded
,
832 LPDWORD lpServicesReturned
)
834 ENUM_SERVICE_STATUSW ServiceStatus
;
835 LPENUM_SERVICE_STATUSW lpStatusPtr
;
840 TRACE("EnumDependentServicesW() called\n");
842 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
844 lpStatusPtr
= &ServiceStatus
;
845 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
849 lpStatusPtr
= lpServices
;
850 dwBufferSize
= cbBufSize
;
855 dwError
= REnumDependentServicesW((SC_RPC_HANDLE
)hService
,
862 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
864 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
868 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
870 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
872 if (lpStatusPtr
->lpServiceName
)
873 lpStatusPtr
->lpServiceName
=
874 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
876 if (lpStatusPtr
->lpDisplayName
)
877 lpStatusPtr
->lpDisplayName
=
878 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
884 if (dwError
!= ERROR_SUCCESS
)
886 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError
);
887 SetLastError(dwError
);
891 TRACE("EnumDependentServicesW() done\n");
897 /**********************************************************************
903 EnumServiceGroupW(SC_HANDLE hSCManager
,
905 DWORD dwServiceState
,
906 LPENUM_SERVICE_STATUSW lpServices
,
908 LPDWORD pcbBytesNeeded
,
909 LPDWORD lpServicesReturned
,
910 LPDWORD lpResumeHandle
,
913 ENUM_SERVICE_STATUSW ServiceStatus
;
914 LPENUM_SERVICE_STATUSW lpStatusPtr
;
919 TRACE("EnumServiceGroupW() called\n");
923 SetLastError(ERROR_INVALID_HANDLE
);
927 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
929 SetLastError(ERROR_INVALID_ADDRESS
);
933 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
935 lpStatusPtr
= &ServiceStatus
;
936 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
940 lpStatusPtr
= lpServices
;
941 dwBufferSize
= cbBufSize
;
948 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
959 dwError
= REnumServiceGroupW((SC_RPC_HANDLE
)hSCManager
,
970 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
972 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
976 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
978 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
980 if (lpStatusPtr
->lpServiceName
)
981 lpStatusPtr
->lpServiceName
=
982 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
984 if (lpStatusPtr
->lpDisplayName
)
985 lpStatusPtr
->lpDisplayName
=
986 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
992 if (dwError
!= ERROR_SUCCESS
)
994 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError
);
995 SetLastError(dwError
);
999 TRACE("EnumServiceGroupW() done\n");
1005 /**********************************************************************
1006 * EnumServicesStatusA
1011 EnumServicesStatusA(SC_HANDLE hSCManager
,
1012 DWORD dwServiceType
,
1013 DWORD dwServiceState
,
1014 LPENUM_SERVICE_STATUSA lpServices
,
1016 LPDWORD pcbBytesNeeded
,
1017 LPDWORD lpServicesReturned
,
1018 LPDWORD lpResumeHandle
)
1020 ENUM_SERVICE_STATUSA ServiceStatus
;
1021 LPENUM_SERVICE_STATUSA lpStatusPtr
;
1026 TRACE("EnumServicesStatusA() called\n");
1030 SetLastError(ERROR_INVALID_HANDLE
);
1034 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1036 SetLastError(ERROR_INVALID_ADDRESS
);
1040 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSA
))
1042 lpStatusPtr
= &ServiceStatus
;
1043 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSA
);
1047 lpStatusPtr
= lpServices
;
1048 dwBufferSize
= cbBufSize
;
1053 dwError
= REnumServicesStatusA((SC_RPC_HANDLE
)hSCManager
,
1056 (LPBYTE
)lpStatusPtr
,
1062 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1064 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1068 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1070 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1072 if (lpStatusPtr
->lpServiceName
)
1073 lpStatusPtr
->lpServiceName
=
1074 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1076 if (lpStatusPtr
->lpDisplayName
)
1077 lpStatusPtr
->lpDisplayName
=
1078 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1084 if (dwError
!= ERROR_SUCCESS
)
1086 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError
);
1087 SetLastError(dwError
);
1091 TRACE("EnumServicesStatusA() done\n");
1097 /**********************************************************************
1098 * EnumServicesStatusW
1103 EnumServicesStatusW(SC_HANDLE hSCManager
,
1104 DWORD dwServiceType
,
1105 DWORD dwServiceState
,
1106 LPENUM_SERVICE_STATUSW lpServices
,
1108 LPDWORD pcbBytesNeeded
,
1109 LPDWORD lpServicesReturned
,
1110 LPDWORD lpResumeHandle
)
1112 ENUM_SERVICE_STATUSW ServiceStatus
;
1113 LPENUM_SERVICE_STATUSW lpStatusPtr
;
1118 TRACE("EnumServicesStatusW() called\n");
1122 SetLastError(ERROR_INVALID_HANDLE
);
1126 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1128 SetLastError(ERROR_INVALID_ADDRESS
);
1132 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUSW
))
1134 lpStatusPtr
= &ServiceStatus
;
1135 dwBufferSize
= sizeof(ENUM_SERVICE_STATUSW
);
1139 lpStatusPtr
= lpServices
;
1140 dwBufferSize
= cbBufSize
;
1145 dwError
= REnumServicesStatusW((SC_RPC_HANDLE
)hSCManager
,
1148 (LPBYTE
)lpStatusPtr
,
1154 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1156 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1160 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1162 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1164 if (lpStatusPtr
->lpServiceName
)
1165 lpStatusPtr
->lpServiceName
=
1166 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1168 if (lpStatusPtr
->lpDisplayName
)
1169 lpStatusPtr
->lpDisplayName
=
1170 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1176 if (dwError
!= ERROR_SUCCESS
)
1178 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError
);
1179 SetLastError(dwError
);
1183 TRACE("EnumServicesStatusW() done\n");
1189 /**********************************************************************
1190 * EnumServicesStatusExA
1195 EnumServicesStatusExA(SC_HANDLE hSCManager
,
1196 SC_ENUM_TYPE InfoLevel
,
1197 DWORD dwServiceType
,
1198 DWORD dwServiceState
,
1201 LPDWORD pcbBytesNeeded
,
1202 LPDWORD lpServicesReturned
,
1203 LPDWORD lpResumeHandle
,
1204 LPCSTR pszGroupName
)
1206 ENUM_SERVICE_STATUS_PROCESSA ServiceStatus
;
1207 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr
;
1212 TRACE("EnumServicesStatusExA() called\n");
1214 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1216 SetLastError(ERROR_INVALID_LEVEL
);
1222 SetLastError(ERROR_INVALID_HANDLE
);
1226 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1228 SetLastError(ERROR_INVALID_ADDRESS
);
1232 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSA
))
1234 lpStatusPtr
= &ServiceStatus
;
1235 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSA
);
1239 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSA
)lpServices
;
1240 dwBufferSize
= cbBufSize
;
1245 dwError
= REnumServicesStatusExA((SC_RPC_HANDLE
)hSCManager
,
1249 (LPBYTE
)lpStatusPtr
,
1254 (LPSTR
)pszGroupName
);
1256 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1258 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1262 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1264 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1266 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1268 if (lpStatusPtr
->lpServiceName
)
1269 lpStatusPtr
->lpServiceName
=
1270 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1272 if (lpStatusPtr
->lpDisplayName
)
1273 lpStatusPtr
->lpDisplayName
=
1274 (LPSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1281 if (dwError
!= ERROR_SUCCESS
)
1283 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError
);
1284 SetLastError(dwError
);
1288 TRACE("EnumServicesStatusExA() done\n");
1294 /**********************************************************************
1295 * EnumServicesStatusExW
1300 EnumServicesStatusExW(SC_HANDLE hSCManager
,
1301 SC_ENUM_TYPE InfoLevel
,
1302 DWORD dwServiceType
,
1303 DWORD dwServiceState
,
1306 LPDWORD pcbBytesNeeded
,
1307 LPDWORD lpServicesReturned
,
1308 LPDWORD lpResumeHandle
,
1309 LPCWSTR pszGroupName
)
1311 ENUM_SERVICE_STATUS_PROCESSW ServiceStatus
;
1312 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr
;
1317 TRACE("EnumServicesStatusExW() called\n");
1319 if (InfoLevel
!= SC_ENUM_PROCESS_INFO
)
1321 SetLastError(ERROR_INVALID_LEVEL
);
1327 SetLastError(ERROR_INVALID_HANDLE
);
1331 if (pcbBytesNeeded
== NULL
|| lpServicesReturned
== NULL
)
1333 SetLastError(ERROR_INVALID_ADDRESS
);
1337 if (lpServices
== NULL
|| cbBufSize
< sizeof(ENUM_SERVICE_STATUS_PROCESSW
))
1339 lpStatusPtr
= &ServiceStatus
;
1340 dwBufferSize
= sizeof(ENUM_SERVICE_STATUS_PROCESSW
);
1344 lpStatusPtr
= (LPENUM_SERVICE_STATUS_PROCESSW
)lpServices
;
1345 dwBufferSize
= cbBufSize
;
1350 dwError
= REnumServicesStatusExW((SC_RPC_HANDLE
)hSCManager
,
1354 (LPBYTE
)lpStatusPtr
,
1359 (LPWSTR
)pszGroupName
);
1361 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1363 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1367 if (dwError
== ERROR_SUCCESS
|| dwError
== ERROR_MORE_DATA
)
1369 if (InfoLevel
== SC_ENUM_PROCESS_INFO
)
1371 for (dwCount
= 0; dwCount
< *lpServicesReturned
; dwCount
++)
1373 if (lpStatusPtr
->lpServiceName
)
1374 lpStatusPtr
->lpServiceName
=
1375 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpServiceName
);
1377 if (lpStatusPtr
->lpDisplayName
)
1378 lpStatusPtr
->lpDisplayName
=
1379 (LPWSTR
)((ULONG_PTR
)lpServices
+ (ULONG_PTR
)lpStatusPtr
->lpDisplayName
);
1386 if (dwError
!= ERROR_SUCCESS
)
1388 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError
);
1389 SetLastError(dwError
);
1393 TRACE("EnumServicesStatusExW() done\n");
1399 /**********************************************************************
1400 * GetServiceDisplayNameA
1405 GetServiceDisplayNameA(SC_HANDLE hSCManager
,
1406 LPCSTR lpServiceName
,
1407 LPSTR lpDisplayName
,
1408 LPDWORD lpcchBuffer
)
1412 CHAR szEmptyName
[] = "";
1414 TRACE("GetServiceDisplayNameA() called\n");
1415 TRACE("%p %s %p %p\n", hSCManager
,
1416 debugstr_a(lpServiceName
), lpDisplayName
, lpcchBuffer
);
1420 SetLastError(ERROR_INVALID_HANDLE
);
1424 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(CHAR
))
1426 lpNameBuffer
= szEmptyName
;
1427 *lpcchBuffer
= sizeof(CHAR
);
1431 lpNameBuffer
= lpDisplayName
;
1436 dwError
= RGetServiceDisplayNameA((SC_RPC_HANDLE
)hSCManager
,
1441 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1443 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1444 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1448 if (dwError
!= ERROR_SUCCESS
)
1450 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError
);
1451 SetLastError(dwError
);
1459 /**********************************************************************
1460 * GetServiceDisplayNameW
1465 GetServiceDisplayNameW(SC_HANDLE hSCManager
,
1466 LPCWSTR lpServiceName
,
1467 LPWSTR lpDisplayName
,
1468 LPDWORD lpcchBuffer
)
1471 LPWSTR lpNameBuffer
;
1472 WCHAR szEmptyName
[] = L
"";
1474 TRACE("GetServiceDisplayNameW() called\n");
1478 SetLastError(ERROR_INVALID_HANDLE
);
1482 if (!lpDisplayName
|| *lpcchBuffer
< sizeof(WCHAR
))
1484 lpNameBuffer
= szEmptyName
;
1485 *lpcchBuffer
= sizeof(WCHAR
);
1489 lpNameBuffer
= lpDisplayName
;
1494 dwError
= RGetServiceDisplayNameW((SC_RPC_HANDLE
)hSCManager
,
1499 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1501 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1505 if (dwError
!= ERROR_SUCCESS
)
1507 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError
);
1508 SetLastError(dwError
);
1516 /**********************************************************************
1517 * GetServiceKeyNameA
1522 GetServiceKeyNameA(SC_HANDLE hSCManager
,
1523 LPCSTR lpDisplayName
,
1524 LPSTR lpServiceName
,
1525 LPDWORD lpcchBuffer
)
1529 CHAR szEmptyName
[] = "";
1531 TRACE("GetServiceKeyNameA() called\n");
1535 SetLastError(ERROR_INVALID_HANDLE
);
1539 if (!lpServiceName
|| *lpcchBuffer
< sizeof(CHAR
))
1541 lpNameBuffer
= szEmptyName
;
1542 *lpcchBuffer
= sizeof(CHAR
);
1546 lpNameBuffer
= lpServiceName
;
1551 dwError
= RGetServiceKeyNameA((SC_RPC_HANDLE
)hSCManager
,
1556 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1558 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1562 if (dwError
!= ERROR_SUCCESS
)
1564 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError
);
1565 SetLastError(dwError
);
1573 /**********************************************************************
1574 * GetServiceKeyNameW
1579 GetServiceKeyNameW(SC_HANDLE hSCManager
,
1580 LPCWSTR lpDisplayName
,
1581 LPWSTR lpServiceName
,
1582 LPDWORD lpcchBuffer
)
1585 LPWSTR lpNameBuffer
;
1586 WCHAR szEmptyName
[] = L
"";
1588 TRACE("GetServiceKeyNameW() called\n");
1592 SetLastError(ERROR_INVALID_HANDLE
);
1596 if (!lpServiceName
|| *lpcchBuffer
< sizeof(WCHAR
))
1598 lpNameBuffer
= szEmptyName
;
1599 *lpcchBuffer
= sizeof(WCHAR
);
1603 lpNameBuffer
= lpServiceName
;
1608 dwError
= RGetServiceKeyNameW((SC_RPC_HANDLE
)hSCManager
,
1613 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1615 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1619 if (dwError
!= ERROR_SUCCESS
)
1621 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError
);
1622 SetLastError(dwError
);
1630 /**********************************************************************
1631 * LockServiceDatabase
1636 LockServiceDatabase(SC_HANDLE hSCManager
)
1641 TRACE("LockServiceDatabase(%x)\n", hSCManager
);
1645 /* Call to services.exe using RPC */
1646 dwError
= RLockServiceDatabase((SC_RPC_HANDLE
)hSCManager
,
1647 (SC_RPC_LOCK
*)&hLock
);
1649 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1651 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1655 if (dwError
!= ERROR_SUCCESS
)
1657 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError
);
1658 SetLastError(dwError
);
1662 TRACE("hLock = %p\n", hLock
);
1669 WaitForSCManager(VOID
)
1673 TRACE("WaitForSCManager() called\n");
1675 /* Try to open the existing event */
1676 hEvent
= OpenEventW(SYNCHRONIZE
,
1678 L
"SvcctrlStartEvent_A3752DX");
1681 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
1684 /* Try to create a new event */
1685 hEvent
= CreateEventW(NULL
,
1688 L
"SvcctrlStartEvent_A3752DX");
1691 /* Try to open the existing event again */
1692 hEvent
= OpenEventW(SYNCHRONIZE
,
1694 L
"SvcctrlStartEvent_A3752DX");
1700 /* Wait for 3 minutes */
1701 WaitForSingleObject(hEvent
, 180000);
1702 CloseHandle(hEvent
);
1704 TRACE("ScmWaitForSCManager() done\n");
1708 /**********************************************************************
1714 OpenSCManagerA(LPCSTR lpMachineName
,
1715 LPCSTR lpDatabaseName
,
1716 DWORD dwDesiredAccess
)
1718 SC_HANDLE hScm
= NULL
;
1721 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1722 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1728 /* Call to services.exe using RPC */
1729 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1730 (LPSTR
)lpDatabaseName
,
1732 (SC_RPC_HANDLE
*)&hScm
);
1734 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1736 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1740 if (dwError
!= ERROR_SUCCESS
)
1742 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1743 SetLastError(dwError
);
1747 TRACE("hScm = %p\n", hScm
);
1753 /**********************************************************************
1759 OpenSCManagerW(LPCWSTR lpMachineName
,
1760 LPCWSTR lpDatabaseName
,
1761 DWORD dwDesiredAccess
)
1763 SC_HANDLE hScm
= NULL
;
1766 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1767 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1773 /* Call to services.exe using RPC */
1774 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1775 (LPWSTR
)lpDatabaseName
,
1777 (SC_RPC_HANDLE
*)&hScm
);
1779 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1781 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1785 if (dwError
!= ERROR_SUCCESS
)
1787 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1788 SetLastError(dwError
);
1792 TRACE("hScm = %p\n", hScm
);
1798 /**********************************************************************
1804 OpenServiceA(SC_HANDLE hSCManager
,
1805 LPCSTR lpServiceName
,
1806 DWORD dwDesiredAccess
)
1808 SC_HANDLE hService
= NULL
;
1811 TRACE("OpenServiceA(%p, %s, %lx)\n",
1812 hSCManager
, lpServiceName
, dwDesiredAccess
);
1816 SetLastError(ERROR_INVALID_HANDLE
);
1822 /* Call to services.exe using RPC */
1823 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1824 (LPSTR
)lpServiceName
,
1826 (SC_RPC_HANDLE
*)&hService
);
1828 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1830 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1834 if (dwError
!= ERROR_SUCCESS
)
1836 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1837 SetLastError(dwError
);
1841 TRACE("hService = %p\n", hService
);
1847 /**********************************************************************
1853 OpenServiceW(SC_HANDLE hSCManager
,
1854 LPCWSTR lpServiceName
,
1855 DWORD dwDesiredAccess
)
1857 SC_HANDLE hService
= NULL
;
1860 TRACE("OpenServiceW(%p, %S, %lx)\n",
1861 hSCManager
, lpServiceName
, dwDesiredAccess
);
1865 SetLastError(ERROR_INVALID_HANDLE
);
1871 /* Call to services.exe using RPC */
1872 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1873 (LPWSTR
)lpServiceName
,
1875 (SC_RPC_HANDLE
*)&hService
);
1877 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1879 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1883 if (dwError
!= ERROR_SUCCESS
)
1885 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1886 SetLastError(dwError
);
1890 TRACE("hService = %p\n", hService
);
1896 /**********************************************************************
1897 * QueryServiceConfigA
1902 QueryServiceConfigA(SC_HANDLE hService
,
1903 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1905 LPDWORD pcbBytesNeeded
)
1907 QUERY_SERVICE_CONFIGA ServiceConfig
;
1908 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1912 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1913 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1915 if (lpServiceConfig
== NULL
||
1916 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1918 lpConfigPtr
= &ServiceConfig
;
1919 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1923 lpConfigPtr
= lpServiceConfig
;
1924 dwBufferSize
= cbBufSize
;
1929 /* Call to services.exe using RPC */
1930 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1931 (LPBYTE
)lpConfigPtr
,
1935 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1937 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1941 if (dwError
!= ERROR_SUCCESS
)
1943 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1944 SetLastError(dwError
);
1948 /* Adjust the pointers */
1949 if (lpConfigPtr
->lpBinaryPathName
)
1950 lpConfigPtr
->lpBinaryPathName
=
1951 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1952 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
1954 if (lpConfigPtr
->lpLoadOrderGroup
)
1955 lpConfigPtr
->lpLoadOrderGroup
=
1956 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1957 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
1959 if (lpConfigPtr
->lpDependencies
)
1960 lpConfigPtr
->lpDependencies
=
1961 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1962 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
1964 if (lpConfigPtr
->lpServiceStartName
)
1965 lpConfigPtr
->lpServiceStartName
=
1966 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1967 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
1969 if (lpConfigPtr
->lpDisplayName
)
1970 lpConfigPtr
->lpDisplayName
=
1971 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1972 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
1974 TRACE("QueryServiceConfigA() done\n");
1980 /**********************************************************************
1981 * QueryServiceConfigW
1986 QueryServiceConfigW(SC_HANDLE hService
,
1987 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1989 LPDWORD pcbBytesNeeded
)
1991 QUERY_SERVICE_CONFIGW ServiceConfig
;
1992 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
1996 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1997 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1999 if (lpServiceConfig
== NULL
||
2000 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
2002 lpConfigPtr
= &ServiceConfig
;
2003 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
2007 lpConfigPtr
= lpServiceConfig
;
2008 dwBufferSize
= cbBufSize
;
2013 /* Call to services.exe using RPC */
2014 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2015 (LPBYTE
)lpConfigPtr
,
2019 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2021 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2025 if (dwError
!= ERROR_SUCCESS
)
2027 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2028 SetLastError(dwError
);
2032 /* Adjust the pointers */
2033 if (lpConfigPtr
->lpBinaryPathName
)
2034 lpConfigPtr
->lpBinaryPathName
=
2035 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2036 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2038 if (lpConfigPtr
->lpLoadOrderGroup
)
2039 lpConfigPtr
->lpLoadOrderGroup
=
2040 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2041 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2043 if (lpConfigPtr
->lpDependencies
)
2044 lpConfigPtr
->lpDependencies
=
2045 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2046 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2048 if (lpConfigPtr
->lpServiceStartName
)
2049 lpConfigPtr
->lpServiceStartName
=
2050 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2051 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2053 if (lpConfigPtr
->lpDisplayName
)
2054 lpConfigPtr
->lpDisplayName
=
2055 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2056 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2058 TRACE("QueryServiceConfigW() done\n");
2064 /**********************************************************************
2065 * QueryServiceConfig2A
2070 QueryServiceConfig2A(SC_HANDLE hService
,
2074 LPDWORD pcbBytesNeeded
)
2076 SERVICE_DESCRIPTIONA ServiceDescription
;
2077 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2078 LPBYTE lpTempBuffer
;
2079 BOOL bUseTempBuffer
= FALSE
;
2083 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2084 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2086 lpTempBuffer
= lpBuffer
;
2087 dwBufferSize
= cbBufSize
;
2089 switch (dwInfoLevel
)
2091 case SERVICE_CONFIG_DESCRIPTION
:
2092 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2094 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2095 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2096 bUseTempBuffer
= TRUE
;
2100 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2101 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2103 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2104 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2105 bUseTempBuffer
= TRUE
;
2110 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2111 SetLastError(ERROR_INVALID_LEVEL
);
2117 /* Call to services.exe using RPC */
2118 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2124 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2126 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2130 if (dwError
!= ERROR_SUCCESS
)
2132 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2133 SetLastError(dwError
);
2137 if (bUseTempBuffer
== TRUE
)
2139 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2140 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2144 switch (dwInfoLevel
)
2146 case SERVICE_CONFIG_DESCRIPTION
:
2148 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2150 if (lpPtr
->lpDescription
!= NULL
)
2151 lpPtr
->lpDescription
=
2152 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2156 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2158 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2160 if (lpPtr
->lpRebootMsg
!= NULL
)
2161 lpPtr
->lpRebootMsg
=
2162 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2164 if (lpPtr
->lpCommand
!= NULL
)
2166 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2168 if (lpPtr
->lpsaActions
!= NULL
)
2169 lpPtr
->lpsaActions
=
2170 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2175 TRACE("QueryServiceConfig2A() done\n");
2181 /**********************************************************************
2182 * QueryServiceConfig2W
2187 QueryServiceConfig2W(SC_HANDLE hService
,
2191 LPDWORD pcbBytesNeeded
)
2193 SERVICE_DESCRIPTIONW ServiceDescription
;
2194 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2195 LPBYTE lpTempBuffer
;
2196 BOOL bUseTempBuffer
= FALSE
;
2200 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2201 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2203 lpTempBuffer
= lpBuffer
;
2204 dwBufferSize
= cbBufSize
;
2206 switch (dwInfoLevel
)
2208 case SERVICE_CONFIG_DESCRIPTION
:
2209 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2211 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2212 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2213 bUseTempBuffer
= TRUE
;
2217 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2218 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2220 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2221 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2222 bUseTempBuffer
= TRUE
;
2227 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2228 SetLastError(ERROR_INVALID_LEVEL
);
2234 /* Call to services.exe using RPC */
2235 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2241 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2243 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2247 if (dwError
!= ERROR_SUCCESS
)
2249 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2250 SetLastError(dwError
);
2254 if (bUseTempBuffer
== TRUE
)
2256 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2257 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2261 switch (dwInfoLevel
)
2263 case SERVICE_CONFIG_DESCRIPTION
:
2265 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2267 if (lpPtr
->lpDescription
!= NULL
)
2268 lpPtr
->lpDescription
=
2269 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2273 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2275 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2277 if (lpPtr
->lpRebootMsg
!= NULL
)
2278 lpPtr
->lpRebootMsg
=
2279 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2281 if (lpPtr
->lpCommand
!= NULL
)
2283 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2285 if (lpPtr
->lpsaActions
!= NULL
)
2286 lpPtr
->lpsaActions
=
2287 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2292 TRACE("QueryServiceConfig2W() done\n");
2298 /**********************************************************************
2299 * QueryServiceLockStatusA
2304 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2305 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2307 LPDWORD pcbBytesNeeded
)
2309 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2310 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2314 TRACE("QueryServiceLockStatusA() called\n");
2316 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2318 lpStatusPtr
= &LockStatus
;
2319 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2323 lpStatusPtr
= lpLockStatus
;
2324 dwBufferSize
= cbBufSize
;
2329 /* Call to services.exe using RPC */
2330 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2331 (LPBYTE
)lpStatusPtr
,
2335 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2337 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2341 if (dwError
!= ERROR_SUCCESS
)
2343 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2344 SetLastError(dwError
);
2348 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2350 lpStatusPtr
->lpLockOwner
=
2351 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2354 TRACE("QueryServiceLockStatusA() done\n");
2360 /**********************************************************************
2361 * QueryServiceLockStatusW
2366 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2367 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2369 LPDWORD pcbBytesNeeded
)
2371 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2372 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2376 TRACE("QueryServiceLockStatusW() called\n");
2378 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2380 lpStatusPtr
= &LockStatus
;
2381 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2385 lpStatusPtr
= lpLockStatus
;
2386 dwBufferSize
= cbBufSize
;
2391 /* Call to services.exe using RPC */
2392 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2393 (LPBYTE
)lpStatusPtr
,
2397 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2399 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2403 if (dwError
!= ERROR_SUCCESS
)
2405 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2406 SetLastError(dwError
);
2410 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2412 lpStatusPtr
->lpLockOwner
=
2413 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2416 TRACE("QueryServiceLockStatusW() done\n");
2422 /**********************************************************************
2423 * QueryServiceObjectSecurity
2428 QueryServiceObjectSecurity(SC_HANDLE hService
,
2429 SECURITY_INFORMATION dwSecurityInformation
,
2430 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2432 LPDWORD pcbBytesNeeded
)
2436 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2437 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2441 /* Call to services.exe using RPC */
2442 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2443 dwSecurityInformation
,
2444 (LPBYTE
)lpSecurityDescriptor
,
2448 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2450 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2454 if (dwError
!= ERROR_SUCCESS
)
2456 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2457 SetLastError(dwError
);
2464 /**********************************************************************
2465 * SetServiceObjectSecurity
2470 SetServiceObjectSecurity(SC_HANDLE hService
,
2471 SECURITY_INFORMATION dwSecurityInformation
,
2472 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2474 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2480 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2483 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2485 SetLastError(ERROR_INVALID_PARAMETER
);
2489 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2490 if (SelfRelativeSD
== NULL
)
2492 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2496 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2499 if (!NT_SUCCESS(Status
))
2501 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2502 SetLastError(RtlNtStatusToDosError(Status
));
2508 /* Call to services.exe using RPC */
2509 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2510 dwSecurityInformation
,
2511 (LPBYTE
)SelfRelativeSD
,
2514 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2516 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2520 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2522 if (dwError
!= ERROR_SUCCESS
)
2524 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2525 SetLastError(dwError
);
2533 /**********************************************************************
2534 * QueryServiceStatus
2539 QueryServiceStatus(SC_HANDLE hService
,
2540 LPSERVICE_STATUS lpServiceStatus
)
2544 TRACE("QueryServiceStatus(%p, %p)\n",
2545 hService
, lpServiceStatus
);
2549 SetLastError(ERROR_INVALID_HANDLE
);
2555 /* Call to services.exe using RPC */
2556 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2559 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2561 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2565 if (dwError
!= ERROR_SUCCESS
)
2567 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2568 SetLastError(dwError
);
2576 /**********************************************************************
2577 * QueryServiceStatusEx
2582 QueryServiceStatusEx(SC_HANDLE hService
,
2583 SC_STATUS_TYPE InfoLevel
,
2586 LPDWORD pcbBytesNeeded
)
2590 TRACE("QueryServiceStatusEx() called\n");
2592 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2594 SetLastError(ERROR_INVALID_LEVEL
);
2598 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2600 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2601 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2607 /* Call to services.exe using RPC */
2608 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2614 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2616 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2620 if (dwError
!= ERROR_SUCCESS
)
2622 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2623 SetLastError(dwError
);
2631 /**********************************************************************
2637 StartServiceA(SC_HANDLE hService
,
2638 DWORD dwNumServiceArgs
,
2639 LPCSTR
*lpServiceArgVectors
)
2645 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2647 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2649 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2651 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2655 if (dwError
!= ERROR_SUCCESS
)
2657 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2658 SetLastError(dwError
);
2666 /**********************************************************************
2672 StartServiceW(SC_HANDLE hService
,
2673 DWORD dwNumServiceArgs
,
2674 LPCWSTR
*lpServiceArgVectors
)
2680 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2682 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2684 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2686 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2690 if (dwError
!= ERROR_SUCCESS
)
2692 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2693 SetLastError(dwError
);
2701 /**********************************************************************
2702 * UnlockServiceDatabase
2707 UnlockServiceDatabase(SC_LOCK ScLock
)
2711 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2715 /* Call to services.exe using RPC */
2716 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2718 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2720 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2724 if (dwError
!= ERROR_SUCCESS
)
2726 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2727 SetLastError(dwError
);
2735 /**********************************************************************
2736 * NotifyBootConfigStatus
2741 NotifyBootConfigStatus(BOOL BootAcceptable
)
2745 TRACE("NotifyBootConfigStatus()\n");
2749 /* Call to services.exe using RPC */
2750 dwError
= RNotifyBootConfigStatus(NULL
,
2753 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2755 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2759 if (dwError
!= ERROR_SUCCESS
)
2761 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2762 SetLastError(dwError
);