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