e148407d46f80f2d2bd10d595e39db53494e5a2e
[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 * @implemented
84 */
85 BOOL STDCALL
86 ChangeServiceConfigA(SC_HANDLE hService,
87 DWORD dwServiceType,
88 DWORD dwStartType,
89 DWORD dwErrorControl,
90 LPCSTR lpBinaryPathName,
91 LPCSTR lpLoadOrderGroup,
92 LPDWORD lpdwTagId,
93 LPCSTR lpDependencies,
94 LPCSTR lpServiceStartName,
95 LPCSTR lpPassword,
96 LPCSTR lpDisplayName)
97 {
98 DWORD dwError;
99 DWORD dwDependenciesLength = 0;
100 DWORD dwLength;
101 LPSTR lpStr;
102
103 DPRINT("ChangeServiceConfigA() called\n");
104
105 /* Calculate the Dependencies length*/
106 if (lpDependencies != NULL)
107 {
108 lpStr = (LPSTR)lpDependencies;
109 while (*lpStr)
110 {
111 dwLength = strlen(lpStr) + 1;
112 dwDependenciesLength += dwLength;
113 lpStr = lpStr + dwLength;
114 }
115 dwDependenciesLength++;
116 }
117
118 /* FIXME: Encrypt the password */
119
120 HandleBind();
121
122 /* Call to services.exe using RPC */
123 dwError = ScmrChangeServiceConfigA(BindingHandle,
124 (unsigned int)hService,
125 dwServiceType,
126 dwStartType,
127 dwErrorControl,
128 (LPSTR)lpBinaryPathName,
129 (LPSTR)lpLoadOrderGroup,
130 lpdwTagId,
131 (LPSTR)lpDependencies,
132 dwDependenciesLength,
133 (LPSTR)lpServiceStartName,
134 NULL, /* FIXME: lpPassword */
135 0, /* FIXME: dwPasswordLength */
136 (LPSTR)lpDisplayName);
137 if (dwError != ERROR_SUCCESS)
138 {
139 DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError);
140 SetLastError(dwError);
141 return FALSE;
142 }
143
144 return TRUE;
145 }
146
147
148 /**********************************************************************
149 * ChangeServiceConfigW
150 *
151 * @implemented
152 */
153 BOOL STDCALL
154 ChangeServiceConfigW(SC_HANDLE hService,
155 DWORD dwServiceType,
156 DWORD dwStartType,
157 DWORD dwErrorControl,
158 LPCWSTR lpBinaryPathName,
159 LPCWSTR lpLoadOrderGroup,
160 LPDWORD lpdwTagId,
161 LPCWSTR lpDependencies,
162 LPCWSTR lpServiceStartName,
163 LPCWSTR lpPassword,
164 LPCWSTR lpDisplayName)
165 {
166 DWORD dwError;
167 DWORD dwDependenciesLength = 0;
168 DWORD dwLength;
169 LPWSTR lpStr;
170
171 DPRINT("ChangeServiceConfigW() called\n");
172
173 /* Calculate the Dependencies length*/
174 if (lpDependencies != NULL)
175 {
176 lpStr = (LPWSTR)lpDependencies;
177 while (*lpStr)
178 {
179 dwLength = wcslen(lpStr) + 1;
180 dwDependenciesLength += dwLength;
181 lpStr = lpStr + dwLength;
182 }
183 dwDependenciesLength++;
184 }
185
186 /* FIXME: Encrypt the password */
187
188 HandleBind();
189
190 /* Call to services.exe using RPC */
191 dwError = ScmrChangeServiceConfigW(BindingHandle,
192 (unsigned int)hService,
193 dwServiceType,
194 dwStartType,
195 dwErrorControl,
196 (LPWSTR)lpBinaryPathName,
197 (LPWSTR)lpLoadOrderGroup,
198 lpdwTagId,
199 (LPWSTR)lpDependencies,
200 dwDependenciesLength,
201 (LPWSTR)lpServiceStartName,
202 NULL, /* FIXME: lpPassword */
203 0, /* FIXME: dwPasswordLength */
204 (LPWSTR)lpDisplayName);
205 if (dwError != ERROR_SUCCESS)
206 {
207 DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
208 SetLastError(dwError);
209 return FALSE;
210 }
211
212 return TRUE;
213 }
214
215
216 /**********************************************************************
217 * CloseServiceHandle
218 *
219 * @implemented
220 */
221 BOOL STDCALL
222 CloseServiceHandle(SC_HANDLE hSCObject)
223 {
224 DWORD dwError;
225
226 DPRINT("CloseServiceHandle() called\n");
227
228 HandleBind();
229
230 /* Call to services.exe using RPC */
231 dwError = ScmrCloseServiceHandle(BindingHandle,
232 (unsigned int)hSCObject);
233 if (dwError)
234 {
235 DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError);
236 SetLastError(dwError);
237 return FALSE;
238 }
239
240 DPRINT("CloseServiceHandle() done\n");
241
242 return TRUE;
243 }
244
245
246 /**********************************************************************
247 * ControlService
248 *
249 * @implemented
250 */
251 BOOL STDCALL
252 ControlService(SC_HANDLE hService,
253 DWORD dwControl,
254 LPSERVICE_STATUS lpServiceStatus)
255 {
256 DWORD dwError;
257
258 DPRINT("ControlService(%x, %x, %p)\n",
259 hService, dwControl, lpServiceStatus);
260
261 HandleBind();
262
263 /* Call to services.exe using RPC */
264 dwError = ScmrControlService(BindingHandle,
265 (unsigned int)hService,
266 dwControl,
267 lpServiceStatus);
268 if (dwError != ERROR_SUCCESS)
269 {
270 DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError);
271 SetLastError(dwError);
272 return FALSE;
273 }
274
275 DPRINT("ControlService() done\n");
276
277 return TRUE;
278 }
279
280
281 /**********************************************************************
282 * ControlServiceEx
283 *
284 * @unimplemented
285 */
286 BOOL STDCALL
287 ControlServiceEx(IN SC_HANDLE hService,
288 IN DWORD dwControl,
289 IN DWORD dwInfoLevel,
290 IN OUT PVOID pControlParams)
291 {
292 DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
293 hService, dwControl, dwInfoLevel, pControlParams);
294 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
295 return FALSE;
296 }
297
298
299
300 /**********************************************************************
301 * CreateServiceA
302 *
303 * @implemented
304 */
305 SC_HANDLE
306 STDCALL
307 CreateServiceA(SC_HANDLE hSCManager,
308 LPCSTR lpServiceName,
309 LPCSTR lpDisplayName,
310 DWORD dwDesiredAccess,
311 DWORD dwServiceType,
312 DWORD dwStartType,
313 DWORD dwErrorControl,
314 LPCSTR lpBinaryPathName,
315 LPCSTR lpLoadOrderGroup,
316 LPDWORD lpdwTagId,
317 LPCSTR lpDependencies,
318 LPCSTR lpServiceStartName,
319 LPCSTR lpPassword)
320 {
321 SC_HANDLE RetVal = NULL;
322 LPWSTR lpServiceNameW = NULL;
323 LPWSTR lpDisplayNameW = NULL;
324 LPWSTR lpBinaryPathNameW = NULL;
325 LPWSTR lpLoadOrderGroupW = NULL;
326 LPWSTR lpDependenciesW = NULL;
327 LPWSTR lpServiceStartNameW = NULL;
328 LPWSTR lpPasswordW = NULL;
329 DWORD dwDependenciesLength = 0;
330 DWORD dwLength;
331 LPSTR lpStr;
332
333 int len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
334 lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
335 if (!lpServiceNameW)
336 {
337 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
338 goto cleanup;
339 }
340 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
341
342 len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
343 lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
344 if (!lpDisplayNameW)
345 {
346 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
347 goto cleanup;
348 }
349 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
350
351 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
352 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
353 if (!lpBinaryPathNameW)
354 {
355 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
356 goto cleanup;
357 }
358 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpBinaryPathNameW, len);
359
360 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
361 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
362 if (!lpLoadOrderGroupW)
363 {
364 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
365 goto cleanup;
366 }
367 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
368
369 if (lpDependencies != NULL)
370 {
371 lpStr = (LPSTR)lpDependencies;
372 while (*lpStr)
373 {
374 dwLength = strlen(lpStr) + 1;
375 dwDependenciesLength += dwLength;
376 lpStr = lpStr + dwLength;
377 }
378 dwDependenciesLength++;
379 }
380
381 lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
382 if (!lpDependenciesW)
383 {
384 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
385 goto cleanup;
386 }
387 MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, dwDependenciesLength);
388
389 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
390 lpServiceStartName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
391 if (!lpServiceStartNameW)
392 {
393 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
394 goto cleanup;
395 }
396 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
397
398 len = MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, NULL, 0);
399 lpPasswordW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
400 if (!lpPasswordW)
401 {
402 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
403 goto cleanup;
404 }
405 MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
406
407 RetVal = CreateServiceW(hSCManager,
408 lpServiceNameW,
409 lpDisplayNameW,
410 dwDesiredAccess,
411 dwServiceType,
412 dwStartType,
413 dwErrorControl,
414 lpBinaryPathNameW,
415 lpLoadOrderGroupW,
416 lpdwTagId,
417 lpDependenciesW,
418 lpServiceStartNameW,
419 lpPasswordW);
420
421 cleanup:
422 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
423 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
424 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
425 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
426 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
427 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
428 HeapFree(GetProcessHeap(), 0, lpPasswordW);
429
430 return RetVal;
431 }
432
433
434 /**********************************************************************
435 * CreateServiceW
436 *
437 * @implemented
438 */
439 SC_HANDLE STDCALL
440 CreateServiceW(SC_HANDLE hSCManager,
441 LPCWSTR lpServiceName,
442 LPCWSTR lpDisplayName,
443 DWORD dwDesiredAccess,
444 DWORD dwServiceType,
445 DWORD dwStartType,
446 DWORD dwErrorControl,
447 LPCWSTR lpBinaryPathName,
448 LPCWSTR lpLoadOrderGroup,
449 LPDWORD lpdwTagId,
450 LPCWSTR lpDependencies,
451 LPCWSTR lpServiceStartName,
452 LPCWSTR lpPassword)
453 {
454 SC_HANDLE hService = NULL;
455 DWORD dwError;
456 DWORD dwDependenciesLength = 0;
457 DWORD dwLength;
458 LPWSTR lpStr;
459
460 DPRINT1("CreateServiceW() called\n");
461
462 /* Calculate the Dependencies length*/
463 if (lpDependencies != NULL)
464 {
465 lpStr = (LPWSTR)lpDependencies;
466 while (*lpStr)
467 {
468 dwLength = wcslen(lpStr) + 1;
469 dwDependenciesLength += dwLength;
470 lpStr = lpStr + dwLength;
471 }
472 dwDependenciesLength++;
473 }
474
475 /* FIXME: Encrypt the password */
476
477 HandleBind();
478
479 /* Call to services.exe using RPC */
480 dwError = ScmrCreateServiceW(BindingHandle,
481 (unsigned int)hSCManager,
482 (LPWSTR)lpServiceName,
483 (LPWSTR)lpDisplayName,
484 dwDesiredAccess,
485 dwServiceType,
486 dwStartType,
487 dwErrorControl,
488 (LPWSTR)lpBinaryPathName,
489 (LPWSTR)lpLoadOrderGroup,
490 lpdwTagId,
491 (LPWSTR)lpDependencies,
492 dwDependenciesLength,
493 (LPWSTR)lpServiceStartName,
494 NULL, /* FIXME: lpPassword */
495 0, /* FIXME: dwPasswordLength */
496 (unsigned int *)&hService);
497 if (dwError != ERROR_SUCCESS)
498 {
499 DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
500 SetLastError(dwError);
501 return NULL;
502 }
503
504 return hService;
505 }
506
507
508 /**********************************************************************
509 * DeleteService
510 *
511 * @implemented
512 */
513 BOOL STDCALL
514 DeleteService(SC_HANDLE hService)
515 {
516 DWORD dwError;
517
518 DPRINT("DeleteService(%x)\n", hService);
519
520 HandleBind();
521
522 /* Call to services.exe using RPC */
523 dwError = ScmrDeleteService(BindingHandle,
524 (unsigned int)hService);
525 if (dwError != ERROR_SUCCESS)
526 {
527 DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError);
528 SetLastError(dwError);
529 return FALSE;
530 }
531
532 return TRUE;
533 }
534
535
536 /**********************************************************************
537 * EnumDependentServicesA
538 *
539 * @unimplemented
540 */
541 BOOL
542 STDCALL
543 EnumDependentServicesA(
544 SC_HANDLE hService,
545 DWORD dwServiceState,
546 LPENUM_SERVICE_STATUSA lpServices,
547 DWORD cbBufSize,
548 LPDWORD pcbBytesNeeded,
549 LPDWORD lpServicesReturned)
550 {
551 DPRINT1("EnumDependentServicesA is unimplemented\n");
552 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
553 return FALSE;
554 }
555
556
557 /**********************************************************************
558 * EnumDependentServicesW
559 *
560 * @unimplemented
561 */
562 BOOL
563 STDCALL
564 EnumDependentServicesW(SC_HANDLE hService,
565 DWORD dwServiceState,
566 LPENUM_SERVICE_STATUSW lpServices,
567 DWORD cbBufSize,
568 LPDWORD pcbBytesNeeded,
569 LPDWORD lpServicesReturned)
570 {
571 DPRINT1("EnumDependentServicesW is unimplemented\n");
572 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
573 return FALSE;
574 }
575
576
577 /**********************************************************************
578 * EnumServiceGroupW
579 *
580 * @unimplemented
581 */
582 BOOL
583 STDCALL
584 EnumServiceGroupW(
585 SC_HANDLE hSCManager,
586 DWORD dwServiceType,
587 DWORD dwServiceState,
588 LPENUM_SERVICE_STATUSA lpServices,
589 DWORD cbBufSize,
590 LPDWORD pcbBytesNeeded,
591 LPDWORD lpServicesReturned,
592 LPDWORD lpResumeHandle,
593 LPCWSTR lpGroup)
594 {
595 DPRINT1("EnumServiceGroupW is unimplemented\n");
596 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
597 return FALSE;
598 }
599
600
601 /**********************************************************************
602 * EnumServicesStatusA
603 *
604 * @unimplemented
605 */
606 BOOL
607 STDCALL
608 EnumServicesStatusA(
609 SC_HANDLE hSCManager,
610 DWORD dwServiceType,
611 DWORD dwServiceState,
612 LPENUM_SERVICE_STATUSA lpServices,
613 DWORD cbBufSize,
614 LPDWORD pcbBytesNeeded,
615 LPDWORD lpServicesReturned,
616 LPDWORD lpResumeHandle)
617 {
618 DPRINT1("EnumServicesStatusA is unimplemented\n");
619 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
620 return FALSE;
621 }
622
623
624 /**********************************************************************
625 * EnumServicesStatusW
626 *
627 * @implemented
628 */
629 BOOL STDCALL
630 EnumServicesStatusW(SC_HANDLE hSCManager,
631 DWORD dwServiceType,
632 DWORD dwServiceState,
633 LPENUM_SERVICE_STATUSW lpServices,
634 DWORD cbBufSize,
635 LPDWORD pcbBytesNeeded,
636 LPDWORD lpServicesReturned,
637 LPDWORD lpResumeHandle)
638 {
639 LPENUM_SERVICE_STATUSW lpStatusPtr;
640 DWORD dwError = ERROR_SUCCESS;
641 DWORD dwCount;
642
643 DPRINT("EnumServicesStatusW() called\n");
644
645 HandleBind();
646
647 dwError = ScmrEnumServicesStatusW(BindingHandle,
648 (unsigned int)hSCManager,
649 dwServiceType,
650 dwServiceState,
651 (unsigned char *)lpServices,
652 cbBufSize,
653 pcbBytesNeeded,
654 lpServicesReturned,
655 lpResumeHandle);
656
657 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
658 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
659 {
660 if (lpStatusPtr->lpServiceName)
661 lpStatusPtr->lpServiceName =
662 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
663
664 if (lpStatusPtr->lpDisplayName)
665 lpStatusPtr->lpDisplayName =
666 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
667
668 lpStatusPtr++;
669 }
670
671 if (dwError != ERROR_SUCCESS)
672 {
673 DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
674 SetLastError(dwError);
675 return FALSE;
676 }
677
678 DPRINT("ScmrEnumServicesStatusW() done\n");
679
680 return TRUE;
681 }
682
683
684 /**********************************************************************
685 * EnumServicesStatusExA
686 *
687 * @unimplemented
688 */
689 BOOL
690 STDCALL
691 EnumServicesStatusExA(SC_HANDLE hSCManager,
692 SC_ENUM_TYPE InfoLevel,
693 DWORD dwServiceType,
694 DWORD dwServiceState,
695 LPBYTE lpServices,
696 DWORD cbBufSize,
697 LPDWORD pcbBytesNeeded,
698 LPDWORD lpServicesReturned,
699 LPDWORD lpResumeHandle,
700 LPCSTR pszGroupName)
701 {
702 DPRINT1("EnumServicesStatusExA is unimplemented\n");
703 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
704 return FALSE;
705 }
706
707
708 /**********************************************************************
709 * EnumServicesStatusExW
710 *
711 * @implemented
712 */
713 BOOL STDCALL
714 EnumServicesStatusExW(SC_HANDLE hSCManager,
715 SC_ENUM_TYPE InfoLevel,
716 DWORD dwServiceType,
717 DWORD dwServiceState,
718 LPBYTE lpServices,
719 DWORD cbBufSize,
720 LPDWORD pcbBytesNeeded,
721 LPDWORD lpServicesReturned,
722 LPDWORD lpResumeHandle,
723 LPCWSTR pszGroupName)
724 {
725 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
726 DWORD dwError = ERROR_SUCCESS;
727 DWORD dwCount;
728
729 DPRINT1("EnumServicesStatusExW() called\n");
730
731 HandleBind();
732
733 dwError = ScmrEnumServicesStatusExW(BindingHandle,
734 (unsigned int)hSCManager,
735 (unsigned long)InfoLevel,
736 dwServiceType,
737 dwServiceState,
738 (unsigned char *)lpServices,
739 cbBufSize,
740 pcbBytesNeeded,
741 lpServicesReturned,
742 lpResumeHandle,
743 (wchar_t *)pszGroupName);
744
745 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
746 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
747 {
748 if (lpStatusPtr->lpServiceName)
749 lpStatusPtr->lpServiceName =
750 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
751
752 if (lpStatusPtr->lpDisplayName)
753 lpStatusPtr->lpDisplayName =
754 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
755
756 lpStatusPtr++;
757 }
758
759 if (dwError != ERROR_SUCCESS)
760 {
761 DPRINT1("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError);
762 SetLastError(dwError);
763 return FALSE;
764 }
765
766 DPRINT1("ScmrEnumServicesStatusExW() done\n");
767
768 return TRUE;
769 }
770
771
772 /**********************************************************************
773 * GetServiceDisplayNameA
774 *
775 * @implemented
776 */
777 BOOL STDCALL
778 GetServiceDisplayNameA(SC_HANDLE hSCManager,
779 LPCSTR lpServiceName,
780 LPSTR lpDisplayName,
781 LPDWORD lpcchBuffer)
782 {
783 DWORD dwError;
784
785 DPRINT("GetServiceDisplayNameA() called\n");
786
787 HandleBind();
788
789 dwError = ScmrGetServiceDisplayNameA(BindingHandle,
790 (unsigned int)hSCManager,
791 (LPSTR)lpServiceName,
792 lpDisplayName,
793 lpcchBuffer);
794 if (dwError != ERROR_SUCCESS)
795 {
796 DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
797 SetLastError(dwError);
798 return FALSE;
799 }
800
801 (*lpcchBuffer)--;
802
803 return TRUE;
804 }
805
806
807 /**********************************************************************
808 * GetServiceDisplayNameW
809 *
810 * @implemented
811 */
812 BOOL STDCALL
813 GetServiceDisplayNameW(SC_HANDLE hSCManager,
814 LPCWSTR lpServiceName,
815 LPWSTR lpDisplayName,
816 LPDWORD lpcchBuffer)
817 {
818 DWORD dwError;
819
820 DPRINT("GetServiceDisplayNameW() called\n");
821
822 HandleBind();
823
824 dwError = ScmrGetServiceDisplayNameW(BindingHandle,
825 (unsigned int)hSCManager,
826 (LPWSTR)lpServiceName,
827 lpDisplayName,
828 lpcchBuffer);
829 if (dwError != ERROR_SUCCESS)
830 {
831 DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
832 SetLastError(dwError);
833 return FALSE;
834 }
835
836 (*lpcchBuffer)--;
837
838 return TRUE;
839 }
840
841
842 /**********************************************************************
843 * GetServiceKeyNameA
844 *
845 * @implemented
846 */
847 BOOL STDCALL
848 GetServiceKeyNameA(SC_HANDLE hSCManager,
849 LPCSTR lpDisplayName,
850 LPSTR lpServiceName,
851 LPDWORD lpcchBuffer)
852 {
853 DWORD dwError;
854
855 DPRINT("GetServiceKeyNameA() called\n");
856
857 HandleBind();
858
859 dwError = ScmrGetServiceKeyNameA(BindingHandle,
860 (unsigned int)hSCManager,
861 (LPSTR)lpDisplayName,
862 lpServiceName,
863 lpcchBuffer);
864 if (dwError != ERROR_SUCCESS)
865 {
866 DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError);
867 SetLastError(dwError);
868 return FALSE;
869 }
870
871 (*lpcchBuffer)--;
872
873 return TRUE;
874 }
875
876
877 /**********************************************************************
878 * GetServiceKeyNameW
879 *
880 * @implemented
881 */
882 BOOL STDCALL
883 GetServiceKeyNameW(SC_HANDLE hSCManager,
884 LPCWSTR lpDisplayName,
885 LPWSTR lpServiceName,
886 LPDWORD lpcchBuffer)
887 {
888 DWORD dwError;
889
890 DPRINT("GetServiceKeyNameW() called\n");
891
892 HandleBind();
893
894 dwError = ScmrGetServiceKeyNameW(BindingHandle,
895 (unsigned int)hSCManager,
896 (LPWSTR)lpDisplayName,
897 lpServiceName,
898 lpcchBuffer);
899 if (dwError != ERROR_SUCCESS)
900 {
901 DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError);
902 SetLastError(dwError);
903 return FALSE;
904 }
905
906 (*lpcchBuffer)--;
907
908 return TRUE;
909 }
910
911
912 /**********************************************************************
913 * LockServiceDatabase
914 *
915 * @implemented
916 */
917 SC_LOCK STDCALL
918 LockServiceDatabase(SC_HANDLE hSCManager)
919 {
920 SC_LOCK hLock;
921 DWORD dwError;
922
923 DPRINT("LockServiceDatabase(%x)\n", hSCManager);
924
925 HandleBind();
926
927 /* Call to services.exe using RPC */
928 dwError = ScmrLockServiceDatabase(BindingHandle,
929 (unsigned int)hSCManager,
930 (unsigned int *)&hLock);
931 if (dwError != ERROR_SUCCESS)
932 {
933 DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
934 SetLastError(dwError);
935 return NULL;
936 }
937
938 DPRINT("hLock = %p\n", hLock);
939
940 return hLock;
941 }
942
943
944 static VOID
945 WaitForSCManager(VOID)
946 {
947 HANDLE hEvent;
948
949 DPRINT("WaitForSCManager() called\n");
950
951 /* Try to open the existing event */
952 hEvent = OpenEventW(SYNCHRONIZE,
953 FALSE,
954 L"SvcctrlStartEvent_A3725DX");
955 if (hEvent == NULL)
956 {
957 if (GetLastError() != ERROR_FILE_NOT_FOUND)
958 return;
959
960 /* Try to create a new event */
961 hEvent = CreateEventW(NULL,
962 TRUE,
963 FALSE,
964 L"SvcctrlStartEvent_A3725DX");
965 if (hEvent == NULL)
966 {
967 /* Try to open the existing event again */
968 hEvent = OpenEventW(SYNCHRONIZE,
969 FALSE,
970 L"SvcctrlStartEvent_A3725DX");
971 if (hEvent == NULL)
972 return;
973 }
974 }
975
976 /* Wait for 3 minutes */
977 WaitForSingleObject(hEvent, 180000);
978 CloseHandle(hEvent);
979
980 DPRINT("ScmWaitForSCManager() done\n");
981 }
982
983
984 /**********************************************************************
985 * OpenSCManagerA
986 *
987 * @implemented
988 */
989 SC_HANDLE STDCALL
990 OpenSCManagerA(LPCSTR lpMachineName,
991 LPCSTR lpDatabaseName,
992 DWORD dwDesiredAccess)
993 {
994 SC_HANDLE hScm = NULL;
995 DWORD dwError;
996
997 DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
998 lpMachineName, lpDatabaseName, dwDesiredAccess);
999
1000 WaitForSCManager();
1001
1002 HandleBind();
1003
1004 /* Call to services.exe using RPC */
1005 dwError = ScmrOpenSCManagerA(BindingHandle,
1006 (LPSTR)lpMachineName,
1007 (LPSTR)lpDatabaseName,
1008 dwDesiredAccess,
1009 (unsigned int*)&hScm);
1010 if (dwError != ERROR_SUCCESS)
1011 {
1012 DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
1013 SetLastError(dwError);
1014 return NULL;
1015 }
1016
1017 DPRINT("hScm = %p\n", hScm);
1018
1019 return hScm;
1020 }
1021
1022
1023 /**********************************************************************
1024 * OpenSCManagerW
1025 *
1026 * @implemented
1027 */
1028 SC_HANDLE STDCALL
1029 OpenSCManagerW(LPCWSTR lpMachineName,
1030 LPCWSTR lpDatabaseName,
1031 DWORD dwDesiredAccess)
1032 {
1033 SC_HANDLE hScm = NULL;
1034 DWORD dwError;
1035
1036 DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
1037 lpMachineName, lpDatabaseName, dwDesiredAccess);
1038
1039 WaitForSCManager();
1040
1041 HandleBind();
1042
1043 /* Call to services.exe using RPC */
1044 dwError = ScmrOpenSCManagerW(BindingHandle,
1045 (LPWSTR)lpMachineName,
1046 (LPWSTR)lpDatabaseName,
1047 dwDesiredAccess,
1048 (unsigned int*)&hScm);
1049 if (dwError != ERROR_SUCCESS)
1050 {
1051 DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
1052 SetLastError(dwError);
1053 return NULL;
1054 }
1055
1056 DPRINT("hScm = %p\n", hScm);
1057
1058 return hScm;
1059 }
1060
1061
1062 /**********************************************************************
1063 * OpenServiceA
1064 *
1065 * @implemented
1066 */
1067 SC_HANDLE STDCALL
1068 OpenServiceA(SC_HANDLE hSCManager,
1069 LPCSTR lpServiceName,
1070 DWORD dwDesiredAccess)
1071 {
1072 SC_HANDLE hService = NULL;
1073 DWORD dwError;
1074
1075 DPRINT("OpenServiceA(%p, %s, %lx)\n",
1076 hSCManager, lpServiceName, dwDesiredAccess);
1077
1078 HandleBind();
1079
1080 /* Call to services.exe using RPC */
1081 dwError = ScmrOpenServiceA(BindingHandle,
1082 (unsigned int)hSCManager,
1083 (LPSTR)lpServiceName,
1084 dwDesiredAccess,
1085 (unsigned int*)&hService);
1086 if (dwError != ERROR_SUCCESS)
1087 {
1088 DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
1089 SetLastError(dwError);
1090 return NULL;
1091 }
1092
1093 DPRINT("hService = %p\n", hService);
1094
1095 return hService;
1096 }
1097
1098
1099 /**********************************************************************
1100 * OpenServiceW
1101 *
1102 * @implemented
1103 */
1104 SC_HANDLE STDCALL
1105 OpenServiceW(SC_HANDLE hSCManager,
1106 LPCWSTR lpServiceName,
1107 DWORD dwDesiredAccess)
1108 {
1109 SC_HANDLE hService = NULL;
1110 DWORD dwError;
1111
1112 DPRINT("OpenServiceW(%p, %S, %lx)\n",
1113 hSCManager, lpServiceName, dwDesiredAccess);
1114
1115 HandleBind();
1116
1117 /* Call to services.exe using RPC */
1118 dwError = ScmrOpenServiceW(BindingHandle,
1119 (unsigned int)hSCManager,
1120 (LPWSTR)lpServiceName,
1121 dwDesiredAccess,
1122 (unsigned int*)&hService);
1123 if (dwError != ERROR_SUCCESS)
1124 {
1125 DPRINT1("ScmrOpenServiceW() failed (Error %lu)\n", dwError);
1126 SetLastError(dwError);
1127 return NULL;
1128 }
1129
1130 DPRINT("hService = %p\n", hService);
1131
1132 return hService;
1133 }
1134
1135
1136 /**********************************************************************
1137 * QueryServiceConfigA
1138 *
1139 * @implemented
1140 */
1141 BOOL STDCALL
1142 QueryServiceConfigA(SC_HANDLE hService,
1143 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
1144 DWORD cbBufSize,
1145 LPDWORD pcbBytesNeeded)
1146 {
1147 DWORD dwError;
1148
1149 DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1150 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1151
1152 HandleBind();
1153
1154 /* Call to services.exe using RPC */
1155 dwError = ScmrQueryServiceConfigA(BindingHandle,
1156 (unsigned int)hService,
1157 (unsigned char *)lpServiceConfig,
1158 cbBufSize,
1159 pcbBytesNeeded);
1160 if (dwError != ERROR_SUCCESS)
1161 {
1162 DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError);
1163 SetLastError(dwError);
1164 return FALSE;
1165 }
1166
1167 /* Adjust the pointers */
1168 if (lpServiceConfig->lpBinaryPathName)
1169 lpServiceConfig->lpBinaryPathName =
1170 (LPSTR)((ULONG_PTR)lpServiceConfig +
1171 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1172
1173 if (lpServiceConfig->lpLoadOrderGroup)
1174 lpServiceConfig->lpLoadOrderGroup =
1175 (LPSTR)((ULONG_PTR)lpServiceConfig +
1176 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1177
1178 if (lpServiceConfig->lpDependencies)
1179 lpServiceConfig->lpDependencies =
1180 (LPSTR)((ULONG_PTR)lpServiceConfig +
1181 (ULONG_PTR)lpServiceConfig->lpDependencies);
1182
1183 if (lpServiceConfig->lpServiceStartName)
1184 lpServiceConfig->lpServiceStartName =
1185 (LPSTR)((ULONG_PTR)lpServiceConfig +
1186 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1187
1188 if (lpServiceConfig->lpDisplayName)
1189 lpServiceConfig->lpDisplayName =
1190 (LPSTR)((ULONG_PTR)lpServiceConfig +
1191 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1192
1193 DPRINT("QueryServiceConfigA() done\n");
1194
1195 return TRUE;
1196 }
1197
1198
1199 /**********************************************************************
1200 * QueryServiceConfigW
1201 *
1202 * @implemented
1203 */
1204 BOOL STDCALL
1205 QueryServiceConfigW(SC_HANDLE hService,
1206 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1207 DWORD cbBufSize,
1208 LPDWORD pcbBytesNeeded)
1209 {
1210 DWORD dwError;
1211
1212 DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1213 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1214
1215 HandleBind();
1216
1217 /* Call to services.exe using RPC */
1218 dwError = ScmrQueryServiceConfigW(BindingHandle,
1219 (unsigned int)hService,
1220 (unsigned char *)lpServiceConfig,
1221 cbBufSize,
1222 pcbBytesNeeded);
1223 if (dwError != ERROR_SUCCESS)
1224 {
1225 DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
1226 SetLastError(dwError);
1227 return FALSE;
1228 }
1229
1230 /* Adjust the pointers */
1231 if (lpServiceConfig->lpBinaryPathName)
1232 lpServiceConfig->lpBinaryPathName =
1233 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1234 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1235
1236 if (lpServiceConfig->lpLoadOrderGroup)
1237 lpServiceConfig->lpLoadOrderGroup =
1238 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1239 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1240
1241 if (lpServiceConfig->lpDependencies)
1242 lpServiceConfig->lpDependencies =
1243 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1244 (ULONG_PTR)lpServiceConfig->lpDependencies);
1245
1246 if (lpServiceConfig->lpServiceStartName)
1247 lpServiceConfig->lpServiceStartName =
1248 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1249 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1250
1251 if (lpServiceConfig->lpDisplayName)
1252 lpServiceConfig->lpDisplayName =
1253 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1254 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1255
1256 DPRINT("QueryServiceConfigW() done\n");
1257
1258 return TRUE;
1259 }
1260
1261
1262 /**********************************************************************
1263 * QueryServiceConfig2A
1264 *
1265 * @unimplemented
1266 */
1267 BOOL
1268 STDCALL
1269 QueryServiceConfig2A(
1270 SC_HANDLE hService,
1271 DWORD dwInfo,
1272 LPBYTE lpBuffer,
1273 DWORD cbBufSize,
1274 LPDWORD pcbBytesNeeded)
1275 {
1276 DPRINT1("QueryServiceConfig2A is unimplemented\n");
1277 return FALSE;
1278 }
1279
1280
1281 /**********************************************************************
1282 * QueryServiceConfig2W
1283 *
1284 * @unimplemented
1285 */
1286 BOOL
1287 STDCALL
1288 QueryServiceConfig2W(
1289 SC_HANDLE hService,
1290 DWORD dwInfo,
1291 LPBYTE lpBuffer,
1292 DWORD cbBufSize,
1293 LPDWORD pcbBytesNeeded)
1294 {
1295 DPRINT1("QueryServiceConfig2W is unimplemented\n");
1296 return FALSE;
1297 }
1298
1299
1300 /**********************************************************************
1301 * QueryServiceLockStatusA
1302 *
1303 * @unimplemented
1304 */
1305 BOOL
1306 STDCALL
1307 QueryServiceLockStatusA(
1308 SC_HANDLE hSCManager,
1309 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
1310 DWORD cbBufSize,
1311 LPDWORD pcbBytesNeeded)
1312 {
1313 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1314 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1315 return FALSE;
1316 }
1317
1318
1319 /**********************************************************************
1320 * QueryServiceLockStatusW
1321 *
1322 * @unimplemented
1323 */
1324 BOOL
1325 STDCALL
1326 QueryServiceLockStatusW(
1327 SC_HANDLE hSCManager,
1328 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
1329 DWORD cbBufSize,
1330 LPDWORD pcbBytesNeeded)
1331 {
1332 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1333 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1334 return FALSE;
1335 }
1336
1337
1338 /**********************************************************************
1339 * QueryServiceObjectSecurity
1340 *
1341 * @implemented
1342 */
1343 BOOL STDCALL
1344 QueryServiceObjectSecurity(SC_HANDLE hService,
1345 SECURITY_INFORMATION dwSecurityInformation,
1346 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
1347 DWORD cbBufSize,
1348 LPDWORD pcbBytesNeeded)
1349 {
1350 DWORD dwError;
1351
1352 DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
1353 hService, dwSecurityInformation, lpSecurityDescriptor);
1354
1355 HandleBind();
1356
1357 /* Call to services.exe using RPC */
1358 dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
1359 (unsigned int)hService,
1360 dwSecurityInformation,
1361 (unsigned char *)lpSecurityDescriptor,
1362 cbBufSize,
1363 pcbBytesNeeded);
1364 if (dwError != ERROR_SUCCESS)
1365 {
1366 DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
1367 SetLastError(dwError);
1368 return FALSE;
1369 }
1370
1371 return TRUE;
1372 }
1373
1374
1375 /**********************************************************************
1376 * QueryServiceStatus
1377 *
1378 * @implemented
1379 */
1380 BOOL STDCALL
1381 QueryServiceStatus(SC_HANDLE hService,
1382 LPSERVICE_STATUS lpServiceStatus)
1383 {
1384 DWORD dwError;
1385
1386 DPRINT("QueryServiceStatus(%p, %p)\n",
1387 hService, lpServiceStatus);
1388
1389 HandleBind();
1390
1391 /* Call to services.exe using RPC */
1392 dwError = ScmrQueryServiceStatus(BindingHandle,
1393 (unsigned int)hService,
1394 lpServiceStatus);
1395 if (dwError != ERROR_SUCCESS)
1396 {
1397 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
1398 SetLastError(dwError);
1399 return FALSE;
1400 }
1401
1402 return TRUE;
1403 }
1404
1405
1406 /**********************************************************************
1407 * QueryServiceStatusEx
1408 *
1409 * @implemented
1410 */
1411 BOOL STDCALL
1412 QueryServiceStatusEx(SC_HANDLE hService,
1413 SC_STATUS_TYPE InfoLevel,
1414 LPBYTE lpBuffer,
1415 DWORD cbBufSize,
1416 LPDWORD pcbBytesNeeded)
1417 {
1418 DWORD dwError;
1419
1420 DPRINT("QueryServiceStatusEx() called\n");
1421
1422 HandleBind();
1423
1424 /* Call to services.exe using RPC */
1425 dwError = ScmrQueryServiceStatusEx(BindingHandle,
1426 (unsigned int)hService,
1427 InfoLevel,
1428 lpBuffer,
1429 cbBufSize,
1430 pcbBytesNeeded);
1431 if (dwError != ERROR_SUCCESS)
1432 {
1433 DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
1434 SetLastError(dwError);
1435 return FALSE;
1436 }
1437
1438 return TRUE;
1439 }
1440
1441
1442 /**********************************************************************
1443 * SetServiceObjectSecurity
1444 *
1445 * @implemented
1446 */
1447 BOOL STDCALL
1448 SetServiceObjectSecurity(SC_HANDLE hService,
1449 SECURITY_INFORMATION dwSecurityInformation,
1450 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
1451 {
1452 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
1453 ULONG Length;
1454 NTSTATUS Status;
1455 DWORD dwError;
1456
1457 Length = 0;
1458 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
1459 SelfRelativeSD,
1460 &Length);
1461 if (Status != STATUS_BUFFER_TOO_SMALL)
1462 {
1463 SetLastError(ERROR_INVALID_PARAMETER);
1464 return FALSE;
1465 }
1466
1467 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
1468 if (SelfRelativeSD == NULL)
1469 {
1470 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1471 return FALSE;
1472 }
1473
1474 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
1475 SelfRelativeSD,
1476 &Length);
1477 if (!NT_SUCCESS(Status))
1478 {
1479 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
1480 SetLastError(RtlNtStatusToDosError(Status));
1481 return FALSE;
1482 }
1483
1484 HandleBind();
1485
1486 /* Call to services.exe using RPC */
1487 dwError = ScmrSetServiceObjectSecurity(BindingHandle,
1488 (unsigned int)hService,
1489 dwSecurityInformation,
1490 (unsigned char *)SelfRelativeSD,
1491 Length);
1492
1493 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
1494
1495 if (dwError != ERROR_SUCCESS)
1496 {
1497 DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
1498 SetLastError(dwError);
1499 return FALSE;
1500 }
1501
1502 return TRUE;
1503 }
1504
1505
1506 /**********************************************************************
1507 * StartServiceA
1508 *
1509 * @unimplemented
1510 */
1511 BOOL
1512 STDCALL
1513 StartServiceA(
1514 SC_HANDLE hService,
1515 DWORD dwNumServiceArgs,
1516 LPCSTR *lpServiceArgVectors)
1517 {
1518 DPRINT1("StartServiceA is unimplemented\n");
1519 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1520 return FALSE;
1521 }
1522
1523
1524 /**********************************************************************
1525 * StartServiceW
1526 *
1527 * @unimplemented
1528 */
1529 BOOL
1530 STDCALL
1531 StartServiceW(
1532 SC_HANDLE hService,
1533 DWORD dwNumServiceArgs,
1534 LPCWSTR *lpServiceArgVectors)
1535 {
1536 #if 0
1537 DWORD dwError;
1538
1539 DPRINT("StartServiceW()\n", ScLock);
1540
1541 HandleBind();
1542
1543 /* Call to services.exe using RPC */
1544 dwError = ScmrStartServiceW(BindingHandle,
1545 dwNumServiceArgs,
1546 lpServiceArgVectors);
1547 if (dwError != ERROR_SUCCESS)
1548 {
1549 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
1550 SetLastError(dwError);
1551 return FALSE;
1552 }
1553
1554 return TRUE;
1555 #endif
1556 DPRINT1("StartServiceW is unimplemented, but returns success...\n");
1557 //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1558 //return FALSE;
1559 return TRUE;
1560 }
1561
1562
1563 /**********************************************************************
1564 * UnlockServiceDatabase
1565 *
1566 * @implemented
1567 */
1568 BOOL STDCALL
1569 UnlockServiceDatabase(SC_LOCK ScLock)
1570 {
1571 DWORD dwError;
1572
1573 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
1574
1575 HandleBind();
1576
1577 /* Call to services.exe using RPC */
1578 dwError = ScmrUnlockServiceDatabase(BindingHandle,
1579 (unsigned int)ScLock);
1580 if (dwError != ERROR_SUCCESS)
1581 {
1582 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
1583 SetLastError(dwError);
1584 return FALSE;
1585 }
1586
1587 return TRUE;
1588 }
1589
1590
1591 /**********************************************************************
1592 * NotifyBootConfigStatus
1593 *
1594 * @implemented
1595 */
1596 BOOL STDCALL
1597 NotifyBootConfigStatus(BOOL BootAcceptable)
1598 {
1599 DWORD dwError;
1600
1601 DPRINT1("NotifyBootConfigStatus()\n");
1602
1603 HandleBind();
1604
1605 /* Call to services.exe using RPC */
1606 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
1607 BootAcceptable);
1608 if (dwError != ERROR_SUCCESS)
1609 {
1610 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
1611 SetLastError(dwError);
1612 return FALSE;
1613 }
1614
1615 return TRUE;
1616 }
1617
1618
1619 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
1620 {
1621 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1622 }
1623
1624
1625 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
1626 {
1627 HeapFree(GetProcessHeap(), 0, ptr);
1628 }
1629
1630 /* EOF */