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