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