- QueryServiceConfig2A/W: Fail if lpBuffer is NULL but cbBufSize is not 0.
[reactos.git] / reactos / dll / win32 / advapi32 / service / scm.c
1 /*
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
7 * Eric Kohl
8 * UPDATE HISTORY:
9 * 19990413 EA created
10 * 19990515 EA
11 */
12
13 /* INCLUDES ******************************************************************/
14
15 #include <advapi32.h>
16
17 #include "wine/debug.h"
18
19 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
20
21
22 /* FUNCTIONS *****************************************************************/
23
24 handle_t BindingHandle = NULL;
25
26 VOID
27 HandleBind(VOID)
28 {
29 LPWSTR pszStringBinding;
30 RPC_STATUS status;
31
32 if (BindingHandle != NULL)
33 return;
34
35 status = RpcStringBindingComposeW(NULL,
36 L"ncacn_np",
37 NULL,
38 L"\\pipe\\ntsvcs",
39 NULL,
40 &pszStringBinding);
41 if (status)
42 {
43 TRACE("RpcStringBindingCompose returned 0x%x\n", status);
44 return;
45 }
46
47 /* Set the binding handle that will be used to bind to the server. */
48 status = RpcBindingFromStringBindingW(pszStringBinding,
49 &BindingHandle);
50 if (status)
51 {
52 TRACE("RpcBindingFromStringBinding returned 0x%x\n", status);
53 }
54
55 status = RpcStringFreeW(&pszStringBinding);
56 if (status)
57 {
58 TRACE("RpcStringFree returned 0x%x\n", status);
59 }
60 }
61
62
63 #if 0
64 static VOID
65 HandleUnbind(VOID)
66 {
67 RPC_STATUS status;
68
69 if (BindingHandle == NULL)
70 return;
71
72 status = RpcBindingFree(&BindingHandle);
73 if (status)
74 {
75 TRACE("RpcBindingFree returned 0x%x\n", status);
76 }
77 }
78 #endif
79
80
81 static DWORD
82 ScmRpcStatusToWinError(RPC_STATUS Status)
83 {
84 switch (Status)
85 {
86 case RPC_X_SS_IN_NULL_CONTEXT:
87 return ERROR_INVALID_HANDLE;
88
89 case RPC_X_NULL_REF_POINTER:
90 return ERROR_INVALID_PARAMETER;
91
92 case STATUS_ACCESS_VIOLATION:
93 return ERROR_INVALID_ADDRESS;
94
95 default:
96 return (DWORD)Status;
97 }
98 }
99
100
101 /**********************************************************************
102 * ChangeServiceConfig2A
103 *
104 * @implemented
105 */
106 BOOL WINAPI
107 ChangeServiceConfig2A(SC_HANDLE hService,
108 DWORD dwInfoLevel,
109 LPVOID lpInfo)
110 {
111 SC_RPC_CONFIG_INFOA Info;
112 DWORD dwError;
113
114 TRACE("ChangeServiceConfig2A() called\n");
115
116 /* Fill relevent field of the Info structure */
117 Info.dwInfoLevel = dwInfoLevel;
118 switch (dwInfoLevel)
119 {
120 case SERVICE_CONFIG_DESCRIPTION:
121 Info.psd = (LPSERVICE_DESCRIPTIONA)&lpInfo;
122 break;
123
124 case SERVICE_CONFIG_FAILURE_ACTIONS:
125 Info.psfa = (LPSERVICE_FAILURE_ACTIONSA)&lpInfo;
126 break;
127
128 default:
129 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
130 SetLastError(ERROR_INVALID_PARAMETER);
131 return FALSE;
132 }
133
134 if (lpInfo == NULL)
135 return TRUE;
136
137 HandleBind();
138
139 _SEH_TRY
140 {
141 dwError = RChangeServiceConfig2A(BindingHandle,
142 (SC_RPC_HANDLE)hService,
143 Info);
144 }
145 _SEH_HANDLE
146 {
147 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
148 }
149 _SEH_END;
150
151 if (dwError != ERROR_SUCCESS)
152 {
153 ERR("RChangeServiceConfig2A() failed (Error %lu)\n", dwError);
154 SetLastError(dwError);
155 return FALSE;
156 }
157
158 return TRUE;
159 }
160
161
162 /**********************************************************************
163 * ChangeServiceConfig2W
164 *
165 * @implemented
166 */
167 BOOL WINAPI
168 ChangeServiceConfig2W(SC_HANDLE hService,
169 DWORD dwInfoLevel,
170 LPVOID lpInfo)
171 {
172 SC_RPC_CONFIG_INFOW Info;
173 DWORD dwError;
174
175 TRACE("ChangeServiceConfig2W() called\n");
176
177 /* Fill relevent field of the Info structure */
178 Info.dwInfoLevel = dwInfoLevel;
179 switch (dwInfoLevel)
180 {
181 case SERVICE_CONFIG_DESCRIPTION:
182 {
183 Info.psd = (LPSERVICE_DESCRIPTIONW)&lpInfo;
184 break;
185 }
186
187 case SERVICE_CONFIG_FAILURE_ACTIONS:
188 Info.psfa = (LPSERVICE_FAILURE_ACTIONSW)&lpInfo;
189 break;
190
191 default:
192 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
193 SetLastError(ERROR_INVALID_PARAMETER);
194 return FALSE;
195 }
196
197 if (lpInfo == NULL)
198 return TRUE;
199
200 HandleBind();
201
202 _SEH_TRY
203 {
204 dwError = RChangeServiceConfig2W(BindingHandle,
205 (SC_RPC_HANDLE)hService,
206 Info);
207 }
208 _SEH_HANDLE
209 {
210 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
211 }
212 _SEH_END;
213
214 if (dwError != ERROR_SUCCESS)
215 {
216 ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError);
217 SetLastError(dwError);
218 return FALSE;
219 }
220
221 return TRUE;
222 }
223
224
225 /**********************************************************************
226 * ChangeServiceConfigA
227 *
228 * @implemented
229 */
230 BOOL STDCALL
231 ChangeServiceConfigA(SC_HANDLE hService,
232 DWORD dwServiceType,
233 DWORD dwStartType,
234 DWORD dwErrorControl,
235 LPCSTR lpBinaryPathName,
236 LPCSTR lpLoadOrderGroup,
237 LPDWORD lpdwTagId,
238 LPCSTR lpDependencies,
239 LPCSTR lpServiceStartName,
240 LPCSTR lpPassword,
241 LPCSTR lpDisplayName)
242 {
243 DWORD dwError;
244 DWORD dwDependenciesLength = 0;
245 DWORD dwLength;
246 LPSTR lpStr;
247
248 TRACE("ChangeServiceConfigA() called\n");
249
250 /* Calculate the Dependencies length*/
251 if (lpDependencies != NULL)
252 {
253 lpStr = (LPSTR)lpDependencies;
254 while (*lpStr)
255 {
256 dwLength = strlen(lpStr) + 1;
257 dwDependenciesLength += dwLength;
258 lpStr = lpStr + dwLength;
259 }
260 dwDependenciesLength++;
261 }
262
263 /* FIXME: Encrypt the password */
264
265 HandleBind();
266
267 _SEH_TRY
268 {
269 /* Call to services.exe using RPC */
270 dwError = RChangeServiceConfigA(BindingHandle,
271 (SC_RPC_HANDLE)hService,
272 dwServiceType,
273 dwStartType,
274 dwErrorControl,
275 (LPSTR)lpBinaryPathName,
276 (LPSTR)lpLoadOrderGroup,
277 lpdwTagId,
278 (LPSTR)lpDependencies,
279 dwDependenciesLength,
280 (LPSTR)lpServiceStartName,
281 NULL, /* FIXME: lpPassword */
282 0, /* FIXME: dwPasswordLength */
283 (LPSTR)lpDisplayName);
284 }
285 _SEH_HANDLE
286 {
287 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
288 }
289 _SEH_END;
290
291 if (dwError != ERROR_SUCCESS)
292 {
293 ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
294 SetLastError(dwError);
295 return FALSE;
296 }
297
298 return TRUE;
299 }
300
301
302 /**********************************************************************
303 * ChangeServiceConfigW
304 *
305 * @implemented
306 */
307 BOOL STDCALL
308 ChangeServiceConfigW(SC_HANDLE hService,
309 DWORD dwServiceType,
310 DWORD dwStartType,
311 DWORD dwErrorControl,
312 LPCWSTR lpBinaryPathName,
313 LPCWSTR lpLoadOrderGroup,
314 LPDWORD lpdwTagId,
315 LPCWSTR lpDependencies,
316 LPCWSTR lpServiceStartName,
317 LPCWSTR lpPassword,
318 LPCWSTR lpDisplayName)
319 {
320 DWORD dwError;
321 DWORD dwDependenciesLength = 0;
322 DWORD dwLength;
323 LPWSTR lpStr;
324
325 TRACE("ChangeServiceConfigW() called\n");
326
327 /* Calculate the Dependencies length*/
328 if (lpDependencies != NULL)
329 {
330 lpStr = (LPWSTR)lpDependencies;
331 while (*lpStr)
332 {
333 dwLength = wcslen(lpStr) + 1;
334 dwDependenciesLength += dwLength;
335 lpStr = lpStr + dwLength;
336 }
337 dwDependenciesLength++;
338 }
339
340 /* FIXME: Encrypt the password */
341
342 HandleBind();
343
344 _SEH_TRY
345 {
346 /* Call to services.exe using RPC */
347 dwError = RChangeServiceConfigW(BindingHandle,
348 (SC_RPC_HANDLE)hService,
349 dwServiceType,
350 dwStartType,
351 dwErrorControl,
352 (LPWSTR)lpBinaryPathName,
353 (LPWSTR)lpLoadOrderGroup,
354 lpdwTagId,
355 (LPBYTE)lpDependencies,
356 dwDependenciesLength,
357 (LPWSTR)lpServiceStartName,
358 NULL, /* FIXME: lpPassword */
359 0, /* FIXME: dwPasswordLength */
360 (LPWSTR)lpDisplayName);
361 }
362 _SEH_HANDLE
363 {
364 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
365 }
366 _SEH_END;
367
368 if (dwError != ERROR_SUCCESS)
369 {
370 ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError);
371 SetLastError(dwError);
372 return FALSE;
373 }
374
375 return TRUE;
376 }
377
378
379 /**********************************************************************
380 * CloseServiceHandle
381 *
382 * @implemented
383 */
384 BOOL STDCALL
385 CloseServiceHandle(SC_HANDLE hSCObject)
386 {
387 DWORD dwError;
388
389 TRACE("CloseServiceHandle() called\n");
390
391 HandleBind();
392
393 _SEH_TRY
394 {
395 /* Call to services.exe using RPC */
396 dwError = RCloseServiceHandle(BindingHandle,
397 (LPSC_RPC_HANDLE)&hSCObject);
398 }
399 _SEH_HANDLE
400 {
401 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
402 }
403 _SEH_END;
404
405 if (dwError)
406 {
407 ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError);
408 SetLastError(dwError);
409 return FALSE;
410 }
411
412 TRACE("CloseServiceHandle() done\n");
413
414 return TRUE;
415 }
416
417
418 /**********************************************************************
419 * ControlService
420 *
421 * @implemented
422 */
423 BOOL STDCALL
424 ControlService(SC_HANDLE hService,
425 DWORD dwControl,
426 LPSERVICE_STATUS lpServiceStatus)
427 {
428 DWORD dwError;
429
430 TRACE("ControlService(%x, %x, %p)\n",
431 hService, dwControl, lpServiceStatus);
432
433 HandleBind();
434
435 _SEH_TRY
436 {
437 /* Call to services.exe using RPC */
438 dwError = RControlService(BindingHandle,
439 (SC_RPC_HANDLE)hService,
440 dwControl,
441 lpServiceStatus);
442 }
443 _SEH_HANDLE
444 {
445 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
446 }
447 _SEH_END;
448
449 if (dwError != ERROR_SUCCESS)
450 {
451 ERR("RControlService() failed (Error %lu)\n", dwError);
452 SetLastError(dwError);
453 return FALSE;
454 }
455
456 TRACE("ControlService() done\n");
457
458 return TRUE;
459 }
460
461
462 /**********************************************************************
463 * ControlServiceEx
464 *
465 * @unimplemented
466 */
467 BOOL STDCALL
468 ControlServiceEx(IN SC_HANDLE hService,
469 IN DWORD dwControl,
470 IN DWORD dwInfoLevel,
471 IN OUT PVOID pControlParams)
472 {
473 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
474 hService, dwControl, dwInfoLevel, pControlParams);
475 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
476 return FALSE;
477 }
478
479
480 /**********************************************************************
481 * CreateServiceA
482 *
483 * @implemented
484 */
485 SC_HANDLE STDCALL
486 CreateServiceA(SC_HANDLE hSCManager,
487 LPCSTR lpServiceName,
488 LPCSTR lpDisplayName,
489 DWORD dwDesiredAccess,
490 DWORD dwServiceType,
491 DWORD dwStartType,
492 DWORD dwErrorControl,
493 LPCSTR lpBinaryPathName,
494 LPCSTR lpLoadOrderGroup,
495 LPDWORD lpdwTagId,
496 LPCSTR lpDependencies,
497 LPCSTR lpServiceStartName,
498 LPCSTR lpPassword)
499 {
500 SC_HANDLE RetVal = NULL;
501 LPWSTR lpServiceNameW = NULL;
502 LPWSTR lpDisplayNameW = NULL;
503 LPWSTR lpBinaryPathNameW = NULL;
504 LPWSTR lpLoadOrderGroupW = NULL;
505 LPWSTR lpDependenciesW = NULL;
506 LPWSTR lpServiceStartNameW = NULL;
507 LPWSTR lpPasswordW = NULL;
508 DWORD dwDependenciesLength = 0;
509 DWORD dwLength;
510 int len;
511 LPSTR lpStr;
512
513 if (lpServiceName)
514 {
515 len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
516 lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
517 if (!lpServiceNameW)
518 {
519 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
520 goto cleanup;
521 }
522 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
523 }
524
525 if (lpDisplayName)
526 {
527 len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
528 lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
529 if (!lpDisplayNameW)
530 {
531 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
532 goto cleanup;
533 }
534 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
535 }
536
537 if (lpBinaryPathName)
538 {
539 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
540 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
541 if (!lpBinaryPathNameW)
542 {
543 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
544 goto cleanup;
545 }
546 MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
547 }
548
549 if (lpLoadOrderGroup)
550 {
551 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
552 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
553 if (!lpLoadOrderGroupW)
554 {
555 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
556 goto cleanup;
557 }
558 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
559 }
560
561 if (lpDependencies)
562 {
563 lpStr = (LPSTR)lpDependencies;
564 while (*lpStr)
565 {
566 dwLength = strlen(lpStr) + 1;
567 dwDependenciesLength += dwLength;
568 lpStr = lpStr + dwLength;
569 }
570 dwDependenciesLength++;
571
572 lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
573 if (!lpDependenciesW)
574 {
575 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
576 goto cleanup;
577 }
578 MultiByteToWideChar(CP_ACP, 0, lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
579 }
580
581 if (lpServiceStartName)
582 {
583 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
584 lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
585 if (!lpServiceStartNameW)
586 {
587 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
588 goto cleanup;
589 }
590 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
591 }
592
593 if (lpPassword)
594 {
595 len = MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, NULL, 0);
596 lpPasswordW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
597 if (!lpPasswordW)
598 {
599 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
600 goto cleanup;
601 }
602 MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
603 }
604
605 RetVal = CreateServiceW(hSCManager,
606 lpServiceNameW,
607 lpDisplayNameW,
608 dwDesiredAccess,
609 dwServiceType,
610 dwStartType,
611 dwErrorControl,
612 lpBinaryPathNameW,
613 lpLoadOrderGroupW,
614 lpdwTagId,
615 lpDependenciesW,
616 lpServiceStartNameW,
617 lpPasswordW);
618
619 cleanup:
620 if (lpServiceNameW !=NULL)
621 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
622
623 if (lpDisplayNameW != NULL)
624 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
625
626 if (lpBinaryPathNameW != NULL)
627 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
628
629 if (lpLoadOrderGroupW != NULL)
630 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
631
632 if (lpDependenciesW != NULL)
633 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
634
635 if (lpServiceStartNameW != NULL)
636 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
637
638 if (lpPasswordW != NULL)
639 HeapFree(GetProcessHeap(), 0, lpPasswordW);
640
641 return RetVal;
642 }
643
644
645 /**********************************************************************
646 * CreateServiceW
647 *
648 * @implemented
649 */
650 SC_HANDLE STDCALL
651 CreateServiceW(SC_HANDLE hSCManager,
652 LPCWSTR lpServiceName,
653 LPCWSTR lpDisplayName,
654 DWORD dwDesiredAccess,
655 DWORD dwServiceType,
656 DWORD dwStartType,
657 DWORD dwErrorControl,
658 LPCWSTR lpBinaryPathName,
659 LPCWSTR lpLoadOrderGroup,
660 LPDWORD lpdwTagId,
661 LPCWSTR lpDependencies,
662 LPCWSTR lpServiceStartName,
663 LPCWSTR lpPassword)
664 {
665 SC_HANDLE hService = NULL;
666 DWORD dwDependenciesLength = 0;
667 DWORD dwError;
668 DWORD dwLength;
669 LPWSTR lpStr;
670
671 TRACE("CreateServiceW() called\n");
672
673 /* Calculate the Dependencies length*/
674 if (lpDependencies != NULL)
675 {
676 lpStr = (LPWSTR)lpDependencies;
677 while (*lpStr)
678 {
679 dwLength = wcslen(lpStr) + 1;
680 dwDependenciesLength += dwLength;
681 lpStr = lpStr + dwLength;
682 }
683 dwDependenciesLength++;
684
685 dwDependenciesLength *= sizeof(WCHAR);
686 }
687
688 /* FIXME: Encrypt the password */
689
690 HandleBind();
691
692 _SEH_TRY
693 {
694 /* Call to services.exe using RPC */
695 dwError = RCreateServiceW(BindingHandle,
696 (SC_RPC_HANDLE)hSCManager,
697 (LPWSTR)lpServiceName,
698 (LPWSTR)lpDisplayName,
699 dwDesiredAccess,
700 dwServiceType,
701 dwStartType,
702 dwErrorControl,
703 (LPWSTR)lpBinaryPathName,
704 (LPWSTR)lpLoadOrderGroup,
705 lpdwTagId,
706 (LPBYTE)lpDependencies,
707 dwDependenciesLength,
708 (LPWSTR)lpServiceStartName,
709 NULL, /* FIXME: lpPassword */
710 0, /* FIXME: dwPasswordLength */
711 (SC_RPC_HANDLE *)&hService);
712 }
713 _SEH_HANDLE
714 {
715 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
716 }
717 _SEH_END;
718
719 if (dwError != ERROR_SUCCESS)
720 {
721 ERR("RCreateServiceW() failed (Error %lu)\n", dwError);
722 SetLastError(dwError);
723 return NULL;
724 }
725
726 return hService;
727 }
728
729
730 /**********************************************************************
731 * DeleteService
732 *
733 * @implemented
734 */
735 BOOL STDCALL
736 DeleteService(SC_HANDLE hService)
737 {
738 DWORD dwError;
739
740 TRACE("DeleteService(%x)\n", hService);
741
742 HandleBind();
743
744 _SEH_TRY
745 {
746 /* Call to services.exe using RPC */
747 dwError = RDeleteService(BindingHandle,
748 (SC_RPC_HANDLE)hService);
749 }
750 _SEH_HANDLE
751 {
752 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
753 }
754 _SEH_END;
755
756 if (dwError != ERROR_SUCCESS)
757 {
758 ERR("RDeleteService() failed (Error %lu)\n", dwError);
759 SetLastError(dwError);
760 return FALSE;
761 }
762
763 return TRUE;
764 }
765
766
767 /**********************************************************************
768 * EnumDependentServicesA
769 *
770 * @implemented
771 */
772 BOOL STDCALL
773 EnumDependentServicesA(SC_HANDLE hService,
774 DWORD dwServiceState,
775 LPENUM_SERVICE_STATUSA lpServices,
776 DWORD cbBufSize,
777 LPDWORD pcbBytesNeeded,
778 LPDWORD lpServicesReturned)
779 {
780 LPENUM_SERVICE_STATUSA lpStatusPtr;
781 DWORD dwError;
782 DWORD dwCount;
783
784 TRACE("EnumServicesStatusA() called\n");
785
786 HandleBind();
787
788 _SEH_TRY
789 {
790 dwError = REnumDependentServicesA(BindingHandle,
791 (SC_RPC_HANDLE)hService,
792 dwServiceState,
793 (LPBYTE)lpServices,
794 cbBufSize,
795 pcbBytesNeeded,
796 lpServicesReturned);
797 }
798 _SEH_HANDLE
799 {
800 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
801 }
802 _SEH_END;
803
804 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
805 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
806 {
807 if (lpStatusPtr->lpServiceName)
808 lpStatusPtr->lpServiceName =
809 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
810
811 if (lpStatusPtr->lpDisplayName)
812 lpStatusPtr->lpDisplayName =
813 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
814
815 lpStatusPtr++;
816 }
817
818 if (dwError != ERROR_SUCCESS)
819 {
820 ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError);
821 SetLastError(dwError);
822 return FALSE;
823 }
824
825 TRACE("EnumDependentServicesA() done\n");
826
827 return TRUE;
828 }
829
830
831 /**********************************************************************
832 * EnumDependentServicesW
833 *
834 * @implemented
835 */
836 BOOL STDCALL
837 EnumDependentServicesW(SC_HANDLE hService,
838 DWORD dwServiceState,
839 LPENUM_SERVICE_STATUSW lpServices,
840 DWORD cbBufSize,
841 LPDWORD pcbBytesNeeded,
842 LPDWORD lpServicesReturned)
843 {
844 LPENUM_SERVICE_STATUSW lpStatusPtr;
845 DWORD dwError;
846 DWORD dwCount;
847
848 TRACE("EnumServicesStatusW() called\n");
849
850 HandleBind();
851
852 _SEH_TRY
853 {
854 dwError = REnumDependentServicesW(BindingHandle,
855 (SC_RPC_HANDLE)hService,
856 dwServiceState,
857 (LPBYTE)lpServices,
858 cbBufSize,
859 pcbBytesNeeded,
860 lpServicesReturned);
861 }
862 _SEH_HANDLE
863 {
864 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
865 }
866 _SEH_END;
867
868 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
869 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
870 {
871 if (lpStatusPtr->lpServiceName)
872 lpStatusPtr->lpServiceName =
873 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
874
875 if (lpStatusPtr->lpDisplayName)
876 lpStatusPtr->lpDisplayName =
877 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
878
879 lpStatusPtr++;
880 }
881
882 if (dwError != ERROR_SUCCESS)
883 {
884 ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError);
885 SetLastError(dwError);
886 return FALSE;
887 }
888
889 TRACE("EnumDependentServicesW() done\n");
890
891 return TRUE;
892 }
893
894
895 /**********************************************************************
896 * EnumServiceGroupW
897 *
898 * @unimplemented
899 */
900 BOOL
901 STDCALL
902 EnumServiceGroupW(
903 SC_HANDLE hSCManager,
904 DWORD dwServiceType,
905 DWORD dwServiceState,
906 LPENUM_SERVICE_STATUSW lpServices,
907 DWORD cbBufSize,
908 LPDWORD pcbBytesNeeded,
909 LPDWORD lpServicesReturned,
910 LPDWORD lpResumeHandle,
911 LPCWSTR lpGroup)
912 {
913 FIXME("EnumServiceGroupW is unimplemented\n");
914 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
915 return FALSE;
916 }
917
918
919 /**********************************************************************
920 * EnumServicesStatusA
921 *
922 * @implemented
923 */
924 BOOL STDCALL
925 EnumServicesStatusA(SC_HANDLE hSCManager,
926 DWORD dwServiceType,
927 DWORD dwServiceState,
928 LPENUM_SERVICE_STATUSA lpServices,
929 DWORD cbBufSize,
930 LPDWORD pcbBytesNeeded,
931 LPDWORD lpServicesReturned,
932 LPDWORD lpResumeHandle)
933 {
934 LPENUM_SERVICE_STATUSA lpStatusPtr;
935 DWORD dwError;
936 DWORD dwCount;
937
938 TRACE("EnumServicesStatusA() called\n");
939
940 HandleBind();
941
942 _SEH_TRY
943 {
944 dwError = REnumServicesStatusA(BindingHandle,
945 (SC_RPC_HANDLE)hSCManager,
946 dwServiceType,
947 dwServiceState,
948 (LPBYTE)lpServices,
949 cbBufSize,
950 pcbBytesNeeded,
951 lpServicesReturned,
952 lpResumeHandle);
953 }
954 _SEH_HANDLE
955 {
956 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
957 }
958 _SEH_END;
959
960 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
961 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
962 {
963 if (lpStatusPtr->lpServiceName)
964 lpStatusPtr->lpServiceName =
965 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
966
967 if (lpStatusPtr->lpDisplayName)
968 lpStatusPtr->lpDisplayName =
969 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
970
971 lpStatusPtr++;
972 }
973
974 if (dwError != ERROR_SUCCESS)
975 {
976 ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError);
977 SetLastError(dwError);
978 return FALSE;
979 }
980
981 TRACE("EnumServicesStatusA() done\n");
982
983 return TRUE;
984 }
985
986
987 /**********************************************************************
988 * EnumServicesStatusW
989 *
990 * @implemented
991 */
992 BOOL STDCALL
993 EnumServicesStatusW(SC_HANDLE hSCManager,
994 DWORD dwServiceType,
995 DWORD dwServiceState,
996 LPENUM_SERVICE_STATUSW lpServices,
997 DWORD cbBufSize,
998 LPDWORD pcbBytesNeeded,
999 LPDWORD lpServicesReturned,
1000 LPDWORD lpResumeHandle)
1001 {
1002 LPENUM_SERVICE_STATUSW lpStatusPtr;
1003 DWORD dwError;
1004 DWORD dwCount;
1005
1006 TRACE("EnumServicesStatusW() called\n");
1007
1008 HandleBind();
1009
1010 _SEH_TRY
1011 {
1012 dwError = REnumServicesStatusW(BindingHandle,
1013 (SC_RPC_HANDLE)hSCManager,
1014 dwServiceType,
1015 dwServiceState,
1016 (LPBYTE)lpServices,
1017 cbBufSize,
1018 pcbBytesNeeded,
1019 lpServicesReturned,
1020 lpResumeHandle);
1021 }
1022 _SEH_HANDLE
1023 {
1024 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1025 }
1026 _SEH_END;
1027
1028 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
1029 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1030 {
1031 if (lpStatusPtr->lpServiceName)
1032 lpStatusPtr->lpServiceName =
1033 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1034
1035 if (lpStatusPtr->lpDisplayName)
1036 lpStatusPtr->lpDisplayName =
1037 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1038
1039 lpStatusPtr++;
1040 }
1041
1042 if (dwError != ERROR_SUCCESS)
1043 {
1044 ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError);
1045 SetLastError(dwError);
1046 return FALSE;
1047 }
1048
1049 TRACE("EnumServicesStatusW() done\n");
1050
1051 return TRUE;
1052 }
1053
1054
1055 /**********************************************************************
1056 * EnumServicesStatusExA
1057 *
1058 * @implemented
1059 */
1060 BOOL STDCALL
1061 EnumServicesStatusExA(SC_HANDLE hSCManager,
1062 SC_ENUM_TYPE InfoLevel,
1063 DWORD dwServiceType,
1064 DWORD dwServiceState,
1065 LPBYTE lpServices,
1066 DWORD cbBufSize,
1067 LPDWORD pcbBytesNeeded,
1068 LPDWORD lpServicesReturned,
1069 LPDWORD lpResumeHandle,
1070 LPCSTR pszGroupName)
1071 {
1072 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
1073 DWORD dwError;
1074 DWORD dwCount;
1075
1076 TRACE("EnumServicesStatusExA() called\n");
1077
1078 HandleBind();
1079
1080 _SEH_TRY
1081 {
1082 dwError = REnumServicesStatusExA(BindingHandle,
1083 (SC_RPC_HANDLE)hSCManager,
1084 InfoLevel,
1085 dwServiceType,
1086 dwServiceState,
1087 (LPBYTE)lpServices,
1088 cbBufSize,
1089 pcbBytesNeeded,
1090 lpServicesReturned,
1091 lpResumeHandle,
1092 (LPSTR)pszGroupName);
1093 }
1094 _SEH_HANDLE
1095 {
1096 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1097 }
1098 _SEH_END;
1099
1100 if (dwError == ERROR_MORE_DATA)
1101 {
1102 WARN("Required buffer size %ul\n", *pcbBytesNeeded);
1103 SetLastError(dwError);
1104 return FALSE;
1105 }
1106 else if (dwError == ERROR_SUCCESS)
1107 {
1108 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
1109 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1110 {
1111 if (lpStatusPtr->lpServiceName)
1112 lpStatusPtr->lpServiceName =
1113 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1114
1115 if (lpStatusPtr->lpDisplayName)
1116 lpStatusPtr->lpDisplayName =
1117 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1118
1119 lpStatusPtr++;
1120 }
1121 }
1122 else
1123 {
1124 ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError);
1125 SetLastError(dwError);
1126 return FALSE;
1127 }
1128
1129 TRACE("EnumServicesStatusExA() done\n");
1130
1131 return TRUE;
1132 }
1133
1134
1135 /**********************************************************************
1136 * EnumServicesStatusExW
1137 *
1138 * @implemented
1139 */
1140 BOOL STDCALL
1141 EnumServicesStatusExW(SC_HANDLE hSCManager,
1142 SC_ENUM_TYPE InfoLevel,
1143 DWORD dwServiceType,
1144 DWORD dwServiceState,
1145 LPBYTE lpServices,
1146 DWORD cbBufSize,
1147 LPDWORD pcbBytesNeeded,
1148 LPDWORD lpServicesReturned,
1149 LPDWORD lpResumeHandle,
1150 LPCWSTR pszGroupName)
1151 {
1152 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
1153 DWORD dwError;
1154 DWORD dwCount;
1155
1156 TRACE("EnumServicesStatusExW() called\n");
1157
1158 HandleBind();
1159
1160 _SEH_TRY
1161 {
1162 dwError = REnumServicesStatusExW(BindingHandle,
1163 (SC_RPC_HANDLE)hSCManager,
1164 InfoLevel,
1165 dwServiceType,
1166 dwServiceState,
1167 (LPBYTE)lpServices,
1168 cbBufSize,
1169 pcbBytesNeeded,
1170 lpServicesReturned,
1171 lpResumeHandle,
1172 (LPWSTR)pszGroupName);
1173 }
1174 _SEH_HANDLE
1175 {
1176 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1177 }
1178 _SEH_END;
1179
1180 if (dwError == ERROR_MORE_DATA)
1181 {
1182 WARN("Required buffer size %ul\n", *pcbBytesNeeded);
1183 SetLastError(dwError);
1184 return FALSE;
1185 }
1186 else if (dwError == ERROR_SUCCESS)
1187 {
1188 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
1189 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1190 {
1191 if (lpStatusPtr->lpServiceName)
1192 lpStatusPtr->lpServiceName =
1193 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1194
1195 if (lpStatusPtr->lpDisplayName)
1196 lpStatusPtr->lpDisplayName =
1197 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1198
1199 lpStatusPtr++;
1200 }
1201 }
1202 else
1203 {
1204 ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError);
1205 SetLastError(dwError);
1206 return FALSE;
1207 }
1208
1209 TRACE("EnumServicesStatusExW() done\n");
1210
1211 return TRUE;
1212 }
1213
1214
1215 /**********************************************************************
1216 * GetServiceDisplayNameA
1217 *
1218 * @implemented
1219 */
1220 BOOL STDCALL
1221 GetServiceDisplayNameA(SC_HANDLE hSCManager,
1222 LPCSTR lpServiceName,
1223 LPSTR lpDisplayName,
1224 LPDWORD lpcchBuffer)
1225 {
1226 DWORD dwError;
1227
1228 TRACE("GetServiceDisplayNameA() called\n");
1229
1230 if (!lpDisplayName)
1231 *lpcchBuffer = 0;
1232
1233 HandleBind();
1234
1235 _SEH_TRY
1236 {
1237 dwError = RGetServiceDisplayNameA(BindingHandle,
1238 (SC_RPC_HANDLE)hSCManager,
1239 (LPSTR)lpServiceName,
1240 lpDisplayName,
1241 lpcchBuffer);
1242 }
1243 _SEH_HANDLE
1244 {
1245 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1246 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1247 }
1248
1249
1250 _SEH_END;
1251
1252 if (dwError != ERROR_SUCCESS)
1253 {
1254 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
1255 SetLastError(dwError);
1256 return FALSE;
1257 }
1258
1259 return TRUE;
1260 }
1261
1262
1263 /**********************************************************************
1264 * GetServiceDisplayNameW
1265 *
1266 * @implemented
1267 */
1268 BOOL STDCALL
1269 GetServiceDisplayNameW(SC_HANDLE hSCManager,
1270 LPCWSTR lpServiceName,
1271 LPWSTR lpDisplayName,
1272 LPDWORD lpcchBuffer)
1273 {
1274 DWORD dwError;
1275
1276 TRACE("GetServiceDisplayNameW() called\n");
1277
1278 if (!lpDisplayName)
1279 *lpcchBuffer = 0;
1280
1281 HandleBind();
1282
1283 _SEH_TRY
1284 {
1285 dwError = RGetServiceDisplayNameW(BindingHandle,
1286 (SC_RPC_HANDLE)hSCManager,
1287 (LPWSTR)lpServiceName,
1288 lpDisplayName,
1289 lpcchBuffer);
1290 }
1291 _SEH_HANDLE
1292 {
1293 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1294 }
1295 _SEH_END;
1296
1297 if (dwError != ERROR_SUCCESS)
1298 {
1299 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
1300 SetLastError(dwError);
1301 return FALSE;
1302 }
1303
1304 return TRUE;
1305 }
1306
1307
1308 /**********************************************************************
1309 * GetServiceKeyNameA
1310 *
1311 * @implemented
1312 */
1313 BOOL STDCALL
1314 GetServiceKeyNameA(SC_HANDLE hSCManager,
1315 LPCSTR lpDisplayName,
1316 LPSTR lpServiceName,
1317 LPDWORD lpcchBuffer)
1318 {
1319 DWORD dwError;
1320
1321 TRACE("GetServiceKeyNameA() called\n");
1322
1323 if (!lpServiceName)
1324 *lpcchBuffer = 0;
1325
1326 HandleBind();
1327
1328 _SEH_TRY
1329 {
1330 dwError = RGetServiceKeyNameA(BindingHandle,
1331 (SC_RPC_HANDLE)hSCManager,
1332 (LPSTR)lpDisplayName,
1333 lpServiceName,
1334 lpcchBuffer);
1335 }
1336 _SEH_HANDLE
1337 {
1338 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1339 }
1340 _SEH_END;
1341
1342 if (dwError != ERROR_SUCCESS)
1343 {
1344 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
1345 SetLastError(dwError);
1346 return FALSE;
1347 }
1348
1349 return TRUE;
1350 }
1351
1352
1353 /**********************************************************************
1354 * GetServiceKeyNameW
1355 *
1356 * @implemented
1357 */
1358 BOOL STDCALL
1359 GetServiceKeyNameW(SC_HANDLE hSCManager,
1360 LPCWSTR lpDisplayName,
1361 LPWSTR lpServiceName,
1362 LPDWORD lpcchBuffer)
1363 {
1364 DWORD dwError;
1365
1366 TRACE("GetServiceKeyNameW() called\n");
1367
1368 if (!lpDisplayName)
1369 *lpcchBuffer = 0;
1370
1371 HandleBind();
1372
1373 _SEH_TRY
1374 {
1375 dwError = RGetServiceKeyNameW(BindingHandle,
1376 (SC_RPC_HANDLE)hSCManager,
1377 (LPWSTR)lpDisplayName,
1378 lpServiceName,
1379 lpcchBuffer);
1380 }
1381 _SEH_HANDLE
1382 {
1383 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1384 }
1385 _SEH_END;
1386
1387 if (dwError != ERROR_SUCCESS)
1388 {
1389 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
1390 SetLastError(dwError);
1391 return FALSE;
1392 }
1393
1394 return TRUE;
1395 }
1396
1397
1398 /**********************************************************************
1399 * LockServiceDatabase
1400 *
1401 * @implemented
1402 */
1403 SC_LOCK STDCALL
1404 LockServiceDatabase(SC_HANDLE hSCManager)
1405 {
1406 SC_LOCK hLock;
1407 DWORD dwError;
1408
1409 TRACE("LockServiceDatabase(%x)\n", hSCManager);
1410
1411 HandleBind();
1412
1413 _SEH_TRY
1414 {
1415 /* Call to services.exe using RPC */
1416 dwError = RLockServiceDatabase(BindingHandle,
1417 (SC_RPC_HANDLE)hSCManager,
1418 (SC_RPC_LOCK *)&hLock);
1419 }
1420 _SEH_HANDLE
1421 {
1422 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1423 }
1424 _SEH_END;
1425
1426 if (dwError != ERROR_SUCCESS)
1427 {
1428 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError);
1429 SetLastError(dwError);
1430 return NULL;
1431 }
1432
1433 TRACE("hLock = %p\n", hLock);
1434
1435 return hLock;
1436 }
1437
1438
1439 static VOID
1440 WaitForSCManager(VOID)
1441 {
1442 HANDLE hEvent;
1443
1444 TRACE("WaitForSCManager() called\n");
1445
1446 /* Try to open the existing event */
1447 hEvent = OpenEventW(SYNCHRONIZE,
1448 FALSE,
1449 L"SvcctrlStartEvent_A3752DX");
1450 if (hEvent == NULL)
1451 {
1452 if (GetLastError() != ERROR_FILE_NOT_FOUND)
1453 return;
1454
1455 /* Try to create a new event */
1456 hEvent = CreateEventW(NULL,
1457 TRUE,
1458 FALSE,
1459 L"SvcctrlStartEvent_A3752DX");
1460 if (hEvent == NULL)
1461 {
1462 /* Try to open the existing event again */
1463 hEvent = OpenEventW(SYNCHRONIZE,
1464 FALSE,
1465 L"SvcctrlStartEvent_A3752DX");
1466 if (hEvent == NULL)
1467 return;
1468 }
1469 }
1470
1471 /* Wait for 3 minutes */
1472 WaitForSingleObject(hEvent, 180000);
1473 CloseHandle(hEvent);
1474
1475 TRACE("ScmWaitForSCManager() done\n");
1476 }
1477
1478
1479 /**********************************************************************
1480 * OpenSCManagerA
1481 *
1482 * @implemented
1483 */
1484 SC_HANDLE STDCALL
1485 OpenSCManagerA(LPCSTR lpMachineName,
1486 LPCSTR lpDatabaseName,
1487 DWORD dwDesiredAccess)
1488 {
1489 SC_HANDLE hScm = NULL;
1490 DWORD dwError;
1491
1492 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1493 lpMachineName, lpDatabaseName, dwDesiredAccess);
1494
1495 WaitForSCManager();
1496
1497 HandleBind();
1498
1499 _SEH_TRY
1500 {
1501 /* Call to services.exe using RPC */
1502 dwError = ROpenSCManagerA(BindingHandle,
1503 (LPSTR)lpMachineName,
1504 (LPSTR)lpDatabaseName,
1505 dwDesiredAccess,
1506 (SC_RPC_HANDLE *)&hScm);
1507 }
1508 _SEH_HANDLE
1509 {
1510 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1511 }
1512 _SEH_END;
1513
1514 if (dwError != ERROR_SUCCESS)
1515 {
1516 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError);
1517 SetLastError(dwError);
1518 return NULL;
1519 }
1520
1521 TRACE("hScm = %p\n", hScm);
1522
1523 return hScm;
1524 }
1525
1526
1527 /**********************************************************************
1528 * OpenSCManagerW
1529 *
1530 * @implemented
1531 */
1532 SC_HANDLE STDCALL
1533 OpenSCManagerW(LPCWSTR lpMachineName,
1534 LPCWSTR lpDatabaseName,
1535 DWORD dwDesiredAccess)
1536 {
1537 SC_HANDLE hScm = NULL;
1538 DWORD dwError;
1539
1540 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1541 lpMachineName, lpDatabaseName, dwDesiredAccess);
1542
1543 WaitForSCManager();
1544
1545 HandleBind();
1546
1547 _SEH_TRY
1548 {
1549 /* Call to services.exe using RPC */
1550 dwError = ROpenSCManagerW(BindingHandle,
1551 (LPWSTR)lpMachineName,
1552 (LPWSTR)lpDatabaseName,
1553 dwDesiredAccess,
1554 (SC_RPC_HANDLE *)&hScm);
1555 }
1556 _SEH_HANDLE
1557 {
1558 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1559 }
1560 _SEH_END;
1561
1562 if (dwError != ERROR_SUCCESS)
1563 {
1564 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError);
1565 SetLastError(dwError);
1566 return NULL;
1567 }
1568
1569 TRACE("hScm = %p\n", hScm);
1570
1571 return hScm;
1572 }
1573
1574
1575 /**********************************************************************
1576 * OpenServiceA
1577 *
1578 * @implemented
1579 */
1580 SC_HANDLE STDCALL
1581 OpenServiceA(SC_HANDLE hSCManager,
1582 LPCSTR lpServiceName,
1583 DWORD dwDesiredAccess)
1584 {
1585 SC_HANDLE hService = NULL;
1586 DWORD dwError;
1587
1588 TRACE("OpenServiceA(%p, %s, %lx)\n",
1589 hSCManager, lpServiceName, dwDesiredAccess);
1590
1591 HandleBind();
1592
1593 _SEH_TRY
1594 {
1595 /* Call to services.exe using RPC */
1596 dwError = ROpenServiceA(BindingHandle,
1597 (SC_RPC_HANDLE)hSCManager,
1598 (LPSTR)lpServiceName,
1599 dwDesiredAccess,
1600 (SC_RPC_HANDLE *)&hService);
1601 }
1602 _SEH_HANDLE
1603 {
1604 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1605 }
1606 _SEH_END;
1607
1608 if (dwError != ERROR_SUCCESS)
1609 {
1610 ERR("ROpenServiceA() failed (Error %lu)\n", dwError);
1611 SetLastError(dwError);
1612 return NULL;
1613 }
1614
1615 TRACE("hService = %p\n", hService);
1616
1617 return hService;
1618 }
1619
1620
1621 /**********************************************************************
1622 * OpenServiceW
1623 *
1624 * @implemented
1625 */
1626 SC_HANDLE STDCALL
1627 OpenServiceW(SC_HANDLE hSCManager,
1628 LPCWSTR lpServiceName,
1629 DWORD dwDesiredAccess)
1630 {
1631 SC_HANDLE hService = NULL;
1632 DWORD dwError;
1633
1634 TRACE("OpenServiceW(%p, %S, %lx)\n",
1635 hSCManager, lpServiceName, dwDesiredAccess);
1636
1637 HandleBind();
1638
1639 _SEH_TRY
1640 {
1641 /* Call to services.exe using RPC */
1642 dwError = ROpenServiceW(BindingHandle,
1643 (SC_RPC_HANDLE)hSCManager,
1644 (LPWSTR)lpServiceName,
1645 dwDesiredAccess,
1646 (SC_RPC_HANDLE *)&hService);
1647 }
1648 _SEH_HANDLE
1649 {
1650 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1651 }
1652 _SEH_END;
1653
1654 if (dwError != ERROR_SUCCESS)
1655 {
1656 if (dwError == ERROR_SERVICE_DOES_NOT_EXIST)
1657 WARN("ROpenServiceW() failed (Error %lu)\n", dwError);
1658 else
1659 ERR("ROpenServiceW() failed (Error %lu)\n", dwError);
1660 SetLastError(dwError);
1661 return NULL;
1662 }
1663
1664 TRACE("hService = %p\n", hService);
1665
1666 return hService;
1667 }
1668
1669
1670 /**********************************************************************
1671 * QueryServiceConfigA
1672 *
1673 * @implemented
1674 */
1675 BOOL STDCALL
1676 QueryServiceConfigA(SC_HANDLE hService,
1677 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
1678 DWORD cbBufSize,
1679 LPDWORD pcbBytesNeeded)
1680 {
1681 DWORD dwError;
1682
1683 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1684 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1685
1686 HandleBind();
1687
1688 _SEH_TRY
1689 {
1690 /* Call to services.exe using RPC */
1691 dwError = RQueryServiceConfigA(BindingHandle,
1692 (SC_RPC_HANDLE)hService,
1693 (LPBYTE)lpServiceConfig,
1694 cbBufSize,
1695 pcbBytesNeeded);
1696 }
1697 _SEH_HANDLE
1698 {
1699 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1700 }
1701 _SEH_END;
1702
1703 if (dwError != ERROR_SUCCESS)
1704 {
1705 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
1706 SetLastError(dwError);
1707 return FALSE;
1708 }
1709
1710 /* Adjust the pointers */
1711 if (lpServiceConfig->lpBinaryPathName)
1712 lpServiceConfig->lpBinaryPathName =
1713 (LPSTR)((ULONG_PTR)lpServiceConfig +
1714 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1715
1716 if (lpServiceConfig->lpLoadOrderGroup)
1717 lpServiceConfig->lpLoadOrderGroup =
1718 (LPSTR)((ULONG_PTR)lpServiceConfig +
1719 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1720
1721 if (lpServiceConfig->lpDependencies)
1722 lpServiceConfig->lpDependencies =
1723 (LPSTR)((ULONG_PTR)lpServiceConfig +
1724 (ULONG_PTR)lpServiceConfig->lpDependencies);
1725
1726 if (lpServiceConfig->lpServiceStartName)
1727 lpServiceConfig->lpServiceStartName =
1728 (LPSTR)((ULONG_PTR)lpServiceConfig +
1729 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1730
1731 if (lpServiceConfig->lpDisplayName)
1732 lpServiceConfig->lpDisplayName =
1733 (LPSTR)((ULONG_PTR)lpServiceConfig +
1734 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1735
1736 TRACE("QueryServiceConfigA() done\n");
1737
1738 return TRUE;
1739 }
1740
1741
1742 /**********************************************************************
1743 * QueryServiceConfigW
1744 *
1745 * @implemented
1746 */
1747 BOOL STDCALL
1748 QueryServiceConfigW(SC_HANDLE hService,
1749 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1750 DWORD cbBufSize,
1751 LPDWORD pcbBytesNeeded)
1752 {
1753 DWORD dwError;
1754
1755 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1756 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1757
1758 HandleBind();
1759
1760 _SEH_TRY
1761 {
1762 /* Call to services.exe using RPC */
1763 dwError = RQueryServiceConfigW(BindingHandle,
1764 (SC_RPC_HANDLE)hService,
1765 (LPBYTE)lpServiceConfig,
1766 cbBufSize,
1767 pcbBytesNeeded);
1768 }
1769 _SEH_HANDLE
1770 {
1771 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1772 }
1773 _SEH_END;
1774
1775 if (dwError != ERROR_SUCCESS)
1776 {
1777 if (dwError == ERROR_INSUFFICIENT_BUFFER)
1778 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1779 else
1780 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1781 SetLastError(dwError);
1782 return FALSE;
1783 }
1784
1785 /* Adjust the pointers */
1786 if (lpServiceConfig->lpBinaryPathName)
1787 lpServiceConfig->lpBinaryPathName =
1788 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1789 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1790
1791 if (lpServiceConfig->lpLoadOrderGroup)
1792 lpServiceConfig->lpLoadOrderGroup =
1793 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1794 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1795
1796 if (lpServiceConfig->lpDependencies)
1797 lpServiceConfig->lpDependencies =
1798 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1799 (ULONG_PTR)lpServiceConfig->lpDependencies);
1800
1801 if (lpServiceConfig->lpServiceStartName)
1802 lpServiceConfig->lpServiceStartName =
1803 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1804 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1805
1806 if (lpServiceConfig->lpDisplayName)
1807 lpServiceConfig->lpDisplayName =
1808 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1809 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1810
1811 TRACE("QueryServiceConfigW() done\n");
1812
1813 return TRUE;
1814 }
1815
1816
1817 /**********************************************************************
1818 * QueryServiceConfig2A
1819 *
1820 * @implemented
1821 */
1822 BOOL STDCALL
1823 QueryServiceConfig2A(SC_HANDLE hService,
1824 DWORD dwInfoLevel,
1825 LPBYTE lpBuffer,
1826 DWORD cbBufSize,
1827 LPDWORD pcbBytesNeeded)
1828 {
1829 DWORD dwError;
1830
1831 TRACE("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
1832 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1833
1834 if (lpBuffer == NULL && cbBufSize != 0)
1835 {
1836 SetLastError(ERROR_INVALID_ADDRESS);
1837 return FALSE;
1838 }
1839
1840 HandleBind();
1841
1842 _SEH_TRY
1843 {
1844 /* Call to services.exe using RPC */
1845 dwError = RQueryServiceConfig2A(BindingHandle,
1846 (SC_RPC_HANDLE)hService,
1847 dwInfoLevel,
1848 lpBuffer,
1849 cbBufSize,
1850 pcbBytesNeeded);
1851 }
1852 _SEH_HANDLE
1853 {
1854 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1855 }
1856 _SEH_END;
1857
1858 if (dwError != ERROR_SUCCESS)
1859 {
1860 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
1861 SetLastError(dwError);
1862 return FALSE;
1863 }
1864
1865 switch (dwInfoLevel)
1866 {
1867 case SERVICE_CONFIG_DESCRIPTION:
1868 {
1869 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
1870
1871 if (lpPtr->lpDescription != NULL)
1872 lpPtr->lpDescription =
1873 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1874 }
1875 break;
1876
1877 case SERVICE_CONFIG_FAILURE_ACTIONS:
1878 {
1879 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
1880
1881 if (lpPtr->lpRebootMsg != NULL)
1882 lpPtr->lpRebootMsg =
1883 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1884
1885 if (lpPtr->lpCommand != NULL)
1886 lpPtr->lpCommand =
1887 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1888
1889 if (lpPtr->lpsaActions != NULL)
1890 lpPtr->lpsaActions =
1891 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1892 }
1893 break;
1894
1895 default:
1896 ERR("Unknown info level 0x%lx\n", dwInfoLevel);
1897 SetLastError(ERROR_INVALID_PARAMETER);
1898 return FALSE;
1899 }
1900
1901 TRACE("QueryServiceConfig2A() done\n");
1902
1903 return TRUE;
1904 }
1905
1906
1907 /**********************************************************************
1908 * QueryServiceConfig2W
1909 *
1910 * @implemented
1911 */
1912 BOOL STDCALL
1913 QueryServiceConfig2W(SC_HANDLE hService,
1914 DWORD dwInfoLevel,
1915 LPBYTE lpBuffer,
1916 DWORD cbBufSize,
1917 LPDWORD pcbBytesNeeded)
1918 {
1919 DWORD dwError;
1920
1921 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
1922 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1923
1924 if (lpBuffer == NULL && cbBufSize != 0)
1925 {
1926 SetLastError(ERROR_INVALID_ADDRESS);
1927 return FALSE;
1928 }
1929
1930 HandleBind();
1931
1932 _SEH_TRY
1933 {
1934 /* Call to services.exe using RPC */
1935 dwError = RQueryServiceConfig2W(BindingHandle,
1936 (SC_RPC_HANDLE)hService,
1937 dwInfoLevel,
1938 lpBuffer,
1939 cbBufSize,
1940 pcbBytesNeeded);
1941 }
1942 _SEH_HANDLE
1943 {
1944 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1945 }
1946 _SEH_END;
1947
1948 if (dwError != ERROR_SUCCESS)
1949 {
1950 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
1951 SetLastError(dwError);
1952 return FALSE;
1953 }
1954
1955 switch (dwInfoLevel)
1956 {
1957 case SERVICE_CONFIG_DESCRIPTION:
1958 {
1959 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
1960
1961 if (lpPtr->lpDescription != NULL)
1962 lpPtr->lpDescription =
1963 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1964 }
1965 break;
1966
1967 case SERVICE_CONFIG_FAILURE_ACTIONS:
1968 {
1969 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
1970
1971 if (lpPtr->lpRebootMsg != NULL)
1972 lpPtr->lpRebootMsg =
1973 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1974
1975 if (lpPtr->lpCommand != NULL)
1976 lpPtr->lpCommand =
1977 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1978
1979 if (lpPtr->lpsaActions != NULL)
1980 lpPtr->lpsaActions =
1981 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1982 }
1983 break;
1984
1985 default:
1986 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
1987 SetLastError(ERROR_INVALID_PARAMETER);
1988 return FALSE;
1989 }
1990
1991 TRACE("QueryServiceConfig2W() done\n");
1992
1993 return TRUE;
1994 }
1995
1996
1997 /**********************************************************************
1998 * QueryServiceLockStatusA
1999 *
2000 * @implemented
2001 */
2002 BOOL STDCALL
2003 QueryServiceLockStatusA(SC_HANDLE hSCManager,
2004 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
2005 DWORD cbBufSize,
2006 LPDWORD pcbBytesNeeded)
2007 {
2008 DWORD dwError;
2009
2010 TRACE("QueryServiceLockStatusA() called\n");
2011
2012 HandleBind();
2013
2014 _SEH_TRY
2015 {
2016 /* Call to services.exe using RPC */
2017 dwError = RQueryServiceLockStatusA(BindingHandle,
2018 (SC_RPC_HANDLE)hSCManager,
2019 lpLockStatus,
2020 cbBufSize,
2021 pcbBytesNeeded);
2022 }
2023 _SEH_HANDLE
2024 {
2025 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2026 }
2027 _SEH_END;
2028
2029 if (dwError != ERROR_SUCCESS)
2030 {
2031 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
2032 SetLastError(dwError);
2033 return FALSE;
2034 }
2035
2036 if (lpLockStatus->lpLockOwner != NULL)
2037 {
2038 lpLockStatus->lpLockOwner =
2039 (LPSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2040 }
2041
2042 TRACE("QueryServiceLockStatusA() done\n");
2043
2044 return TRUE;
2045 }
2046
2047
2048 /**********************************************************************
2049 * QueryServiceLockStatusW
2050 *
2051 * @implemented
2052 */
2053 BOOL STDCALL
2054 QueryServiceLockStatusW(SC_HANDLE hSCManager,
2055 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
2056 DWORD cbBufSize,
2057 LPDWORD pcbBytesNeeded)
2058 {
2059 DWORD dwError;
2060
2061 TRACE("QueryServiceLockStatusW() called\n");
2062
2063 HandleBind();
2064
2065 _SEH_TRY
2066 {
2067 /* Call to services.exe using RPC */
2068 dwError = RQueryServiceLockStatusW(BindingHandle,
2069 (SC_RPC_HANDLE)hSCManager,
2070 lpLockStatus,
2071 cbBufSize,
2072 pcbBytesNeeded);
2073 }
2074 _SEH_HANDLE
2075 {
2076 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2077 }
2078 _SEH_END;
2079
2080 if (dwError != ERROR_SUCCESS)
2081 {
2082 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
2083 SetLastError(dwError);
2084 return FALSE;
2085 }
2086
2087 if (lpLockStatus->lpLockOwner != NULL)
2088 {
2089 lpLockStatus->lpLockOwner =
2090 (LPWSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2091 }
2092
2093 TRACE("QueryServiceLockStatusW() done\n");
2094
2095 return TRUE;
2096 }
2097
2098
2099 /**********************************************************************
2100 * QueryServiceObjectSecurity
2101 *
2102 * @implemented
2103 */
2104 BOOL STDCALL
2105 QueryServiceObjectSecurity(SC_HANDLE hService,
2106 SECURITY_INFORMATION dwSecurityInformation,
2107 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
2108 DWORD cbBufSize,
2109 LPDWORD pcbBytesNeeded)
2110 {
2111 DWORD dwError;
2112
2113 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2114 hService, dwSecurityInformation, lpSecurityDescriptor);
2115
2116 HandleBind();
2117
2118 _SEH_TRY
2119 {
2120 /* Call to services.exe using RPC */
2121 dwError = RQueryServiceObjectSecurity(BindingHandle,
2122 (SC_RPC_HANDLE)hService,
2123 dwSecurityInformation,
2124 (LPBYTE)lpSecurityDescriptor,
2125 cbBufSize,
2126 pcbBytesNeeded);
2127 }
2128 _SEH_HANDLE
2129 {
2130 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2131 }
2132 _SEH_END;
2133
2134 if (dwError != ERROR_SUCCESS)
2135 {
2136 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
2137 SetLastError(dwError);
2138 return FALSE;
2139 }
2140
2141 return TRUE;
2142 }
2143
2144 /**********************************************************************
2145 * SetServiceObjectSecurity
2146 *
2147 * @implemented
2148 */
2149 BOOL STDCALL
2150 SetServiceObjectSecurity(SC_HANDLE hService,
2151 SECURITY_INFORMATION dwSecurityInformation,
2152 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
2153 {
2154 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
2155 ULONG Length;
2156 NTSTATUS Status;
2157 DWORD dwError;
2158
2159 Length = 0;
2160 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2161 SelfRelativeSD,
2162 &Length);
2163 if (Status != STATUS_BUFFER_TOO_SMALL)
2164 {
2165 SetLastError(ERROR_INVALID_PARAMETER);
2166 return FALSE;
2167 }
2168
2169 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
2170 if (SelfRelativeSD == NULL)
2171 {
2172 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2173 return FALSE;
2174 }
2175
2176 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2177 SelfRelativeSD,
2178 &Length);
2179 if (!NT_SUCCESS(Status))
2180 {
2181 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2182 SetLastError(RtlNtStatusToDosError(Status));
2183 return FALSE;
2184 }
2185
2186 HandleBind();
2187
2188 _SEH_TRY
2189 {
2190 /* Call to services.exe using RPC */
2191 dwError = RSetServiceObjectSecurity(BindingHandle,
2192 (SC_RPC_HANDLE)hService,
2193 dwSecurityInformation,
2194 (LPBYTE)SelfRelativeSD,
2195 Length);
2196 }
2197 _SEH_HANDLE
2198 {
2199 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2200 }
2201 _SEH_END;
2202
2203 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2204
2205 if (dwError != ERROR_SUCCESS)
2206 {
2207 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
2208 SetLastError(dwError);
2209 return FALSE;
2210 }
2211
2212 return TRUE;
2213 }
2214
2215
2216 /**********************************************************************
2217 * QueryServiceStatus
2218 *
2219 * @implemented
2220 */
2221 BOOL STDCALL
2222 QueryServiceStatus(SC_HANDLE hService,
2223 LPSERVICE_STATUS lpServiceStatus)
2224 {
2225 DWORD dwError;
2226
2227 TRACE("QueryServiceStatus(%p, %p)\n",
2228 hService, lpServiceStatus);
2229
2230 HandleBind();
2231
2232 _SEH_TRY
2233 {
2234 /* Call to services.exe using RPC */
2235 dwError = RQueryServiceStatus(BindingHandle,
2236 (SC_RPC_HANDLE)hService,
2237 lpServiceStatus);
2238 }
2239 _SEH_HANDLE
2240 {
2241 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2242 }
2243 _SEH_END;
2244
2245 if (dwError != ERROR_SUCCESS)
2246 {
2247 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError);
2248 SetLastError(dwError);
2249 return FALSE;
2250 }
2251
2252 return TRUE;
2253 }
2254
2255
2256 /**********************************************************************
2257 * QueryServiceStatusEx
2258 *
2259 * @implemented
2260 */
2261 BOOL STDCALL
2262 QueryServiceStatusEx(SC_HANDLE hService,
2263 SC_STATUS_TYPE InfoLevel,
2264 LPBYTE lpBuffer,
2265 DWORD cbBufSize,
2266 LPDWORD pcbBytesNeeded)
2267 {
2268 DWORD dwError;
2269
2270 TRACE("QueryServiceStatusEx() called\n");
2271
2272 HandleBind();
2273
2274 _SEH_TRY
2275 {
2276 /* Call to services.exe using RPC */
2277 dwError = RQueryServiceStatusEx(BindingHandle,
2278 (SC_RPC_HANDLE)hService,
2279 InfoLevel,
2280 lpBuffer,
2281 cbBufSize,
2282 pcbBytesNeeded);
2283 }
2284 _SEH_HANDLE
2285 {
2286 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2287 }
2288 _SEH_END;
2289
2290 if (dwError != ERROR_SUCCESS)
2291 {
2292 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
2293 SetLastError(dwError);
2294 return FALSE;
2295 }
2296
2297 return TRUE;
2298 }
2299
2300
2301 /**********************************************************************
2302 * StartServiceA
2303 *
2304 * @implemented
2305 */
2306 BOOL STDCALL
2307 StartServiceA(SC_HANDLE hService,
2308 DWORD dwNumServiceArgs,
2309 LPCSTR *lpServiceArgVectors)
2310 {
2311 DWORD dwError;
2312
2313 _SEH_TRY
2314 {
2315 dwError = RStartServiceA(BindingHandle,
2316 (SC_RPC_HANDLE)hService,
2317 dwNumServiceArgs,
2318 (LPSTRING_PTRSA)lpServiceArgVectors);
2319 }
2320 _SEH_HANDLE
2321 {
2322 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2323 }
2324 _SEH_END;
2325
2326 if (dwError != ERROR_SUCCESS)
2327 {
2328 ERR("RStartServiceA() failed (Error %lu)\n", dwError);
2329 SetLastError(dwError);
2330 return FALSE;
2331 }
2332
2333 return TRUE;
2334 }
2335
2336
2337 /**********************************************************************
2338 * StartServiceW
2339 *
2340 * @implemented
2341 */
2342 BOOL STDCALL
2343 StartServiceW(SC_HANDLE hService,
2344 DWORD dwNumServiceArgs,
2345 LPCWSTR *lpServiceArgVectors)
2346 {
2347 DWORD dwError;
2348
2349 _SEH_TRY
2350 {
2351 dwError = RStartServiceW(BindingHandle,
2352 (SC_RPC_HANDLE)hService,
2353 dwNumServiceArgs,
2354 (LPSTRING_PTRSW)lpServiceArgVectors);
2355 }
2356 _SEH_HANDLE
2357 {
2358 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2359 }
2360 _SEH_END;
2361
2362 if (dwError != ERROR_SUCCESS)
2363 {
2364 ERR("RStartServiceW() failed (Error %lu)\n", dwError);
2365 SetLastError(dwError);
2366 return FALSE;
2367 }
2368
2369 return TRUE;
2370 }
2371
2372
2373 /**********************************************************************
2374 * UnlockServiceDatabase
2375 *
2376 * @implemented
2377 */
2378 BOOL STDCALL
2379 UnlockServiceDatabase(SC_LOCK ScLock)
2380 {
2381 DWORD dwError;
2382
2383 TRACE("UnlockServiceDatabase(%x)\n", ScLock);
2384
2385 HandleBind();
2386
2387 _SEH_TRY
2388 {
2389 /* Call to services.exe using RPC */
2390 dwError = RUnlockServiceDatabase(BindingHandle,
2391 (SC_RPC_LOCK)ScLock);
2392 }
2393 _SEH_HANDLE
2394 {
2395 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2396 }
2397 _SEH_END;
2398
2399 if (dwError != ERROR_SUCCESS)
2400 {
2401 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
2402 SetLastError(dwError);
2403 return FALSE;
2404 }
2405
2406 return TRUE;
2407 }
2408
2409
2410 /**********************************************************************
2411 * NotifyBootConfigStatus
2412 *
2413 * @implemented
2414 */
2415 BOOL STDCALL
2416 NotifyBootConfigStatus(BOOL BootAcceptable)
2417 {
2418 DWORD dwError;
2419
2420 TRACE("NotifyBootConfigStatus()\n");
2421
2422 HandleBind();
2423
2424 _SEH_TRY
2425 {
2426 /* Call to services.exe using RPC */
2427 dwError = RNotifyBootConfigStatus(BindingHandle,
2428 NULL,
2429 BootAcceptable);
2430 }
2431 _SEH_HANDLE
2432 {
2433 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2434 }
2435 _SEH_END;
2436
2437 if (dwError != ERROR_SUCCESS)
2438 {
2439 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
2440 SetLastError(dwError);
2441 return FALSE;
2442 }
2443
2444 return TRUE;
2445 }
2446
2447 /* EOF */