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