e10e7f1fb4caa204156c5c567f5dad5596e6e33f
[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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 TRACE("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 || dwError == ERROR_MORE_DATA)
824 {
825 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
826 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
827 {
828 if (lpStatusPtr->lpServiceName)
829 lpStatusPtr->lpServiceName =
830 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
831
832 if (lpStatusPtr->lpDisplayName)
833 lpStatusPtr->lpDisplayName =
834 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
835
836 lpStatusPtr++;
837 }
838 }
839
840 if (dwError != ERROR_SUCCESS)
841 {
842 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError);
843 SetLastError(dwError);
844 return FALSE;
845 }
846
847 TRACE("EnumDependentServicesA() done\n");
848
849 return TRUE;
850 }
851
852
853 /**********************************************************************
854 * EnumDependentServicesW
855 *
856 * @implemented
857 */
858 BOOL WINAPI
859 EnumDependentServicesW(SC_HANDLE hService,
860 DWORD dwServiceState,
861 LPENUM_SERVICE_STATUSW lpServices,
862 DWORD cbBufSize,
863 LPDWORD pcbBytesNeeded,
864 LPDWORD lpServicesReturned)
865 {
866 LPENUM_SERVICE_STATUSW lpStatusPtr;
867 DWORD dwError;
868 DWORD dwCount;
869
870 TRACE("EnumServicesStatusW() called\n");
871
872 RpcTryExcept
873 {
874 dwError = REnumDependentServicesW((SC_RPC_HANDLE)hService,
875 dwServiceState,
876 (LPBYTE)lpServices,
877 cbBufSize,
878 pcbBytesNeeded,
879 lpServicesReturned);
880 }
881 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
882 {
883 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
884 }
885 RpcEndExcept;
886
887 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
888 {
889 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
890 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
891 {
892 if (lpStatusPtr->lpServiceName)
893 lpStatusPtr->lpServiceName =
894 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
895
896 if (lpStatusPtr->lpDisplayName)
897 lpStatusPtr->lpDisplayName =
898 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
899
900 lpStatusPtr++;
901 }
902 }
903
904 if (dwError != ERROR_SUCCESS)
905 {
906 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError);
907 SetLastError(dwError);
908 return FALSE;
909 }
910
911 TRACE("EnumDependentServicesW() done\n");
912
913 return TRUE;
914 }
915
916
917 /**********************************************************************
918 * EnumServiceGroupW
919 *
920 * @unimplemented
921 */
922 BOOL
923 WINAPI
924 EnumServiceGroupW(
925 SC_HANDLE hSCManager,
926 DWORD dwServiceType,
927 DWORD dwServiceState,
928 LPENUM_SERVICE_STATUSW lpServices,
929 DWORD cbBufSize,
930 LPDWORD pcbBytesNeeded,
931 LPDWORD lpServicesReturned,
932 LPDWORD lpResumeHandle,
933 LPCWSTR lpGroup)
934 {
935 FIXME("EnumServiceGroupW is unimplemented\n");
936 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
937 return FALSE;
938 }
939
940
941 /**********************************************************************
942 * EnumServicesStatusA
943 *
944 * @implemented
945 */
946 BOOL WINAPI
947 EnumServicesStatusA(SC_HANDLE hSCManager,
948 DWORD dwServiceType,
949 DWORD dwServiceState,
950 LPENUM_SERVICE_STATUSA lpServices,
951 DWORD cbBufSize,
952 LPDWORD pcbBytesNeeded,
953 LPDWORD lpServicesReturned,
954 LPDWORD lpResumeHandle)
955 {
956 LPENUM_SERVICE_STATUSA lpStatusPtr;
957 DWORD dwError;
958 DWORD dwCount;
959
960 TRACE("EnumServicesStatusA() called\n");
961
962 if (!hSCManager)
963 {
964 SetLastError(ERROR_INVALID_HANDLE);
965 return FALSE;
966 }
967
968 if (dwServiceType != SERVICE_DRIVER && dwServiceType != SERVICE_WIN32)
969 {
970 if (pcbBytesNeeded && lpServicesReturned)
971 {
972 *pcbBytesNeeded = 0;
973 *lpServicesReturned = 0;
974 }
975
976 SetLastError(ERROR_INVALID_PARAMETER);
977 return FALSE;
978 }
979
980 if (dwServiceState != SERVICE_ACTIVE && dwServiceState != SERVICE_INACTIVE && dwServiceState != SERVICE_STATE_ALL)
981 {
982 if (pcbBytesNeeded)
983 *pcbBytesNeeded = 0;
984
985 if (lpServicesReturned)
986 *lpServicesReturned = 0;
987
988 SetLastError(ERROR_INVALID_PARAMETER);
989 return FALSE;
990 }
991
992 if (!pcbBytesNeeded || !lpServicesReturned)
993 {
994 SetLastError(ERROR_INVALID_ADDRESS);
995 return FALSE;
996 }
997
998 if (!lpServices && cbBufSize != 0)
999 {
1000 SetLastError(ERROR_INVALID_ADDRESS);
1001 return FALSE;
1002 }
1003
1004 RpcTryExcept
1005 {
1006 dwError = REnumServicesStatusA((SC_RPC_HANDLE)hSCManager,
1007 dwServiceType,
1008 dwServiceState,
1009 (LPBYTE)lpServices,
1010 cbBufSize,
1011 pcbBytesNeeded,
1012 lpServicesReturned,
1013 lpResumeHandle);
1014 }
1015 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1016 {
1017 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1018 }
1019 RpcEndExcept;
1020
1021 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1022 {
1023 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
1024 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1025 {
1026 if (lpStatusPtr->lpServiceName)
1027 lpStatusPtr->lpServiceName =
1028 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1029
1030 if (lpStatusPtr->lpDisplayName)
1031 lpStatusPtr->lpDisplayName =
1032 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1033
1034 lpStatusPtr++;
1035 }
1036 }
1037
1038 if (dwError != ERROR_SUCCESS)
1039 {
1040 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError);
1041 SetLastError(dwError);
1042 return FALSE;
1043 }
1044
1045 TRACE("EnumServicesStatusA() done\n");
1046
1047 return TRUE;
1048 }
1049
1050
1051 /**********************************************************************
1052 * EnumServicesStatusW
1053 *
1054 * @implemented
1055 */
1056 BOOL WINAPI
1057 EnumServicesStatusW(SC_HANDLE hSCManager,
1058 DWORD dwServiceType,
1059 DWORD dwServiceState,
1060 LPENUM_SERVICE_STATUSW lpServices,
1061 DWORD cbBufSize,
1062 LPDWORD pcbBytesNeeded,
1063 LPDWORD lpServicesReturned,
1064 LPDWORD lpResumeHandle)
1065 {
1066 LPENUM_SERVICE_STATUSW lpStatusPtr;
1067 DWORD dwError;
1068 DWORD dwCount;
1069
1070 TRACE("EnumServicesStatusW() called\n");
1071
1072 if (!hSCManager)
1073 {
1074 SetLastError(ERROR_INVALID_HANDLE);
1075 return FALSE;
1076 }
1077
1078 RpcTryExcept
1079 {
1080 dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager,
1081 dwServiceType,
1082 dwServiceState,
1083 (LPBYTE)lpServices,
1084 cbBufSize,
1085 pcbBytesNeeded,
1086 lpServicesReturned,
1087 lpResumeHandle);
1088 }
1089 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1090 {
1091 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1092 }
1093 RpcEndExcept;
1094
1095 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1096 {
1097 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
1098 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1099 {
1100 if (lpStatusPtr->lpServiceName)
1101 lpStatusPtr->lpServiceName =
1102 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1103
1104 if (lpStatusPtr->lpDisplayName)
1105 lpStatusPtr->lpDisplayName =
1106 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1107
1108 lpStatusPtr++;
1109 }
1110 }
1111
1112 if (dwError != ERROR_SUCCESS)
1113 {
1114 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError);
1115 SetLastError(dwError);
1116 return FALSE;
1117 }
1118
1119 TRACE("EnumServicesStatusW() done\n");
1120
1121 return TRUE;
1122 }
1123
1124
1125 /**********************************************************************
1126 * EnumServicesStatusExA
1127 *
1128 * @implemented
1129 */
1130 BOOL WINAPI
1131 EnumServicesStatusExA(SC_HANDLE hSCManager,
1132 SC_ENUM_TYPE InfoLevel,
1133 DWORD dwServiceType,
1134 DWORD dwServiceState,
1135 LPBYTE lpServices,
1136 DWORD cbBufSize,
1137 LPDWORD pcbBytesNeeded,
1138 LPDWORD lpServicesReturned,
1139 LPDWORD lpResumeHandle,
1140 LPCSTR pszGroupName)
1141 {
1142 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
1143 DWORD dwError;
1144 DWORD dwCount;
1145
1146 TRACE("EnumServicesStatusExA() called\n");
1147
1148 if (InfoLevel != SC_ENUM_PROCESS_INFO)
1149 {
1150 SetLastError(ERROR_INVALID_LEVEL);
1151 return FALSE;
1152 }
1153
1154 if (!hSCManager)
1155 {
1156 SetLastError(ERROR_INVALID_HANDLE);
1157 return FALSE;
1158 }
1159
1160 RpcTryExcept
1161 {
1162 dwError = REnumServicesStatusExA((SC_RPC_HANDLE)hSCManager,
1163 InfoLevel,
1164 dwServiceType,
1165 dwServiceState,
1166 (LPBYTE)lpServices,
1167 cbBufSize,
1168 pcbBytesNeeded,
1169 lpServicesReturned,
1170 lpResumeHandle,
1171 (LPSTR)pszGroupName);
1172 }
1173 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1174 {
1175 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1176 }
1177 RpcEndExcept;
1178
1179 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1180 {
1181 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
1182 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1183 {
1184 if (lpStatusPtr->lpServiceName)
1185 lpStatusPtr->lpServiceName =
1186 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1187
1188 if (lpStatusPtr->lpDisplayName)
1189 lpStatusPtr->lpDisplayName =
1190 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1191
1192 lpStatusPtr++;
1193 }
1194 }
1195
1196 if (dwError != ERROR_SUCCESS)
1197 {
1198 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError);
1199 SetLastError(dwError);
1200 return FALSE;
1201 }
1202
1203 TRACE("EnumServicesStatusExA() done\n");
1204
1205 return TRUE;
1206 }
1207
1208
1209 /**********************************************************************
1210 * EnumServicesStatusExW
1211 *
1212 * @implemented
1213 */
1214 BOOL WINAPI
1215 EnumServicesStatusExW(SC_HANDLE hSCManager,
1216 SC_ENUM_TYPE InfoLevel,
1217 DWORD dwServiceType,
1218 DWORD dwServiceState,
1219 LPBYTE lpServices,
1220 DWORD cbBufSize,
1221 LPDWORD pcbBytesNeeded,
1222 LPDWORD lpServicesReturned,
1223 LPDWORD lpResumeHandle,
1224 LPCWSTR pszGroupName)
1225 {
1226 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
1227 DWORD dwError;
1228 DWORD dwCount;
1229
1230 TRACE("EnumServicesStatusExW() called\n");
1231
1232 RpcTryExcept
1233 {
1234 dwError = REnumServicesStatusExW((SC_RPC_HANDLE)hSCManager,
1235 InfoLevel,
1236 dwServiceType,
1237 dwServiceState,
1238 (LPBYTE)lpServices,
1239 cbBufSize,
1240 pcbBytesNeeded,
1241 lpServicesReturned,
1242 lpResumeHandle,
1243 (LPWSTR)pszGroupName);
1244 }
1245 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1246 {
1247 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1248 }
1249 RpcEndExcept;
1250
1251 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
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
1268 if (dwError != ERROR_SUCCESS)
1269 {
1270 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError);
1271 SetLastError(dwError);
1272 return FALSE;
1273 }
1274
1275 TRACE("EnumServicesStatusExW() done\n");
1276
1277 return TRUE;
1278 }
1279
1280
1281 /**********************************************************************
1282 * GetServiceDisplayNameA
1283 *
1284 * @implemented
1285 */
1286 BOOL WINAPI
1287 GetServiceDisplayNameA(SC_HANDLE hSCManager,
1288 LPCSTR lpServiceName,
1289 LPSTR lpDisplayName,
1290 LPDWORD lpcchBuffer)
1291 {
1292 DWORD dwError;
1293 LPSTR lpNameBuffer;
1294 CHAR szEmptyName[] = "";
1295
1296 TRACE("GetServiceDisplayNameA() called\n");
1297 TRACE("%p %s %p %p\n", hSCManager,
1298 debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer);
1299
1300 if (!hSCManager)
1301 {
1302 SetLastError(ERROR_INVALID_HANDLE);
1303 return FALSE;
1304 }
1305
1306 if (!lpDisplayName || *lpcchBuffer < sizeof(CHAR))
1307 {
1308 lpNameBuffer = szEmptyName;
1309 *lpcchBuffer = sizeof(CHAR);
1310 }
1311 else
1312 {
1313 lpNameBuffer = lpDisplayName;
1314 }
1315
1316 RpcTryExcept
1317 {
1318 dwError = RGetServiceDisplayNameA((SC_RPC_HANDLE)hSCManager,
1319 lpServiceName,
1320 lpNameBuffer,
1321 lpcchBuffer);
1322 }
1323 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1324 {
1325 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1326 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1327 }
1328 RpcEndExcept;
1329
1330 if (dwError != ERROR_SUCCESS)
1331 {
1332 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
1333 SetLastError(dwError);
1334 return FALSE;
1335 }
1336
1337 return TRUE;
1338 }
1339
1340
1341 /**********************************************************************
1342 * GetServiceDisplayNameW
1343 *
1344 * @implemented
1345 */
1346 BOOL WINAPI
1347 GetServiceDisplayNameW(SC_HANDLE hSCManager,
1348 LPCWSTR lpServiceName,
1349 LPWSTR lpDisplayName,
1350 LPDWORD lpcchBuffer)
1351 {
1352 DWORD dwError;
1353 LPWSTR lpNameBuffer;
1354 WCHAR szEmptyName[] = L"";
1355
1356 TRACE("GetServiceDisplayNameW() called\n");
1357
1358 if (!hSCManager)
1359 {
1360 SetLastError(ERROR_INVALID_HANDLE);
1361 return FALSE;
1362 }
1363
1364 if (!lpDisplayName || *lpcchBuffer < sizeof(WCHAR))
1365 {
1366 lpNameBuffer = szEmptyName;
1367 *lpcchBuffer = sizeof(WCHAR);
1368 }
1369 else
1370 {
1371 lpNameBuffer = lpDisplayName;
1372 }
1373
1374 RpcTryExcept
1375 {
1376 dwError = RGetServiceDisplayNameW((SC_RPC_HANDLE)hSCManager,
1377 lpServiceName,
1378 lpNameBuffer,
1379 lpcchBuffer);
1380 }
1381 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1382 {
1383 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1384 }
1385 RpcEndExcept;
1386
1387 if (dwError != ERROR_SUCCESS)
1388 {
1389 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
1390 SetLastError(dwError);
1391 return FALSE;
1392 }
1393
1394 return TRUE;
1395 }
1396
1397
1398 /**********************************************************************
1399 * GetServiceKeyNameA
1400 *
1401 * @implemented
1402 */
1403 BOOL WINAPI
1404 GetServiceKeyNameA(SC_HANDLE hSCManager,
1405 LPCSTR lpDisplayName,
1406 LPSTR lpServiceName,
1407 LPDWORD lpcchBuffer)
1408 {
1409 DWORD dwError;
1410 LPSTR lpNameBuffer;
1411 CHAR szEmptyName[] = "";
1412
1413 TRACE("GetServiceKeyNameA() called\n");
1414
1415 if (!hSCManager)
1416 {
1417 SetLastError(ERROR_INVALID_HANDLE);
1418 return FALSE;
1419 }
1420
1421 if (!lpServiceName || *lpcchBuffer < sizeof(CHAR))
1422 {
1423 lpNameBuffer = szEmptyName;
1424 *lpcchBuffer = sizeof(CHAR);
1425 }
1426 else
1427 {
1428 lpNameBuffer = lpServiceName;
1429 }
1430
1431 RpcTryExcept
1432 {
1433 dwError = RGetServiceKeyNameA((SC_RPC_HANDLE)hSCManager,
1434 lpDisplayName,
1435 lpNameBuffer,
1436 lpcchBuffer);
1437 }
1438 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1439 {
1440 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1441 }
1442 RpcEndExcept;
1443
1444 if (dwError != ERROR_SUCCESS)
1445 {
1446 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
1447 SetLastError(dwError);
1448 return FALSE;
1449 }
1450
1451 return TRUE;
1452 }
1453
1454
1455 /**********************************************************************
1456 * GetServiceKeyNameW
1457 *
1458 * @implemented
1459 */
1460 BOOL WINAPI
1461 GetServiceKeyNameW(SC_HANDLE hSCManager,
1462 LPCWSTR lpDisplayName,
1463 LPWSTR lpServiceName,
1464 LPDWORD lpcchBuffer)
1465 {
1466 DWORD dwError;
1467 LPWSTR lpNameBuffer;
1468 WCHAR szEmptyName[] = L"";
1469
1470 TRACE("GetServiceKeyNameW() called\n");
1471
1472 if (!hSCManager)
1473 {
1474 SetLastError(ERROR_INVALID_HANDLE);
1475 return FALSE;
1476 }
1477
1478 if (!lpServiceName || *lpcchBuffer < sizeof(WCHAR))
1479 {
1480 lpNameBuffer = szEmptyName;
1481 *lpcchBuffer = sizeof(WCHAR);
1482 }
1483 else
1484 {
1485 lpNameBuffer = lpServiceName;
1486 }
1487
1488 RpcTryExcept
1489 {
1490 dwError = RGetServiceKeyNameW((SC_RPC_HANDLE)hSCManager,
1491 lpDisplayName,
1492 lpNameBuffer,
1493 lpcchBuffer);
1494 }
1495 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1496 {
1497 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1498 }
1499 RpcEndExcept;
1500
1501 if (dwError != ERROR_SUCCESS)
1502 {
1503 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
1504 SetLastError(dwError);
1505 return FALSE;
1506 }
1507
1508 return TRUE;
1509 }
1510
1511
1512 /**********************************************************************
1513 * LockServiceDatabase
1514 *
1515 * @implemented
1516 */
1517 SC_LOCK WINAPI
1518 LockServiceDatabase(SC_HANDLE hSCManager)
1519 {
1520 SC_LOCK hLock;
1521 DWORD dwError;
1522
1523 TRACE("LockServiceDatabase(%x)\n", hSCManager);
1524
1525 RpcTryExcept
1526 {
1527 /* Call to services.exe using RPC */
1528 dwError = RLockServiceDatabase((SC_RPC_HANDLE)hSCManager,
1529 (SC_RPC_LOCK *)&hLock);
1530 }
1531 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1532 {
1533 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1534 }
1535 RpcEndExcept;
1536
1537 if (dwError != ERROR_SUCCESS)
1538 {
1539 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError);
1540 SetLastError(dwError);
1541 return NULL;
1542 }
1543
1544 TRACE("hLock = %p\n", hLock);
1545
1546 return hLock;
1547 }
1548
1549
1550 static VOID
1551 WaitForSCManager(VOID)
1552 {
1553 HANDLE hEvent;
1554
1555 TRACE("WaitForSCManager() called\n");
1556
1557 /* Try to open the existing event */
1558 hEvent = OpenEventW(SYNCHRONIZE,
1559 FALSE,
1560 L"SvcctrlStartEvent_A3752DX");
1561 if (hEvent == NULL)
1562 {
1563 if (GetLastError() != ERROR_FILE_NOT_FOUND)
1564 return;
1565
1566 /* Try to create a new event */
1567 hEvent = CreateEventW(NULL,
1568 TRUE,
1569 FALSE,
1570 L"SvcctrlStartEvent_A3752DX");
1571 if (hEvent == NULL)
1572 {
1573 /* Try to open the existing event again */
1574 hEvent = OpenEventW(SYNCHRONIZE,
1575 FALSE,
1576 L"SvcctrlStartEvent_A3752DX");
1577 if (hEvent == NULL)
1578 return;
1579 }
1580 }
1581
1582 /* Wait for 3 minutes */
1583 WaitForSingleObject(hEvent, 180000);
1584 CloseHandle(hEvent);
1585
1586 TRACE("ScmWaitForSCManager() done\n");
1587 }
1588
1589
1590 /**********************************************************************
1591 * OpenSCManagerA
1592 *
1593 * @implemented
1594 */
1595 SC_HANDLE WINAPI
1596 OpenSCManagerA(LPCSTR lpMachineName,
1597 LPCSTR lpDatabaseName,
1598 DWORD dwDesiredAccess)
1599 {
1600 SC_HANDLE hScm = NULL;
1601 DWORD dwError;
1602
1603 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1604 lpMachineName, lpDatabaseName, dwDesiredAccess);
1605
1606 WaitForSCManager();
1607
1608 RpcTryExcept
1609 {
1610 /* Call to services.exe using RPC */
1611 dwError = ROpenSCManagerA((LPSTR)lpMachineName,
1612 (LPSTR)lpDatabaseName,
1613 dwDesiredAccess,
1614 (SC_RPC_HANDLE *)&hScm);
1615 }
1616 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1617 {
1618 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1619 }
1620 RpcEndExcept;
1621
1622 if (dwError != ERROR_SUCCESS)
1623 {
1624 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError);
1625 SetLastError(dwError);
1626 return NULL;
1627 }
1628
1629 TRACE("hScm = %p\n", hScm);
1630
1631 return hScm;
1632 }
1633
1634
1635 /**********************************************************************
1636 * OpenSCManagerW
1637 *
1638 * @implemented
1639 */
1640 SC_HANDLE WINAPI
1641 OpenSCManagerW(LPCWSTR lpMachineName,
1642 LPCWSTR lpDatabaseName,
1643 DWORD dwDesiredAccess)
1644 {
1645 SC_HANDLE hScm = NULL;
1646 DWORD dwError;
1647
1648 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1649 lpMachineName, lpDatabaseName, dwDesiredAccess);
1650
1651 WaitForSCManager();
1652
1653 RpcTryExcept
1654 {
1655 /* Call to services.exe using RPC */
1656 dwError = ROpenSCManagerW((LPWSTR)lpMachineName,
1657 (LPWSTR)lpDatabaseName,
1658 dwDesiredAccess,
1659 (SC_RPC_HANDLE *)&hScm);
1660 }
1661 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1662 {
1663 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1664 }
1665 RpcEndExcept;
1666
1667 if (dwError != ERROR_SUCCESS)
1668 {
1669 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError);
1670 SetLastError(dwError);
1671 return NULL;
1672 }
1673
1674 TRACE("hScm = %p\n", hScm);
1675
1676 return hScm;
1677 }
1678
1679
1680 /**********************************************************************
1681 * OpenServiceA
1682 *
1683 * @implemented
1684 */
1685 SC_HANDLE WINAPI
1686 OpenServiceA(SC_HANDLE hSCManager,
1687 LPCSTR lpServiceName,
1688 DWORD dwDesiredAccess)
1689 {
1690 SC_HANDLE hService = NULL;
1691 DWORD dwError;
1692
1693 TRACE("OpenServiceA(%p, %s, %lx)\n",
1694 hSCManager, lpServiceName, dwDesiredAccess);
1695
1696 if (!hSCManager)
1697 {
1698 SetLastError(ERROR_INVALID_HANDLE);
1699 return NULL;
1700 }
1701
1702 RpcTryExcept
1703 {
1704 /* Call to services.exe using RPC */
1705 dwError = ROpenServiceA((SC_RPC_HANDLE)hSCManager,
1706 (LPSTR)lpServiceName,
1707 dwDesiredAccess,
1708 (SC_RPC_HANDLE *)&hService);
1709 }
1710 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1711 {
1712 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1713 }
1714 RpcEndExcept;
1715
1716 if (dwError != ERROR_SUCCESS)
1717 {
1718 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError);
1719 SetLastError(dwError);
1720 return NULL;
1721 }
1722
1723 TRACE("hService = %p\n", hService);
1724
1725 return hService;
1726 }
1727
1728
1729 /**********************************************************************
1730 * OpenServiceW
1731 *
1732 * @implemented
1733 */
1734 SC_HANDLE WINAPI
1735 OpenServiceW(SC_HANDLE hSCManager,
1736 LPCWSTR lpServiceName,
1737 DWORD dwDesiredAccess)
1738 {
1739 SC_HANDLE hService = NULL;
1740 DWORD dwError;
1741
1742 TRACE("OpenServiceW(%p, %S, %lx)\n",
1743 hSCManager, lpServiceName, dwDesiredAccess);
1744
1745 if (!hSCManager)
1746 {
1747 SetLastError(ERROR_INVALID_HANDLE);
1748 return NULL;
1749 }
1750
1751 RpcTryExcept
1752 {
1753 /* Call to services.exe using RPC */
1754 dwError = ROpenServiceW((SC_RPC_HANDLE)hSCManager,
1755 (LPWSTR)lpServiceName,
1756 dwDesiredAccess,
1757 (SC_RPC_HANDLE *)&hService);
1758 }
1759 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1760 {
1761 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1762 }
1763 RpcEndExcept;
1764
1765 if (dwError != ERROR_SUCCESS)
1766 {
1767 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError);
1768 SetLastError(dwError);
1769 return NULL;
1770 }
1771
1772 TRACE("hService = %p\n", hService);
1773
1774 return hService;
1775 }
1776
1777
1778 /**********************************************************************
1779 * QueryServiceConfigA
1780 *
1781 * @implemented
1782 */
1783 BOOL WINAPI
1784 QueryServiceConfigA(SC_HANDLE hService,
1785 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
1786 DWORD cbBufSize,
1787 LPDWORD pcbBytesNeeded)
1788 {
1789 DWORD dwError;
1790
1791 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1792 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1793
1794 RpcTryExcept
1795 {
1796 /* Call to services.exe using RPC */
1797 dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
1798 (LPBYTE)lpServiceConfig,
1799 cbBufSize,
1800 pcbBytesNeeded);
1801 }
1802 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1803 {
1804 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1805 }
1806 RpcEndExcept;
1807
1808 if (dwError != ERROR_SUCCESS)
1809 {
1810 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
1811 SetLastError(dwError);
1812 return FALSE;
1813 }
1814
1815 /* Adjust the pointers */
1816 if (lpServiceConfig->lpBinaryPathName)
1817 lpServiceConfig->lpBinaryPathName =
1818 (LPSTR)((ULONG_PTR)lpServiceConfig +
1819 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1820
1821 if (lpServiceConfig->lpLoadOrderGroup)
1822 lpServiceConfig->lpLoadOrderGroup =
1823 (LPSTR)((ULONG_PTR)lpServiceConfig +
1824 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1825
1826 if (lpServiceConfig->lpDependencies)
1827 lpServiceConfig->lpDependencies =
1828 (LPSTR)((ULONG_PTR)lpServiceConfig +
1829 (ULONG_PTR)lpServiceConfig->lpDependencies);
1830
1831 if (lpServiceConfig->lpServiceStartName)
1832 lpServiceConfig->lpServiceStartName =
1833 (LPSTR)((ULONG_PTR)lpServiceConfig +
1834 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1835
1836 if (lpServiceConfig->lpDisplayName)
1837 lpServiceConfig->lpDisplayName =
1838 (LPSTR)((ULONG_PTR)lpServiceConfig +
1839 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1840
1841 TRACE("QueryServiceConfigA() done\n");
1842
1843 return TRUE;
1844 }
1845
1846
1847 /**********************************************************************
1848 * QueryServiceConfigW
1849 *
1850 * @implemented
1851 */
1852 BOOL WINAPI
1853 QueryServiceConfigW(SC_HANDLE hService,
1854 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1855 DWORD cbBufSize,
1856 LPDWORD pcbBytesNeeded)
1857 {
1858 DWORD dwError;
1859
1860 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1861 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1862
1863 RpcTryExcept
1864 {
1865 /* Call to services.exe using RPC */
1866 dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
1867 (LPBYTE)lpServiceConfig,
1868 cbBufSize,
1869 pcbBytesNeeded);
1870 }
1871 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1872 {
1873 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1874 }
1875 RpcEndExcept;
1876
1877 if (dwError != ERROR_SUCCESS)
1878 {
1879 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1880 SetLastError(dwError);
1881 return FALSE;
1882 }
1883
1884 /* Adjust the pointers */
1885 if (lpServiceConfig->lpBinaryPathName)
1886 lpServiceConfig->lpBinaryPathName =
1887 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1888 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1889
1890 if (lpServiceConfig->lpLoadOrderGroup)
1891 lpServiceConfig->lpLoadOrderGroup =
1892 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1893 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1894
1895 if (lpServiceConfig->lpDependencies)
1896 lpServiceConfig->lpDependencies =
1897 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1898 (ULONG_PTR)lpServiceConfig->lpDependencies);
1899
1900 if (lpServiceConfig->lpServiceStartName)
1901 lpServiceConfig->lpServiceStartName =
1902 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1903 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1904
1905 if (lpServiceConfig->lpDisplayName)
1906 lpServiceConfig->lpDisplayName =
1907 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1908 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1909
1910 TRACE("QueryServiceConfigW() done\n");
1911
1912 return TRUE;
1913 }
1914
1915
1916 /**********************************************************************
1917 * QueryServiceConfig2A
1918 *
1919 * @implemented
1920 */
1921 BOOL WINAPI
1922 QueryServiceConfig2A(SC_HANDLE hService,
1923 DWORD dwInfoLevel,
1924 LPBYTE lpBuffer,
1925 DWORD cbBufSize,
1926 LPDWORD pcbBytesNeeded)
1927 {
1928 DWORD dwError;
1929
1930 TRACE("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
1931 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1932
1933 if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
1934 dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
1935 {
1936 SetLastError(ERROR_INVALID_LEVEL);
1937 return FALSE;
1938 }
1939
1940 if ((lpBuffer == NULL && cbBufSize != 0) ||
1941 pcbBytesNeeded == NULL)
1942 {
1943 SetLastError(ERROR_INVALID_ADDRESS);
1944 return FALSE;
1945 }
1946
1947 RpcTryExcept
1948 {
1949 /* Call to services.exe using RPC */
1950 dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService,
1951 dwInfoLevel,
1952 lpBuffer,
1953 cbBufSize,
1954 pcbBytesNeeded);
1955 }
1956 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1957 {
1958 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1959 }
1960 RpcEndExcept;
1961
1962 if (dwError != ERROR_SUCCESS)
1963 {
1964 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
1965 SetLastError(dwError);
1966 return FALSE;
1967 }
1968
1969 switch (dwInfoLevel)
1970 {
1971 case SERVICE_CONFIG_DESCRIPTION:
1972 {
1973 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
1974
1975 if (lpPtr->lpDescription != NULL)
1976 lpPtr->lpDescription =
1977 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1978 }
1979 break;
1980
1981 case SERVICE_CONFIG_FAILURE_ACTIONS:
1982 {
1983 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
1984
1985 if (lpPtr->lpRebootMsg != NULL)
1986 lpPtr->lpRebootMsg =
1987 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1988
1989 if (lpPtr->lpCommand != NULL)
1990 lpPtr->lpCommand =
1991 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1992
1993 if (lpPtr->lpsaActions != NULL)
1994 lpPtr->lpsaActions =
1995 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1996 }
1997 break;
1998
1999 default:
2000 ERR("Unknown info level 0x%lx\n", dwInfoLevel);
2001 SetLastError(ERROR_INVALID_PARAMETER);
2002 return FALSE;
2003 }
2004
2005 TRACE("QueryServiceConfig2A() done\n");
2006
2007 return TRUE;
2008 }
2009
2010
2011 /**********************************************************************
2012 * QueryServiceConfig2W
2013 *
2014 * @implemented
2015 */
2016 BOOL WINAPI
2017 QueryServiceConfig2W(SC_HANDLE hService,
2018 DWORD dwInfoLevel,
2019 LPBYTE lpBuffer,
2020 DWORD cbBufSize,
2021 LPDWORD pcbBytesNeeded)
2022 {
2023 DWORD dwError;
2024
2025 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2026 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
2027
2028 if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
2029 dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
2030 {
2031 SetLastError(ERROR_INVALID_LEVEL);
2032 return FALSE;
2033 }
2034
2035 if ((lpBuffer == NULL && cbBufSize != 0) ||
2036 pcbBytesNeeded == NULL)
2037 {
2038 SetLastError(ERROR_INVALID_ADDRESS);
2039 return FALSE;
2040 }
2041
2042 RpcTryExcept
2043 {
2044 /* Call to services.exe using RPC */
2045 dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService,
2046 dwInfoLevel,
2047 lpBuffer,
2048 cbBufSize,
2049 pcbBytesNeeded);
2050 }
2051 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2052 {
2053 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2054 }
2055 RpcEndExcept;
2056
2057 if (dwError != ERROR_SUCCESS)
2058 {
2059 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
2060 SetLastError(dwError);
2061 return FALSE;
2062 }
2063
2064 switch (dwInfoLevel)
2065 {
2066 case SERVICE_CONFIG_DESCRIPTION:
2067 {
2068 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
2069
2070 if (lpPtr->lpDescription != NULL)
2071 lpPtr->lpDescription =
2072 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
2073 }
2074 break;
2075
2076 case SERVICE_CONFIG_FAILURE_ACTIONS:
2077 {
2078 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
2079
2080 if (lpPtr->lpRebootMsg != NULL)
2081 lpPtr->lpRebootMsg =
2082 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
2083
2084 if (lpPtr->lpCommand != NULL)
2085 lpPtr->lpCommand =
2086 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
2087
2088 if (lpPtr->lpsaActions != NULL)
2089 lpPtr->lpsaActions =
2090 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
2091 }
2092 break;
2093
2094 default:
2095 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
2096 SetLastError(ERROR_INVALID_PARAMETER);
2097 return FALSE;
2098 }
2099
2100 TRACE("QueryServiceConfig2W() done\n");
2101
2102 return TRUE;
2103 }
2104
2105
2106 /**********************************************************************
2107 * QueryServiceLockStatusA
2108 *
2109 * @implemented
2110 */
2111 BOOL WINAPI
2112 QueryServiceLockStatusA(SC_HANDLE hSCManager,
2113 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
2114 DWORD cbBufSize,
2115 LPDWORD pcbBytesNeeded)
2116 {
2117 DWORD dwError;
2118
2119 TRACE("QueryServiceLockStatusA() called\n");
2120
2121 RpcTryExcept
2122 {
2123 /* Call to services.exe using RPC */
2124 dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager,
2125 lpLockStatus,
2126 cbBufSize,
2127 pcbBytesNeeded);
2128 }
2129 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2130 {
2131 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2132 }
2133 RpcEndExcept;
2134
2135 if (dwError != ERROR_SUCCESS)
2136 {
2137 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
2138 SetLastError(dwError);
2139 return FALSE;
2140 }
2141
2142 if (lpLockStatus->lpLockOwner != NULL)
2143 {
2144 lpLockStatus->lpLockOwner =
2145 (LPSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2146 }
2147
2148 TRACE("QueryServiceLockStatusA() done\n");
2149
2150 return TRUE;
2151 }
2152
2153
2154 /**********************************************************************
2155 * QueryServiceLockStatusW
2156 *
2157 * @implemented
2158 */
2159 BOOL WINAPI
2160 QueryServiceLockStatusW(SC_HANDLE hSCManager,
2161 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
2162 DWORD cbBufSize,
2163 LPDWORD pcbBytesNeeded)
2164 {
2165 DWORD dwError;
2166
2167 TRACE("QueryServiceLockStatusW() called\n");
2168
2169 RpcTryExcept
2170 {
2171 /* Call to services.exe using RPC */
2172 dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager,
2173 lpLockStatus,
2174 cbBufSize,
2175 pcbBytesNeeded);
2176 }
2177 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2178 {
2179 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2180 }
2181 RpcEndExcept;
2182
2183 if (dwError != ERROR_SUCCESS)
2184 {
2185 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
2186 SetLastError(dwError);
2187 return FALSE;
2188 }
2189
2190 if (lpLockStatus->lpLockOwner != NULL)
2191 {
2192 lpLockStatus->lpLockOwner =
2193 (LPWSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2194 }
2195
2196 TRACE("QueryServiceLockStatusW() done\n");
2197
2198 return TRUE;
2199 }
2200
2201
2202 /**********************************************************************
2203 * QueryServiceObjectSecurity
2204 *
2205 * @implemented
2206 */
2207 BOOL WINAPI
2208 QueryServiceObjectSecurity(SC_HANDLE hService,
2209 SECURITY_INFORMATION dwSecurityInformation,
2210 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
2211 DWORD cbBufSize,
2212 LPDWORD pcbBytesNeeded)
2213 {
2214 DWORD dwError;
2215
2216 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2217 hService, dwSecurityInformation, lpSecurityDescriptor);
2218
2219 RpcTryExcept
2220 {
2221 /* Call to services.exe using RPC */
2222 dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService,
2223 dwSecurityInformation,
2224 (LPBYTE)lpSecurityDescriptor,
2225 cbBufSize,
2226 pcbBytesNeeded);
2227 }
2228 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2229 {
2230 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2231 }
2232 RpcEndExcept;
2233
2234 if (dwError != ERROR_SUCCESS)
2235 {
2236 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
2237 SetLastError(dwError);
2238 return FALSE;
2239 }
2240
2241 return TRUE;
2242 }
2243
2244 /**********************************************************************
2245 * SetServiceObjectSecurity
2246 *
2247 * @implemented
2248 */
2249 BOOL WINAPI
2250 SetServiceObjectSecurity(SC_HANDLE hService,
2251 SECURITY_INFORMATION dwSecurityInformation,
2252 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
2253 {
2254 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
2255 ULONG Length;
2256 NTSTATUS Status;
2257 DWORD dwError;
2258
2259 Length = 0;
2260 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2261 SelfRelativeSD,
2262 &Length);
2263 if (Status != STATUS_BUFFER_TOO_SMALL)
2264 {
2265 SetLastError(ERROR_INVALID_PARAMETER);
2266 return FALSE;
2267 }
2268
2269 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
2270 if (SelfRelativeSD == NULL)
2271 {
2272 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2273 return FALSE;
2274 }
2275
2276 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2277 SelfRelativeSD,
2278 &Length);
2279 if (!NT_SUCCESS(Status))
2280 {
2281 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2282 SetLastError(RtlNtStatusToDosError(Status));
2283 return FALSE;
2284 }
2285
2286 RpcTryExcept
2287 {
2288 /* Call to services.exe using RPC */
2289 dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService,
2290 dwSecurityInformation,
2291 (LPBYTE)SelfRelativeSD,
2292 Length);
2293 }
2294 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2295 {
2296 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2297 }
2298 RpcEndExcept;
2299
2300 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2301
2302 if (dwError != ERROR_SUCCESS)
2303 {
2304 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
2305 SetLastError(dwError);
2306 return FALSE;
2307 }
2308
2309 return TRUE;
2310 }
2311
2312
2313 /**********************************************************************
2314 * QueryServiceStatus
2315 *
2316 * @implemented
2317 */
2318 BOOL WINAPI
2319 QueryServiceStatus(SC_HANDLE hService,
2320 LPSERVICE_STATUS lpServiceStatus)
2321 {
2322 DWORD dwError;
2323
2324 TRACE("QueryServiceStatus(%p, %p)\n",
2325 hService, lpServiceStatus);
2326
2327 if (!hService)
2328 {
2329 SetLastError(ERROR_INVALID_HANDLE);
2330 return FALSE;
2331 }
2332
2333 RpcTryExcept
2334 {
2335 /* Call to services.exe using RPC */
2336 dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService,
2337 lpServiceStatus);
2338 }
2339 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2340 {
2341 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2342 }
2343 RpcEndExcept;
2344
2345 if (dwError != ERROR_SUCCESS)
2346 {
2347 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError);
2348 SetLastError(dwError);
2349 return FALSE;
2350 }
2351
2352 return TRUE;
2353 }
2354
2355
2356 /**********************************************************************
2357 * QueryServiceStatusEx
2358 *
2359 * @implemented
2360 */
2361 BOOL WINAPI
2362 QueryServiceStatusEx(SC_HANDLE hService,
2363 SC_STATUS_TYPE InfoLevel,
2364 LPBYTE lpBuffer,
2365 DWORD cbBufSize,
2366 LPDWORD pcbBytesNeeded)
2367 {
2368 DWORD dwError;
2369
2370 TRACE("QueryServiceStatusEx() called\n");
2371
2372 if (InfoLevel != SC_STATUS_PROCESS_INFO)
2373 {
2374 SetLastError(ERROR_INVALID_LEVEL);
2375 return FALSE;
2376 }
2377
2378 RpcTryExcept
2379 {
2380 /* Call to services.exe using RPC */
2381 dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService,
2382 InfoLevel,
2383 lpBuffer,
2384 cbBufSize,
2385 pcbBytesNeeded);
2386 }
2387 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2388 {
2389 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2390 }
2391 RpcEndExcept;
2392
2393 if (dwError != ERROR_SUCCESS)
2394 {
2395 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
2396 SetLastError(dwError);
2397 return FALSE;
2398 }
2399
2400 return TRUE;
2401 }
2402
2403
2404 /**********************************************************************
2405 * StartServiceA
2406 *
2407 * @implemented
2408 */
2409 BOOL WINAPI
2410 StartServiceA(SC_HANDLE hService,
2411 DWORD dwNumServiceArgs,
2412 LPCSTR *lpServiceArgVectors)
2413 {
2414 DWORD dwError;
2415
2416 RpcTryExcept
2417 {
2418 dwError = RStartServiceA((SC_RPC_HANDLE)hService,
2419 dwNumServiceArgs,
2420 (LPSTRING_PTRSA)lpServiceArgVectors);
2421 }
2422 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2423 {
2424 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2425 }
2426 RpcEndExcept;
2427
2428 if (dwError != ERROR_SUCCESS)
2429 {
2430 TRACE("RStartServiceA() failed (Error %lu)\n", dwError);
2431 SetLastError(dwError);
2432 return FALSE;
2433 }
2434
2435 return TRUE;
2436 }
2437
2438
2439 /**********************************************************************
2440 * StartServiceW
2441 *
2442 * @implemented
2443 */
2444 BOOL WINAPI
2445 StartServiceW(SC_HANDLE hService,
2446 DWORD dwNumServiceArgs,
2447 LPCWSTR *lpServiceArgVectors)
2448 {
2449 DWORD dwError;
2450
2451 RpcTryExcept
2452 {
2453 dwError = RStartServiceW((SC_RPC_HANDLE)hService,
2454 dwNumServiceArgs,
2455 (LPSTRING_PTRSW)lpServiceArgVectors);
2456 }
2457 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2458 {
2459 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2460 }
2461 RpcEndExcept;
2462
2463 if (dwError != ERROR_SUCCESS)
2464 {
2465 TRACE("RStartServiceW() failed (Error %lu)\n", dwError);
2466 SetLastError(dwError);
2467 return FALSE;
2468 }
2469
2470 return TRUE;
2471 }
2472
2473
2474 /**********************************************************************
2475 * UnlockServiceDatabase
2476 *
2477 * @implemented
2478 */
2479 BOOL WINAPI
2480 UnlockServiceDatabase(SC_LOCK ScLock)
2481 {
2482 DWORD dwError;
2483
2484 TRACE("UnlockServiceDatabase(%x)\n", ScLock);
2485
2486 RpcTryExcept
2487 {
2488 /* Call to services.exe using RPC */
2489 dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock);
2490 }
2491 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2492 {
2493 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2494 }
2495 RpcEndExcept;
2496
2497 if (dwError != ERROR_SUCCESS)
2498 {
2499 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
2500 SetLastError(dwError);
2501 return FALSE;
2502 }
2503
2504 return TRUE;
2505 }
2506
2507
2508 /**********************************************************************
2509 * NotifyBootConfigStatus
2510 *
2511 * @implemented
2512 */
2513 BOOL WINAPI
2514 NotifyBootConfigStatus(BOOL BootAcceptable)
2515 {
2516 DWORD dwError;
2517
2518 TRACE("NotifyBootConfigStatus()\n");
2519
2520 RpcTryExcept
2521 {
2522 /* Call to services.exe using RPC */
2523 dwError = RNotifyBootConfigStatus(NULL,
2524 BootAcceptable);
2525 }
2526 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2527 {
2528 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2529 }
2530 RpcEndExcept;
2531
2532 if (dwError != ERROR_SUCCESS)
2533 {
2534 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
2535 SetLastError(dwError);
2536 return FALSE;
2537 }
2538
2539 return TRUE;
2540 }
2541
2542 /* EOF */