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 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2130 switch (dwInfoLevel
)
2132 case SERVICE_CONFIG_DESCRIPTION
:
2134 LPSERVICE_DESCRIPTIONA lpPtr
= (LPSERVICE_DESCRIPTIONA
)lpTempBuffer
;
2136 if (lpPtr
->lpDescription
!= NULL
)
2137 lpPtr
->lpDescription
=
2138 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2142 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2144 LPSERVICE_FAILURE_ACTIONSA lpPtr
= (LPSERVICE_FAILURE_ACTIONSA
)lpTempBuffer
;
2146 if (lpPtr
->lpRebootMsg
!= NULL
)
2147 lpPtr
->lpRebootMsg
=
2148 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2150 if (lpPtr
->lpCommand
!= NULL
)
2152 (LPSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2154 if (lpPtr
->lpsaActions
!= NULL
)
2155 lpPtr
->lpsaActions
=
2156 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2161 TRACE("QueryServiceConfig2A() done\n");
2167 /**********************************************************************
2168 * QueryServiceConfig2W
2173 QueryServiceConfig2W(SC_HANDLE hService
,
2177 LPDWORD pcbBytesNeeded
)
2179 SERVICE_DESCRIPTIONW ServiceDescription
;
2180 SERVICE_FAILURE_ACTIONSW ServiceFailureActions
;
2181 LPBYTE lpTempBuffer
;
2182 BOOL bUseTempBuffer
= FALSE
;
2186 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2187 hService
, dwInfoLevel
, lpBuffer
, cbBufSize
, pcbBytesNeeded
);
2189 lpTempBuffer
= lpBuffer
;
2190 dwBufferSize
= cbBufSize
;
2192 switch (dwInfoLevel
)
2194 case SERVICE_CONFIG_DESCRIPTION
:
2195 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_DESCRIPTIONW
)))
2197 lpTempBuffer
= (LPBYTE
)&ServiceDescription
;
2198 dwBufferSize
= sizeof(SERVICE_DESCRIPTIONW
);
2199 bUseTempBuffer
= TRUE
;
2203 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2204 if ((lpBuffer
== NULL
) || (cbBufSize
< sizeof(SERVICE_FAILURE_ACTIONSW
)))
2206 lpTempBuffer
= (LPBYTE
)&ServiceFailureActions
;
2207 dwBufferSize
= sizeof(SERVICE_FAILURE_ACTIONSW
);
2208 bUseTempBuffer
= TRUE
;
2213 WARN("Unknown info level 0x%lx\n", dwInfoLevel
);
2214 SetLastError(ERROR_INVALID_LEVEL
);
2220 /* Call to services.exe using RPC */
2221 dwError
= RQueryServiceConfig2W((SC_RPC_HANDLE
)hService
,
2227 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2229 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2233 if (dwError
!= ERROR_SUCCESS
)
2235 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError
);
2236 SetLastError(dwError
);
2240 if (bUseTempBuffer
== TRUE
)
2242 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2243 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2247 switch (dwInfoLevel
)
2249 case SERVICE_CONFIG_DESCRIPTION
:
2251 LPSERVICE_DESCRIPTIONW lpPtr
= (LPSERVICE_DESCRIPTIONW
)lpTempBuffer
;
2253 if (lpPtr
->lpDescription
!= NULL
)
2254 lpPtr
->lpDescription
=
2255 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpDescription
);
2259 case SERVICE_CONFIG_FAILURE_ACTIONS
:
2261 LPSERVICE_FAILURE_ACTIONSW lpPtr
= (LPSERVICE_FAILURE_ACTIONSW
)lpTempBuffer
;
2263 if (lpPtr
->lpRebootMsg
!= NULL
)
2264 lpPtr
->lpRebootMsg
=
2265 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpRebootMsg
);
2267 if (lpPtr
->lpCommand
!= NULL
)
2269 (LPWSTR
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpCommand
);
2271 if (lpPtr
->lpsaActions
!= NULL
)
2272 lpPtr
->lpsaActions
=
2273 (LPSC_ACTION
)((ULONG_PTR
)lpPtr
+ (ULONG_PTR
)lpPtr
->lpsaActions
);
2278 TRACE("QueryServiceConfig2W() done\n");
2284 /**********************************************************************
2285 * QueryServiceLockStatusA
2290 QueryServiceLockStatusA(SC_HANDLE hSCManager
,
2291 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus
,
2293 LPDWORD pcbBytesNeeded
)
2295 QUERY_SERVICE_LOCK_STATUSA LockStatus
;
2296 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr
;
2300 TRACE("QueryServiceLockStatusA() called\n");
2302 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSA
))
2304 lpStatusPtr
= &LockStatus
;
2305 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSA
);
2309 lpStatusPtr
= lpLockStatus
;
2310 dwBufferSize
= cbBufSize
;
2315 /* Call to services.exe using RPC */
2316 dwError
= RQueryServiceLockStatusA((SC_RPC_HANDLE
)hSCManager
,
2317 (LPBYTE
)lpStatusPtr
,
2321 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2323 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2327 if (dwError
!= ERROR_SUCCESS
)
2329 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError
);
2330 SetLastError(dwError
);
2334 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2336 lpStatusPtr
->lpLockOwner
=
2337 (LPSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2340 TRACE("QueryServiceLockStatusA() done\n");
2346 /**********************************************************************
2347 * QueryServiceLockStatusW
2352 QueryServiceLockStatusW(SC_HANDLE hSCManager
,
2353 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus
,
2355 LPDWORD pcbBytesNeeded
)
2357 QUERY_SERVICE_LOCK_STATUSW LockStatus
;
2358 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr
;
2362 TRACE("QueryServiceLockStatusW() called\n");
2364 if (lpLockStatus
== NULL
|| cbBufSize
< sizeof(QUERY_SERVICE_LOCK_STATUSW
))
2366 lpStatusPtr
= &LockStatus
;
2367 dwBufferSize
= sizeof(QUERY_SERVICE_LOCK_STATUSW
);
2371 lpStatusPtr
= lpLockStatus
;
2372 dwBufferSize
= cbBufSize
;
2377 /* Call to services.exe using RPC */
2378 dwError
= RQueryServiceLockStatusW((SC_RPC_HANDLE
)hSCManager
,
2379 (LPBYTE
)lpStatusPtr
,
2383 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2385 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2389 if (dwError
!= ERROR_SUCCESS
)
2391 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError
);
2392 SetLastError(dwError
);
2396 if (lpStatusPtr
->lpLockOwner
!= NULL
)
2398 lpStatusPtr
->lpLockOwner
=
2399 (LPWSTR
)((ULONG_PTR
)lpStatusPtr
+ (ULONG_PTR
)lpStatusPtr
->lpLockOwner
);
2402 TRACE("QueryServiceLockStatusW() done\n");
2408 /**********************************************************************
2409 * QueryServiceObjectSecurity
2414 QueryServiceObjectSecurity(SC_HANDLE hService
,
2415 SECURITY_INFORMATION dwSecurityInformation
,
2416 PSECURITY_DESCRIPTOR lpSecurityDescriptor
,
2418 LPDWORD pcbBytesNeeded
)
2422 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2423 hService
, dwSecurityInformation
, lpSecurityDescriptor
);
2427 /* Call to services.exe using RPC */
2428 dwError
= RQueryServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2429 dwSecurityInformation
,
2430 (LPBYTE
)lpSecurityDescriptor
,
2434 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2436 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2440 if (dwError
!= ERROR_SUCCESS
)
2442 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2443 SetLastError(dwError
);
2450 /**********************************************************************
2451 * SetServiceObjectSecurity
2456 SetServiceObjectSecurity(SC_HANDLE hService
,
2457 SECURITY_INFORMATION dwSecurityInformation
,
2458 PSECURITY_DESCRIPTOR lpSecurityDescriptor
)
2460 PSECURITY_DESCRIPTOR SelfRelativeSD
= NULL
;
2466 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2469 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
2471 SetLastError(ERROR_INVALID_PARAMETER
);
2475 SelfRelativeSD
= HeapAlloc(GetProcessHeap(), 0, Length
);
2476 if (SelfRelativeSD
== NULL
)
2478 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2482 Status
= RtlMakeSelfRelativeSD(lpSecurityDescriptor
,
2485 if (!NT_SUCCESS(Status
))
2487 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2488 SetLastError(RtlNtStatusToDosError(Status
));
2494 /* Call to services.exe using RPC */
2495 dwError
= RSetServiceObjectSecurity((SC_RPC_HANDLE
)hService
,
2496 dwSecurityInformation
,
2497 (LPBYTE
)SelfRelativeSD
,
2500 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2502 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2506 HeapFree(GetProcessHeap(), 0, SelfRelativeSD
);
2508 if (dwError
!= ERROR_SUCCESS
)
2510 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError
);
2511 SetLastError(dwError
);
2519 /**********************************************************************
2520 * QueryServiceStatus
2525 QueryServiceStatus(SC_HANDLE hService
,
2526 LPSERVICE_STATUS lpServiceStatus
)
2530 TRACE("QueryServiceStatus(%p, %p)\n",
2531 hService
, lpServiceStatus
);
2535 SetLastError(ERROR_INVALID_HANDLE
);
2541 /* Call to services.exe using RPC */
2542 dwError
= RQueryServiceStatus((SC_RPC_HANDLE
)hService
,
2545 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2547 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2551 if (dwError
!= ERROR_SUCCESS
)
2553 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError
);
2554 SetLastError(dwError
);
2562 /**********************************************************************
2563 * QueryServiceStatusEx
2568 QueryServiceStatusEx(SC_HANDLE hService
,
2569 SC_STATUS_TYPE InfoLevel
,
2572 LPDWORD pcbBytesNeeded
)
2576 TRACE("QueryServiceStatusEx() called\n");
2578 if (InfoLevel
!= SC_STATUS_PROCESS_INFO
)
2580 SetLastError(ERROR_INVALID_LEVEL
);
2584 if (cbBufSize
< sizeof(SERVICE_STATUS_PROCESS
))
2586 *pcbBytesNeeded
= sizeof(SERVICE_STATUS_PROCESS
);
2587 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
2593 /* Call to services.exe using RPC */
2594 dwError
= RQueryServiceStatusEx((SC_RPC_HANDLE
)hService
,
2600 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2602 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2606 if (dwError
!= ERROR_SUCCESS
)
2608 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError
);
2609 SetLastError(dwError
);
2617 /**********************************************************************
2623 StartServiceA(SC_HANDLE hService
,
2624 DWORD dwNumServiceArgs
,
2625 LPCSTR
*lpServiceArgVectors
)
2631 dwError
= RStartServiceA((SC_RPC_HANDLE
)hService
,
2633 (LPSTRING_PTRSA
)lpServiceArgVectors
);
2635 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2637 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2641 if (dwError
!= ERROR_SUCCESS
)
2643 ERR("RStartServiceA() failed (Error %lu)\n", dwError
);
2644 SetLastError(dwError
);
2652 /**********************************************************************
2658 StartServiceW(SC_HANDLE hService
,
2659 DWORD dwNumServiceArgs
,
2660 LPCWSTR
*lpServiceArgVectors
)
2666 dwError
= RStartServiceW((SC_RPC_HANDLE
)hService
,
2668 (LPSTRING_PTRSW
)lpServiceArgVectors
);
2670 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2672 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2676 if (dwError
!= ERROR_SUCCESS
)
2678 ERR("RStartServiceW() failed (Error %lu)\n", dwError
);
2679 SetLastError(dwError
);
2687 /**********************************************************************
2688 * UnlockServiceDatabase
2693 UnlockServiceDatabase(SC_LOCK ScLock
)
2697 TRACE("UnlockServiceDatabase(%x)\n", ScLock
);
2701 /* Call to services.exe using RPC */
2702 dwError
= RUnlockServiceDatabase((LPSC_RPC_LOCK
)&ScLock
);
2704 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2706 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2710 if (dwError
!= ERROR_SUCCESS
)
2712 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError
);
2713 SetLastError(dwError
);
2721 /**********************************************************************
2722 * NotifyBootConfigStatus
2727 NotifyBootConfigStatus(BOOL BootAcceptable
)
2731 TRACE("NotifyBootConfigStatus()\n");
2735 /* Call to services.exe using RPC */
2736 dwError
= RNotifyBootConfigStatus(NULL
,
2739 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
2741 dwError
= ScmRpcStatusToWinError(RpcExceptionCode());
2745 if (dwError
!= ERROR_SUCCESS
)
2747 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError
);
2748 SetLastError(dwError
);