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