Replace implementation of QueryServiceConfigW by a stub (like in pre-20255), as rpcrt...
[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 DPRINT("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(%S) failed (Error %lu)\n", lpServiceName, 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 DPRINT("ScmrOpenServiceA(%s) failed (Error %lu)\n", lpServiceName, 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 DPRINT("ScmrOpenServiceW(%S) failed (Error %lu)\n", lpServiceName, 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 #if 0
1211 DWORD dwError;
1212
1213 DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1214 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1215
1216 HandleBind();
1217
1218 /* Call to services.exe using RPC */
1219 CHECKPOINT1;
1220 dwError = ScmrQueryServiceConfigW(BindingHandle,
1221 (unsigned int)hService,
1222 (unsigned char *)lpServiceConfig,
1223 cbBufSize,
1224 pcbBytesNeeded);
1225 CHECKPOINT1;
1226 if (dwError != ERROR_SUCCESS)
1227 {
1228 DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
1229 SetLastError(dwError);
1230 return FALSE;
1231 }
1232
1233 /* Adjust the pointers */
1234 if (lpServiceConfig->lpBinaryPathName)
1235 lpServiceConfig->lpBinaryPathName =
1236 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1237 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1238
1239 if (lpServiceConfig->lpLoadOrderGroup)
1240 lpServiceConfig->lpLoadOrderGroup =
1241 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1242 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1243
1244 if (lpServiceConfig->lpDependencies)
1245 lpServiceConfig->lpDependencies =
1246 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1247 (ULONG_PTR)lpServiceConfig->lpDependencies);
1248
1249 if (lpServiceConfig->lpServiceStartName)
1250 lpServiceConfig->lpServiceStartName =
1251 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1252 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1253
1254 if (lpServiceConfig->lpDisplayName)
1255 lpServiceConfig->lpDisplayName =
1256 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1257 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1258
1259 DPRINT("QueryServiceConfigW() done\n");
1260
1261 return TRUE;
1262 #else
1263 DPRINT1("QueryServiceConfigW is unimplemented\n");
1264 if (lpServiceConfig && cbBufSize >= sizeof(QUERY_SERVICE_CONFIGW))
1265 {
1266 memset(lpServiceConfig, 0, *pcbBytesNeeded);
1267 return TRUE;
1268 }
1269 else
1270 {
1271 *pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
1272 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1273 return FALSE;
1274 }
1275 #endif
1276 }
1277
1278
1279 /**********************************************************************
1280 * QueryServiceConfig2A
1281 *
1282 * @unimplemented
1283 */
1284 BOOL
1285 STDCALL
1286 QueryServiceConfig2A(
1287 SC_HANDLE hService,
1288 DWORD dwInfo,
1289 LPBYTE lpBuffer,
1290 DWORD cbBufSize,
1291 LPDWORD pcbBytesNeeded)
1292 {
1293 DPRINT1("QueryServiceConfig2A is unimplemented\n");
1294 return FALSE;
1295 }
1296
1297
1298 /**********************************************************************
1299 * QueryServiceConfig2W
1300 *
1301 * @unimplemented
1302 */
1303 BOOL
1304 STDCALL
1305 QueryServiceConfig2W(
1306 SC_HANDLE hService,
1307 DWORD dwInfo,
1308 LPBYTE lpBuffer,
1309 DWORD cbBufSize,
1310 LPDWORD pcbBytesNeeded)
1311 {
1312 DPRINT1("QueryServiceConfig2W is unimplemented\n");
1313 return FALSE;
1314 }
1315
1316
1317 /**********************************************************************
1318 * QueryServiceLockStatusA
1319 *
1320 * @unimplemented
1321 */
1322 BOOL
1323 STDCALL
1324 QueryServiceLockStatusA(
1325 SC_HANDLE hSCManager,
1326 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
1327 DWORD cbBufSize,
1328 LPDWORD pcbBytesNeeded)
1329 {
1330 DPRINT1("QueryServiceLockStatusA is unimplemented\n");
1331 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1332 return FALSE;
1333 }
1334
1335
1336 /**********************************************************************
1337 * QueryServiceLockStatusW
1338 *
1339 * @unimplemented
1340 */
1341 BOOL
1342 STDCALL
1343 QueryServiceLockStatusW(
1344 SC_HANDLE hSCManager,
1345 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
1346 DWORD cbBufSize,
1347 LPDWORD pcbBytesNeeded)
1348 {
1349 DPRINT1("QueryServiceLockStatusW is unimplemented\n");
1350 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1351 return FALSE;
1352 }
1353
1354
1355 /**********************************************************************
1356 * QueryServiceObjectSecurity
1357 *
1358 * @implemented
1359 */
1360 BOOL STDCALL
1361 QueryServiceObjectSecurity(SC_HANDLE hService,
1362 SECURITY_INFORMATION dwSecurityInformation,
1363 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
1364 DWORD cbBufSize,
1365 LPDWORD pcbBytesNeeded)
1366 {
1367 DWORD dwError;
1368
1369 DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
1370 hService, dwSecurityInformation, lpSecurityDescriptor);
1371
1372 HandleBind();
1373
1374 /* Call to services.exe using RPC */
1375 dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
1376 (unsigned int)hService,
1377 dwSecurityInformation,
1378 (unsigned char *)lpSecurityDescriptor,
1379 cbBufSize,
1380 pcbBytesNeeded);
1381 if (dwError != ERROR_SUCCESS)
1382 {
1383 DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
1384 SetLastError(dwError);
1385 return FALSE;
1386 }
1387
1388 return TRUE;
1389 }
1390
1391
1392 /**********************************************************************
1393 * QueryServiceStatus
1394 *
1395 * @implemented
1396 */
1397 BOOL STDCALL
1398 QueryServiceStatus(SC_HANDLE hService,
1399 LPSERVICE_STATUS lpServiceStatus)
1400 {
1401 DWORD dwError;
1402
1403 DPRINT("QueryServiceStatus(%p, %p)\n",
1404 hService, lpServiceStatus);
1405
1406 HandleBind();
1407
1408 /* Call to services.exe using RPC */
1409 dwError = ScmrQueryServiceStatus(BindingHandle,
1410 (unsigned int)hService,
1411 lpServiceStatus);
1412 if (dwError != ERROR_SUCCESS)
1413 {
1414 DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
1415 SetLastError(dwError);
1416 return FALSE;
1417 }
1418
1419 return TRUE;
1420 }
1421
1422
1423 /**********************************************************************
1424 * QueryServiceStatusEx
1425 *
1426 * @implemented
1427 */
1428 BOOL STDCALL
1429 QueryServiceStatusEx(SC_HANDLE hService,
1430 SC_STATUS_TYPE InfoLevel,
1431 LPBYTE lpBuffer,
1432 DWORD cbBufSize,
1433 LPDWORD pcbBytesNeeded)
1434 {
1435 DWORD dwError;
1436
1437 DPRINT("QueryServiceStatusEx() called\n");
1438
1439 HandleBind();
1440
1441 /* Call to services.exe using RPC */
1442 dwError = ScmrQueryServiceStatusEx(BindingHandle,
1443 (unsigned int)hService,
1444 InfoLevel,
1445 lpBuffer,
1446 cbBufSize,
1447 pcbBytesNeeded);
1448 if (dwError != ERROR_SUCCESS)
1449 {
1450 DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
1451 SetLastError(dwError);
1452 return FALSE;
1453 }
1454
1455 return TRUE;
1456 }
1457
1458
1459 /**********************************************************************
1460 * SetServiceObjectSecurity
1461 *
1462 * @implemented
1463 */
1464 BOOL STDCALL
1465 SetServiceObjectSecurity(SC_HANDLE hService,
1466 SECURITY_INFORMATION dwSecurityInformation,
1467 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
1468 {
1469 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
1470 ULONG Length;
1471 NTSTATUS Status;
1472 DWORD dwError;
1473
1474 Length = 0;
1475 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
1476 SelfRelativeSD,
1477 &Length);
1478 if (Status != STATUS_BUFFER_TOO_SMALL)
1479 {
1480 SetLastError(ERROR_INVALID_PARAMETER);
1481 return FALSE;
1482 }
1483
1484 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
1485 if (SelfRelativeSD == NULL)
1486 {
1487 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1488 return FALSE;
1489 }
1490
1491 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
1492 SelfRelativeSD,
1493 &Length);
1494 if (!NT_SUCCESS(Status))
1495 {
1496 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
1497 SetLastError(RtlNtStatusToDosError(Status));
1498 return FALSE;
1499 }
1500
1501 HandleBind();
1502
1503 /* Call to services.exe using RPC */
1504 dwError = ScmrSetServiceObjectSecurity(BindingHandle,
1505 (unsigned int)hService,
1506 dwSecurityInformation,
1507 (unsigned char *)SelfRelativeSD,
1508 Length);
1509
1510 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
1511
1512 if (dwError != ERROR_SUCCESS)
1513 {
1514 DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
1515 SetLastError(dwError);
1516 return FALSE;
1517 }
1518
1519 return TRUE;
1520 }
1521
1522
1523 /**********************************************************************
1524 * StartServiceA
1525 *
1526 * @unimplemented
1527 */
1528 BOOL
1529 STDCALL
1530 StartServiceA(
1531 SC_HANDLE hService,
1532 DWORD dwNumServiceArgs,
1533 LPCSTR *lpServiceArgVectors)
1534 {
1535 DPRINT1("StartServiceA is unimplemented\n");
1536 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1537 return FALSE;
1538 }
1539
1540
1541 /**********************************************************************
1542 * StartServiceW
1543 *
1544 * @unimplemented
1545 */
1546 BOOL
1547 STDCALL
1548 StartServiceW(
1549 SC_HANDLE hService,
1550 DWORD dwNumServiceArgs,
1551 LPCWSTR *lpServiceArgVectors)
1552 {
1553 #if 0
1554 DWORD dwError;
1555
1556 DPRINT("StartServiceW()\n", ScLock);
1557
1558 HandleBind();
1559
1560 /* Call to services.exe using RPC */
1561 dwError = ScmrStartServiceW(BindingHandle,
1562 dwNumServiceArgs,
1563 lpServiceArgVectors);
1564 if (dwError != ERROR_SUCCESS)
1565 {
1566 DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
1567 SetLastError(dwError);
1568 return FALSE;
1569 }
1570
1571 return TRUE;
1572 #endif
1573 DPRINT1("StartServiceW is unimplemented, but returns success...\n");
1574 //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1575 //return FALSE;
1576 return TRUE;
1577 }
1578
1579
1580 /**********************************************************************
1581 * UnlockServiceDatabase
1582 *
1583 * @implemented
1584 */
1585 BOOL STDCALL
1586 UnlockServiceDatabase(SC_LOCK ScLock)
1587 {
1588 DWORD dwError;
1589
1590 DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
1591
1592 HandleBind();
1593
1594 /* Call to services.exe using RPC */
1595 dwError = ScmrUnlockServiceDatabase(BindingHandle,
1596 (unsigned int)ScLock);
1597 if (dwError != ERROR_SUCCESS)
1598 {
1599 DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
1600 SetLastError(dwError);
1601 return FALSE;
1602 }
1603
1604 return TRUE;
1605 }
1606
1607
1608 /**********************************************************************
1609 * NotifyBootConfigStatus
1610 *
1611 * @implemented
1612 */
1613 BOOL STDCALL
1614 NotifyBootConfigStatus(BOOL BootAcceptable)
1615 {
1616 DWORD dwError;
1617
1618 DPRINT1("NotifyBootConfigStatus()\n");
1619
1620 HandleBind();
1621
1622 /* Call to services.exe using RPC */
1623 dwError = ScmrNotifyBootConfigStatus(BindingHandle,
1624 BootAcceptable);
1625 if (dwError != ERROR_SUCCESS)
1626 {
1627 DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
1628 SetLastError(dwError);
1629 return FALSE;
1630 }
1631
1632 return TRUE;
1633 }
1634
1635
1636 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
1637 {
1638 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
1639 }
1640
1641
1642 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
1643 {
1644 HeapFree(GetProcessHeap(), 0, ptr);
1645 }
1646
1647 /* EOF */