Forward EnumDependentServicesA/W to services.exe.
[reactos.git] / reactos / lib / 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 #include "svcctl_c.h"
17
18 #define NDEBUG
19 #include <debug.h>
20
21 /* FUNCTIONS *****************************************************************/
22
23 handle_t BindingHandle = NULL;
24
25 static VOID
26 HandleBind(VOID)
27 {
28 LPWSTR pszStringBinding;
29 RPC_STATUS status;
30
31 if (BindingHandle != NULL)
32 return;
33
34 status = RpcStringBindingComposeW(NULL,
35 L"ncacn_np",
36 NULL,
37 L"\\pipe\\ntsvcs",
38 NULL,
39 &pszStringBinding);
40 if (status)
41 {
42 DPRINT1("RpcStringBindingCompose returned 0x%x\n", status);
43 return;
44 }
45
46 /* Set the binding handle that will be used to bind to the server. */
47 status = RpcBindingFromStringBindingW(pszStringBinding,
48 &BindingHandle);
49 if (status)
50 {
51 DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status);
52 }
53
54 status = RpcStringFreeW(&pszStringBinding);
55 if (status)
56 {
57 DPRINT1("RpcStringFree returned 0x%x\n", status);
58 }
59 }
60
61
62 #if 0
63 static VOID
64 HandleUnbind(VOID)
65 {
66 RPC_STATUS status;
67
68 if (BindingHandle == NULL)
69 return;
70
71 status = RpcBindingFree(&BindingHandle);
72 if (status)
73 {
74 DPRINT1("RpcBindingFree returned 0x%x\n", status);
75 }
76 }
77 #endif
78
79
80 /**********************************************************************
81 * ChangeServiceConfig2A
82 *
83 * @implemented
84 */
85 BOOL WINAPI
86 ChangeServiceConfig2A(SC_HANDLE hService,
87 DWORD dwInfoLevel,
88 LPVOID lpInfo)
89 {
90 DWORD lpInfoSize;
91 DWORD dwError;
92
93 DPRINT("ChangeServiceConfig2A() called\n");
94
95 /* Determine the length of the lpInfo parameter */
96 switch (dwInfoLevel)
97 {
98 case SERVICE_CONFIG_DESCRIPTION:
99 lpInfoSize = sizeof(SERVICE_DESCRIPTIONA);
100 break;
101
102 case SERVICE_CONFIG_FAILURE_ACTIONS:
103 lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSA);
104 break;
105
106 default:
107 DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
108 SetLastError(ERROR_INVALID_PARAMETER);
109 return FALSE;
110 }
111
112 if (lpInfo == NULL)
113 return TRUE;
114
115 HandleBind();
116
117 dwError = ScmrChangeServiceConfig2A(BindingHandle,
118 (unsigned int)hService,
119 dwInfoLevel,
120 lpInfo,
121 lpInfoSize);
122 if (dwError != ERROR_SUCCESS)
123 {
124 DPRINT1("ScmrChangeServiceConfig2A() failed (Error %lu)\n", dwError);
125 SetLastError(dwError);
126 return FALSE;
127 }
128
129 return TRUE;
130 }
131
132
133 /**********************************************************************
134 * ChangeServiceConfig2W
135 *
136 * @implemented
137 */
138 BOOL WINAPI
139 ChangeServiceConfig2W(SC_HANDLE hService,
140 DWORD dwInfoLevel,
141 LPVOID lpInfo)
142 {
143 DWORD lpInfoSize;
144 DWORD dwError;
145
146 DPRINT("ChangeServiceConfig2W() called\n");
147
148 /* Determine the length of the lpInfo parameter */
149 switch (dwInfoLevel)
150 {
151 case SERVICE_CONFIG_DESCRIPTION:
152 lpInfoSize = sizeof(SERVICE_DESCRIPTIONW);
153 break;
154
155 case SERVICE_CONFIG_FAILURE_ACTIONS:
156 lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSW);
157 break;
158
159 default:
160 DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
161 SetLastError(ERROR_INVALID_PARAMETER);
162 return FALSE;
163 }
164
165 if (lpInfo == NULL)
166 return TRUE;
167
168 HandleBind();
169
170 dwError = ScmrChangeServiceConfig2W(BindingHandle,
171 (unsigned int)hService,
172 dwInfoLevel,
173 lpInfo,
174 lpInfoSize);
175 if (dwError != ERROR_SUCCESS)
176 {
177 DPRINT1("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError);
178 SetLastError(dwError);
179 return FALSE;
180 }
181
182 return TRUE;
183 }
184
185
186 /**********************************************************************
187 * ChangeServiceConfigA
188 *
189 * @implemented
190 */
191 BOOL STDCALL
192 ChangeServiceConfigA(SC_HANDLE hService,
193 DWORD dwServiceType,
194 DWORD dwStartType,
195 DWORD dwErrorControl,
196 LPCSTR lpBinaryPathName,
197 LPCSTR lpLoadOrderGroup,
198 LPDWORD lpdwTagId,
199 LPCSTR lpDependencies,
200 LPCSTR lpServiceStartName,
201 LPCSTR lpPassword,
202 LPCSTR lpDisplayName)
203 {
204 DWORD dwError;
205 DWORD dwDependenciesLength = 0;
206 DWORD dwLength;
207 LPSTR lpStr;
208
209 DPRINT("ChangeServiceConfigA() called\n");
210
211 /* Calculate the Dependencies length*/
212 if (lpDependencies != NULL)
213 {
214 lpStr = (LPSTR)lpDependencies;
215 while (*lpStr)
216 {
217 dwLength = strlen(lpStr) + 1;
218 dwDependenciesLength += dwLength;
219 lpStr = lpStr + dwLength;
220 }
221 dwDependenciesLength++;
222 }
223
224 /* FIXME: Encrypt the password */
225
226 HandleBind();
227
228 /* Call to services.exe using RPC */
229 dwError = ScmrChangeServiceConfigA(BindingHandle,
230 (unsigned int)hService,
231 dwServiceType,
232 dwStartType,
233 dwErrorControl,
234 (LPSTR)lpBinaryPathName,
235 (LPSTR)lpLoadOrderGroup,
236 lpdwTagId,
237 (LPSTR)lpDependencies,
238 dwDependenciesLength,
239 (LPSTR)lpServiceStartName,
240 NULL, /* FIXME: lpPassword */
241 0, /* FIXME: dwPasswordLength */
242 (LPSTR)lpDisplayName);
243 if (dwError != ERROR_SUCCESS)
244 {
245 DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError);
246 SetLastError(dwError);
247 return FALSE;
248 }
249
250 return TRUE;
251 }
252
253
254 /**********************************************************************
255 * ChangeServiceConfigW
256 *
257 * @implemented
258 */
259 BOOL STDCALL
260 ChangeServiceConfigW(SC_HANDLE hService,
261 DWORD dwServiceType,
262 DWORD dwStartType,
263 DWORD dwErrorControl,
264 LPCWSTR lpBinaryPathName,
265 LPCWSTR lpLoadOrderGroup,
266 LPDWORD lpdwTagId,
267 LPCWSTR lpDependencies,
268 LPCWSTR lpServiceStartName,
269 LPCWSTR lpPassword,
270 LPCWSTR lpDisplayName)
271 {
272 DWORD dwError;
273 DWORD dwDependenciesLength = 0;
274 DWORD dwLength;
275 LPWSTR lpStr;
276
277 DPRINT("ChangeServiceConfigW() called\n");
278
279 /* Calculate the Dependencies length*/
280 if (lpDependencies != NULL)
281 {
282 lpStr = (LPWSTR)lpDependencies;
283 while (*lpStr)
284 {
285 dwLength = wcslen(lpStr) + 1;
286 dwDependenciesLength += dwLength;
287 lpStr = lpStr + dwLength;
288 }
289 dwDependenciesLength++;
290 }
291
292 /* FIXME: Encrypt the password */
293
294 HandleBind();
295
296 /* Call to services.exe using RPC */
297 dwError = ScmrChangeServiceConfigW(BindingHandle,
298 (unsigned int)hService,
299 dwServiceType,
300 dwStartType,
301 dwErrorControl,
302 (LPWSTR)lpBinaryPathName,
303 (LPWSTR)lpLoadOrderGroup,
304 lpdwTagId,
305 (LPWSTR)lpDependencies,
306 dwDependenciesLength,
307 (LPWSTR)lpServiceStartName,
308 NULL, /* FIXME: lpPassword */
309 0, /* FIXME: dwPasswordLength */
310 (LPWSTR)lpDisplayName);
311 if (dwError != ERROR_SUCCESS)
312 {
313 DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
314 SetLastError(dwError);
315 return FALSE;
316 }
317
318 return TRUE;
319 }
320
321
322 /**********************************************************************
323 * CloseServiceHandle
324 *
325 * @implemented
326 */
327 BOOL STDCALL
328 CloseServiceHandle(SC_HANDLE hSCObject)
329 {
330 DWORD dwError;
331
332 DPRINT("CloseServiceHandle() called\n");
333
334 HandleBind();
335
336 /* Call to services.exe using RPC */
337 dwError = ScmrCloseServiceHandle(BindingHandle,
338 (unsigned int)hSCObject);
339 if (dwError)
340 {
341 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError);
342 SetLastError(dwError);
343 return FALSE;
344 }
345
346 DPRINT("CloseServiceHandle() done\n");
347
348 return TRUE;
349 }
350
351
352 /**********************************************************************
353 * ControlService
354 *
355 * @implemented
356 */
357 BOOL STDCALL
358 ControlService(SC_HANDLE hService,
359 DWORD dwControl,
360 LPSERVICE_STATUS lpServiceStatus)
361 {
362 DWORD dwError;
363
364 DPRINT("ControlService(%x, %x, %p)\n",
365 hService, dwControl, lpServiceStatus);
366
367 HandleBind();
368
369 /* Call to services.exe using RPC */
370 dwError = ScmrControlService(BindingHandle,
371 (unsigned int)hService,
372 dwControl,
373 lpServiceStatus);
374 if (dwError != ERROR_SUCCESS)
375 {
376 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError);
377 SetLastError(dwError);
378 return FALSE;
379 }
380
381 DPRINT("ControlService() done\n");
382
383 return TRUE;
384 }
385
386
387 /**********************************************************************
388 * ControlServiceEx
389 *
390 * @unimplemented
391 */
392 BOOL STDCALL
393 ControlServiceEx(IN SC_HANDLE hService,
394 IN DWORD dwControl,
395 IN DWORD dwInfoLevel,
396 IN OUT PVOID pControlParams)
397 {
398 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
399 hService, dwControl, dwInfoLevel, pControlParams);
400 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
401 return FALSE;
402 }
403
404
405
406 /**********************************************************************
407 * CreateServiceA
408 *
409 * @implemented
410 */
411 SC_HANDLE STDCALL
412 CreateServiceA(SC_HANDLE hSCManager,
413 LPCSTR lpServiceName,
414 LPCSTR lpDisplayName,
415 DWORD dwDesiredAccess,
416 DWORD dwServiceType,
417 DWORD dwStartType,
418 DWORD dwErrorControl,
419 LPCSTR lpBinaryPathName,
420 LPCSTR lpLoadOrderGroup,
421 LPDWORD lpdwTagId,
422 LPCSTR lpDependencies,
423 LPCSTR lpServiceStartName,
424 LPCSTR lpPassword)
425 {
426 SC_HANDLE RetVal = NULL;
427 LPWSTR lpServiceNameW = NULL;
428 LPWSTR lpDisplayNameW = NULL;
429 LPWSTR lpBinaryPathNameW = NULL;
430 LPWSTR lpLoadOrderGroupW = NULL;
431 LPWSTR lpDependenciesW = NULL;
432 LPWSTR lpServiceStartNameW = NULL;
433 LPWSTR lpPasswordW = NULL;
434 DWORD dwDependenciesLength = 0;
435 DWORD dwLength;
436 LPSTR lpStr;
437
438 int len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
439 lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
440 if (!lpServiceNameW)
441 {
442 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
443 goto cleanup;
444 }
445 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
446
447 len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
448 lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
449 if (!lpDisplayNameW)
450 {
451 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
452 goto cleanup;
453 }
454 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
455
456 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
457 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
458 if (!lpBinaryPathNameW)
459 {
460 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
461 goto cleanup;
462 }
463 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpBinaryPathNameW, len);
464
465 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
466 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
467 if (!lpLoadOrderGroupW)
468 {
469 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
470 goto cleanup;
471 }
472 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
473
474 if (lpDependencies != NULL)
475 {
476 lpStr = (LPSTR)lpDependencies;
477 while (*lpStr)
478 {
479 dwLength = strlen(lpStr) + 1;
480 dwDependenciesLength += dwLength;
481 lpStr = lpStr + dwLength;
482 }
483 dwDependenciesLength++;
484 }
485
486 lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
487 if (!lpDependenciesW)
488 {
489 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
490 goto cleanup;
491 }
492 MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, dwDependenciesLength);
493
494 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
495 lpServiceStartName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
496 if (!lpServiceStartNameW)
497 {
498 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
499 goto cleanup;
500 }
501 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
502
503 len = MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, NULL, 0);
504 lpPasswordW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
505 if (!lpPasswordW)
506 {
507 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
508 goto cleanup;
509 }
510 MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
511
512 RetVal = CreateServiceW(hSCManager,
513 lpServiceNameW,
514 lpDisplayNameW,
515 dwDesiredAccess,
516 dwServiceType,
517 dwStartType,
518 dwErrorControl,
519 lpBinaryPathNameW,
520 lpLoadOrderGroupW,
521 lpdwTagId,
522 lpDependenciesW,
523 lpServiceStartNameW,
524 lpPasswordW);
525
526 cleanup:
527 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
528 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
529 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
530 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
531 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
532 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
533 HeapFree(GetProcessHeap(), 0, lpPasswordW);
534
535 return RetVal;
536 }
537
538
539 /**********************************************************************
540 * CreateServiceW
541 *
542 * @implemented
543 */
544 SC_HANDLE STDCALL
545 CreateServiceW(SC_HANDLE hSCManager,
546 LPCWSTR lpServiceName,
547 LPCWSTR lpDisplayName,
548 DWORD dwDesiredAccess,
549 DWORD dwServiceType,
550 DWORD dwStartType,
551 DWORD dwErrorControl,
552 LPCWSTR lpBinaryPathName,
553 LPCWSTR lpLoadOrderGroup,
554 LPDWORD lpdwTagId,
555 LPCWSTR lpDependencies,
556 LPCWSTR lpServiceStartName,
557 LPCWSTR lpPassword)
558 {
559 SC_HANDLE hService = NULL;
560 DWORD dwDependenciesLength = 0;
561 DWORD dwError;
562 DWORD dwLength;
563 LPWSTR lpStr;
564
565 DPRINT("CreateServiceW() called\n");
566
567 /* Calculate the Dependencies length*/
568 if (lpDependencies != NULL)
569 {
570 lpStr = (LPWSTR)lpDependencies;
571 while (*lpStr)
572 {
573 dwLength = wcslen(lpStr) + 1;
574 dwDependenciesLength += dwLength;
575 lpStr = lpStr + dwLength;
576 }
577 dwDependenciesLength++;
578 }
579
580 /* FIXME: Encrypt the password */
581
582 HandleBind();
583
584 /* Call to services.exe using RPC */
585 dwError = ScmrCreateServiceW(BindingHandle,
586 (unsigned int)hSCManager,
587 (LPWSTR)lpServiceName,
588 (LPWSTR)lpDisplayName,
589 dwDesiredAccess,
590 dwServiceType,
591 dwStartType,
592 dwErrorControl,
593 (LPWSTR)lpBinaryPathName,
594 (LPWSTR)lpLoadOrderGroup,
595 lpdwTagId,
596 (LPWSTR)lpDependencies,
597 dwDependenciesLength,
598 (LPWSTR)lpServiceStartName,
599 NULL, /* FIXME: lpPassword */
600 0, /* FIXME: dwPasswordLength */
601 (unsigned int *)&hService);
602 if (dwError != ERROR_SUCCESS)
603 {
604 DPRINT("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
605 SetLastError(dwError);
606 return NULL;
607 }
608
609 return hService;
610 }
611
612
613 /**********************************************************************
614 * DeleteService
615 *
616 * @implemented
617 */
618 BOOL STDCALL
619 DeleteService(SC_HANDLE hService)
620 {
621 DWORD dwError;
622
623 DPRINT("DeleteService(%x)\n", hService);
624
625 HandleBind();
626
627 /* Call to services.exe using RPC */
628 dwError = ScmrDeleteService(BindingHandle,
629 (unsigned int)hService);
630 if (dwError != ERROR_SUCCESS)
631 {
632 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError);
633 SetLastError(dwError);
634 return FALSE;
635 }
636
637 return TRUE;
638 }
639
640
641 /**********************************************************************
642 * EnumDependentServicesA
643 *
644 * @implemented
645 */
646 BOOL STDCALL
647 EnumDependentServicesA(SC_HANDLE hService,
648 DWORD dwServiceState,
649 LPENUM_SERVICE_STATUSA lpServices,
650 DWORD cbBufSize,
651 LPDWORD pcbBytesNeeded,
652 LPDWORD lpServicesReturned)
653 {
654 LPENUM_SERVICE_STATUSA lpStatusPtr;
655 DWORD dwError = ERROR_SUCCESS;
656 DWORD dwCount;
657
658 DPRINT("EnumServicesStatusA() called\n");
659
660 HandleBind();
661
662 dwError = ScmrEnumDependentServicesA(BindingHandle,
663 (unsigned int)hService,
664 dwServiceState,
665 (unsigned char *)lpServices,
666 cbBufSize,
667 pcbBytesNeeded,
668 lpServicesReturned);
669
670 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
671 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
672 {
673 if (lpStatusPtr->lpServiceName)
674 lpStatusPtr->lpServiceName =
675 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
676
677 if (lpStatusPtr->lpDisplayName)
678 lpStatusPtr->lpDisplayName =
679 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
680
681 lpStatusPtr++;
682 }
683
684 if (dwError != ERROR_SUCCESS)
685 {
686 DPRINT("ScmrEnumDependentServicesA() failed (Error %lu)\n", dwError);
687 SetLastError(dwError);
688 return FALSE;
689 }
690
691 DPRINT("EnumDependentServicesA() done\n");
692
693 return TRUE;
694 }
695
696
697 /**********************************************************************
698 * EnumDependentServicesW
699 *
700 * @implemented
701 */
702 BOOL STDCALL
703 EnumDependentServicesW(SC_HANDLE hService,
704 DWORD dwServiceState,
705 LPENUM_SERVICE_STATUSW lpServices,
706 DWORD cbBufSize,
707 LPDWORD pcbBytesNeeded,
708 LPDWORD lpServicesReturned)
709 {
710 LPENUM_SERVICE_STATUSW lpStatusPtr;
711 DWORD dwError = ERROR_SUCCESS;
712 DWORD dwCount;
713
714 DPRINT("EnumServicesStatusW() called\n");
715
716 HandleBind();
717
718 dwError = ScmrEnumDependentServicesW(BindingHandle,
719 (unsigned int)hService,
720 dwServiceState,
721 (unsigned char *)lpServices,
722 cbBufSize,
723 pcbBytesNeeded,
724 lpServicesReturned);
725
726 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
727 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
728 {
729 if (lpStatusPtr->lpServiceName)
730 lpStatusPtr->lpServiceName =
731 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
732
733 if (lpStatusPtr->lpDisplayName)
734 lpStatusPtr->lpDisplayName =
735 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
736
737 lpStatusPtr++;
738 }
739
740 if (dwError != ERROR_SUCCESS)
741 {
742 DPRINT("ScmrEnumDependentServicesW() failed (Error %lu)\n", dwError);
743 SetLastError(dwError);
744 return FALSE;
745 }
746
747 DPRINT("EnumDependentServicesW() done\n");
748
749 return TRUE;
750 }
751
752
753 /**********************************************************************
754 * EnumServiceGroupW
755 *
756 * @unimplemented
757 */
758 BOOL
759 STDCALL
760 EnumServiceGroupW(
761 SC_HANDLE hSCManager,
762 DWORD dwServiceType,
763 DWORD dwServiceState,
764 LPENUM_SERVICE_STATUSW lpServices,
765 DWORD cbBufSize,
766 LPDWORD pcbBytesNeeded,
767 LPDWORD lpServicesReturned,
768 LPDWORD lpResumeHandle,
769 LPCWSTR lpGroup)
770 {
771 DPRINT1("EnumServiceGroupW is unimplemented\n");
772 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
773 return FALSE;
774 }
775
776
777 /**********************************************************************
778 * EnumServicesStatusA
779 *
780 * @implemented
781 */
782 BOOL STDCALL
783 EnumServicesStatusA(SC_HANDLE hSCManager,
784 DWORD dwServiceType,
785 DWORD dwServiceState,
786 LPENUM_SERVICE_STATUSA lpServices,
787 DWORD cbBufSize,
788 LPDWORD pcbBytesNeeded,
789 LPDWORD lpServicesReturned,
790 LPDWORD lpResumeHandle)
791 {
792 LPENUM_SERVICE_STATUSA lpStatusPtr;
793 DWORD dwError = ERROR_SUCCESS;
794 DWORD dwCount;
795
796 DPRINT("EnumServicesStatusA() called\n");
797
798 HandleBind();
799
800 dwError = ScmrEnumServicesStatusA(BindingHandle,
801 (unsigned int)hSCManager,
802 dwServiceType,
803 dwServiceState,
804 (unsigned char *)lpServices,
805 cbBufSize,
806 pcbBytesNeeded,
807 lpServicesReturned,
808 lpResumeHandle);
809
810 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
811 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
812 {
813 if (lpStatusPtr->lpServiceName)
814 lpStatusPtr->lpServiceName =
815 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
816
817 if (lpStatusPtr->lpDisplayName)
818 lpStatusPtr->lpDisplayName =
819 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
820
821 lpStatusPtr++;
822 }
823
824 if (dwError != ERROR_SUCCESS)
825 {
826 DPRINT("ScmrEnumServicesStatusA() failed (Error %lu)\n", dwError);
827 SetLastError(dwError);
828 return FALSE;
829 }
830
831 DPRINT("EnumServicesStatusA() done\n");
832
833 return TRUE;
834 }
835
836
837 /**********************************************************************
838 * EnumServicesStatusW
839 *
840 * @implemented
841 */
842 BOOL STDCALL
843 EnumServicesStatusW(SC_HANDLE hSCManager,
844 DWORD dwServiceType,
845 DWORD dwServiceState,
846 LPENUM_SERVICE_STATUSW lpServices,
847 DWORD cbBufSize,
848 LPDWORD pcbBytesNeeded,
849 LPDWORD lpServicesReturned,
850 LPDWORD lpResumeHandle)
851 {
852 LPENUM_SERVICE_STATUSW lpStatusPtr;
853 DWORD dwError = ERROR_SUCCESS;
854 DWORD dwCount;
855
856 DPRINT("EnumServicesStatusW() called\n");
857
858 HandleBind();
859
860 dwError = ScmrEnumServicesStatusW(BindingHandle,
861 (unsigned int)hSCManager,
862 dwServiceType,
863 dwServiceState,
864 (unsigned char *)lpServices,
865 cbBufSize,
866 pcbBytesNeeded,
867 lpServicesReturned,
868 lpResumeHandle);
869
870 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
871 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
872 {
873 if (lpStatusPtr->lpServiceName)
874 lpStatusPtr->lpServiceName =
875 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
876
877 if (lpStatusPtr->lpDisplayName)
878 lpStatusPtr->lpDisplayName =
879 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
880
881 lpStatusPtr++;
882 }
883
884 if (dwError != ERROR_SUCCESS)
885 {
886 DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
887 SetLastError(dwError);
888 return FALSE;
889 }
890
891 DPRINT("EnumServicesStatusW() done\n");
892
893 return TRUE;
894 }
895
896
897 /**********************************************************************
898 * EnumServicesStatusExA
899 *
900 * @implemented
901 */
902 BOOL STDCALL
903 EnumServicesStatusExA(SC_HANDLE hSCManager,
904 SC_ENUM_TYPE InfoLevel,
905 DWORD dwServiceType,
906 DWORD dwServiceState,
907 LPBYTE lpServices,
908 DWORD cbBufSize,
909 LPDWORD pcbBytesNeeded,
910 LPDWORD lpServicesReturned,
911 LPDWORD lpResumeHandle,
912 LPCSTR pszGroupName)
913 {
914 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
915 DWORD dwError = ERROR_SUCCESS;
916 DWORD dwCount;
917
918 DPRINT("EnumServicesStatusExA() called\n");
919
920 HandleBind();
921
922 dwError = ScmrEnumServicesStatusExA(BindingHandle,
923 (unsigned int)hSCManager,
924 (unsigned long)InfoLevel,
925 dwServiceType,
926 dwServiceState,
927 (unsigned char *)lpServices,
928 cbBufSize,
929 pcbBytesNeeded,
930 lpServicesReturned,
931 lpResumeHandle,
932 (char *)pszGroupName);
933
934 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
935 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
936 {
937 if (lpStatusPtr->lpServiceName)
938 lpStatusPtr->lpServiceName =
939 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
940
941 if (lpStatusPtr->lpDisplayName)
942 lpStatusPtr->lpDisplayName =
943 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
944
945 lpStatusPtr++;
946 }
947
948 if (dwError != ERROR_SUCCESS)
949 {
950 DPRINT1("ScmrEnumServicesStatusExA() failed (Error %lu)\n", dwError);
951 SetLastError(dwError);
952 return FALSE;
953 }
954
955 DPRINT("EnumServicesStatusExA() done\n");
956
957 return TRUE;
958 }
959
960
961 /**********************************************************************
962 * EnumServicesStatusExW
963 *
964 * @implemented
965 */
966 BOOL STDCALL
967 EnumServicesStatusExW(SC_HANDLE hSCManager,
968 SC_ENUM_TYPE InfoLevel,
969 DWORD dwServiceType,
970 DWORD dwServiceState,
971 LPBYTE lpServices,
972 DWORD cbBufSize,
973 LPDWORD pcbBytesNeeded,
974 LPDWORD lpServicesReturned,
975 LPDWORD lpResumeHandle,
976 LPCWSTR pszGroupName)
977 {
978 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
979 DWORD dwError = ERROR_SUCCESS;
980 DWORD dwCount;
981
982 DPRINT("EnumServicesStatusExW() called\n");
983
984 HandleBind();
985
986 dwError = ScmrEnumServicesStatusExW(BindingHandle,
987 (unsigned int)hSCManager,
988 (unsigned long)InfoLevel,
989 dwServiceType,
990 dwServiceState,
991 (unsigned char *)lpServices,
992 cbBufSize,
993 pcbBytesNeeded,
994 lpServicesReturned,
995 lpResumeHandle,
996 (wchar_t *)pszGroupName);
997
998 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
999 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1000 {
1001 if (lpStatusPtr->lpServiceName)
1002 lpStatusPtr->lpServiceName =
1003 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1004
1005 if (lpStatusPtr->lpDisplayName)
1006 lpStatusPtr->lpDisplayName =
1007 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1008
1009 lpStatusPtr++;
1010 }
1011
1012 if (dwError != ERROR_SUCCESS)
1013 {
1014 DPRINT1("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError);
1015 SetLastError(dwError);
1016 return FALSE;
1017 }
1018
1019 DPRINT("EnumServicesStatusExW() done\n");
1020
1021 return TRUE;
1022 }
1023
1024
1025 /**********************************************************************
1026 * GetServiceDisplayNameA
1027 *
1028 * @implemented
1029 */
1030 BOOL STDCALL
1031 GetServiceDisplayNameA(SC_HANDLE hSCManager,
1032 LPCSTR lpServiceName,
1033 LPSTR lpDisplayName,
1034 LPDWORD lpcchBuffer)
1035 {
1036 DWORD dwError;
1037
1038 DPRINT("GetServiceDisplayNameA() called\n");
1039
1040 HandleBind();
1041
1042 dwError = ScmrGetServiceDisplayNameA(BindingHandle,
1043 (unsigned int)hSCManager,
1044 (LPSTR)lpServiceName,
1045 lpDisplayName,
1046 lpcchBuffer);
1047 if (dwError != ERROR_SUCCESS)
1048 {
1049 DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
1050 SetLastError(dwError);
1051 return FALSE;
1052 }
1053
1054 (*lpcchBuffer)--;
1055
1056 return TRUE;
1057 }
1058
1059
1060 /**********************************************************************
1061 * GetServiceDisplayNameW
1062 *
1063 * @implemented
1064 */
1065 BOOL STDCALL
1066 GetServiceDisplayNameW(SC_HANDLE hSCManager,
1067 LPCWSTR lpServiceName,
1068 LPWSTR lpDisplayName,
1069 LPDWORD lpcchBuffer)
1070 {
1071 DWORD dwError;
1072
1073 DPRINT("GetServiceDisplayNameW() called\n");
1074
1075 HandleBind();
1076
1077 dwError = ScmrGetServiceDisplayNameW(BindingHandle,
1078 (unsigned int)hSCManager,
1079 (LPWSTR)lpServiceName,
1080 lpDisplayName,
1081 lpcchBuffer);
1082 if (dwError != ERROR_SUCCESS)
1083 {
1084 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
1085 SetLastError(dwError);
1086 return FALSE;
1087 }
1088
1089 (*lpcchBuffer)--;
1090
1091 return TRUE;
1092 }
1093
1094
1095 /**********************************************************************
1096 * GetServiceKeyNameA
1097 *
1098 * @implemented
1099 */
1100 BOOL STDCALL
1101 GetServiceKeyNameA(SC_HANDLE hSCManager,
1102 LPCSTR lpDisplayName,
1103 LPSTR lpServiceName,
1104 LPDWORD lpcchBuffer)
1105 {
1106 DWORD dwError;
1107
1108 DPRINT("GetServiceKeyNameA() called\n");
1109
1110 HandleBind();
1111
1112 dwError = ScmrGetServiceKeyNameA(BindingHandle,
1113 (unsigned int)hSCManager,
1114 (LPSTR)lpDisplayName,
1115 lpServiceName,
1116 lpcchBuffer);
1117 if (dwError != ERROR_SUCCESS)
1118 {
1119 DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError);
1120 SetLastError(dwError);
1121 return FALSE;
1122 }
1123
1124 (*lpcchBuffer)--;
1125
1126 return TRUE;
1127 }
1128
1129
1130 /**********************************************************************
1131 * GetServiceKeyNameW
1132 *
1133 * @implemented
1134 */
1135 BOOL STDCALL
1136 GetServiceKeyNameW(SC_HANDLE hSCManager,
1137 LPCWSTR lpDisplayName,
1138 LPWSTR lpServiceName,
1139 LPDWORD lpcchBuffer)
1140 {
1141 DWORD dwError;
1142
1143 DPRINT("GetServiceKeyNameW() called\n");
1144
1145 HandleBind();
1146
1147 dwError = ScmrGetServiceKeyNameW(BindingHandle,
1148 (unsigned int)hSCManager,
1149 (LPWSTR)lpDisplayName,
1150 lpServiceName,
1151 lpcchBuffer);
1152 if (dwError != ERROR_SUCCESS)
1153 {
1154 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError);
1155 SetLastError(dwError);
1156 return FALSE;
1157 }
1158
1159 (*lpcchBuffer)--;
1160
1161 return TRUE;
1162 }
1163
1164
1165 /**********************************************************************
1166 * LockServiceDatabase
1167 *
1168 * @implemented
1169 */
1170 SC_LOCK STDCALL
1171 LockServiceDatabase(SC_HANDLE hSCManager)
1172 {
1173 SC_LOCK hLock;
1174 DWORD dwError;
1175
1176 DPRINT("LockServiceDatabase(%x)\n", hSCManager);
1177
1178 HandleBind();
1179
1180 /* Call to services.exe using RPC */
1181 dwError = ScmrLockServiceDatabase(BindingHandle,
1182 (unsigned int)hSCManager,
1183 (unsigned int *)&hLock);
1184 if (dwError != ERROR_SUCCESS)
1185 {
1186 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
1187 SetLastError(dwError);
1188 return NULL;
1189 }
1190
1191 DPRINT("hLock = %p\n", hLock);
1192
1193 return hLock;
1194 }
1195
1196
1197 static VOID
1198 WaitForSCManager(VOID)
1199 {
1200 HANDLE hEvent;
1201
1202 DPRINT("WaitForSCManager() called\n");
1203
1204 /* Try to open the existing event */
1205 hEvent = OpenEventW(SYNCHRONIZE,
1206 FALSE,
1207 L"SvcctrlStartEvent_A3725DX");
1208 if (hEvent == NULL)
1209 {
1210 if (GetLastError() != ERROR_FILE_NOT_FOUND)
1211 return;
1212
1213 /* Try to create a new event */
1214 hEvent = CreateEventW(NULL,
1215 TRUE,
1216 FALSE,
1217 L"SvcctrlStartEvent_A3725DX");
1218 if (hEvent == NULL)
1219 {
1220 /* Try to open the existing event again */
1221 hEvent = OpenEventW(SYNCHRONIZE,
1222 FALSE,
1223 L"SvcctrlStartEvent_A3725DX");
1224 if (hEvent == NULL)
1225 return;
1226 }
1227 }
1228
1229 /* Wait for 3 minutes */
1230 WaitForSingleObject(hEvent, 180000);
1231 CloseHandle(hEvent);
1232
1233 DPRINT("ScmWaitForSCManager() done\n");
1234 }
1235
1236
1237 /**********************************************************************
1238 * OpenSCManagerA
1239 *
1240 * @implemented
1241 */
1242 SC_HANDLE STDCALL
1243 OpenSCManagerA(LPCSTR lpMachineName,
1244 LPCSTR lpDatabaseName,
1245 DWORD dwDesiredAccess)
1246 {
1247 SC_HANDLE hScm = NULL;
1248 DWORD dwError;
1249
1250 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
1251 lpMachineName, lpDatabaseName, dwDesiredAccess);
1252
1253 WaitForSCManager();
1254
1255 HandleBind();
1256
1257 /* Call to services.exe using RPC */
1258 dwError = ScmrOpenSCManagerA(BindingHandle,
1259 (LPSTR)lpMachineName,
1260 (LPSTR)lpDatabaseName,
1261 dwDesiredAccess,
1262 (unsigned int*)&hScm);
1263 if (dwError != ERROR_SUCCESS)
1264 {
1265 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
1266 SetLastError(dwError);
1267 return NULL;
1268 }
1269
1270 DPRINT("hScm = %p\n", hScm);
1271
1272 return hScm;
1273 }
1274
1275
1276 /**********************************************************************
1277 * OpenSCManagerW
1278 *
1279 * @implemented
1280 */
1281 SC_HANDLE STDCALL
1282 OpenSCManagerW(LPCWSTR lpMachineName,
1283 LPCWSTR lpDatabaseName,
1284 DWORD dwDesiredAccess)
1285 {
1286 SC_HANDLE hScm = NULL;
1287 DWORD dwError;
1288
1289 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
1290 lpMachineName, lpDatabaseName, dwDesiredAccess);
1291
1292 WaitForSCManager();
1293
1294 HandleBind();
1295
1296 /* Call to services.exe using RPC */
1297 dwError = ScmrOpenSCManagerW(BindingHandle,
1298 (LPWSTR)lpMachineName,
1299 (LPWSTR)lpDatabaseName,
1300 dwDesiredAccess,
1301 (unsigned int*)&hScm);
1302 if (dwError != ERROR_SUCCESS)
1303 {
1304 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
1305 SetLastError(dwError);
1306 return NULL;
1307 }
1308
1309 DPRINT("hScm = %p\n", hScm);
1310
1311 return hScm;
1312 }
1313
1314
1315 /**********************************************************************
1316 * OpenServiceA
1317 *
1318 * @implemented
1319 */
1320 SC_HANDLE STDCALL
1321 OpenServiceA(SC_HANDLE hSCManager,
1322 LPCSTR lpServiceName,
1323 DWORD dwDesiredAccess)
1324 {
1325 SC_HANDLE hService = NULL;
1326 DWORD dwError;
1327
1328 DPRINT("OpenServiceA(%p, %s, %lx)\n",
1329 hSCManager, lpServiceName, dwDesiredAccess);
1330
1331 HandleBind();
1332
1333 /* Call to services.exe using RPC */
1334 dwError = ScmrOpenServiceA(BindingHandle,
1335 (unsigned int)hSCManager,
1336 (LPSTR)lpServiceName,
1337 dwDesiredAccess,
1338 (unsigned int*)&hService);
1339 if (dwError != ERROR_SUCCESS)
1340 {
1341 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
1342 SetLastError(dwError);
1343 return NULL;
1344 }
1345
1346 DPRINT("hService = %p\n", hService);
1347
1348 return hService;
1349 }
1350
1351
1352 /**********************************************************************
1353 * OpenServiceW
1354 *
1355 * @implemented
1356 */
1357 SC_HANDLE STDCALL
1358 OpenServiceW(SC_HANDLE hSCManager,
1359 LPCWSTR lpServiceName,
1360 DWORD dwDesiredAccess)
1361 {
1362 SC_HANDLE hService = NULL;
1363 DWORD dwError;
1364
1365 DPRINT("OpenServiceW(%p, %S, %lx)\n",
1366 hSCManager, lpServiceName, dwDesiredAccess);
1367
1368 HandleBind();
1369
1370 /* Call to services.exe using RPC */
1371 dwError = ScmrOpenServiceW(BindingHandle,
1372 (unsigned int)hSCManager,
1373 (LPWSTR)lpServiceName,
1374 dwDesiredAccess,
1375 (unsigned int*)&hService);
1376 if (dwError != ERROR_SUCCESS)
1377 {
1378 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError);
1379 SetLastError(dwError);
1380 return NULL;
1381 }
1382
1383 DPRINT("hService = %p\n", hService);
1384
1385 return hService;
1386 }
1387
1388
1389 /**********************************************************************
1390 * QueryServiceConfigA
1391 *
1392 * @implemented
1393 */
1394 BOOL STDCALL
1395 QueryServiceConfigA(SC_HANDLE hService,
1396 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
1397 DWORD cbBufSize,
1398 LPDWORD pcbBytesNeeded)
1399 {
1400 DWORD dwError;
1401
1402 DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1403 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1404
1405 HandleBind();
1406
1407 /* Call to services.exe using RPC */
1408 dwError = ScmrQueryServiceConfigA(BindingHandle,
1409 (unsigned int)hService,
1410 (unsigned char *)lpServiceConfig,
1411 cbBufSize,
1412 pcbBytesNeeded);
1413 if (dwError != ERROR_SUCCESS)
1414 {
1415 DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError);
1416 SetLastError(dwError);
1417 return FALSE;
1418 }
1419
1420 /* Adjust the pointers */
1421 if (lpServiceConfig->lpBinaryPathName)
1422 lpServiceConfig->lpBinaryPathName =
1423 (LPSTR)((ULONG_PTR)lpServiceConfig +
1424 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1425
1426 if (lpServiceConfig->lpLoadOrderGroup)
1427 lpServiceConfig->lpLoadOrderGroup =
1428 (LPSTR)((ULONG_PTR)lpServiceConfig +
1429 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1430
1431 if (lpServiceConfig->lpDependencies)
1432 lpServiceConfig->lpDependencies =
1433 (LPSTR)((ULONG_PTR)lpServiceConfig +
1434 (ULONG_PTR)lpServiceConfig->lpDependencies);
1435
1436 if (lpServiceConfig->lpServiceStartName)
1437 lpServiceConfig->lpServiceStartName =
1438 (LPSTR)((ULONG_PTR)lpServiceConfig +
1439 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1440
1441 if (lpServiceConfig->lpDisplayName)
1442 lpServiceConfig->lpDisplayName =
1443 (LPSTR)((ULONG_PTR)lpServiceConfig +
1444 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1445
1446 DPRINT("QueryServiceConfigA() done\n");
1447
1448 return TRUE;
1449 }
1450
1451
1452 /**********************************************************************
1453 * QueryServiceConfigW
1454 *
1455 * @implemented
1456 */
1457 BOOL STDCALL
1458 QueryServiceConfigW(SC_HANDLE hService,
1459 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1460 DWORD cbBufSize,
1461 LPDWORD pcbBytesNeeded)
1462 {
1463 DWORD dwError;
1464
1465 DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1466 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1467
1468 HandleBind();
1469
1470 /* Call to services.exe using RPC */
1471 dwError = ScmrQueryServiceConfigW(BindingHandle,
1472 (unsigned int)hService,
1473 (unsigned char *)lpServiceConfig,
1474 cbBufSize,
1475 pcbBytesNeeded);
1476 if (dwError != ERROR_SUCCESS)
1477 {
1478 DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
1479 SetLastError(dwError);
1480 return FALSE;
1481 }
1482
1483 /* Adjust the pointers */
1484 if (lpServiceConfig->lpBinaryPathName)
1485 lpServiceConfig->lpBinaryPathName =
1486 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1487 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1488
1489 if (lpServiceConfig->lpLoadOrderGroup)
1490 lpServiceConfig->lpLoadOrderGroup =
1491 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1492 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1493
1494 if (lpServiceConfig->lpDependencies)
1495 lpServiceConfig->lpDependencies =
1496 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1497 (ULONG_PTR)lpServiceConfig->lpDependencies);
1498
1499 if (lpServiceConfig->lpServiceStartName)
1500 lpServiceConfig->lpServiceStartName =
1501 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1502 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1503
1504 if (lpServiceConfig->lpDisplayName)
1505 lpServiceConfig->lpDisplayName =
1506 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1507 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1508
1509 DPRINT("QueryServiceConfigW() done\n");
1510
1511 return TRUE;
1512 }
1513
1514
1515 /**********************************************************************
1516 * QueryServiceConfig2A
1517 *
1518 * @implemented
1519 */
1520 BOOL STDCALL
1521 QueryServiceConfig2A(SC_HANDLE hService,
1522 DWORD dwInfoLevel,
1523 LPBYTE lpBuffer,
1524 DWORD cbBufSize,
1525 LPDWORD pcbBytesNeeded)
1526 {
1527 DWORD dwError;
1528
1529 DPRINT("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
1530 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1531
1532 HandleBind();
1533
1534 /* Call to services.exe using RPC */
1535 dwError = ScmrQueryServiceConfig2A(BindingHandle,
1536 (unsigned int)hService,
1537 dwInfoLevel,
1538 (unsigned char *)lpBuffer,
1539 cbBufSize,
1540 pcbBytesNeeded);
1541 if (dwError != ERROR_SUCCESS)
1542 {
1543 DPRINT("ScmrQueryServiceConfig2A() failed (Error %lu)\n", dwError);
1544 SetLastError(dwError);
1545 return FALSE;
1546 }
1547
1548 switch (dwInfoLevel)
1549 {
1550 case SERVICE_CONFIG_DESCRIPTION:
1551 {
1552 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
1553
1554 if (lpPtr->lpDescription != NULL)
1555 lpPtr->lpDescription =
1556 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1557 }
1558 break;
1559
1560 case SERVICE_CONFIG_FAILURE_ACTIONS:
1561 {
1562 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
1563
1564 if (lpPtr->lpRebootMsg != NULL)
1565 lpPtr->lpRebootMsg =
1566 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1567
1568 if (lpPtr->lpCommand != NULL)
1569 lpPtr->lpCommand =
1570 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1571
1572 if (lpPtr->lpsaActions != NULL)
1573 lpPtr->lpsaActions =
1574 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1575 }
1576 break;
1577
1578 default:
1579 DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
1580 SetLastError(ERROR_INVALID_PARAMETER);
1581 return FALSE;
1582 }
1583
1584 DPRINT("QueryServiceConfig2A() done\n");
1585
1586 return TRUE;
1587 }
1588
1589
1590 /**********************************************************************
1591 * QueryServiceConfig2W
1592 *
1593 * @implemented
1594 */
1595 BOOL STDCALL
1596 QueryServiceConfig2W(SC_HANDLE hService,
1597 DWORD dwInfoLevel,
1598 LPBYTE lpBuffer,
1599 DWORD cbBufSize,
1600 LPDWORD pcbBytesNeeded)
1601 {
1602 DWORD dwError;
1603
1604 DPRINT("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
1605 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
1606
1607 HandleBind();
1608
1609 /* Call to services.exe using RPC */
1610 dwError = ScmrQueryServiceConfig2W(BindingHandle,
1611 (unsigned int)hService,
1612 dwInfoLevel,
1613 (unsigned char *)lpBuffer,
1614 cbBufSize,
1615 pcbBytesNeeded);
1616 if (dwError != ERROR_SUCCESS)
1617 {
1618 DPRINT("ScmrQueryServiceConfig2W() failed (Error %lu)\n", dwError);
1619 SetLastError(dwError);
1620 return FALSE;
1621 }
1622
1623 switch (dwInfoLevel)
1624 {
1625 case SERVICE_CONFIG_DESCRIPTION:
1626 {
1627 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
1628
1629 if (lpPtr->lpDescription != NULL)
1630 lpPtr->lpDescription =
1631 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
1632 }
1633 break;
1634
1635 case SERVICE_CONFIG_FAILURE_ACTIONS:
1636 {
1637 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
1638
1639 if (lpPtr->lpRebootMsg != NULL)
1640 lpPtr->lpRebootMsg =
1641 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
1642
1643 if (lpPtr->lpCommand != NULL)
1644 lpPtr->lpCommand =
1645 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
1646
1647 if (lpPtr->lpsaActions != NULL)
1648 lpPtr->lpsaActions =
1649 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
1650 }
1651 break;
1652
1653 default:
1654 DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
1655 SetLastError(ERROR_INVALID_PARAMETER);
1656 return FALSE;
1657 }
1658
1659 DPRINT("QueryServiceConfig2W() done\n");
1660
1661 return TRUE;
1662 }
1663
1664
1665 /**********************************************************************
1666 * QueryServiceLockStatusA
1667 *
1668 * @unimplemented
1669 */
1670 BOOL
1671 STDCALL
1672 QueryServiceLockStatusA(
1673 SC_HANDLE hSCManager,
1674 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
1675 DWORD cbBufSize,
1676 LPDWORD pcbBytesNeeded)
1677 {
1678 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1679 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1680 return FALSE;
1681 }
1682
1683
1684 /**********************************************************************
1685 * QueryServiceLockStatusW
1686 *
1687 * @unimplemented
1688 */
1689 BOOL
1690 STDCALL
1691 QueryServiceLockStatusW(
1692 SC_HANDLE hSCManager,
1693 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
1694 DWORD cbBufSize,
1695 LPDWORD pcbBytesNeeded)
1696 {
1697 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1698 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1699 return FALSE;
1700 }
1701
1702
1703 /**********************************************************************
1704 * QueryServiceObjectSecurity
1705 *
1706 * @implemented
1707 */
1708 BOOL STDCALL
1709 QueryServiceObjectSecurity(SC_HANDLE hService,
1710 SECURITY_INFORMATION dwSecurityInformation,
1711 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
1712 DWORD cbBufSize,
1713 LPDWORD pcbBytesNeeded)
1714 {
1715 DWORD dwError;
1716
1717 DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
1718 hService, dwSecurityInformation, lpSecurityDescriptor);
1719
1720 HandleBind();
1721
1722 /* Call to services.exe using RPC */
1723 dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
1724 (unsigned int)hService,
1725 dwSecurityInformation,
1726 (unsigned char *)lpSecurityDescriptor,
1727 cbBufSize,
1728 pcbBytesNeeded);
1729 if (dwError != ERROR_SUCCESS)
1730 {
1731 DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
1732 SetLastError(dwError);
1733 return FALSE;
1734 }
1735
1736 return TRUE;
1737 }
1738
1739
1740 /**********************************************************************
1741 * QueryServiceStatus
1742 *
1743 * @implemented
1744 */
1745 BOOL STDCALL
1746 QueryServiceStatus(SC_HANDLE hService,
1747 LPSERVICE_STATUS lpServiceStatus)
1748 {
1749 DWORD dwError;
1750
1751 DPRINT("QueryServiceStatus(%p, %p)\n",
1752 hService, lpServiceStatus);
1753
1754 HandleBind();
1755
1756 /* Call to services.exe using RPC */
1757 dwError = ScmrQueryServiceStatus(BindingHandle,
1758 (unsigned int)hService,
1759 lpServiceStatus);
1760 if (dwError != ERROR_SUCCESS)
1761 {
1762 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
1763 SetLastError(dwError);
1764 return FALSE;
1765 }
1766
1767 return TRUE;
1768 }
1769
1770
1771 /**********************************************************************
1772 * QueryServiceStatusEx
1773 *
1774 * @implemented
1775 */
1776 BOOL STDCALL
1777 QueryServiceStatusEx(SC_HANDLE hService,
1778 SC_STATUS_TYPE InfoLevel,
1779 LPBYTE lpBuffer,
1780 DWORD cbBufSize,
1781 LPDWORD pcbBytesNeeded)
1782 {
1783 DWORD dwError;
1784
1785 DPRINT("QueryServiceStatusEx() called\n");
1786
1787 HandleBind();
1788
1789 /* Call to services.exe using RPC */
1790 dwError = ScmrQueryServiceStatusEx(BindingHandle,
1791 (unsigned int)hService,
1792 InfoLevel,
1793 lpBuffer,
1794 cbBufSize,
1795 pcbBytesNeeded);
1796 if (dwError != ERROR_SUCCESS)
1797 {
1798 DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
1799 SetLastError(dwError);
1800 return FALSE;
1801 }
1802
1803 return TRUE;
1804 }
1805
1806
1807 /**********************************************************************
1808 * SetServiceObjectSecurity
1809 *
1810 * @implemented
1811 */
1812 BOOL STDCALL
1813 SetServiceObjectSecurity(SC_HANDLE hService,
1814 SECURITY_INFORMATION dwSecurityInformation,
1815 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
1816 {
1817 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
1818 ULONG Length;
1819 NTSTATUS Status;
1820 DWORD dwError;
1821
1822 Length = 0;
1823 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
1824 SelfRelativeSD,
1825 &Length);
1826 if (Status != STATUS_BUFFER_TOO_SMALL)
1827 {
1828 SetLastError(ERROR_INVALID_PARAMETER);
1829 return FALSE;
1830 }
1831
1832 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
1833 if (SelfRelativeSD == NULL)
1834 {
1835 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1836 return FALSE;
1837 }
1838
1839 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
1840 SelfRelativeSD,
1841 &Length);
1842 if (!NT_SUCCESS(Status))
1843 {
1844 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
1845 SetLastError(RtlNtStatusToDosError(Status));
1846 return FALSE;
1847 }
1848
1849 HandleBind();
1850
1851 /* Call to services.exe using RPC */
1852 dwError = ScmrSetServiceObjectSecurity(BindingHandle,
1853 (unsigned int)hService,
1854 dwSecurityInformation,
1855 (unsigned char *)SelfRelativeSD,
1856 Length);
1857
1858 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
1859
1860 if (dwError != ERROR_SUCCESS)
1861 {
1862 DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
1863 SetLastError(dwError);
1864 return FALSE;
1865 }
1866
1867 return TRUE;
1868 }
1869
1870
1871 /**********************************************************************
1872 * StartServiceA
1873 *
1874 * @implemented
1875 */
1876 BOOL STDCALL
1877 StartServiceA(SC_HANDLE hService,
1878 DWORD dwNumServiceArgs,
1879 LPCSTR *lpServiceArgVectors)
1880 {
1881 #if 0
1882 DWORD dwError;
1883
1884 DPRINT("StartServiceA()\n");
1885
1886 HandleBind();
1887
1888 /* Call to services.exe using RPC */
1889 dwError = ScmrStartServiceA(BindingHandle,
1890 hService,
1891 dwNumServiceArgs,
1892 lpServiceArgVectors);
1893 if (dwError != ERROR_SUCCESS)
1894 {
1895 DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError);
1896 SetLastError(dwError);
1897 return FALSE;
1898 }
1899
1900 return TRUE;
1901 #endif
1902 LPSTR lpBuffer;
1903 LPSTR lpStr;
1904 DWORD dwError;
1905 DWORD dwBufSize;
1906 DWORD i;
1907
1908 dwBufSize = 0;
1909 for (i = 0; i < dwNumServiceArgs; i++)
1910 {
1911 dwBufSize += (strlen(lpServiceArgVectors[i]) + 1);
1912 }
1913 DPRINT1("dwBufSize: %lu\n", dwBufSize);
1914
1915 lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
1916 if (lpBuffer == NULL)
1917 {
1918 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1919 return FALSE;
1920 }
1921
1922 lpStr = lpBuffer;
1923 for (i = 0; i < dwNumServiceArgs; i++)
1924 {
1925 strcpy(lpStr, lpServiceArgVectors[i]);
1926 lpStr += (strlen(lpServiceArgVectors[i]) + 1);
1927 }
1928
1929 dwError = ScmrStartServiceA(BindingHandle,
1930 (unsigned int)hService,
1931 dwNumServiceArgs,
1932 (unsigned char *)lpBuffer,
1933 dwBufSize);
1934
1935 HeapFree(GetProcessHeap(), 0, lpBuffer);
1936
1937 if (dwError != ERROR_SUCCESS)
1938 {
1939 DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError);
1940 SetLastError(dwError);
1941 return FALSE;
1942 }
1943
1944 return TRUE;
1945 }
1946
1947
1948 /**********************************************************************
1949 * StartServiceW
1950 *
1951 * @implemented
1952 */
1953 BOOL STDCALL
1954 StartServiceW(SC_HANDLE hService,
1955 DWORD dwNumServiceArgs,
1956 LPCWSTR *lpServiceArgVectors)
1957 {
1958 #if 0
1959 DWORD dwError;
1960
1961 DPRINT("StartServiceW()\n");
1962
1963 HandleBind();
1964
1965 /* Call to services.exe using RPC */
1966 dwError = ScmrStartServiceW(BindingHandle,
1967 hService,
1968 dwNumServiceArgs,
1969 lpServiceArgVectors);
1970 if (dwError != ERROR_SUCCESS)
1971 {
1972 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
1973 SetLastError(dwError);
1974 return FALSE;
1975 }
1976
1977 return TRUE;
1978 #endif
1979 LPWSTR lpBuffer;
1980 LPWSTR lpStr;
1981 DWORD dwError;
1982 DWORD dwBufSize;
1983 DWORD i;
1984
1985 dwBufSize = 0;
1986 for (i = 0; i < dwNumServiceArgs; i++)
1987 {
1988 dwBufSize += ((wcslen(lpServiceArgVectors[i]) + 1) * sizeof(WCHAR));
1989 }
1990 DPRINT1("dwBufSize: %lu\n", dwBufSize);
1991
1992 lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
1993 if (lpBuffer == NULL)
1994 {
1995 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1996 return FALSE;
1997 }
1998
1999 lpStr = lpBuffer;
2000 for (i = 0; i < dwNumServiceArgs; i++)
2001 {
2002 wcscpy(lpStr, lpServiceArgVectors[i]);
2003 lpStr += (wcslen(lpServiceArgVectors[i]) + 1);
2004 }
2005
2006 dwError = ScmrStartServiceW(BindingHandle,
2007 (unsigned int)hService,
2008 dwNumServiceArgs,
2009 (unsigned char *)lpBuffer,
2010 dwBufSize);
2011
2012 HeapFree(GetProcessHeap(), 0, lpBuffer);
2013
2014 if (dwError != ERROR_SUCCESS)
2015 {
2016 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
2017 SetLastError(dwError);
2018 return FALSE;
2019 }
2020
2021 return TRUE;
2022 }
2023
2024
2025 /**********************************************************************
2026 * UnlockServiceDatabase
2027 *
2028 * @implemented
2029 */
2030 BOOL STDCALL
2031 UnlockServiceDatabase(SC_LOCK ScLock)
2032 {
2033 DWORD dwError;
2034
2035 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
2036
2037 HandleBind();
2038
2039 /* Call to services.exe using RPC */
2040 dwError = ScmrUnlockServiceDatabase(BindingHandle,
2041 (unsigned int)ScLock);
2042 if (dwError != ERROR_SUCCESS)
2043 {
2044 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
2045 SetLastError(dwError);
2046 return FALSE;
2047 }
2048
2049 return TRUE;
2050 }
2051
2052
2053 /**********************************************************************
2054 * NotifyBootConfigStatus
2055 *
2056 * @implemented
2057 */
2058 BOOL STDCALL
2059 NotifyBootConfigStatus(BOOL BootAcceptable)
2060 {
2061 DWORD dwError;
2062
2063 DPRINT1("NotifyBootConfigStatus()\n");
2064
2065 HandleBind();
2066
2067 /* Call to services.exe using RPC */
2068 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
2069 BootAcceptable);
2070 if (dwError != ERROR_SUCCESS)
2071 {
2072 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
2073 SetLastError(dwError);
2074 return FALSE;
2075 }
2076
2077 return TRUE;
2078 }
2079
2080
2081 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
2082 {
2083 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
2084 }
2085
2086
2087 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
2088 {
2089 HeapFree(GetProcessHeap(), 0, ptr);
2090 }
2091
2092 /* EOF */