sorry, forgot to change one var
[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 INVALID_HANDLE_VALUE;
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 /**********************************************************************
1036 * QueryServiceLockStatusA
1037 *
1038 * @unimplemented
1039 */
1040 BOOL
1041 STDCALL
1042 QueryServiceLockStatusA(
1043 SC_HANDLE hSCManager,
1044 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
1045 DWORD cbBufSize,
1046 LPDWORD pcbBytesNeeded)
1047 {
1048 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1049 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1050 return FALSE;
1051 }
1052
1053
1054 /**********************************************************************
1055 * QueryServiceLockStatusW
1056 *
1057 * @unimplemented
1058 */
1059 BOOL
1060 STDCALL
1061 QueryServiceLockStatusW(
1062 SC_HANDLE hSCManager,
1063 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
1064 DWORD cbBufSize,
1065 LPDWORD pcbBytesNeeded)
1066 {
1067 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1068 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1069 return FALSE;
1070 }
1071
1072
1073 /**********************************************************************
1074 * QueryServiceObjectSecurity
1075 *
1076 * @unimplemented
1077 */
1078 BOOL
1079 STDCALL
1080 QueryServiceObjectSecurity(
1081 SC_HANDLE hService,
1082 SECURITY_INFORMATION dwSecurityInformation,
1083 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
1084 DWORD cbBufSize,
1085 LPDWORD pcbBytesNeeded)
1086 {
1087 DPRINT1("QueryServiceObjectSecurity is unimplemented\n");
1088 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1089 return FALSE;
1090 }
1091
1092
1093 /**********************************************************************
1094 * QueryServiceStatus
1095 *
1096 * @implemented
1097 */
1098 BOOL STDCALL
1099 QueryServiceStatus(SC_HANDLE hService,
1100 LPSERVICE_STATUS lpServiceStatus)
1101 {
1102 DWORD dwError;
1103
1104 DPRINT("QueryServiceStatus(%p, %p)\n",
1105 hService, lpServiceStatus);
1106
1107 HandleBind();
1108
1109 /* Call to services.exe using RPC */
1110 dwError = ScmrQueryServiceStatus(BindingHandle,
1111 (unsigned int)hService,
1112 lpServiceStatus);
1113 if (dwError != ERROR_SUCCESS)
1114 {
1115 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
1116 SetLastError(dwError);
1117 return FALSE;
1118 }
1119
1120 return TRUE;
1121 }
1122
1123
1124 /**********************************************************************
1125 * QueryServiceStatusEx
1126 *
1127 * @unimplemented
1128 */
1129 BOOL
1130 STDCALL
1131 QueryServiceStatusEx(SC_HANDLE hService,
1132 SC_STATUS_TYPE InfoLevel,
1133 LPBYTE lpBuffer,
1134 DWORD cbBufSize,
1135 LPDWORD pcbBytesNeeded)
1136 {
1137 DPRINT1("QueryServiceStatusEx is unimplemented\n");
1138 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1139 return FALSE;
1140 }
1141
1142
1143 /**********************************************************************
1144 * StartServiceA
1145 *
1146 * @unimplemented
1147 */
1148 BOOL
1149 STDCALL
1150 StartServiceA(
1151 SC_HANDLE hService,
1152 DWORD dwNumServiceArgs,
1153 LPCSTR *lpServiceArgVectors)
1154 {
1155 DPRINT1("StartServiceA is unimplemented\n");
1156 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1157 return FALSE;
1158 }
1159
1160
1161 /**********************************************************************
1162 * StartServiceW
1163 *
1164 * @unimplemented
1165 */
1166 BOOL
1167 STDCALL
1168 StartServiceW(
1169 SC_HANDLE hService,
1170 DWORD dwNumServiceArgs,
1171 LPCWSTR *lpServiceArgVectors)
1172 {
1173 DPRINT1("StartServiceW is unimplemented, but returns success...\n");
1174 //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1175 //return FALSE;
1176 return TRUE;
1177 }
1178
1179
1180 /**********************************************************************
1181 * UnlockServiceDatabase
1182 *
1183 * @implemented
1184 */
1185 BOOL STDCALL
1186 UnlockServiceDatabase(SC_LOCK ScLock)
1187 {
1188 DWORD dwError;
1189
1190 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
1191
1192 HandleBind();
1193
1194 /* Call to services.exe using RPC */
1195 dwError = ScmrUnlockServiceDatabase(BindingHandle,
1196 (unsigned int)ScLock);
1197 if (dwError != ERROR_SUCCESS)
1198 {
1199 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
1200 SetLastError(dwError);
1201 return FALSE;
1202 }
1203
1204 return TRUE;
1205 }
1206
1207
1208 /**********************************************************************
1209 * NotifyBootConfigStatus
1210 *
1211 * @implemented
1212 */
1213 BOOL STDCALL
1214 NotifyBootConfigStatus(BOOL BootAcceptable)
1215 {
1216 DWORD dwError;
1217
1218 DPRINT1("NotifyBootConfigStatus()\n");
1219
1220 HandleBind();
1221
1222 /* Call to services.exe using RPC */
1223 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
1224 BootAcceptable);
1225 if (dwError != ERROR_SUCCESS)
1226 {
1227 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
1228 SetLastError(dwError);
1229 return FALSE;
1230 }
1231
1232 return TRUE;
1233 }
1234
1235
1236 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
1237 {
1238 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1239 }
1240
1241
1242 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
1243 {
1244 HeapFree(GetProcessHeap(), 0, ptr);
1245 }
1246
1247 /* EOF */