36d0716acb4fe8c36c02dcbd155d351b43ad8920
[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 DPRINT("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 * @implemented
570 */
571 BOOL STDCALL
572 GetServiceDisplayNameW(SC_HANDLE hSCManager,
573 LPCWSTR lpServiceName,
574 LPWSTR lpDisplayName,
575 LPDWORD lpcchBuffer)
576 {
577 DWORD dwError;
578
579 DPRINT("GetServiceDisplayNameW() called\n");
580
581 HandleBind();
582
583 dwError = ScmrGetServiceDisplayNameW(BindingHandle,
584 (unsigned int)hSCManager,
585 (LPWSTR)lpServiceName,
586 lpDisplayName,
587 lpcchBuffer);
588 if (dwError != ERROR_SUCCESS)
589 {
590 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
591 SetLastError(dwError);
592 return FALSE;
593 }
594
595 (*lpcchBuffer)--;
596
597 return TRUE;
598 }
599
600
601 /**********************************************************************
602 * GetServiceKeyNameA
603 *
604 * @unimplemented
605 */
606 BOOL
607 STDCALL
608 GetServiceKeyNameA(
609 SC_HANDLE hSCManager,
610 LPCSTR lpDisplayName,
611 LPSTR lpServiceName,
612 LPDWORD lpcchBuffer)
613 {
614 DPRINT1("GetServiceKeyNameA is unimplemented\n");
615 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
616 return FALSE;
617 }
618
619
620 /**********************************************************************
621 * GetServiceKeyNameW
622 *
623 * @implemented
624 */
625 BOOL STDCALL
626 GetServiceKeyNameW(SC_HANDLE hSCManager,
627 LPCWSTR lpDisplayName,
628 LPWSTR lpServiceName,
629 LPDWORD lpcchBuffer)
630 {
631 DWORD dwError;
632
633 DPRINT("GetServiceKeyNameW() called\n");
634
635 HandleBind();
636
637 dwError = ScmrGetServiceKeyNameW(BindingHandle,
638 (unsigned int)hSCManager,
639 (LPWSTR)lpDisplayName,
640 lpServiceName,
641 lpcchBuffer);
642 if (dwError != ERROR_SUCCESS)
643 {
644 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError);
645 SetLastError(dwError);
646 return FALSE;
647 }
648
649 (*lpcchBuffer)--;
650
651 return TRUE;
652 }
653
654
655 /**********************************************************************
656 * LockServiceDatabase
657 *
658 * @implemented
659 */
660 SC_LOCK STDCALL
661 LockServiceDatabase(SC_HANDLE hSCManager)
662 {
663 SC_LOCK hLock;
664 DWORD dwError;
665
666 DPRINT("LockServiceDatabase(%x)\n", hSCManager);
667
668 HandleBind();
669
670 /* Call to services.exe using RPC */
671 dwError = ScmrLockServiceDatabase(BindingHandle,
672 (unsigned int)hSCManager,
673 (unsigned int *)&hLock);
674 if (dwError != ERROR_SUCCESS)
675 {
676 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
677 SetLastError(dwError);
678 return NULL;
679 }
680
681 DPRINT("hLock = %p\n", hLock);
682
683 return hLock;
684 }
685
686
687 static VOID
688 WaitForSCManager(VOID)
689 {
690 HANDLE hEvent;
691
692 DPRINT("WaitForSCManager() called\n");
693
694 /* Try to open the existing event */
695 hEvent = OpenEventW(SYNCHRONIZE,
696 FALSE,
697 L"SvcctrlStartEvent_A3725DX");
698 if (hEvent == NULL)
699 {
700 if (GetLastError() != ERROR_FILE_NOT_FOUND)
701 return;
702
703 /* Try to create a new event */
704 hEvent = CreateEventW(NULL,
705 TRUE,
706 FALSE,
707 L"SvcctrlStartEvent_A3725DX");
708 if (hEvent == NULL)
709 {
710 /* Try to open the existing event again */
711 hEvent = OpenEventW(SYNCHRONIZE,
712 FALSE,
713 L"SvcctrlStartEvent_A3725DX");
714 if (hEvent == NULL)
715 return;
716 }
717 }
718
719 /* Wait for 3 minutes */
720 WaitForSingleObject(hEvent, 180000);
721 CloseHandle(hEvent);
722
723 DPRINT("ScmWaitForSCManager() done\n");
724 }
725
726
727 /**********************************************************************
728 * OpenSCManagerA
729 *
730 * @implemented
731 */
732 SC_HANDLE STDCALL
733 OpenSCManagerA(LPCSTR lpMachineName,
734 LPCSTR lpDatabaseName,
735 DWORD dwDesiredAccess)
736 {
737 SC_HANDLE hScm = NULL;
738 DWORD dwError;
739
740 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
741 lpMachineName, lpDatabaseName, dwDesiredAccess);
742
743 WaitForSCManager();
744
745 HandleBind();
746
747 /* Call to services.exe using RPC */
748 dwError = ScmrOpenSCManagerA(BindingHandle,
749 (LPSTR)lpMachineName,
750 (LPSTR)lpDatabaseName,
751 dwDesiredAccess,
752 (unsigned int*)&hScm);
753 if (dwError != ERROR_SUCCESS)
754 {
755 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
756 SetLastError(dwError);
757 return NULL;
758 }
759
760 DPRINT("hScm = %p\n", hScm);
761
762 return hScm;
763 }
764
765
766 /**********************************************************************
767 * OpenSCManagerW
768 *
769 * @implemented
770 */
771 SC_HANDLE STDCALL
772 OpenSCManagerW(LPCWSTR lpMachineName,
773 LPCWSTR lpDatabaseName,
774 DWORD dwDesiredAccess)
775 {
776 SC_HANDLE hScm = NULL;
777 DWORD dwError;
778
779 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
780 lpMachineName, lpDatabaseName, dwDesiredAccess);
781
782 WaitForSCManager();
783
784 HandleBind();
785
786 /* Call to services.exe using RPC */
787 dwError = ScmrOpenSCManagerW(BindingHandle,
788 (LPWSTR)lpMachineName,
789 (LPWSTR)lpDatabaseName,
790 dwDesiredAccess,
791 (unsigned int*)&hScm);
792 if (dwError != ERROR_SUCCESS)
793 {
794 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
795 SetLastError(dwError);
796 return NULL;
797 }
798
799 DPRINT("hScm = %p\n", hScm);
800
801 return hScm;
802 }
803
804
805 /**********************************************************************
806 * OpenServiceA
807 *
808 * @implemented
809 */
810 SC_HANDLE STDCALL
811 OpenServiceA(SC_HANDLE hSCManager,
812 LPCSTR lpServiceName,
813 DWORD dwDesiredAccess)
814 {
815 SC_HANDLE hService = NULL;
816 DWORD dwError;
817
818 DPRINT("OpenServiceA(%p, %s, %lx)\n",
819 hSCManager, lpServiceName, dwDesiredAccess);
820
821 HandleBind();
822
823 /* Call to services.exe using RPC */
824 dwError = ScmrOpenServiceA(BindingHandle,
825 (unsigned int)hSCManager,
826 (LPSTR)lpServiceName,
827 dwDesiredAccess,
828 (unsigned int*)&hService);
829 if (dwError != ERROR_SUCCESS)
830 {
831 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
832 SetLastError(dwError);
833 return NULL;
834 }
835
836 DPRINT("hService = %p\n", hService);
837
838 return hService;
839 }
840
841
842 /**********************************************************************
843 * OpenServiceW
844 *
845 * @implemented
846 */
847 SC_HANDLE STDCALL
848 OpenServiceW(SC_HANDLE hSCManager,
849 LPCWSTR lpServiceName,
850 DWORD dwDesiredAccess)
851 {
852 SC_HANDLE hService = NULL;
853 DWORD dwError;
854
855 DPRINT("OpenServiceW(%p, %S, %lx)\n",
856 hSCManager, lpServiceName, dwDesiredAccess);
857
858 HandleBind();
859
860 /* Call to services.exe using RPC */
861 dwError = ScmrOpenServiceW(BindingHandle,
862 (unsigned int)hSCManager,
863 (LPWSTR)lpServiceName,
864 dwDesiredAccess,
865 (unsigned int*)&hService);
866 if (dwError != ERROR_SUCCESS)
867 {
868 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError);
869 SetLastError(dwError);
870 return NULL;
871 }
872
873 DPRINT("hService = %p\n", hService);
874
875 return hService;
876 }
877
878
879 /**********************************************************************
880 * QueryServiceConfigA
881 *
882 * @unimplemented
883 */
884 BOOL
885 STDCALL
886 QueryServiceConfigA(
887 SC_HANDLE hService,
888 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
889 DWORD cbBufSize,
890 LPDWORD pcbBytesNeeded)
891 {
892 DPRINT1("QueryServiceConfigA is unimplemented\n");
893 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
894 return FALSE;
895 }
896
897
898 /**********************************************************************
899 * QueryServiceConfigW
900 *
901 * @unimplemented
902 */
903 BOOL
904 STDCALL
905 QueryServiceConfigW(
906 SC_HANDLE hService,
907 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
908 DWORD cbBufSize,
909 LPDWORD pcbBytesNeeded)
910 {
911 DPRINT1("QueryServiceConfigW is unimplemented\n");
912 if (lpServiceConfig && cbBufSize >= sizeof(QUERY_SERVICE_CONFIGW))
913 {
914 memset(lpServiceConfig, 0, *pcbBytesNeeded);
915 return TRUE;
916 }
917 else
918 {
919 *pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
920 SetLastError(ERROR_INSUFFICIENT_BUFFER);
921 return FALSE;
922 }
923 }
924
925
926 /**********************************************************************
927 * QueryServiceLockStatusA
928 *
929 * @unimplemented
930 */
931 BOOL
932 STDCALL
933 QueryServiceLockStatusA(
934 SC_HANDLE hSCManager,
935 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
936 DWORD cbBufSize,
937 LPDWORD pcbBytesNeeded)
938 {
939 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
940 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
941 return FALSE;
942 }
943
944
945 /**********************************************************************
946 * QueryServiceLockStatusW
947 *
948 * @unimplemented
949 */
950 BOOL
951 STDCALL
952 QueryServiceLockStatusW(
953 SC_HANDLE hSCManager,
954 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
955 DWORD cbBufSize,
956 LPDWORD pcbBytesNeeded)
957 {
958 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
959 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
960 return FALSE;
961 }
962
963
964 /**********************************************************************
965 * QueryServiceObjectSecurity
966 *
967 * @unimplemented
968 */
969 BOOL
970 STDCALL
971 QueryServiceObjectSecurity(
972 SC_HANDLE hService,
973 SECURITY_INFORMATION dwSecurityInformation,
974 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
975 DWORD cbBufSize,
976 LPDWORD pcbBytesNeeded)
977 {
978 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
979 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
980 return FALSE;
981 }
982
983
984 /**********************************************************************
985 * QueryServiceStatus
986 *
987 * @implemented
988 */
989 BOOL STDCALL
990 QueryServiceStatus(SC_HANDLE hService,
991 LPSERVICE_STATUS lpServiceStatus)
992 {
993 DWORD dwError;
994
995 DPRINT("QueryServiceStatus(%p, %p)\n",
996 hService, lpServiceStatus);
997
998 HandleBind();
999
1000 /* Call to services.exe using RPC */
1001 dwError = ScmrQueryServiceStatus(BindingHandle,
1002 (unsigned int)hService,
1003 lpServiceStatus);
1004 if (dwError != ERROR_SUCCESS)
1005 {
1006 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
1007 SetLastError(dwError);
1008 return FALSE;
1009 }
1010
1011 return TRUE;
1012 }
1013
1014
1015 /**********************************************************************
1016 * QueryServiceStatusEx
1017 *
1018 * @unimplemented
1019 */
1020 BOOL
1021 STDCALL
1022 QueryServiceStatusEx(SC_HANDLE hService,
1023 SC_STATUS_TYPE InfoLevel,
1024 LPBYTE lpBuffer,
1025 DWORD cbBufSize,
1026 LPDWORD pcbBytesNeeded)
1027 {
1028 DPRINT1("QueryServiceStatusEx is unimplemented\n");
1029 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1030 return FALSE;
1031 }
1032
1033
1034 /**********************************************************************
1035 * StartServiceA
1036 *
1037 * @unimplemented
1038 */
1039 BOOL
1040 STDCALL
1041 StartServiceA(
1042 SC_HANDLE hService,
1043 DWORD dwNumServiceArgs,
1044 LPCSTR *lpServiceArgVectors)
1045 {
1046 DPRINT1("StartServiceA is unimplemented\n");
1047 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1048 return FALSE;
1049 }
1050
1051
1052 /**********************************************************************
1053 * StartServiceW
1054 *
1055 * @unimplemented
1056 */
1057 BOOL
1058 STDCALL
1059 StartServiceW(
1060 SC_HANDLE hService,
1061 DWORD dwNumServiceArgs,
1062 LPCWSTR *lpServiceArgVectors)
1063 {
1064 DPRINT1("StartServiceW is unimplemented, but returns success...\n");
1065 //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1066 //return FALSE;
1067 return TRUE;
1068 }
1069
1070
1071 /**********************************************************************
1072 * UnlockServiceDatabase
1073 *
1074 * @implemented
1075 */
1076 BOOL STDCALL
1077 UnlockServiceDatabase(SC_LOCK ScLock)
1078 {
1079 DWORD dwError;
1080
1081 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
1082
1083 HandleBind();
1084
1085 /* Call to services.exe using RPC */
1086 dwError = ScmrUnlockServiceDatabase(BindingHandle,
1087 (unsigned int)ScLock);
1088 if (dwError != ERROR_SUCCESS)
1089 {
1090 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
1091 SetLastError(dwError);
1092 return FALSE;
1093 }
1094
1095 return TRUE;
1096 }
1097
1098
1099 /**********************************************************************
1100 * NotifyBootConfigStatus
1101 *
1102 * @implemented
1103 */
1104 BOOL STDCALL
1105 NotifyBootConfigStatus(BOOL BootAcceptable)
1106 {
1107 DWORD dwError;
1108
1109 DPRINT1("NotifyBootConfigStatus()\n");
1110
1111 HandleBind();
1112
1113 /* Call to services.exe using RPC */
1114 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
1115 BootAcceptable);
1116 if (dwError != ERROR_SUCCESS)
1117 {
1118 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
1119 SetLastError(dwError);
1120 return FALSE;
1121 }
1122
1123 return TRUE;
1124 }
1125
1126
1127 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
1128 {
1129 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1130 }
1131
1132
1133 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
1134 {
1135 HeapFree(GetProcessHeap(), 0, ptr);
1136 }
1137
1138 /* EOF */