52c3698170934607a478202acb58a554c0284044
[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 HandleBind();
1231
1232 _SEH_TRY
1233 {
1234 dwError = RGetServiceDisplayNameA(BindingHandle,
1235 (SC_RPC_HANDLE)hSCManager,
1236 (LPSTR)lpServiceName,
1237 lpDisplayName,
1238 lpcchBuffer);
1239 }
1240 _SEH_HANDLE
1241 {
1242 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1243 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1244 }
1245
1246
1247 _SEH_END;
1248
1249 if (dwError != ERROR_SUCCESS)
1250 {
1251 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
1252 SetLastError(dwError);
1253 return FALSE;
1254 }
1255
1256 (*lpcchBuffer)--;
1257
1258 return TRUE;
1259 }
1260
1261
1262 /**********************************************************************
1263 * GetServiceDisplayNameW
1264 *
1265 * @implemented
1266 */
1267 BOOL STDCALL
1268 GetServiceDisplayNameW(SC_HANDLE hSCManager,
1269 LPCWSTR lpServiceName,
1270 LPWSTR lpDisplayName,
1271 LPDWORD lpcchBuffer)
1272 {
1273 DWORD dwError;
1274
1275 TRACE("GetServiceDisplayNameW() called\n");
1276
1277 HandleBind();
1278
1279 _SEH_TRY
1280 {
1281 dwError = RGetServiceDisplayNameW(BindingHandle,
1282 (SC_RPC_HANDLE)hSCManager,
1283 (LPWSTR)lpServiceName,
1284 lpDisplayName,
1285 lpcchBuffer);
1286 }
1287 _SEH_HANDLE
1288 {
1289 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1290 }
1291 _SEH_END;
1292
1293 if (dwError != ERROR_SUCCESS)
1294 {
1295 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
1296 SetLastError(dwError);
1297 return FALSE;
1298 }
1299
1300 (*lpcchBuffer)--;
1301
1302 return TRUE;
1303 }
1304
1305
1306 /**********************************************************************
1307 * GetServiceKeyNameA
1308 *
1309 * @implemented
1310 */
1311 BOOL STDCALL
1312 GetServiceKeyNameA(SC_HANDLE hSCManager,
1313 LPCSTR lpDisplayName,
1314 LPSTR lpServiceName,
1315 LPDWORD lpcchBuffer)
1316 {
1317 DWORD dwError;
1318
1319 TRACE("GetServiceKeyNameA() called\n");
1320
1321 HandleBind();
1322
1323 _SEH_TRY
1324 {
1325 dwError = RGetServiceKeyNameA(BindingHandle,
1326 (SC_RPC_HANDLE)hSCManager,
1327 (LPSTR)lpDisplayName,
1328 lpServiceName,
1329 lpcchBuffer);
1330 }
1331 _SEH_HANDLE
1332 {
1333 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1334 }
1335 _SEH_END;
1336
1337 if (dwError != ERROR_SUCCESS)
1338 {
1339 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
1340 SetLastError(dwError);
1341 return FALSE;
1342 }
1343
1344 (*lpcchBuffer)--;
1345
1346 return TRUE;
1347 }
1348
1349
1350 /**********************************************************************
1351 * GetServiceKeyNameW
1352 *
1353 * @implemented
1354 */
1355 BOOL STDCALL
1356 GetServiceKeyNameW(SC_HANDLE hSCManager,
1357 LPCWSTR lpDisplayName,
1358 LPWSTR lpServiceName,
1359 LPDWORD lpcchBuffer)
1360 {
1361 DWORD dwError;
1362
1363 TRACE("GetServiceKeyNameW() called\n");
1364
1365 HandleBind();
1366
1367 _SEH_TRY
1368 {
1369 dwError = RGetServiceKeyNameW(BindingHandle,
1370 (SC_RPC_HANDLE)hSCManager,
1371 (LPWSTR)lpDisplayName,
1372 lpServiceName,
1373 lpcchBuffer);
1374 }
1375 _SEH_HANDLE
1376 {
1377 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1378 }
1379 _SEH_END;
1380
1381 if (dwError != ERROR_SUCCESS)
1382 {
1383 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
1384 SetLastError(dwError);
1385 return FALSE;
1386 }
1387
1388 (*lpcchBuffer)--;
1389
1390 return TRUE;
1391 }
1392
1393
1394 /**********************************************************************
1395 * LockServiceDatabase
1396 *
1397 * @implemented
1398 */
1399 SC_LOCK STDCALL
1400 LockServiceDatabase(SC_HANDLE hSCManager)
1401 {
1402 SC_LOCK hLock;
1403 DWORD dwError;
1404
1405 TRACE("LockServiceDatabase(%x)\n", hSCManager);
1406
1407 HandleBind();
1408
1409 _SEH_TRY
1410 {
1411 /* Call to services.exe using RPC */
1412 dwError = RLockServiceDatabase(BindingHandle,
1413 (SC_RPC_HANDLE)hSCManager,
1414 (SC_RPC_LOCK *)&hLock);
1415 }
1416 _SEH_HANDLE
1417 {
1418 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1419 }
1420 _SEH_END;
1421
1422 if (dwError != ERROR_SUCCESS)
1423 {
1424 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError);
1425 SetLastError(dwError);
1426 return NULL;
1427 }
1428
1429 TRACE("hLock = %p\n", hLock);
1430
1431 return hLock;
1432 }
1433
1434
1435 static VOID
1436 WaitForSCManager(VOID)
1437 {
1438 HANDLE hEvent;
1439
1440 TRACE("WaitForSCManager() called\n");
1441
1442 /* Try to open the existing event */
1443 hEvent = OpenEventW(SYNCHRONIZE,
1444 FALSE,
1445 L"SvcctrlStartEvent_A3752DX");
1446 if (hEvent == NULL)
1447 {
1448 if (GetLastError() != ERROR_FILE_NOT_FOUND)
1449 return;
1450
1451 /* Try to create a new event */
1452 hEvent = CreateEventW(NULL,
1453 TRUE,
1454 FALSE,
1455 L"SvcctrlStartEvent_A3752DX");
1456 if (hEvent == NULL)
1457 {
1458 /* Try to open the existing event again */
1459 hEvent = OpenEventW(SYNCHRONIZE,
1460 FALSE,
1461 L"SvcctrlStartEvent_A3752DX");
1462 if (hEvent == NULL)
1463 return;
1464 }
1465 }
1466
1467 /* Wait for 3 minutes */
1468 WaitForSingleObject(hEvent, 180000);
1469 CloseHandle(hEvent);
1470
1471 TRACE("ScmWaitForSCManager() done\n");
1472 }
1473
1474
1475 /**********************************************************************
1476 * OpenSCManagerA
1477 *
1478 * @implemented
1479 */
1480 SC_HANDLE STDCALL
1481 OpenSCManagerA(LPCSTR lpMachineName,
1482 LPCSTR lpDatabaseName,
1483 DWORD dwDesiredAccess)
1484 {
1485 SC_HANDLE hScm = NULL;
1486 DWORD dwError;
1487
1488 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1489 lpMachineName, lpDatabaseName, dwDesiredAccess);
1490
1491 WaitForSCManager();
1492
1493 HandleBind();
1494
1495 _SEH_TRY
1496 {
1497 /* Call to services.exe using RPC */
1498 dwError = ROpenSCManagerA(BindingHandle,
1499 (LPSTR)lpMachineName,
1500 (LPSTR)lpDatabaseName,
1501 dwDesiredAccess,
1502 (SC_RPC_HANDLE *)&hScm);
1503 }
1504 _SEH_HANDLE
1505 {
1506 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1507 }
1508 _SEH_END;
1509
1510 if (dwError != ERROR_SUCCESS)
1511 {
1512 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError);
1513 SetLastError(dwError);
1514 return NULL;
1515 }
1516
1517 TRACE("hScm = %p\n", hScm);
1518
1519 return hScm;
1520 }
1521
1522
1523 /**********************************************************************
1524 * OpenSCManagerW
1525 *
1526 * @implemented
1527 */
1528 SC_HANDLE STDCALL
1529 OpenSCManagerW(LPCWSTR lpMachineName,
1530 LPCWSTR lpDatabaseName,
1531 DWORD dwDesiredAccess)
1532 {
1533 SC_HANDLE hScm = NULL;
1534 DWORD dwError;
1535
1536 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1537 lpMachineName, lpDatabaseName, dwDesiredAccess);
1538
1539 WaitForSCManager();
1540
1541 HandleBind();
1542
1543 _SEH_TRY
1544 {
1545 /* Call to services.exe using RPC */
1546 dwError = ROpenSCManagerW(BindingHandle,
1547 (LPWSTR)lpMachineName,
1548 (LPWSTR)lpDatabaseName,
1549 dwDesiredAccess,
1550 (SC_RPC_HANDLE *)&hScm);
1551 }
1552 _SEH_HANDLE
1553 {
1554 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1555 }
1556 _SEH_END;
1557
1558 if (dwError != ERROR_SUCCESS)
1559 {
1560 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError);
1561 SetLastError(dwError);
1562 return NULL;
1563 }
1564
1565 TRACE("hScm = %p\n", hScm);
1566
1567 return hScm;
1568 }
1569
1570
1571 /**********************************************************************
1572 * OpenServiceA
1573 *
1574 * @implemented
1575 */
1576 SC_HANDLE STDCALL
1577 OpenServiceA(SC_HANDLE hSCManager,
1578 LPCSTR lpServiceName,
1579 DWORD dwDesiredAccess)
1580 {
1581 SC_HANDLE hService = NULL;
1582 DWORD dwError;
1583
1584 TRACE("OpenServiceA(%p, %s, %lx)\n",
1585 hSCManager, lpServiceName, dwDesiredAccess);
1586
1587 HandleBind();
1588
1589 _SEH_TRY
1590 {
1591 /* Call to services.exe using RPC */
1592 dwError = ROpenServiceA(BindingHandle,
1593 (SC_RPC_HANDLE)hSCManager,
1594 (LPSTR)lpServiceName,
1595 dwDesiredAccess,
1596 (SC_RPC_HANDLE *)&hService);
1597 }
1598 _SEH_HANDLE
1599 {
1600 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1601 }
1602 _SEH_END;
1603
1604 if (dwError != ERROR_SUCCESS)
1605 {
1606 ERR("ROpenServiceA() failed (Error %lu)\n", dwError);
1607 SetLastError(dwError);
1608 return NULL;
1609 }
1610
1611 TRACE("hService = %p\n", hService);
1612
1613 return hService;
1614 }
1615
1616
1617 /**********************************************************************
1618 * OpenServiceW
1619 *
1620 * @implemented
1621 */
1622 SC_HANDLE STDCALL
1623 OpenServiceW(SC_HANDLE hSCManager,
1624 LPCWSTR lpServiceName,
1625 DWORD dwDesiredAccess)
1626 {
1627 SC_HANDLE hService = NULL;
1628 DWORD dwError;
1629
1630 TRACE("OpenServiceW(%p, %S, %lx)\n",
1631 hSCManager, lpServiceName, dwDesiredAccess);
1632
1633 HandleBind();
1634
1635 _SEH_TRY
1636 {
1637 /* Call to services.exe using RPC */
1638 dwError = ROpenServiceW(BindingHandle,
1639 (SC_RPC_HANDLE)hSCManager,
1640 (LPWSTR)lpServiceName,
1641 dwDesiredAccess,
1642 (SC_RPC_HANDLE *)&hService);
1643 }
1644 _SEH_HANDLE
1645 {
1646 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1647 }
1648 _SEH_END;
1649
1650 if (dwError != ERROR_SUCCESS)
1651 {
1652 if (dwError == ERROR_SERVICE_DOES_NOT_EXIST)
1653 WARN("ROpenServiceW() failed (Error %lu)\n", dwError);
1654 else
1655 ERR("ROpenServiceW() failed (Error %lu)\n", dwError);
1656 SetLastError(dwError);
1657 return NULL;
1658 }
1659
1660 TRACE("hService = %p\n", hService);
1661
1662 return hService;
1663 }
1664
1665
1666 /**********************************************************************
1667 * QueryServiceConfigA
1668 *
1669 * @implemented
1670 */
1671 BOOL STDCALL
1672 QueryServiceConfigA(SC_HANDLE hService,
1673 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
1674 DWORD cbBufSize,
1675 LPDWORD pcbBytesNeeded)
1676 {
1677 DWORD dwError;
1678
1679 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1680 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1681
1682 HandleBind();
1683
1684 _SEH_TRY
1685 {
1686 /* Call to services.exe using RPC */
1687 dwError = RQueryServiceConfigA(BindingHandle,
1688 (SC_RPC_HANDLE)hService,
1689 (LPBYTE)lpServiceConfig,
1690 cbBufSize,
1691 pcbBytesNeeded);
1692 }
1693 _SEH_HANDLE
1694 {
1695 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1696 }
1697 _SEH_END;
1698
1699 if (dwError != ERROR_SUCCESS)
1700 {
1701 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
1702 SetLastError(dwError);
1703 return FALSE;
1704 }
1705
1706 /* Adjust the pointers */
1707 if (lpServiceConfig->lpBinaryPathName)
1708 lpServiceConfig->lpBinaryPathName =
1709 (LPSTR)((ULONG_PTR)lpServiceConfig +
1710 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1711
1712 if (lpServiceConfig->lpLoadOrderGroup)
1713 lpServiceConfig->lpLoadOrderGroup =
1714 (LPSTR)((ULONG_PTR)lpServiceConfig +
1715 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1716
1717 if (lpServiceConfig->lpDependencies)
1718 lpServiceConfig->lpDependencies =
1719 (LPSTR)((ULONG_PTR)lpServiceConfig +
1720 (ULONG_PTR)lpServiceConfig->lpDependencies);
1721
1722 if (lpServiceConfig->lpServiceStartName)
1723 lpServiceConfig->lpServiceStartName =
1724 (LPSTR)((ULONG_PTR)lpServiceConfig +
1725 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1726
1727 if (lpServiceConfig->lpDisplayName)
1728 lpServiceConfig->lpDisplayName =
1729 (LPSTR)((ULONG_PTR)lpServiceConfig +
1730 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1731
1732 TRACE("QueryServiceConfigA() done\n");
1733
1734 return TRUE;
1735 }
1736
1737
1738 /**********************************************************************
1739 * QueryServiceConfigW
1740 *
1741 * @implemented
1742 */
1743 BOOL STDCALL
1744 QueryServiceConfigW(SC_HANDLE hService,
1745 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1746 DWORD cbBufSize,
1747 LPDWORD pcbBytesNeeded)
1748 {
1749 DWORD dwError;
1750
1751 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1752 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1753
1754 HandleBind();
1755
1756 _SEH_TRY
1757 {
1758 /* Call to services.exe using RPC */
1759 dwError = RQueryServiceConfigW(BindingHandle,
1760 (SC_RPC_HANDLE)hService,
1761 (LPBYTE)lpServiceConfig,
1762 cbBufSize,
1763 pcbBytesNeeded);
1764 }
1765 _SEH_HANDLE
1766 {
1767 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1768 }
1769 _SEH_END;
1770
1771 if (dwError != ERROR_SUCCESS)
1772 {
1773 if (dwError == ERROR_INSUFFICIENT_BUFFER)
1774 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1775 else
1776 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1777 SetLastError(dwError);
1778 return FALSE;
1779 }
1780
1781 /* Adjust the pointers */
1782 if (lpServiceConfig->lpBinaryPathName)
1783 lpServiceConfig->lpBinaryPathName =
1784 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1785 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1786
1787 if (lpServiceConfig->lpLoadOrderGroup)
1788 lpServiceConfig->lpLoadOrderGroup =
1789 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1790 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1791
1792 if (lpServiceConfig->lpDependencies)
1793 lpServiceConfig->lpDependencies =
1794 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1795 (ULONG_PTR)lpServiceConfig->lpDependencies);
1796
1797 if (lpServiceConfig->lpServiceStartName)
1798 lpServiceConfig->lpServiceStartName =
1799 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1800 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1801
1802 if (lpServiceConfig->lpDisplayName)
1803 lpServiceConfig->lpDisplayName =
1804 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1805 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1806
1807 TRACE("QueryServiceConfigW() done\n");
1808
1809 return TRUE;
1810 }
1811
1812
1813 /**********************************************************************
1814 * QueryServiceConfig2A
1815 *
1816 * @implemented
1817 */
1818 BOOL STDCALL
1819 QueryServiceConfig2A(SC_HANDLE hService,
1820 DWORD dwInfoLevel,
1821 LPBYTE lpBuffer,
1822 DWORD cbBufSize,
1823 LPDWORD pcbBytesNeeded)
1824 {
1825 DWORD dwError;
1826
1827 TRACE("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
1828 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1829
1830 HandleBind();
1831
1832 _SEH_TRY
1833 {
1834 /* Call to services.exe using RPC */
1835 dwError = RQueryServiceConfig2A(BindingHandle,
1836 (SC_RPC_HANDLE)hService,
1837 dwInfoLevel,
1838 lpBuffer,
1839 cbBufSize,
1840 pcbBytesNeeded);
1841 }
1842 _SEH_HANDLE
1843 {
1844 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1845 }
1846 _SEH_END;
1847
1848 if (dwError != ERROR_SUCCESS)
1849 {
1850 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
1851 SetLastError(dwError);
1852 return FALSE;
1853 }
1854
1855 switch (dwInfoLevel)
1856 {
1857 case SERVICE_CONFIG_DESCRIPTION:
1858 {
1859 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
1860
1861 if (lpPtr->lpDescription != NULL)
1862 lpPtr->lpDescription =
1863 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1864 }
1865 break;
1866
1867 case SERVICE_CONFIG_FAILURE_ACTIONS:
1868 {
1869 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
1870
1871 if (lpPtr->lpRebootMsg != NULL)
1872 lpPtr->lpRebootMsg =
1873 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1874
1875 if (lpPtr->lpCommand != NULL)
1876 lpPtr->lpCommand =
1877 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1878
1879 if (lpPtr->lpsaActions != NULL)
1880 lpPtr->lpsaActions =
1881 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1882 }
1883 break;
1884
1885 default:
1886 ERR("Unknown info level 0x%lx\n", dwInfoLevel);
1887 SetLastError(ERROR_INVALID_PARAMETER);
1888 return FALSE;
1889 }
1890
1891 TRACE("QueryServiceConfig2A() done\n");
1892
1893 return TRUE;
1894 }
1895
1896
1897 /**********************************************************************
1898 * QueryServiceConfig2W
1899 *
1900 * @implemented
1901 */
1902 BOOL STDCALL
1903 QueryServiceConfig2W(SC_HANDLE hService,
1904 DWORD dwInfoLevel,
1905 LPBYTE lpBuffer,
1906 DWORD cbBufSize,
1907 LPDWORD pcbBytesNeeded)
1908 {
1909 DWORD dwError;
1910
1911 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
1912 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1913
1914 HandleBind();
1915
1916 _SEH_TRY
1917 {
1918 /* Call to services.exe using RPC */
1919 dwError = RQueryServiceConfig2W(BindingHandle,
1920 (SC_RPC_HANDLE)hService,
1921 dwInfoLevel,
1922 lpBuffer,
1923 cbBufSize,
1924 pcbBytesNeeded);
1925 }
1926 _SEH_HANDLE
1927 {
1928 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1929 }
1930 _SEH_END;
1931
1932 if (dwError != ERROR_SUCCESS)
1933 {
1934 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
1935 SetLastError(dwError);
1936 return FALSE;
1937 }
1938
1939 switch (dwInfoLevel)
1940 {
1941 case SERVICE_CONFIG_DESCRIPTION:
1942 {
1943 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
1944
1945 if (lpPtr->lpDescription != NULL)
1946 lpPtr->lpDescription =
1947 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1948 }
1949 break;
1950
1951 case SERVICE_CONFIG_FAILURE_ACTIONS:
1952 {
1953 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
1954
1955 if (lpPtr->lpRebootMsg != NULL)
1956 lpPtr->lpRebootMsg =
1957 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1958
1959 if (lpPtr->lpCommand != NULL)
1960 lpPtr->lpCommand =
1961 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1962
1963 if (lpPtr->lpsaActions != NULL)
1964 lpPtr->lpsaActions =
1965 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1966 }
1967 break;
1968
1969 default:
1970 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
1971 SetLastError(ERROR_INVALID_PARAMETER);
1972 return FALSE;
1973 }
1974
1975 TRACE("QueryServiceConfig2W() done\n");
1976
1977 return TRUE;
1978 }
1979
1980
1981 /**********************************************************************
1982 * QueryServiceLockStatusA
1983 *
1984 * @implemented
1985 */
1986 BOOL STDCALL
1987 QueryServiceLockStatusA(SC_HANDLE hSCManager,
1988 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
1989 DWORD cbBufSize,
1990 LPDWORD pcbBytesNeeded)
1991 {
1992 DWORD dwError;
1993
1994 TRACE("QueryServiceLockStatusA() called\n");
1995
1996 HandleBind();
1997
1998 _SEH_TRY
1999 {
2000 /* Call to services.exe using RPC */
2001 dwError = RQueryServiceLockStatusA(BindingHandle,
2002 (SC_RPC_HANDLE)hSCManager,
2003 lpLockStatus,
2004 cbBufSize,
2005 pcbBytesNeeded);
2006 }
2007 _SEH_HANDLE
2008 {
2009 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2010 }
2011 _SEH_END;
2012
2013 if (dwError != ERROR_SUCCESS)
2014 {
2015 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
2016 SetLastError(dwError);
2017 return FALSE;
2018 }
2019
2020 if (lpLockStatus->lpLockOwner != NULL)
2021 {
2022 lpLockStatus->lpLockOwner =
2023 (LPSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2024 }
2025
2026 TRACE("QueryServiceLockStatusA() done\n");
2027
2028 return TRUE;
2029 }
2030
2031
2032 /**********************************************************************
2033 * QueryServiceLockStatusW
2034 *
2035 * @implemented
2036 */
2037 BOOL STDCALL
2038 QueryServiceLockStatusW(SC_HANDLE hSCManager,
2039 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
2040 DWORD cbBufSize,
2041 LPDWORD pcbBytesNeeded)
2042 {
2043 DWORD dwError;
2044
2045 TRACE("QueryServiceLockStatusW() called\n");
2046
2047 HandleBind();
2048
2049 _SEH_TRY
2050 {
2051 /* Call to services.exe using RPC */
2052 dwError = RQueryServiceLockStatusW(BindingHandle,
2053 (SC_RPC_HANDLE)hSCManager,
2054 lpLockStatus,
2055 cbBufSize,
2056 pcbBytesNeeded);
2057 }
2058 _SEH_HANDLE
2059 {
2060 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2061 }
2062 _SEH_END;
2063
2064 if (dwError != ERROR_SUCCESS)
2065 {
2066 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
2067 SetLastError(dwError);
2068 return FALSE;
2069 }
2070
2071 if (lpLockStatus->lpLockOwner != NULL)
2072 {
2073 lpLockStatus->lpLockOwner =
2074 (LPWSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2075 }
2076
2077 TRACE("QueryServiceLockStatusW() done\n");
2078
2079 return TRUE;
2080 }
2081
2082
2083 /**********************************************************************
2084 * QueryServiceObjectSecurity
2085 *
2086 * @implemented
2087 */
2088 BOOL STDCALL
2089 QueryServiceObjectSecurity(SC_HANDLE hService,
2090 SECURITY_INFORMATION dwSecurityInformation,
2091 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
2092 DWORD cbBufSize,
2093 LPDWORD pcbBytesNeeded)
2094 {
2095 DWORD dwError;
2096
2097 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2098 hService, dwSecurityInformation, lpSecurityDescriptor);
2099
2100 HandleBind();
2101
2102 _SEH_TRY
2103 {
2104 /* Call to services.exe using RPC */
2105 dwError = RQueryServiceObjectSecurity(BindingHandle,
2106 (SC_RPC_HANDLE)hService,
2107 dwSecurityInformation,
2108 (LPBYTE)lpSecurityDescriptor,
2109 cbBufSize,
2110 pcbBytesNeeded);
2111 }
2112 _SEH_HANDLE
2113 {
2114 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2115 }
2116 _SEH_END;
2117
2118 if (dwError != ERROR_SUCCESS)
2119 {
2120 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
2121 SetLastError(dwError);
2122 return FALSE;
2123 }
2124
2125 return TRUE;
2126 }
2127
2128 /**********************************************************************
2129 * SetServiceObjectSecurity
2130 *
2131 * @implemented
2132 */
2133 BOOL STDCALL
2134 SetServiceObjectSecurity(SC_HANDLE hService,
2135 SECURITY_INFORMATION dwSecurityInformation,
2136 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
2137 {
2138 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
2139 ULONG Length;
2140 NTSTATUS Status;
2141 DWORD dwError;
2142
2143 Length = 0;
2144 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2145 SelfRelativeSD,
2146 &Length);
2147 if (Status != STATUS_BUFFER_TOO_SMALL)
2148 {
2149 SetLastError(ERROR_INVALID_PARAMETER);
2150 return FALSE;
2151 }
2152
2153 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
2154 if (SelfRelativeSD == NULL)
2155 {
2156 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2157 return FALSE;
2158 }
2159
2160 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2161 SelfRelativeSD,
2162 &Length);
2163 if (!NT_SUCCESS(Status))
2164 {
2165 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2166 SetLastError(RtlNtStatusToDosError(Status));
2167 return FALSE;
2168 }
2169
2170 HandleBind();
2171
2172 _SEH_TRY
2173 {
2174 /* Call to services.exe using RPC */
2175 dwError = RSetServiceObjectSecurity(BindingHandle,
2176 (SC_RPC_HANDLE)hService,
2177 dwSecurityInformation,
2178 (LPBYTE)SelfRelativeSD,
2179 Length);
2180 }
2181 _SEH_HANDLE
2182 {
2183 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2184 }
2185 _SEH_END;
2186
2187 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2188
2189 if (dwError != ERROR_SUCCESS)
2190 {
2191 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
2192 SetLastError(dwError);
2193 return FALSE;
2194 }
2195
2196 return TRUE;
2197 }
2198
2199
2200 /**********************************************************************
2201 * QueryServiceStatus
2202 *
2203 * @implemented
2204 */
2205 BOOL STDCALL
2206 QueryServiceStatus(SC_HANDLE hService,
2207 LPSERVICE_STATUS lpServiceStatus)
2208 {
2209 DWORD dwError;
2210
2211 TRACE("QueryServiceStatus(%p, %p)\n",
2212 hService, lpServiceStatus);
2213
2214 HandleBind();
2215
2216 _SEH_TRY
2217 {
2218 /* Call to services.exe using RPC */
2219 dwError = RQueryServiceStatus(BindingHandle,
2220 (SC_RPC_HANDLE)hService,
2221 lpServiceStatus);
2222 }
2223 _SEH_HANDLE
2224 {
2225 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2226 }
2227 _SEH_END;
2228
2229 if (dwError != ERROR_SUCCESS)
2230 {
2231 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError);
2232 SetLastError(dwError);
2233 return FALSE;
2234 }
2235
2236 return TRUE;
2237 }
2238
2239
2240 /**********************************************************************
2241 * QueryServiceStatusEx
2242 *
2243 * @implemented
2244 */
2245 BOOL STDCALL
2246 QueryServiceStatusEx(SC_HANDLE hService,
2247 SC_STATUS_TYPE InfoLevel,
2248 LPBYTE lpBuffer,
2249 DWORD cbBufSize,
2250 LPDWORD pcbBytesNeeded)
2251 {
2252 DWORD dwError;
2253
2254 TRACE("QueryServiceStatusEx() called\n");
2255
2256 HandleBind();
2257
2258 _SEH_TRY
2259 {
2260 /* Call to services.exe using RPC */
2261 dwError = RQueryServiceStatusEx(BindingHandle,
2262 (SC_RPC_HANDLE)hService,
2263 InfoLevel,
2264 lpBuffer,
2265 cbBufSize,
2266 pcbBytesNeeded);
2267 }
2268 _SEH_HANDLE
2269 {
2270 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2271 }
2272 _SEH_END;
2273
2274 if (dwError != ERROR_SUCCESS)
2275 {
2276 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
2277 SetLastError(dwError);
2278 return FALSE;
2279 }
2280
2281 return TRUE;
2282 }
2283
2284
2285 /**********************************************************************
2286 * StartServiceA
2287 *
2288 * @implemented
2289 */
2290 BOOL STDCALL
2291 StartServiceA(SC_HANDLE hService,
2292 DWORD dwNumServiceArgs,
2293 LPCSTR *lpServiceArgVectors)
2294 {
2295 DWORD dwError;
2296
2297 _SEH_TRY
2298 {
2299 dwError = RStartServiceA(BindingHandle,
2300 (SC_RPC_HANDLE)hService,
2301 dwNumServiceArgs,
2302 (LPSTRING_PTRSA)lpServiceArgVectors);
2303 }
2304 _SEH_HANDLE
2305 {
2306 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2307 }
2308 _SEH_END;
2309
2310 if (dwError != ERROR_SUCCESS)
2311 {
2312 ERR("RStartServiceA() failed (Error %lu)\n", dwError);
2313 SetLastError(dwError);
2314 return FALSE;
2315 }
2316
2317 return TRUE;
2318 }
2319
2320
2321 /**********************************************************************
2322 * StartServiceW
2323 *
2324 * @implemented
2325 */
2326 BOOL STDCALL
2327 StartServiceW(SC_HANDLE hService,
2328 DWORD dwNumServiceArgs,
2329 LPCWSTR *lpServiceArgVectors)
2330 {
2331 DWORD dwError;
2332
2333 _SEH_TRY
2334 {
2335 dwError = RStartServiceW(BindingHandle,
2336 (SC_RPC_HANDLE)hService,
2337 dwNumServiceArgs,
2338 (LPSTRING_PTRSW)lpServiceArgVectors);
2339 }
2340 _SEH_HANDLE
2341 {
2342 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2343 }
2344 _SEH_END;
2345
2346 if (dwError != ERROR_SUCCESS)
2347 {
2348 ERR("RStartServiceW() failed (Error %lu)\n", dwError);
2349 SetLastError(dwError);
2350 return FALSE;
2351 }
2352
2353 return TRUE;
2354 }
2355
2356
2357 /**********************************************************************
2358 * UnlockServiceDatabase
2359 *
2360 * @implemented
2361 */
2362 BOOL STDCALL
2363 UnlockServiceDatabase(SC_LOCK ScLock)
2364 {
2365 DWORD dwError;
2366
2367 TRACE("UnlockServiceDatabase(%x)\n", ScLock);
2368
2369 HandleBind();
2370
2371 _SEH_TRY
2372 {
2373 /* Call to services.exe using RPC */
2374 dwError = RUnlockServiceDatabase(BindingHandle,
2375 (SC_RPC_LOCK)ScLock);
2376 }
2377 _SEH_HANDLE
2378 {
2379 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2380 }
2381 _SEH_END;
2382
2383 if (dwError != ERROR_SUCCESS)
2384 {
2385 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
2386 SetLastError(dwError);
2387 return FALSE;
2388 }
2389
2390 return TRUE;
2391 }
2392
2393
2394 /**********************************************************************
2395 * NotifyBootConfigStatus
2396 *
2397 * @implemented
2398 */
2399 BOOL STDCALL
2400 NotifyBootConfigStatus(BOOL BootAcceptable)
2401 {
2402 DWORD dwError;
2403
2404 TRACE("NotifyBootConfigStatus()\n");
2405
2406 HandleBind();
2407
2408 _SEH_TRY
2409 {
2410 /* Call to services.exe using RPC */
2411 dwError = RNotifyBootConfigStatus(BindingHandle,
2412 NULL,
2413 BootAcceptable);
2414 }
2415 _SEH_HANDLE
2416 {
2417 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2418 }
2419 _SEH_END;
2420
2421 if (dwError != ERROR_SUCCESS)
2422 {
2423 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
2424 SetLastError(dwError);
2425 return FALSE;
2426 }
2427
2428 return TRUE;
2429 }
2430
2431 /* EOF */