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