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
, FALSE
, SCM_START_EVENT
);
1679 if (GetLastError() != ERROR_FILE_NOT_FOUND
) return;
1681 /* Try to create a new event */
1682 hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, SCM_START_EVENT
);
1683 if (hEvent
== NULL
) return;
1686 /* Wait for 3 minutes */
1687 WaitForSingleObject(hEvent
, 180000);
1688 CloseHandle(hEvent
);
1690 TRACE("ScmWaitForSCManager() done\n");
1694 /**********************************************************************
1700 OpenSCManagerA(LPCSTR lpMachineName
,
1701 LPCSTR lpDatabaseName
,
1702 DWORD dwDesiredAccess
)
1704 SC_HANDLE hScm
= NULL
;
1707 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1708 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1714 /* Call to services.exe using RPC */
1715 dwError
= ROpenSCManagerA((LPSTR
)lpMachineName
,
1716 (LPSTR
)lpDatabaseName
,
1718 (SC_RPC_HANDLE
*)&hScm
);
1720 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1722 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1726 if (dwError
!= ERROR_SUCCESS
)
1728 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError
);
1729 SetLastError(dwError
);
1733 TRACE("hScm = %p\n", hScm
);
1739 /**********************************************************************
1745 OpenSCManagerW(LPCWSTR lpMachineName
,
1746 LPCWSTR lpDatabaseName
,
1747 DWORD dwDesiredAccess
)
1749 SC_HANDLE hScm
= NULL
;
1752 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1753 lpMachineName
, lpDatabaseName
, dwDesiredAccess
);
1759 /* Call to services.exe using RPC */
1760 dwError
= ROpenSCManagerW((LPWSTR
)lpMachineName
,
1761 (LPWSTR
)lpDatabaseName
,
1763 (SC_RPC_HANDLE
*)&hScm
);
1765 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1767 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1771 if (dwError
!= ERROR_SUCCESS
)
1773 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError
);
1774 SetLastError(dwError
);
1778 TRACE("hScm = %p\n", hScm
);
1784 /**********************************************************************
1790 OpenServiceA(SC_HANDLE hSCManager
,
1791 LPCSTR lpServiceName
,
1792 DWORD dwDesiredAccess
)
1794 SC_HANDLE hService
= NULL
;
1797 TRACE("OpenServiceA(%p, %s, %lx)\n",
1798 hSCManager
, lpServiceName
, dwDesiredAccess
);
1802 SetLastError(ERROR_INVALID_HANDLE
);
1808 /* Call to services.exe using RPC */
1809 dwError
= ROpenServiceA((SC_RPC_HANDLE
)hSCManager
,
1810 (LPSTR
)lpServiceName
,
1812 (SC_RPC_HANDLE
*)&hService
);
1814 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1816 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1820 if (dwError
!= ERROR_SUCCESS
)
1822 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError
);
1823 SetLastError(dwError
);
1827 TRACE("hService = %p\n", hService
);
1833 /**********************************************************************
1839 OpenServiceW(SC_HANDLE hSCManager
,
1840 LPCWSTR lpServiceName
,
1841 DWORD dwDesiredAccess
)
1843 SC_HANDLE hService
= NULL
;
1846 TRACE("OpenServiceW(%p, %S, %lx)\n",
1847 hSCManager
, lpServiceName
, dwDesiredAccess
);
1851 SetLastError(ERROR_INVALID_HANDLE
);
1857 /* Call to services.exe using RPC */
1858 dwError
= ROpenServiceW((SC_RPC_HANDLE
)hSCManager
,
1859 (LPWSTR
)lpServiceName
,
1861 (SC_RPC_HANDLE
*)&hService
);
1863 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1865 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1869 if (dwError
!= ERROR_SUCCESS
)
1871 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError
);
1872 SetLastError(dwError
);
1876 TRACE("hService = %p\n", hService
);
1882 /**********************************************************************
1883 * QueryServiceConfigA
1888 QueryServiceConfigA(SC_HANDLE hService
,
1889 LPQUERY_SERVICE_CONFIGA lpServiceConfig
,
1891 LPDWORD pcbBytesNeeded
)
1893 QUERY_SERVICE_CONFIGA ServiceConfig
;
1894 LPQUERY_SERVICE_CONFIGA lpConfigPtr
;
1898 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1899 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1901 if (lpServiceConfig
== NULL
||
1902 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGA
))
1904 lpConfigPtr
= &ServiceConfig
;
1905 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGA
);
1909 lpConfigPtr
= lpServiceConfig
;
1910 dwBufferSize
= cbBufSize
;
1915 /* Call to services.exe using RPC */
1916 dwError
= RQueryServiceConfigA((SC_RPC_HANDLE
)hService
,
1917 (LPBYTE
)lpConfigPtr
,
1921 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
1923 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
1927 if (dwError
!= ERROR_SUCCESS
)
1929 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError
);
1930 SetLastError(dwError
);
1934 /* Adjust the pointers */
1935 if (lpConfigPtr
->lpBinaryPathName
)
1936 lpConfigPtr
->lpBinaryPathName
=
1937 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1938 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
1940 if (lpConfigPtr
->lpLoadOrderGroup
)
1941 lpConfigPtr
->lpLoadOrderGroup
=
1942 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1943 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
1945 if (lpConfigPtr
->lpDependencies
)
1946 lpConfigPtr
->lpDependencies
=
1947 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1948 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
1950 if (lpConfigPtr
->lpServiceStartName
)
1951 lpConfigPtr
->lpServiceStartName
=
1952 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1953 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
1955 if (lpConfigPtr
->lpDisplayName
)
1956 lpConfigPtr
->lpDisplayName
=
1957 (LPSTR
)((ULONG_PTR
)lpConfigPtr
+
1958 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
1960 TRACE("QueryServiceConfigA() done\n");
1966 /**********************************************************************
1967 * QueryServiceConfigW
1972 QueryServiceConfigW(SC_HANDLE hService
,
1973 LPQUERY_SERVICE_CONFIGW lpServiceConfig
,
1975 LPDWORD pcbBytesNeeded
)
1977 QUERY_SERVICE_CONFIGW ServiceConfig
;
1978 LPQUERY_SERVICE_CONFIGW lpConfigPtr
;
1982 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1983 hService
, lpServiceConfig
, cbBufSize
, pcbBytesNeeded
);
1985 if (lpServiceConfig
== NULL
||
1986 cbBufSize
< sizeof(QUERY_SERVICE_CONFIGW
))
1988 lpConfigPtr
= &ServiceConfig
;
1989 dwBufferSize
= sizeof(QUERY_SERVICE_CONFIGW
);
1993 lpConfigPtr
= lpServiceConfig
;
1994 dwBufferSize
= cbBufSize
;
1999 /* Call to services.exe using RPC */
2000 dwError
= RQueryServiceConfigW((SC_RPC_HANDLE
)hService
,
2001 (LPBYTE
)lpConfigPtr
,
2005 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2007 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2011 if (dwError
!= ERROR_SUCCESS
)
2013 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError
);
2014 SetLastError(dwError
);
2018 /* Adjust the pointers */
2019 if (lpConfigPtr
->lpBinaryPathName
)
2020 lpConfigPtr
->lpBinaryPathName
=
2021 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2022 (ULONG_PTR
)lpConfigPtr
->lpBinaryPathName
);
2024 if (lpConfigPtr
->lpLoadOrderGroup
)
2025 lpConfigPtr
->lpLoadOrderGroup
=
2026 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2027 (ULONG_PTR
)lpConfigPtr
->lpLoadOrderGroup
);
2029 if (lpConfigPtr
->lpDependencies
)
2030 lpConfigPtr
->lpDependencies
=
2031 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2032 (ULONG_PTR
)lpConfigPtr
->lpDependencies
);
2034 if (lpConfigPtr
->lpServiceStartName
)
2035 lpConfigPtr
->lpServiceStartName
=
2036 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2037 (ULONG_PTR
)lpConfigPtr
->lpServiceStartName
);
2039 if (lpConfigPtr
->lpDisplayName
)
2040 lpConfigPtr
->lpDisplayName
=
2041 (LPWSTR
)((ULONG_PTR
)lpConfigPtr
+
2042 (ULONG_PTR
)lpConfigPtr
->lpDisplayName
);
2044 TRACE("QueryServiceConfigW() done\n");
2050 /**********************************************************************
2051 * QueryServiceConfig2A
2056 QueryServiceConfig2A(SC_HANDLE hService
,
2060 LPDWORD pcbBytesNeeded
)
2062 SERVICE_DESCRIPTIONA ServiceDescription
;
2063 SERVICE_FAILURE_ACTIONSA ServiceFailureActions
;
2064 LPBYTE lpTempBuffer
;
2065 BOOL bUseTempBuffer
= FALSE
;
2069 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2070 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2072 lpTempBuffer
= lpBuffer
;
2073 dwBufferSize
= cbBufSize
;
2075 switch (dwInfoLevel
)
2077 case SERVICE_CONFIG_DESCRIPTION
:
2078 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONA
)))
2080 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2081 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONA
);
2082 bUseTempBuffer
= TRUE
;
2086 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2087 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSA
)))
2089 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2090 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSA
);
2091 bUseTempBuffer
= TRUE
;
2096 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2097 SetLastError(ERROR_INVALID_LEVEL
);
2103 /* Call to services.exe using RPC */
2104 dwError
= RQueryServiceConfig2A((SC_RPC_HANDLE
)hService
,
2110 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2112 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2116 if (dwError
!= ERROR_SUCCESS
)
2118 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError
);
2119 SetLastError(dwError
);
2123 if (bUseTempBuffer
== TRUE
)
2125 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2126 *pcbBytesNeeded
= dwBufferSize
;
2127 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2131 switch (dwInfoLevel
)
2133 case SERVICE_CONFIG_DESCRIPTION
:
2135 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2137 if (lpPtr
->lpDescription
!= NULL
)
2138 lpPtr
->lpDescription
=
2139 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2143 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2145 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2147 if (lpPtr
->lpRebootMsg
!= NULL
)
2148 lpPtr
->lpRebootMsg
=
2149 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2151 if (lpPtr
->lpCommand
!= NULL
)
2153 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2155 if (lpPtr
->lpsaActions
!= NULL
)
2156 lpPtr
->lpsaActions
=
2157 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2162 TRACE("QueryServiceConfig2A() done\n");
2168 /**********************************************************************
2169 * QueryServiceConfig2W
2174 QueryServiceConfig2W(SC_HANDLE hService
,
2178 LPDWORD pcbBytesNeeded
)
2180 SERVICE_DESCRIPTIONW ServiceDescription
;
2181 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2182 LPBYTE lpTempBuffer
;
2183 BOOL bUseTempBuffer
= FALSE
;
2187 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2188 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2190 lpTempBuffer
= lpBuffer
;
2191 dwBufferSize
= cbBufSize
;
2193 switch (dwInfoLevel
)
2195 case SERVICE_CONFIG_DESCRIPTION
:
2196 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2198 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2199 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2200 bUseTempBuffer
= TRUE
;
2204 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2205 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2207 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2208 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2209 bUseTempBuffer
= TRUE
;
2214 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2215 SetLastError(ERROR_INVALID_LEVEL
);
2221 /* Call to services.exe using RPC */
2222 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2228 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2230 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2234 if (dwError
!= ERROR_SUCCESS
)
2236 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2237 SetLastError(dwError
);
2241 if (bUseTempBuffer
== TRUE
)
2243 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2244 *pcbBytesNeeded
= dwBufferSize
;
2245 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2249 switch (dwInfoLevel
)
2251 case SERVICE_CONFIG_DESCRIPTION
:
2253 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2255 if (lpPtr
->lpDescription
!= NULL
)
2256 lpPtr
->lpDescription
=
2257 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2261 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2263 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2265 if (lpPtr
->lpRebootMsg
!= NULL
)
2266 lpPtr
->lpRebootMsg
=
2267 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2269 if (lpPtr
->lpCommand
!= NULL
)
2271 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2273 if (lpPtr
->lpsaActions
!= NULL
)
2274 lpPtr
->lpsaActions
=
2275 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2280 TRACE("QueryServiceConfig2W() done\n");
2286 /**********************************************************************
2287 * QueryServiceLockStatusA
2292 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2293 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2295 LPDWORD pcbBytesNeeded
)
2297 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2298 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2302 TRACE("QueryServiceLockStatusA() called\n");
2304 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2306 lpStatusPtr
= &LockStatus
;
2307 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2311 lpStatusPtr
= lpLockStatus
;
2312 dwBufferSize
= cbBufSize
;
2317 /* Call to services.exe using RPC */
2318 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2319 (LPBYTE
)lpStatusPtr
,
2323 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2325 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2329 if (dwError
!= ERROR_SUCCESS
)
2331 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2332 SetLastError(dwError
);
2336 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2338 lpStatusPtr
->lpLockOwner
=
2339 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2342 TRACE("QueryServiceLockStatusA() done\n");
2348 /**********************************************************************
2349 * QueryServiceLockStatusW
2354 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2355 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2357 LPDWORD pcbBytesNeeded
)
2359 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2360 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2364 TRACE("QueryServiceLockStatusW() called\n");
2366 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2368 lpStatusPtr
= &LockStatus
;
2369 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2373 lpStatusPtr
= lpLockStatus
;
2374 dwBufferSize
= cbBufSize
;
2379 /* Call to services.exe using RPC */
2380 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2381 (LPBYTE
)lpStatusPtr
,
2385 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2387 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2391 if (dwError
!= ERROR_SUCCESS
)
2393 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2394 SetLastError(dwError
);
2398 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2400 lpStatusPtr
->lpLockOwner
=
2401 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2404 TRACE("QueryServiceLockStatusW() done\n");
2410 /**********************************************************************
2411 * QueryServiceObjectSecurity
2416 QueryServiceObjectSecurity(SC_HANDLE hService
,
2417 SECURITY_INFORMATION dwSecurityInformation
,
2418 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2420 LPDWORD pcbBytesNeeded
)
2424 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2425 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2429 /* Call to services.exe using RPC */
2430 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2431 dwSecurityInformation
,
2432 (LPBYTE
)lpSecurityDescriptor
,
2436 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2438 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2442 if (dwError
!= ERROR_SUCCESS
)
2444 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2445 SetLastError(dwError
);
2452 /**********************************************************************
2453 * SetServiceObjectSecurity
2458 SetServiceObjectSecurity(SC_HANDLE hService
,
2459 SECURITY_INFORMATION dwSecurityInformation
,
2460 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2462 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2468 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2471 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2473 SetLastError(ERROR_INVALID_PARAMETER
);
2477 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2478 if (SelfRelativeSD
== NULL
)
2480 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2484 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2487 if (!NT_SUCCESS(Status
))
2489 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2490 SetLastError(RtlNtStatusToDosError(Status
));
2496 /* Call to services.exe using RPC */
2497 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2498 dwSecurityInformation
,
2499 (LPBYTE
)SelfRelativeSD
,
2502 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2504 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2508 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2510 if (dwError
!= ERROR_SUCCESS
)
2512 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2513 SetLastError(dwError
);
2521 /**********************************************************************
2522 * QueryServiceStatus
2527 QueryServiceStatus(SC_HANDLE hService
,
2528 LPSERVICE_STATUS lpServiceStatus
)
2532 TRACE("QueryServiceStatus(%p, %p)\n",
2533 hService
, lpServiceStatus
);
2537 SetLastError(ERROR_INVALID_HANDLE
);
2543 /* Call to services.exe using RPC */
2544 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2547 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2549 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2553 if (dwError
!= ERROR_SUCCESS
)
2555 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2556 SetLastError(dwError
);
2564 /**********************************************************************
2565 * QueryServiceStatusEx
2570 QueryServiceStatusEx(SC_HANDLE hService
,
2571 SC_STATUS_TYPE InfoLevel
,
2574 LPDWORD pcbBytesNeeded
)
2578 TRACE("QueryServiceStatusEx() called\n");
2580 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2582 SetLastError(ERROR_INVALID_LEVEL
);
2586 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2588 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2589 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2595 /* Call to services.exe using RPC */
2596 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2602 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2604 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2608 if (dwError
!= ERROR_SUCCESS
)
2610 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2611 SetLastError(dwError
);
2619 /**********************************************************************
2625 StartServiceA(SC_HANDLE hService
,
2626 DWORD dwNumServiceArgs
,
2627 LPCSTR
*lpServiceArgVectors
)
2633 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2635 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2637 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2639 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2643 if (dwError
!= ERROR_SUCCESS
)
2645 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2646 SetLastError(dwError
);
2654 /**********************************************************************
2660 StartServiceW(SC_HANDLE hService
,
2661 DWORD dwNumServiceArgs
,
2662 LPCWSTR
*lpServiceArgVectors
)
2668 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2670 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2672 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2674 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2678 if (dwError
!= ERROR_SUCCESS
)
2680 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2681 SetLastError(dwError
);
2689 /**********************************************************************
2690 * UnlockServiceDatabase
2695 UnlockServiceDatabase(SC_LOCK ScLock
)
2699 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2703 /* Call to services.exe using RPC */
2704 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2706 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2708 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2712 if (dwError
!= ERROR_SUCCESS
)
2714 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2715 SetLastError(dwError
);
2723 /**********************************************************************
2724 * NotifyBootConfigStatus
2729 NotifyBootConfigStatus(BOOL BootAcceptable
)
2733 TRACE("NotifyBootConfigStatus()\n");
2737 /* Call to services.exe using RPC */
2738 dwError
= RNotifyBootConfigStatus(NULL
,
2741 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2743 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2747 if (dwError
!= ERROR_SUCCESS
)
2749 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2750 SetLastError(dwError
);