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