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