sync to trunk revision 36100
[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)(ULONG_PTR)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 (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
1835 dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
1836 {
1837 SetLastError(ERROR_INVALID_LEVEL);
1838 return FALSE;
1839 }
1840
1841 if ((lpBuffer == NULL && cbBufSize != 0) ||
1842 pcbBytesNeeded == NULL)
1843 {
1844 SetLastError(ERROR_INVALID_ADDRESS);
1845 return FALSE;
1846 }
1847
1848 HandleBind();
1849
1850 _SEH_TRY
1851 {
1852 /* Call to services.exe using RPC */
1853 dwError = RQueryServiceConfig2A(BindingHandle,
1854 (SC_RPC_HANDLE)hService,
1855 dwInfoLevel,
1856 lpBuffer,
1857 cbBufSize,
1858 pcbBytesNeeded);
1859 }
1860 _SEH_HANDLE
1861 {
1862 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1863 }
1864 _SEH_END;
1865
1866 if (dwError != ERROR_SUCCESS)
1867 {
1868 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
1869 SetLastError(dwError);
1870 return FALSE;
1871 }
1872
1873 switch (dwInfoLevel)
1874 {
1875 case SERVICE_CONFIG_DESCRIPTION:
1876 {
1877 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
1878
1879 if (lpPtr->lpDescription != NULL)
1880 lpPtr->lpDescription =
1881 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1882 }
1883 break;
1884
1885 case SERVICE_CONFIG_FAILURE_ACTIONS:
1886 {
1887 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
1888
1889 if (lpPtr->lpRebootMsg != NULL)
1890 lpPtr->lpRebootMsg =
1891 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1892
1893 if (lpPtr->lpCommand != NULL)
1894 lpPtr->lpCommand =
1895 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1896
1897 if (lpPtr->lpsaActions != NULL)
1898 lpPtr->lpsaActions =
1899 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1900 }
1901 break;
1902
1903 default:
1904 ERR("Unknown info level 0x%lx\n", dwInfoLevel);
1905 SetLastError(ERROR_INVALID_PARAMETER);
1906 return FALSE;
1907 }
1908
1909 TRACE("QueryServiceConfig2A() done\n");
1910
1911 return TRUE;
1912 }
1913
1914
1915 /**********************************************************************
1916 * QueryServiceConfig2W
1917 *
1918 * @implemented
1919 */
1920 BOOL STDCALL
1921 QueryServiceConfig2W(SC_HANDLE hService,
1922 DWORD dwInfoLevel,
1923 LPBYTE lpBuffer,
1924 DWORD cbBufSize,
1925 LPDWORD pcbBytesNeeded)
1926 {
1927 DWORD dwError;
1928
1929 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
1930 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1931
1932 if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
1933 dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
1934 {
1935 SetLastError(ERROR_INVALID_LEVEL);
1936 return FALSE;
1937 }
1938
1939 if ((lpBuffer == NULL && cbBufSize != 0) ||
1940 pcbBytesNeeded == NULL)
1941 {
1942 SetLastError(ERROR_INVALID_ADDRESS);
1943 return FALSE;
1944 }
1945
1946 HandleBind();
1947
1948 _SEH_TRY
1949 {
1950 /* Call to services.exe using RPC */
1951 dwError = RQueryServiceConfig2W(BindingHandle,
1952 (SC_RPC_HANDLE)hService,
1953 dwInfoLevel,
1954 lpBuffer,
1955 cbBufSize,
1956 pcbBytesNeeded);
1957 }
1958 _SEH_HANDLE
1959 {
1960 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1961 }
1962 _SEH_END;
1963
1964 if (dwError != ERROR_SUCCESS)
1965 {
1966 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
1967 SetLastError(dwError);
1968 return FALSE;
1969 }
1970
1971 switch (dwInfoLevel)
1972 {
1973 case SERVICE_CONFIG_DESCRIPTION:
1974 {
1975 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
1976
1977 if (lpPtr->lpDescription != NULL)
1978 lpPtr->lpDescription =
1979 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1980 }
1981 break;
1982
1983 case SERVICE_CONFIG_FAILURE_ACTIONS:
1984 {
1985 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
1986
1987 if (lpPtr->lpRebootMsg != NULL)
1988 lpPtr->lpRebootMsg =
1989 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1990
1991 if (lpPtr->lpCommand != NULL)
1992 lpPtr->lpCommand =
1993 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1994
1995 if (lpPtr->lpsaActions != NULL)
1996 lpPtr->lpsaActions =
1997 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1998 }
1999 break;
2000
2001 default:
2002 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
2003 SetLastError(ERROR_INVALID_PARAMETER);
2004 return FALSE;
2005 }
2006
2007 TRACE("QueryServiceConfig2W() done\n");
2008
2009 return TRUE;
2010 }
2011
2012
2013 /**********************************************************************
2014 * QueryServiceLockStatusA
2015 *
2016 * @implemented
2017 */
2018 BOOL STDCALL
2019 QueryServiceLockStatusA(SC_HANDLE hSCManager,
2020 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
2021 DWORD cbBufSize,
2022 LPDWORD pcbBytesNeeded)
2023 {
2024 DWORD dwError;
2025
2026 TRACE("QueryServiceLockStatusA() called\n");
2027
2028 HandleBind();
2029
2030 _SEH_TRY
2031 {
2032 /* Call to services.exe using RPC */
2033 dwError = RQueryServiceLockStatusA(BindingHandle,
2034 (SC_RPC_HANDLE)hSCManager,
2035 lpLockStatus,
2036 cbBufSize,
2037 pcbBytesNeeded);
2038 }
2039 _SEH_HANDLE
2040 {
2041 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2042 }
2043 _SEH_END;
2044
2045 if (dwError != ERROR_SUCCESS)
2046 {
2047 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
2048 SetLastError(dwError);
2049 return FALSE;
2050 }
2051
2052 if (lpLockStatus->lpLockOwner != NULL)
2053 {
2054 lpLockStatus->lpLockOwner =
2055 (LPSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2056 }
2057
2058 TRACE("QueryServiceLockStatusA() done\n");
2059
2060 return TRUE;
2061 }
2062
2063
2064 /**********************************************************************
2065 * QueryServiceLockStatusW
2066 *
2067 * @implemented
2068 */
2069 BOOL STDCALL
2070 QueryServiceLockStatusW(SC_HANDLE hSCManager,
2071 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
2072 DWORD cbBufSize,
2073 LPDWORD pcbBytesNeeded)
2074 {
2075 DWORD dwError;
2076
2077 TRACE("QueryServiceLockStatusW() called\n");
2078
2079 HandleBind();
2080
2081 _SEH_TRY
2082 {
2083 /* Call to services.exe using RPC */
2084 dwError = RQueryServiceLockStatusW(BindingHandle,
2085 (SC_RPC_HANDLE)hSCManager,
2086 lpLockStatus,
2087 cbBufSize,
2088 pcbBytesNeeded);
2089 }
2090 _SEH_HANDLE
2091 {
2092 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2093 }
2094 _SEH_END;
2095
2096 if (dwError != ERROR_SUCCESS)
2097 {
2098 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
2099 SetLastError(dwError);
2100 return FALSE;
2101 }
2102
2103 if (lpLockStatus->lpLockOwner != NULL)
2104 {
2105 lpLockStatus->lpLockOwner =
2106 (LPWSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2107 }
2108
2109 TRACE("QueryServiceLockStatusW() done\n");
2110
2111 return TRUE;
2112 }
2113
2114
2115 /**********************************************************************
2116 * QueryServiceObjectSecurity
2117 *
2118 * @implemented
2119 */
2120 BOOL STDCALL
2121 QueryServiceObjectSecurity(SC_HANDLE hService,
2122 SECURITY_INFORMATION dwSecurityInformation,
2123 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
2124 DWORD cbBufSize,
2125 LPDWORD pcbBytesNeeded)
2126 {
2127 DWORD dwError;
2128
2129 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2130 hService, dwSecurityInformation, lpSecurityDescriptor);
2131
2132 HandleBind();
2133
2134 _SEH_TRY
2135 {
2136 /* Call to services.exe using RPC */
2137 dwError = RQueryServiceObjectSecurity(BindingHandle,
2138 (SC_RPC_HANDLE)hService,
2139 dwSecurityInformation,
2140 (LPBYTE)lpSecurityDescriptor,
2141 cbBufSize,
2142 pcbBytesNeeded);
2143 }
2144 _SEH_HANDLE
2145 {
2146 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2147 }
2148 _SEH_END;
2149
2150 if (dwError != ERROR_SUCCESS)
2151 {
2152 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
2153 SetLastError(dwError);
2154 return FALSE;
2155 }
2156
2157 return TRUE;
2158 }
2159
2160 /**********************************************************************
2161 * SetServiceObjectSecurity
2162 *
2163 * @implemented
2164 */
2165 BOOL STDCALL
2166 SetServiceObjectSecurity(SC_HANDLE hService,
2167 SECURITY_INFORMATION dwSecurityInformation,
2168 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
2169 {
2170 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
2171 ULONG Length;
2172 NTSTATUS Status;
2173 DWORD dwError;
2174
2175 Length = 0;
2176 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2177 SelfRelativeSD,
2178 &Length);
2179 if (Status != STATUS_BUFFER_TOO_SMALL)
2180 {
2181 SetLastError(ERROR_INVALID_PARAMETER);
2182 return FALSE;
2183 }
2184
2185 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
2186 if (SelfRelativeSD == NULL)
2187 {
2188 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2189 return FALSE;
2190 }
2191
2192 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2193 SelfRelativeSD,
2194 &Length);
2195 if (!NT_SUCCESS(Status))
2196 {
2197 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2198 SetLastError(RtlNtStatusToDosError(Status));
2199 return FALSE;
2200 }
2201
2202 HandleBind();
2203
2204 _SEH_TRY
2205 {
2206 /* Call to services.exe using RPC */
2207 dwError = RSetServiceObjectSecurity(BindingHandle,
2208 (SC_RPC_HANDLE)hService,
2209 dwSecurityInformation,
2210 (LPBYTE)SelfRelativeSD,
2211 Length);
2212 }
2213 _SEH_HANDLE
2214 {
2215 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2216 }
2217 _SEH_END;
2218
2219 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2220
2221 if (dwError != ERROR_SUCCESS)
2222 {
2223 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
2224 SetLastError(dwError);
2225 return FALSE;
2226 }
2227
2228 return TRUE;
2229 }
2230
2231
2232 /**********************************************************************
2233 * QueryServiceStatus
2234 *
2235 * @implemented
2236 */
2237 BOOL STDCALL
2238 QueryServiceStatus(SC_HANDLE hService,
2239 LPSERVICE_STATUS lpServiceStatus)
2240 {
2241 DWORD dwError;
2242
2243 TRACE("QueryServiceStatus(%p, %p)\n",
2244 hService, lpServiceStatus);
2245
2246 HandleBind();
2247
2248 _SEH_TRY
2249 {
2250 /* Call to services.exe using RPC */
2251 dwError = RQueryServiceStatus(BindingHandle,
2252 (SC_RPC_HANDLE)hService,
2253 lpServiceStatus);
2254 }
2255 _SEH_HANDLE
2256 {
2257 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2258 }
2259 _SEH_END;
2260
2261 if (dwError != ERROR_SUCCESS)
2262 {
2263 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError);
2264 SetLastError(dwError);
2265 return FALSE;
2266 }
2267
2268 return TRUE;
2269 }
2270
2271
2272 /**********************************************************************
2273 * QueryServiceStatusEx
2274 *
2275 * @implemented
2276 */
2277 BOOL STDCALL
2278 QueryServiceStatusEx(SC_HANDLE hService,
2279 SC_STATUS_TYPE InfoLevel,
2280 LPBYTE lpBuffer,
2281 DWORD cbBufSize,
2282 LPDWORD pcbBytesNeeded)
2283 {
2284 DWORD dwError;
2285
2286 TRACE("QueryServiceStatusEx() called\n");
2287
2288 HandleBind();
2289
2290 _SEH_TRY
2291 {
2292 /* Call to services.exe using RPC */
2293 dwError = RQueryServiceStatusEx(BindingHandle,
2294 (SC_RPC_HANDLE)hService,
2295 InfoLevel,
2296 lpBuffer,
2297 cbBufSize,
2298 pcbBytesNeeded);
2299 }
2300 _SEH_HANDLE
2301 {
2302 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2303 }
2304 _SEH_END;
2305
2306 if (dwError != ERROR_SUCCESS)
2307 {
2308 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
2309 SetLastError(dwError);
2310 return FALSE;
2311 }
2312
2313 return TRUE;
2314 }
2315
2316
2317 /**********************************************************************
2318 * StartServiceA
2319 *
2320 * @implemented
2321 */
2322 BOOL STDCALL
2323 StartServiceA(SC_HANDLE hService,
2324 DWORD dwNumServiceArgs,
2325 LPCSTR *lpServiceArgVectors)
2326 {
2327 DWORD dwError;
2328
2329 _SEH_TRY
2330 {
2331 dwError = RStartServiceA(BindingHandle,
2332 (SC_RPC_HANDLE)hService,
2333 dwNumServiceArgs,
2334 (LPSTRING_PTRSA)lpServiceArgVectors);
2335 }
2336 _SEH_HANDLE
2337 {
2338 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2339 }
2340 _SEH_END;
2341
2342 if (dwError != ERROR_SUCCESS)
2343 {
2344 ERR("RStartServiceA() failed (Error %lu)\n", dwError);
2345 SetLastError(dwError);
2346 return FALSE;
2347 }
2348
2349 return TRUE;
2350 }
2351
2352
2353 /**********************************************************************
2354 * StartServiceW
2355 *
2356 * @implemented
2357 */
2358 BOOL STDCALL
2359 StartServiceW(SC_HANDLE hService,
2360 DWORD dwNumServiceArgs,
2361 LPCWSTR *lpServiceArgVectors)
2362 {
2363 DWORD dwError;
2364
2365 _SEH_TRY
2366 {
2367 dwError = RStartServiceW(BindingHandle,
2368 (SC_RPC_HANDLE)hService,
2369 dwNumServiceArgs,
2370 (LPSTRING_PTRSW)lpServiceArgVectors);
2371 }
2372 _SEH_HANDLE
2373 {
2374 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2375 }
2376 _SEH_END;
2377
2378 if (dwError != ERROR_SUCCESS)
2379 {
2380 ERR("RStartServiceW() failed (Error %lu)\n", dwError);
2381 SetLastError(dwError);
2382 return FALSE;
2383 }
2384
2385 return TRUE;
2386 }
2387
2388
2389 /**********************************************************************
2390 * UnlockServiceDatabase
2391 *
2392 * @implemented
2393 */
2394 BOOL STDCALL
2395 UnlockServiceDatabase(SC_LOCK ScLock)
2396 {
2397 DWORD dwError;
2398
2399 TRACE("UnlockServiceDatabase(%x)\n", ScLock);
2400
2401 HandleBind();
2402
2403 _SEH_TRY
2404 {
2405 /* Call to services.exe using RPC */
2406 dwError = RUnlockServiceDatabase(BindingHandle,
2407 (SC_RPC_LOCK)ScLock);
2408 }
2409 _SEH_HANDLE
2410 {
2411 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2412 }
2413 _SEH_END;
2414
2415 if (dwError != ERROR_SUCCESS)
2416 {
2417 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
2418 SetLastError(dwError);
2419 return FALSE;
2420 }
2421
2422 return TRUE;
2423 }
2424
2425
2426 /**********************************************************************
2427 * NotifyBootConfigStatus
2428 *
2429 * @implemented
2430 */
2431 BOOL STDCALL
2432 NotifyBootConfigStatus(BOOL BootAcceptable)
2433 {
2434 DWORD dwError;
2435
2436 TRACE("NotifyBootConfigStatus()\n");
2437
2438 HandleBind();
2439
2440 _SEH_TRY
2441 {
2442 /* Call to services.exe using RPC */
2443 dwError = RNotifyBootConfigStatus(BindingHandle,
2444 NULL,
2445 BootAcceptable);
2446 }
2447 _SEH_HANDLE
2448 {
2449 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2450 }
2451 _SEH_END;
2452
2453 if (dwError != ERROR_SUCCESS)
2454 {
2455 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
2456 SetLastError(dwError);
2457 return FALSE;
2458 }
2459
2460 return TRUE;
2461 }
2462
2463 /* EOF */