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