bbc8bddc8ab660ac42c511dc020935155e35032e
[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 * @implemented
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 SC_HANDLE RetVal = NULL;
281 LPWSTR lpServiceNameW = NULL;
282 LPWSTR lpDisplayNameW = NULL;
283 LPWSTR lpBinaryPathNameW = NULL;
284 LPWSTR lpLoadOrderGroupW = NULL;
285 LPWSTR lpDependenciesW = NULL;
286 LPWSTR lpServiceStartNameW = NULL;
287 LPWSTR lpPasswordW = NULL;
288 DWORD dwDependenciesLength = 0;
289 DWORD dwLength;
290 LPSTR lpStr;
291
292 int len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
293 lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
294 if (!lpServiceNameW)
295 {
296 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
297 goto cleanup;
298 }
299 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
300
301 len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
302 lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
303 if (!lpDisplayNameW)
304 {
305 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
306 goto cleanup;
307 }
308 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
309
310 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
311 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
312 if (!lpBinaryPathNameW)
313 {
314 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
315 goto cleanup;
316 }
317 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpBinaryPathNameW, len);
318
319 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
320 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
321 if (!lpLoadOrderGroupW)
322 {
323 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
324 goto cleanup;
325 }
326 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
327
328 if (lpDependencies != NULL)
329 {
330 lpStr = (LPSTR)lpDependencies;
331 while (*lpStr)
332 {
333 dwLength = strlen(lpStr) + 1;
334 dwDependenciesLength += dwLength;
335 lpStr = lpStr + dwLength;
336 }
337 dwDependenciesLength++;
338 }
339
340 lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
341 if (!lpDependenciesW)
342 {
343 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
344 goto cleanup;
345 }
346 MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, dwDependenciesLength);
347
348 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
349 lpServiceStartName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
350 if (!lpServiceStartNameW)
351 {
352 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
353 goto cleanup;
354 }
355 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
356
357 len = MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, NULL, 0);
358 lpPasswordW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
359 if (!lpPasswordW)
360 {
361 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
362 goto cleanup;
363 }
364 MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
365
366 RetVal = CreateServiceW(hSCManager,
367 lpServiceNameW,
368 lpDisplayNameW,
369 dwDesiredAccess,
370 dwServiceType,
371 dwStartType,
372 dwErrorControl,
373 lpBinaryPathNameW,
374 lpLoadOrderGroupW,
375 lpdwTagId,
376 lpDependenciesW,
377 lpServiceStartNameW,
378 lpPasswordW);
379
380
381 cleanup:
382 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
383 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
384 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
385 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
386 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
387 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
388 HeapFree(GetProcessHeap(), 0, lpPasswordW);
389
390 return RetVal;
391 }
392
393
394 /**********************************************************************
395 * CreateServiceW
396 *
397 * @implemented
398 */
399 SC_HANDLE STDCALL
400 CreateServiceW(SC_HANDLE hSCManager,
401 LPCWSTR lpServiceName,
402 LPCWSTR lpDisplayName,
403 DWORD dwDesiredAccess,
404 DWORD dwServiceType,
405 DWORD dwStartType,
406 DWORD dwErrorControl,
407 LPCWSTR lpBinaryPathName,
408 LPCWSTR lpLoadOrderGroup,
409 LPDWORD lpdwTagId,
410 LPCWSTR lpDependencies,
411 LPCWSTR lpServiceStartName,
412 LPCWSTR lpPassword)
413 {
414 SC_HANDLE hService = NULL;
415 DWORD dwError;
416 DWORD dwDependenciesLength = 0;
417 DWORD dwLength;
418 LPWSTR lpStr;
419
420 DPRINT1("CreateServiceW() called\n");
421
422 /* Calculate the Dependencies length*/
423 if (lpDependencies != NULL)
424 {
425 lpStr = (LPWSTR)lpDependencies;
426 while (*lpStr)
427 {
428 dwLength = wcslen(lpStr) + 1;
429 dwDependenciesLength += dwLength;
430 lpStr = lpStr + dwLength;
431 }
432 dwDependenciesLength++;
433 }
434
435 /* FIXME: Encrypt the password */
436
437 HandleBind();
438
439 /* Call to services.exe using RPC */
440 dwError = ScmrCreateServiceW(BindingHandle,
441 (unsigned int)hSCManager,
442 (LPWSTR)lpServiceName,
443 (LPWSTR)lpDisplayName,
444 dwDesiredAccess,
445 dwServiceType,
446 dwStartType,
447 dwErrorControl,
448 (LPWSTR)lpBinaryPathName,
449 (LPWSTR)lpLoadOrderGroup,
450 lpdwTagId,
451 (LPWSTR)lpDependencies,
452 dwDependenciesLength,
453 (LPWSTR)lpServiceStartName,
454 NULL, /* FIXME: lpPassword */
455 0, /* FIXME: dwPasswordLength */
456 (unsigned int *)&hService);
457 if (dwError != ERROR_SUCCESS)
458 {
459 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
460 SetLastError(dwError);
461 return NULL;
462 }
463
464 return hService;
465 }
466
467
468 /**********************************************************************
469 * DeleteService
470 *
471 * @implemented
472 */
473 BOOL STDCALL
474 DeleteService(SC_HANDLE hService)
475 {
476 DWORD dwError;
477
478 DPRINT("DeleteService(%x)\n", hService);
479
480 HandleBind();
481
482 /* Call to services.exe using RPC */
483 dwError = ScmrDeleteService(BindingHandle,
484 (unsigned int)hService);
485 if (dwError != ERROR_SUCCESS)
486 {
487 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError);
488 SetLastError(dwError);
489 return FALSE;
490 }
491
492 return TRUE;
493 }
494
495
496 /**********************************************************************
497 * EnumDependentServicesA
498 *
499 * @unimplemented
500 */
501 BOOL
502 STDCALL
503 EnumDependentServicesA(
504 SC_HANDLE hService,
505 DWORD dwServiceState,
506 LPENUM_SERVICE_STATUSA lpServices,
507 DWORD cbBufSize,
508 LPDWORD pcbBytesNeeded,
509 LPDWORD lpServicesReturned)
510 {
511 DPRINT1("EnumDependentServicesA is unimplemented\n");
512 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
513 return FALSE;
514 }
515
516
517 /**********************************************************************
518 * EnumDependentServicesW
519 *
520 * @unimplemented
521 */
522 BOOL
523 STDCALL
524 EnumDependentServicesW(
525 SC_HANDLE hService,
526 DWORD dwServiceState,
527 LPENUM_SERVICE_STATUSW lpServices,
528 DWORD cbBufSize,
529 LPDWORD pcbBytesNeeded,
530 LPDWORD lpServicesReturned)
531 {
532 DPRINT1("EnumDependentServicesW is unimplemented\n");
533 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
534 return FALSE;
535 }
536
537
538 /**********************************************************************
539 * EnumServiceGroupW
540 *
541 * @unimplemented
542 */
543 BOOL
544 STDCALL
545 EnumServiceGroupW (
546 DWORD Unknown0,
547 DWORD Unknown1,
548 DWORD Unknown2,
549 DWORD Unknown3,
550 DWORD Unknown4,
551 DWORD Unknown5,
552 DWORD Unknown6,
553 DWORD Unknown7,
554 DWORD Unknown8)
555 {
556 DPRINT1("EnumServiceGroupW is unimplemented\n");
557 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
558 return FALSE;
559 }
560
561
562 /**********************************************************************
563 * EnumServicesStatusA
564 *
565 * @unimplemented
566 */
567 BOOL
568 STDCALL
569 EnumServicesStatusA (
570 SC_HANDLE hSCManager,
571 DWORD dwServiceType,
572 DWORD dwServiceState,
573 LPENUM_SERVICE_STATUSA lpServices,
574 DWORD cbBufSize,
575 LPDWORD pcbBytesNeeded,
576 LPDWORD lpServicesReturned,
577 LPDWORD lpResumeHandle)
578 {
579 DPRINT1("EnumServicesStatusA is unimplemented\n");
580 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
581 return FALSE;
582 }
583
584
585 /**********************************************************************
586 * EnumServicesStatusExA
587 *
588 * @unimplemented
589 */
590 BOOL
591 STDCALL
592 EnumServicesStatusExA(SC_HANDLE hSCManager,
593 SC_ENUM_TYPE InfoLevel,
594 DWORD dwServiceType,
595 DWORD dwServiceState,
596 LPBYTE lpServices,
597 DWORD cbBufSize,
598 LPDWORD pcbBytesNeeded,
599 LPDWORD lpServicesReturned,
600 LPDWORD lpResumeHandle,
601 LPCSTR pszGroupName)
602 {
603 DPRINT1("EnumServicesStatusExA is unimplemented\n");
604 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
605 return FALSE;
606 }
607
608
609 /**********************************************************************
610 * EnumServicesStatusExW
611 *
612 * @unimplemented
613 */
614 BOOL
615 STDCALL
616 EnumServicesStatusExW(SC_HANDLE hSCManager,
617 SC_ENUM_TYPE InfoLevel,
618 DWORD dwServiceType,
619 DWORD dwServiceState,
620 LPBYTE lpServices,
621 DWORD cbBufSize,
622 LPDWORD pcbBytesNeeded,
623 LPDWORD lpServicesReturned,
624 LPDWORD lpResumeHandle,
625 LPCWSTR pszGroupName)
626 {
627 DPRINT1("EnumServicesStatusExW is unimplemented\n");
628 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
629 return FALSE;
630 }
631
632
633 /**********************************************************************
634 * EnumServicesStatusW
635 *
636 * @unimplemented
637 */
638 BOOL
639 STDCALL
640 EnumServicesStatusW(
641 SC_HANDLE hSCManager,
642 DWORD dwServiceType,
643 DWORD dwServiceState,
644 LPENUM_SERVICE_STATUSW lpServices,
645 DWORD cbBufSize,
646 LPDWORD pcbBytesNeeded,
647 LPDWORD lpServicesReturned,
648 LPDWORD lpResumeHandle)
649 {
650 DPRINT1("EnumServicesStatusW is unimplemented\n");
651 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
652 return FALSE;
653 }
654
655
656 /**********************************************************************
657 * GetServiceDisplayNameA
658 *
659 * @unimplemented
660 */
661 BOOL
662 STDCALL
663 GetServiceDisplayNameA(
664 SC_HANDLE hSCManager,
665 LPCSTR lpServiceName,
666 LPSTR lpDisplayName,
667 LPDWORD lpcchBuffer)
668 {
669 DPRINT1("GetServiceDisplayNameA is unimplemented\n");
670 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
671 return FALSE;
672 }
673
674
675 /**********************************************************************
676 * GetServiceDisplayNameW
677 *
678 * @implemented
679 */
680 BOOL STDCALL
681 GetServiceDisplayNameW(SC_HANDLE hSCManager,
682 LPCWSTR lpServiceName,
683 LPWSTR lpDisplayName,
684 LPDWORD lpcchBuffer)
685 {
686 DWORD dwError;
687
688 DPRINT("GetServiceDisplayNameW() called\n");
689
690 HandleBind();
691
692 dwError = ScmrGetServiceDisplayNameW(BindingHandle,
693 (unsigned int)hSCManager,
694 (LPWSTR)lpServiceName,
695 lpDisplayName,
696 lpcchBuffer);
697 if (dwError != ERROR_SUCCESS)
698 {
699 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
700 SetLastError(dwError);
701 return FALSE;
702 }
703
704 (*lpcchBuffer)--;
705
706 return TRUE;
707 }
708
709
710 /**********************************************************************
711 * GetServiceKeyNameA
712 *
713 * @unimplemented
714 */
715 BOOL
716 STDCALL
717 GetServiceKeyNameA(
718 SC_HANDLE hSCManager,
719 LPCSTR lpDisplayName,
720 LPSTR lpServiceName,
721 LPDWORD lpcchBuffer)
722 {
723 DPRINT1("GetServiceKeyNameA is unimplemented\n");
724 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
725 return FALSE;
726 }
727
728
729 /**********************************************************************
730 * GetServiceKeyNameW
731 *
732 * @implemented
733 */
734 BOOL STDCALL
735 GetServiceKeyNameW(SC_HANDLE hSCManager,
736 LPCWSTR lpDisplayName,
737 LPWSTR lpServiceName,
738 LPDWORD lpcchBuffer)
739 {
740 DWORD dwError;
741
742 DPRINT("GetServiceKeyNameW() called\n");
743
744 HandleBind();
745
746 dwError = ScmrGetServiceKeyNameW(BindingHandle,
747 (unsigned int)hSCManager,
748 (LPWSTR)lpDisplayName,
749 lpServiceName,
750 lpcchBuffer);
751 if (dwError != ERROR_SUCCESS)
752 {
753 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError);
754 SetLastError(dwError);
755 return FALSE;
756 }
757
758 (*lpcchBuffer)--;
759
760 return TRUE;
761 }
762
763
764 /**********************************************************************
765 * LockServiceDatabase
766 *
767 * @implemented
768 */
769 SC_LOCK STDCALL
770 LockServiceDatabase(SC_HANDLE hSCManager)
771 {
772 SC_LOCK hLock;
773 DWORD dwError;
774
775 DPRINT("LockServiceDatabase(%x)\n", hSCManager);
776
777 HandleBind();
778
779 /* Call to services.exe using RPC */
780 dwError = ScmrLockServiceDatabase(BindingHandle,
781 (unsigned int)hSCManager,
782 (unsigned int *)&hLock);
783 if (dwError != ERROR_SUCCESS)
784 {
785 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
786 SetLastError(dwError);
787 return NULL;
788 }
789
790 DPRINT("hLock = %p\n", hLock);
791
792 return hLock;
793 }
794
795
796 static VOID
797 WaitForSCManager(VOID)
798 {
799 HANDLE hEvent;
800
801 DPRINT("WaitForSCManager() called\n");
802
803 /* Try to open the existing event */
804 hEvent = OpenEventW(SYNCHRONIZE,
805 FALSE,
806 L"SvcctrlStartEvent_A3725DX");
807 if (hEvent == NULL)
808 {
809 if (GetLastError() != ERROR_FILE_NOT_FOUND)
810 return;
811
812 /* Try to create a new event */
813 hEvent = CreateEventW(NULL,
814 TRUE,
815 FALSE,
816 L"SvcctrlStartEvent_A3725DX");
817 if (hEvent == NULL)
818 {
819 /* Try to open the existing event again */
820 hEvent = OpenEventW(SYNCHRONIZE,
821 FALSE,
822 L"SvcctrlStartEvent_A3725DX");
823 if (hEvent == NULL)
824 return;
825 }
826 }
827
828 /* Wait for 3 minutes */
829 WaitForSingleObject(hEvent, 180000);
830 CloseHandle(hEvent);
831
832 DPRINT("ScmWaitForSCManager() done\n");
833 }
834
835
836 /**********************************************************************
837 * OpenSCManagerA
838 *
839 * @implemented
840 */
841 SC_HANDLE STDCALL
842 OpenSCManagerA(LPCSTR lpMachineName,
843 LPCSTR lpDatabaseName,
844 DWORD dwDesiredAccess)
845 {
846 SC_HANDLE hScm = NULL;
847 DWORD dwError;
848
849 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
850 lpMachineName, lpDatabaseName, dwDesiredAccess);
851
852 WaitForSCManager();
853
854 HandleBind();
855
856 /* Call to services.exe using RPC */
857 dwError = ScmrOpenSCManagerA(BindingHandle,
858 (LPSTR)lpMachineName,
859 (LPSTR)lpDatabaseName,
860 dwDesiredAccess,
861 (unsigned int*)&hScm);
862 if (dwError != ERROR_SUCCESS)
863 {
864 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
865 SetLastError(dwError);
866 return NULL;
867 }
868
869 DPRINT("hScm = %p\n", hScm);
870
871 return hScm;
872 }
873
874
875 /**********************************************************************
876 * OpenSCManagerW
877 *
878 * @implemented
879 */
880 SC_HANDLE STDCALL
881 OpenSCManagerW(LPCWSTR lpMachineName,
882 LPCWSTR lpDatabaseName,
883 DWORD dwDesiredAccess)
884 {
885 SC_HANDLE hScm = NULL;
886 DWORD dwError;
887
888 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
889 lpMachineName, lpDatabaseName, dwDesiredAccess);
890
891 WaitForSCManager();
892
893 HandleBind();
894
895 /* Call to services.exe using RPC */
896 dwError = ScmrOpenSCManagerW(BindingHandle,
897 (LPWSTR)lpMachineName,
898 (LPWSTR)lpDatabaseName,
899 dwDesiredAccess,
900 (unsigned int*)&hScm);
901 if (dwError != ERROR_SUCCESS)
902 {
903 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
904 SetLastError(dwError);
905 return NULL;
906 }
907
908 DPRINT("hScm = %p\n", hScm);
909
910 return hScm;
911 }
912
913
914 /**********************************************************************
915 * OpenServiceA
916 *
917 * @implemented
918 */
919 SC_HANDLE STDCALL
920 OpenServiceA(SC_HANDLE hSCManager,
921 LPCSTR lpServiceName,
922 DWORD dwDesiredAccess)
923 {
924 SC_HANDLE hService = NULL;
925 DWORD dwError;
926
927 DPRINT("OpenServiceA(%p, %s, %lx)\n",
928 hSCManager, lpServiceName, dwDesiredAccess);
929
930 HandleBind();
931
932 /* Call to services.exe using RPC */
933 dwError = ScmrOpenServiceA(BindingHandle,
934 (unsigned int)hSCManager,
935 (LPSTR)lpServiceName,
936 dwDesiredAccess,
937 (unsigned int*)&hService);
938 if (dwError != ERROR_SUCCESS)
939 {
940 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
941 SetLastError(dwError);
942 return NULL;
943 }
944
945 DPRINT("hService = %p\n", hService);
946
947 return hService;
948 }
949
950
951 /**********************************************************************
952 * OpenServiceW
953 *
954 * @implemented
955 */
956 SC_HANDLE STDCALL
957 OpenServiceW(SC_HANDLE hSCManager,
958 LPCWSTR lpServiceName,
959 DWORD dwDesiredAccess)
960 {
961 SC_HANDLE hService = NULL;
962 DWORD dwError;
963
964 DPRINT("OpenServiceW(%p, %S, %lx)\n",
965 hSCManager, lpServiceName, dwDesiredAccess);
966
967 HandleBind();
968
969 /* Call to services.exe using RPC */
970 dwError = ScmrOpenServiceW(BindingHandle,
971 (unsigned int)hSCManager,
972 (LPWSTR)lpServiceName,
973 dwDesiredAccess,
974 (unsigned int*)&hService);
975 if (dwError != ERROR_SUCCESS)
976 {
977 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError);
978 SetLastError(dwError);
979 return NULL;
980 }
981
982 DPRINT("hService = %p\n", hService);
983
984 return hService;
985 }
986
987
988 /**********************************************************************
989 * QueryServiceConfigA
990 *
991 * @unimplemented
992 */
993 BOOL
994 STDCALL
995 QueryServiceConfigA(
996 SC_HANDLE hService,
997 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
998 DWORD cbBufSize,
999 LPDWORD pcbBytesNeeded)
1000 {
1001 DPRINT1("QueryServiceConfigA is unimplemented\n");
1002 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1003 return FALSE;
1004 }
1005
1006
1007 /**********************************************************************
1008 * QueryServiceConfigW
1009 *
1010 * @unimplemented
1011 */
1012 BOOL
1013 STDCALL
1014 QueryServiceConfigW(
1015 SC_HANDLE hService,
1016 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1017 DWORD cbBufSize,
1018 LPDWORD pcbBytesNeeded)
1019 {
1020 DPRINT1("QueryServiceConfigW is unimplemented\n");
1021 if (lpServiceConfig && cbBufSize >= sizeof(QUERY_SERVICE_CONFIGW))
1022 {
1023 memset(lpServiceConfig, 0, *pcbBytesNeeded);
1024 return TRUE;
1025 }
1026 else
1027 {
1028 *pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
1029 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1030 return FALSE;
1031 }
1032 }
1033
1034 /**********************************************************************
1035 * QueryServiceConfig2W
1036 *
1037 * @unimplemented
1038 */
1039 BOOL
1040 STDCALL
1041 QueryServiceConfig2W
1042 (
1043 SC_HANDLE hService,
1044 DWORD dwInfo,
1045 LPBYTE lpBuffer,
1046 DWORD cbBufSize,
1047 LPDWORD pcbBytesNeeded)
1048 {
1049 DPRINT1("QueryServiceConfigW2 is unimplemented\n");
1050 return FALSE;
1051 }
1052
1053
1054 /**********************************************************************
1055 * QueryServiceLockStatusA
1056 *
1057 * @unimplemented
1058 */
1059 BOOL
1060 STDCALL
1061 QueryServiceLockStatusA(
1062 SC_HANDLE hSCManager,
1063 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
1064 DWORD cbBufSize,
1065 LPDWORD pcbBytesNeeded)
1066 {
1067 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1068 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1069 return FALSE;
1070 }
1071
1072
1073 /**********************************************************************
1074 * QueryServiceLockStatusW
1075 *
1076 * @unimplemented
1077 */
1078 BOOL
1079 STDCALL
1080 QueryServiceLockStatusW(
1081 SC_HANDLE hSCManager,
1082 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
1083 DWORD cbBufSize,
1084 LPDWORD pcbBytesNeeded)
1085 {
1086 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1087 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1088 return FALSE;
1089 }
1090
1091
1092 /**********************************************************************
1093 * QueryServiceObjectSecurity
1094 *
1095 * @unimplemented
1096 */
1097 BOOL
1098 STDCALL
1099 QueryServiceObjectSecurity(
1100 SC_HANDLE hService,
1101 SECURITY_INFORMATION dwSecurityInformation,
1102 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
1103 DWORD cbBufSize,
1104 LPDWORD pcbBytesNeeded)
1105 {
1106 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
1107 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1108 return FALSE;
1109 }
1110
1111
1112 /**********************************************************************
1113 * QueryServiceStatus
1114 *
1115 * @implemented
1116 */
1117 BOOL STDCALL
1118 QueryServiceStatus(SC_HANDLE hService,
1119 LPSERVICE_STATUS lpServiceStatus)
1120 {
1121 DWORD dwError;
1122
1123 DPRINT("QueryServiceStatus(%p, %p)\n",
1124 hService, lpServiceStatus);
1125
1126 HandleBind();
1127
1128 /* Call to services.exe using RPC */
1129 dwError = ScmrQueryServiceStatus(BindingHandle,
1130 (unsigned int)hService,
1131 lpServiceStatus);
1132 if (dwError != ERROR_SUCCESS)
1133 {
1134 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
1135 SetLastError(dwError);
1136 return FALSE;
1137 }
1138
1139 return TRUE;
1140 }
1141
1142
1143 /**********************************************************************
1144 * QueryServiceStatusEx
1145 *
1146 * @unimplemented
1147 */
1148 BOOL
1149 STDCALL
1150 QueryServiceStatusEx(SC_HANDLE hService,
1151 SC_STATUS_TYPE InfoLevel,
1152 LPBYTE lpBuffer,
1153 DWORD cbBufSize,
1154 LPDWORD pcbBytesNeeded)
1155 {
1156 DPRINT1("QueryServiceStatusEx is unimplemented\n");
1157 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1158 return FALSE;
1159 }
1160
1161
1162 /**********************************************************************
1163 * StartServiceA
1164 *
1165 * @unimplemented
1166 */
1167 BOOL
1168 STDCALL
1169 StartServiceA(
1170 SC_HANDLE hService,
1171 DWORD dwNumServiceArgs,
1172 LPCSTR *lpServiceArgVectors)
1173 {
1174 DPRINT1("StartServiceA is unimplemented\n");
1175 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1176 return FALSE;
1177 }
1178
1179
1180 /**********************************************************************
1181 * StartServiceW
1182 *
1183 * @unimplemented
1184 */
1185 BOOL
1186 STDCALL
1187 StartServiceW(
1188 SC_HANDLE hService,
1189 DWORD dwNumServiceArgs,
1190 LPCWSTR *lpServiceArgVectors)
1191 {
1192 DPRINT1("StartServiceW is unimplemented, but returns success...\n");
1193 //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1194 //return FALSE;
1195 return TRUE;
1196 }
1197
1198
1199 /**********************************************************************
1200 * UnlockServiceDatabase
1201 *
1202 * @implemented
1203 */
1204 BOOL STDCALL
1205 UnlockServiceDatabase(SC_LOCK ScLock)
1206 {
1207 DWORD dwError;
1208
1209 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
1210
1211 HandleBind();
1212
1213 /* Call to services.exe using RPC */
1214 dwError = ScmrUnlockServiceDatabase(BindingHandle,
1215 (unsigned int)ScLock);
1216 if (dwError != ERROR_SUCCESS)
1217 {
1218 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
1219 SetLastError(dwError);
1220 return FALSE;
1221 }
1222
1223 return TRUE;
1224 }
1225
1226
1227 /**********************************************************************
1228 * NotifyBootConfigStatus
1229 *
1230 * @implemented
1231 */
1232 BOOL STDCALL
1233 NotifyBootConfigStatus(BOOL BootAcceptable)
1234 {
1235 DWORD dwError;
1236
1237 DPRINT1("NotifyBootConfigStatus()\n");
1238
1239 HandleBind();
1240
1241 /* Call to services.exe using RPC */
1242 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
1243 BootAcceptable);
1244 if (dwError != ERROR_SUCCESS)
1245 {
1246 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
1247 SetLastError(dwError);
1248 return FALSE;
1249 }
1250
1251 return TRUE;
1252 }
1253
1254
1255 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
1256 {
1257 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1258 }
1259
1260
1261 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
1262 {
1263 HeapFree(GetProcessHeap(), 0, ptr);
1264 }
1265
1266 /* EOF */