61cad8b254b5f940c87d28aaddb099bf29b19bb6
[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 * ChangeServiceConfigA
82 *
83 * @unimplemented
84 */
85 BOOL
86 STDCALL
87 ChangeServiceConfigA(
88 SC_HANDLE hService,
89 DWORD dwServiceType,
90 DWORD dwStartType,
91 DWORD dwErrorControl,
92 LPCSTR lpBinaryPathName,
93 LPCSTR lpLoadOrderGroup,
94 LPDWORD lpdwTagId,
95 LPCSTR lpDependencies,
96 LPCSTR lpServiceStartName,
97 LPCSTR lpPassword,
98 LPCSTR lpDisplayName)
99 {
100 DPRINT1("ChangeServiceConfigA is unimplemented\n");
101 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
102 return FALSE;
103 }
104
105
106 /**********************************************************************
107 * ChangeServiceConfigW
108 *
109 * @implemented
110 */
111 BOOL STDCALL
112 ChangeServiceConfigW(SC_HANDLE hService,
113 DWORD dwServiceType,
114 DWORD dwStartType,
115 DWORD dwErrorControl,
116 LPCWSTR lpBinaryPathName,
117 LPCWSTR lpLoadOrderGroup,
118 LPDWORD lpdwTagId,
119 LPCWSTR lpDependencies,
120 LPCWSTR lpServiceStartName,
121 LPCWSTR lpPassword,
122 LPCWSTR lpDisplayName)
123 {
124 #if 0 /* Temporarily deactivated to fix the build (ScmrChangeServiceConfigW is missing */
125 DWORD dwError;
126 DWORD dwDependenciesLength = 0;
127 DWORD dwLength;
128 LPWSTR lpStr;
129
130 DPRINT1("ChangeServiceConfigW() called\n");
131
132 /* Calculate the Dependencies length*/
133 if (lpDependencies != NULL)
134 {
135 lpStr = (LPWSTR)lpDependencies;
136 while (*lpStr)
137 {
138 dwLength = wcslen(lpStr) + 1;
139 dwDependenciesLength += dwLength;
140 lpStr = lpStr + dwLength;
141 }
142 dwDependenciesLength++;
143 }
144
145 /* FIXME: Encrypt the password */
146
147 HandleBind();
148
149 /* Call to services.exe using RPC */
150 dwError = ScmrChangeServiceConfigW(BindingHandle,
151 (unsigned int)hService,
152 dwServiceType,
153 dwStartType,
154 dwErrorControl,
155 (LPWSTR)lpBinaryPathName,
156 (LPWSTR)lpLoadOrderGroup,
157 lpdwTagId,
158 (LPWSTR)lpDependencies,
159 dwDependenciesLength,
160 (LPWSTR)lpServiceStartName,
161 NULL, /* FIXME: lpPassword */
162 0, /* FIXME: dwPasswordLength */
163 (LPWSTR)lpDisplayName);
164 if (dwError != ERROR_SUCCESS)
165 {
166 DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
167 SetLastError(dwError);
168 return FALSE;
169 }
170
171 return TRUE;
172 #else
173 DPRINT1("ChangeServiceConfigW temporarily disabled\n");
174 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
175 return FALSE;
176 #endif
177 }
178
179
180 /**********************************************************************
181 * CloseServiceHandle
182 *
183 * @implemented
184 */
185 BOOL STDCALL
186 CloseServiceHandle(SC_HANDLE hSCObject)
187 {
188 DWORD dwError;
189
190 DPRINT("CloseServiceHandle() called\n");
191
192 HandleBind();
193
194 /* Call to services.exe using RPC */
195 dwError = ScmrCloseServiceHandle(BindingHandle,
196 (unsigned int)hSCObject);
197 if (dwError)
198 {
199 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError);
200 SetLastError(dwError);
201 return FALSE;
202 }
203
204 DPRINT("CloseServiceHandle() done\n");
205
206 return TRUE;
207 }
208
209
210 /**********************************************************************
211 * ControlService
212 *
213 * @unimplemented
214 */
215 BOOL STDCALL
216 ControlService(SC_HANDLE hService,
217 DWORD dwControl,
218 LPSERVICE_STATUS lpServiceStatus)
219 {
220 DWORD dwError;
221
222 DPRINT("ControlService(%x, %x, %p)\n",
223 hService, dwControl, lpServiceStatus);
224
225 HandleBind();
226
227 /* Call to services.exe using RPC */
228 dwError = ScmrControlService(BindingHandle,
229 (unsigned int)hService,
230 dwControl,
231 lpServiceStatus);
232 if (dwError != ERROR_SUCCESS)
233 {
234 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError);
235 SetLastError(dwError);
236 return FALSE;
237 }
238
239 DPRINT("ControlService() done\n");
240
241 return TRUE;
242 }
243
244
245 /**********************************************************************
246 * ControlServiceEx
247 *
248 * @unimplemented
249 */
250 BOOL STDCALL
251 ControlServiceEx(IN SC_HANDLE hService,
252 IN DWORD dwControl,
253 IN DWORD dwInfoLevel,
254 IN OUT PVOID pControlParams)
255 {
256 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
257 hService, dwControl, dwInfoLevel, pControlParams);
258 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
259 return FALSE;
260 }
261
262
263
264 /**********************************************************************
265 * CreateServiceA
266 *
267 * @unimplemented
268 */
269 SC_HANDLE
270 STDCALL
271 CreateServiceA(
272 SC_HANDLE hSCManager,
273 LPCSTR lpServiceName,
274 LPCSTR lpDisplayName,
275 DWORD dwDesiredAccess,
276 DWORD dwServiceType,
277 DWORD dwStartType,
278 DWORD dwErrorControl,
279 LPCSTR lpBinaryPathName,
280 LPCSTR lpLoadOrderGroup,
281 LPDWORD lpdwTagId,
282 LPCSTR lpDependencies,
283 LPCSTR lpServiceStartName,
284 LPCSTR lpPassword)
285 {
286 DPRINT1("CreateServiceA is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
287 return INVALID_HANDLE_VALUE;
288 }
289
290
291 /**********************************************************************
292 * CreateServiceW
293 *
294 * @implemented
295 */
296 SC_HANDLE STDCALL
297 CreateServiceW(SC_HANDLE hSCManager,
298 LPCWSTR lpServiceName,
299 LPCWSTR lpDisplayName,
300 DWORD dwDesiredAccess,
301 DWORD dwServiceType,
302 DWORD dwStartType,
303 DWORD dwErrorControl,
304 LPCWSTR lpBinaryPathName,
305 LPCWSTR lpLoadOrderGroup,
306 LPDWORD lpdwTagId,
307 LPCWSTR lpDependencies,
308 LPCWSTR lpServiceStartName,
309 LPCWSTR lpPassword)
310 {
311 SC_HANDLE hService = NULL;
312 DWORD dwError;
313 DWORD dwDependenciesLength = 0;
314 DWORD dwLength;
315 LPWSTR lpStr;
316
317 DPRINT1("CreateServiceW() called\n");
318
319 /* Calculate the Dependencies length*/
320 if (lpDependencies != NULL)
321 {
322 lpStr = (LPWSTR)lpDependencies;
323 while (*lpStr)
324 {
325 dwLength = wcslen(lpStr) + 1;
326 dwDependenciesLength += dwLength;
327 lpStr = lpStr + dwLength;
328 }
329 dwDependenciesLength++;
330 }
331
332 /* FIXME: Encrypt the password */
333
334 HandleBind();
335
336 /* Call to services.exe using RPC */
337 dwError = ScmrCreateServiceW(BindingHandle,
338 (unsigned int)hSCManager,
339 (LPWSTR)lpServiceName,
340 (LPWSTR)lpDisplayName,
341 dwDesiredAccess,
342 dwServiceType,
343 dwStartType,
344 dwErrorControl,
345 (LPWSTR)lpBinaryPathName,
346 (LPWSTR)lpLoadOrderGroup,
347 lpdwTagId,
348 (LPWSTR)lpDependencies,
349 dwDependenciesLength,
350 (LPWSTR)lpServiceStartName,
351 NULL, /* FIXME: lpPassword */
352 0, /* FIXME: dwPasswordLength */
353 (unsigned int *)&hService);
354 if (dwError != ERROR_SUCCESS)
355 {
356 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
357 SetLastError(dwError);
358 return INVALID_HANDLE_VALUE;
359 }
360
361 return hService;
362 }
363
364
365 /**********************************************************************
366 * DeleteService
367 *
368 * @implemented
369 */
370 BOOL STDCALL
371 DeleteService(SC_HANDLE hService)
372 {
373 DWORD dwError;
374
375 DPRINT("DeleteService(%x)\n", hService);
376
377 HandleBind();
378
379 /* Call to services.exe using RPC */
380 dwError = ScmrDeleteService(BindingHandle,
381 (unsigned int)hService);
382 if (dwError != ERROR_SUCCESS)
383 {
384 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError);
385 SetLastError(dwError);
386 return FALSE;
387 }
388
389 return TRUE;
390 }
391
392
393 /**********************************************************************
394 * EnumDependentServicesA
395 *
396 * @unimplemented
397 */
398 BOOL
399 STDCALL
400 EnumDependentServicesA(
401 SC_HANDLE hService,
402 DWORD dwServiceState,
403 LPENUM_SERVICE_STATUSA lpServices,
404 DWORD cbBufSize,
405 LPDWORD pcbBytesNeeded,
406 LPDWORD lpServicesReturned)
407 {
408 DPRINT1("EnumDependentServicesA is unimplemented\n");
409 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
410 return FALSE;
411 }
412
413
414 /**********************************************************************
415 * EnumDependentServicesW
416 *
417 * @unimplemented
418 */
419 BOOL
420 STDCALL
421 EnumDependentServicesW(
422 SC_HANDLE hService,
423 DWORD dwServiceState,
424 LPENUM_SERVICE_STATUSW lpServices,
425 DWORD cbBufSize,
426 LPDWORD pcbBytesNeeded,
427 LPDWORD lpServicesReturned)
428 {
429 DPRINT1("EnumDependentServicesW is unimplemented\n");
430 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
431 return FALSE;
432 }
433
434
435 /**********************************************************************
436 * EnumServiceGroupW
437 *
438 * @unimplemented
439 */
440 BOOL
441 STDCALL
442 EnumServiceGroupW (
443 DWORD Unknown0,
444 DWORD Unknown1,
445 DWORD Unknown2,
446 DWORD Unknown3,
447 DWORD Unknown4,
448 DWORD Unknown5,
449 DWORD Unknown6,
450 DWORD Unknown7,
451 DWORD Unknown8)
452 {
453 DPRINT1("EnumServiceGroupW is unimplemented\n");
454 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
455 return FALSE;
456 }
457
458
459 /**********************************************************************
460 * EnumServicesStatusA
461 *
462 * @unimplemented
463 */
464 BOOL
465 STDCALL
466 EnumServicesStatusA (
467 SC_HANDLE hSCManager,
468 DWORD dwServiceType,
469 DWORD dwServiceState,
470 LPENUM_SERVICE_STATUSA lpServices,
471 DWORD cbBufSize,
472 LPDWORD pcbBytesNeeded,
473 LPDWORD lpServicesReturned,
474 LPDWORD lpResumeHandle)
475 {
476 DPRINT1("EnumServicesStatusA is unimplemented\n");
477 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
478 return FALSE;
479 }
480
481
482 /**********************************************************************
483 * EnumServicesStatusExA
484 *
485 * @unimplemented
486 */
487 BOOL
488 STDCALL
489 EnumServicesStatusExA(SC_HANDLE hSCManager,
490 SC_ENUM_TYPE InfoLevel,
491 DWORD dwServiceType,
492 DWORD dwServiceState,
493 LPBYTE lpServices,
494 DWORD cbBufSize,
495 LPDWORD pcbBytesNeeded,
496 LPDWORD lpServicesReturned,
497 LPDWORD lpResumeHandle,
498 LPCSTR pszGroupName)
499 {
500 DPRINT1("EnumServicesStatusExA is unimplemented\n");
501 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
502 return FALSE;
503 }
504
505
506 /**********************************************************************
507 * EnumServicesStatusExW
508 *
509 * @unimplemented
510 */
511 BOOL
512 STDCALL
513 EnumServicesStatusExW(SC_HANDLE hSCManager,
514 SC_ENUM_TYPE InfoLevel,
515 DWORD dwServiceType,
516 DWORD dwServiceState,
517 LPBYTE lpServices,
518 DWORD cbBufSize,
519 LPDWORD pcbBytesNeeded,
520 LPDWORD lpServicesReturned,
521 LPDWORD lpResumeHandle,
522 LPCWSTR pszGroupName)
523 {
524 DPRINT1("EnumServicesStatusExW is unimplemented\n");
525 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
526 return FALSE;
527 }
528
529
530 /**********************************************************************
531 * EnumServicesStatusW
532 *
533 * @unimplemented
534 */
535 BOOL
536 STDCALL
537 EnumServicesStatusW(
538 SC_HANDLE hSCManager,
539 DWORD dwServiceType,
540 DWORD dwServiceState,
541 LPENUM_SERVICE_STATUSW lpServices,
542 DWORD cbBufSize,
543 LPDWORD pcbBytesNeeded,
544 LPDWORD lpServicesReturned,
545 LPDWORD lpResumeHandle)
546 {
547 DPRINT1("EnumServicesStatusW is unimplemented\n");
548 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
549 return FALSE;
550 }
551
552
553 /**********************************************************************
554 * GetServiceDisplayNameA
555 *
556 * @unimplemented
557 */
558 BOOL
559 STDCALL
560 GetServiceDisplayNameA(
561 SC_HANDLE hSCManager,
562 LPCSTR lpServiceName,
563 LPSTR lpDisplayName,
564 LPDWORD lpcchBuffer)
565 {
566 DPRINT1("GetServiceDisplayNameA is unimplemented\n");
567 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
568 return FALSE;
569 }
570
571
572 /**********************************************************************
573 * GetServiceDisplayNameW
574 *
575 * @unimplemented
576 */
577 BOOL
578 STDCALL
579 GetServiceDisplayNameW(
580 SC_HANDLE hSCManager,
581 LPCWSTR lpServiceName,
582 LPWSTR lpDisplayName,
583 LPDWORD lpcchBuffer)
584 {
585 DPRINT1("GetServiceDisplayNameW is unimplemented\n");
586 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
587 return FALSE;
588 }
589
590
591 /**********************************************************************
592 * GetServiceKeyNameA
593 *
594 * @unimplemented
595 */
596 BOOL
597 STDCALL
598 GetServiceKeyNameA(
599 SC_HANDLE hSCManager,
600 LPCSTR lpDisplayName,
601 LPSTR lpServiceName,
602 LPDWORD lpcchBuffer)
603 {
604 DPRINT1("GetServiceKeyNameA is unimplemented\n");
605 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
606 return FALSE;
607 }
608
609
610 /**********************************************************************
611 * GetServiceKeyNameW
612 *
613 * @unimplemented
614 */
615 BOOL
616 STDCALL
617 GetServiceKeyNameW(
618 SC_HANDLE hSCManager,
619 LPCWSTR lpDisplayName,
620 LPWSTR lpServiceName,
621 LPDWORD lpcchBuffer)
622 {
623 DPRINT1("GetServiceKeyNameW is unimplemented\n");
624 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
625 return FALSE;
626 }
627
628
629 /**********************************************************************
630 * LockServiceDatabase
631 *
632 * @implemented
633 */
634 SC_LOCK STDCALL
635 LockServiceDatabase(SC_HANDLE hSCManager)
636 {
637 SC_LOCK hLock;
638 DWORD dwError;
639
640 DPRINT("LockServiceDatabase(%x)\n", hSCManager);
641
642 HandleBind();
643
644 /* Call to services.exe using RPC */
645 dwError = ScmrLockServiceDatabase(BindingHandle,
646 (unsigned int)hSCManager,
647 (unsigned int *)&hLock);
648 if (dwError != ERROR_SUCCESS)
649 {
650 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
651 SetLastError(dwError);
652 return NULL;
653 }
654
655 DPRINT("hLock = %p\n", hLock);
656
657 return hLock;
658 }
659
660
661 static VOID
662 WaitForSCManager(VOID)
663 {
664 HANDLE hEvent;
665
666 DPRINT("WaitForSCManager() called\n");
667
668 /* Try to open the existing event */
669 hEvent = OpenEventW(SYNCHRONIZE,
670 FALSE,
671 L"SvcctrlStartEvent_A3725DX");
672 if (hEvent == NULL)
673 {
674 if (GetLastError() != ERROR_FILE_NOT_FOUND)
675 return;
676
677 /* Try to create a new event */
678 hEvent = CreateEventW(NULL,
679 TRUE,
680 FALSE,
681 L"SvcctrlStartEvent_A3725DX");
682 if (hEvent == NULL)
683 {
684 /* Try to open the existing event again */
685 hEvent = OpenEventW(SYNCHRONIZE,
686 FALSE,
687 L"SvcctrlStartEvent_A3725DX");
688 if (hEvent == NULL)
689 return;
690 }
691 }
692
693 /* Wait for 3 minutes */
694 WaitForSingleObject(hEvent, 180000);
695 CloseHandle(hEvent);
696
697 DPRINT("ScmWaitForSCManager() done\n");
698 }
699
700
701 /**********************************************************************
702 * OpenSCManagerA
703 *
704 * @implemented
705 */
706 SC_HANDLE STDCALL
707 OpenSCManagerA(LPCSTR lpMachineName,
708 LPCSTR lpDatabaseName,
709 DWORD dwDesiredAccess)
710 {
711 SC_HANDLE hScm = NULL;
712 DWORD dwError;
713
714 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
715 lpMachineName, lpDatabaseName, dwDesiredAccess);
716
717 WaitForSCManager();
718
719 HandleBind();
720
721 /* Call to services.exe using RPC */
722 dwError = ScmrOpenSCManagerA(BindingHandle,
723 (LPSTR)lpMachineName,
724 (LPSTR)lpDatabaseName,
725 dwDesiredAccess,
726 (unsigned int*)&hScm);
727 if (dwError != ERROR_SUCCESS)
728 {
729 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
730 SetLastError(dwError);
731 return NULL;
732 }
733
734 DPRINT("hScm = %p\n", hScm);
735
736 return hScm;
737 }
738
739
740 /**********************************************************************
741 * OpenSCManagerW
742 *
743 * @implemented
744 */
745 SC_HANDLE STDCALL
746 OpenSCManagerW(LPCWSTR lpMachineName,
747 LPCWSTR lpDatabaseName,
748 DWORD dwDesiredAccess)
749 {
750 SC_HANDLE hScm = NULL;
751 DWORD dwError;
752
753 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
754 lpMachineName, lpDatabaseName, dwDesiredAccess);
755
756 WaitForSCManager();
757
758 HandleBind();
759
760 /* Call to services.exe using RPC */
761 dwError = ScmrOpenSCManagerW(BindingHandle,
762 (LPWSTR)lpMachineName,
763 (LPWSTR)lpDatabaseName,
764 dwDesiredAccess,
765 (unsigned int*)&hScm);
766 if (dwError != ERROR_SUCCESS)
767 {
768 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
769 SetLastError(dwError);
770 return NULL;
771 }
772
773 DPRINT("hScm = %p\n", hScm);
774
775 return hScm;
776 }
777
778
779 /**********************************************************************
780 * OpenServiceA
781 *
782 * @implemented
783 */
784 SC_HANDLE STDCALL
785 OpenServiceA(SC_HANDLE hSCManager,
786 LPCSTR lpServiceName,
787 DWORD dwDesiredAccess)
788 {
789 SC_HANDLE hService = NULL;
790 DWORD dwError;
791
792 DPRINT("OpenServiceA(%p, %s, %lx)\n",
793 hSCManager, lpServiceName, dwDesiredAccess);
794
795 HandleBind();
796
797 /* Call to services.exe using RPC */
798 dwError = ScmrOpenServiceA(BindingHandle,
799 (unsigned int)hSCManager,
800 (LPSTR)lpServiceName,
801 dwDesiredAccess,
802 (unsigned int*)&hService);
803 if (dwError != ERROR_SUCCESS)
804 {
805 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
806 SetLastError(dwError);
807 return NULL;
808 }
809
810 DPRINT("hService = %p\n", hService);
811
812 return hService;
813 }
814
815
816 /**********************************************************************
817 * OpenServiceW
818 *
819 * @implemented
820 */
821 SC_HANDLE STDCALL
822 OpenServiceW(SC_HANDLE hSCManager,
823 LPCWSTR lpServiceName,
824 DWORD dwDesiredAccess)
825 {
826 SC_HANDLE hService = NULL;
827 DWORD dwError;
828
829 DPRINT("OpenServiceW(%p, %S, %lx)\n",
830 hSCManager, lpServiceName, dwDesiredAccess);
831
832 HandleBind();
833
834 /* Call to services.exe using RPC */
835 dwError = ScmrOpenServiceW(BindingHandle,
836 (unsigned int)hSCManager,
837 (LPWSTR)lpServiceName,
838 dwDesiredAccess,
839 (unsigned int*)&hService);
840 if (dwError != ERROR_SUCCESS)
841 {
842 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError);
843 SetLastError(dwError);
844 return NULL;
845 }
846
847 DPRINT("hService = %p\n", hService);
848
849 return hService;
850 }
851
852
853 /**********************************************************************
854 * QueryServiceConfigA
855 *
856 * @unimplemented
857 */
858 BOOL
859 STDCALL
860 QueryServiceConfigA(
861 SC_HANDLE hService,
862 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
863 DWORD cbBufSize,
864 LPDWORD pcbBytesNeeded)
865 {
866 DPRINT1("QueryServiceConfigA is unimplemented\n");
867 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
868 return FALSE;
869 }
870
871
872 /**********************************************************************
873 * QueryServiceConfigW
874 *
875 * @unimplemented
876 */
877 BOOL
878 STDCALL
879 QueryServiceConfigW(
880 SC_HANDLE hService,
881 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
882 DWORD cbBufSize,
883 LPDWORD pcbBytesNeeded)
884 {
885 DPRINT1("QueryServiceConfigW is unimplemented\n");
886 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
887 return FALSE;
888 }
889
890
891 /**********************************************************************
892 * QueryServiceLockStatusA
893 *
894 * @unimplemented
895 */
896 BOOL
897 STDCALL
898 QueryServiceLockStatusA(
899 SC_HANDLE hSCManager,
900 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
901 DWORD cbBufSize,
902 LPDWORD pcbBytesNeeded)
903 {
904 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
905 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
906 return FALSE;
907 }
908
909
910 /**********************************************************************
911 * QueryServiceLockStatusW
912 *
913 * @unimplemented
914 */
915 BOOL
916 STDCALL
917 QueryServiceLockStatusW(
918 SC_HANDLE hSCManager,
919 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
920 DWORD cbBufSize,
921 LPDWORD pcbBytesNeeded)
922 {
923 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
924 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
925 return FALSE;
926 }
927
928
929 /**********************************************************************
930 * QueryServiceObjectSecurity
931 *
932 * @unimplemented
933 */
934 BOOL
935 STDCALL
936 QueryServiceObjectSecurity(
937 SC_HANDLE hService,
938 SECURITY_INFORMATION dwSecurityInformation,
939 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
940 DWORD cbBufSize,
941 LPDWORD pcbBytesNeeded)
942 {
943 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
944 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
945 return FALSE;
946 }
947
948
949 /**********************************************************************
950 * QueryServiceStatus
951 *
952 * @implemented
953 */
954 BOOL STDCALL
955 QueryServiceStatus(SC_HANDLE hService,
956 LPSERVICE_STATUS lpServiceStatus)
957 {
958 DWORD dwError;
959
960 DPRINT("QueryServiceStatus(%p, %p)\n",
961 hService, lpServiceStatus);
962
963 HandleBind();
964
965 /* Call to services.exe using RPC */
966 dwError = ScmrQueryServiceStatus(BindingHandle,
967 (unsigned int)hService,
968 lpServiceStatus);
969 if (dwError != ERROR_SUCCESS)
970 {
971 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
972 SetLastError(dwError);
973 return FALSE;
974 }
975
976 return TRUE;
977 }
978
979
980 /**********************************************************************
981 * QueryServiceStatusEx
982 *
983 * @unimplemented
984 */
985 BOOL
986 STDCALL
987 QueryServiceStatusEx(SC_HANDLE hService,
988 SC_STATUS_TYPE InfoLevel,
989 LPBYTE lpBuffer,
990 DWORD cbBufSize,
991 LPDWORD pcbBytesNeeded)
992 {
993 DPRINT1("QueryServiceStatusEx is unimplemented\n");
994 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
995 return FALSE;
996 }
997
998
999 /**********************************************************************
1000 * StartServiceA
1001 *
1002 * @unimplemented
1003 */
1004 BOOL
1005 STDCALL
1006 StartServiceA(
1007 SC_HANDLE hService,
1008 DWORD dwNumServiceArgs,
1009 LPCSTR *lpServiceArgVectors)
1010 {
1011 DPRINT1("StartServiceA is unimplemented\n");
1012 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1013 return FALSE;
1014 }
1015
1016
1017 /**********************************************************************
1018 * StartServiceW
1019 *
1020 * @unimplemented
1021 */
1022 BOOL
1023 STDCALL
1024 StartServiceW(
1025 SC_HANDLE hService,
1026 DWORD dwNumServiceArgs,
1027 LPCWSTR *lpServiceArgVectors)
1028 {
1029 DPRINT1("StartServiceW is unimplemented\n");
1030 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1031 return FALSE;
1032 }
1033
1034
1035 /**********************************************************************
1036 * UnlockServiceDatabase
1037 *
1038 * @implemented
1039 */
1040 BOOL STDCALL
1041 UnlockServiceDatabase(SC_LOCK ScLock)
1042 {
1043 DWORD dwError;
1044
1045 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
1046
1047 HandleBind();
1048
1049 /* Call to services.exe using RPC */
1050 dwError = ScmrUnlockServiceDatabase(BindingHandle,
1051 (unsigned int)ScLock);
1052 if (dwError != ERROR_SUCCESS)
1053 {
1054 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
1055 SetLastError(dwError);
1056 return FALSE;
1057 }
1058
1059 return TRUE;
1060 }
1061
1062
1063 /**********************************************************************
1064 * NotifyBootConfigStatus
1065 *
1066 * @implemented
1067 */
1068 BOOL STDCALL
1069 NotifyBootConfigStatus(BOOL BootAcceptable)
1070 {
1071 DWORD dwError;
1072
1073 DPRINT1("NotifyBootConfigStatus()\n");
1074
1075 HandleBind();
1076
1077 /* Call to services.exe using RPC */
1078 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
1079 BootAcceptable);
1080 if (dwError != ERROR_SUCCESS)
1081 {
1082 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
1083 SetLastError(dwError);
1084 return FALSE;
1085 }
1086
1087 return TRUE;
1088 }
1089
1090
1091 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
1092 {
1093 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1094 }
1095
1096
1097 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
1098 {
1099 HeapFree(GetProcessHeap(), 0, ptr);
1100 }
1101
1102 /* EOF */