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