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