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