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