b1b1dc9f78ed3a50126d363dcd98a80b2de0ead7
[reactos.git] / reactos / dll / win32 / 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
17 #include "wine/debug.h"
18
19 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
20
21
22 /* FUNCTIONS *****************************************************************/
23
24 handle_t __RPC_USER
25 SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName)
26 {
27 handle_t hBinding = NULL;
28 UCHAR *pszStringBinding;
29 RPC_STATUS status;
30
31 TRACE("SVCCTL_HANDLEA_bind() called\n");
32
33 status = RpcStringBindingComposeA(NULL,
34 (UCHAR *)"ncacn_np",
35 (UCHAR *)szMachineName,
36 (UCHAR *)"\\pipe\\ntsvcs",
37 NULL,
38 (UCHAR **)&pszStringBinding);
39 if (status != RPC_S_OK)
40 {
41 ERR("RpcStringBindingCompose returned 0x%x\n", status);
42 return NULL;
43 }
44
45 /* Set the binding handle that will be used to bind to the server. */
46 status = RpcBindingFromStringBindingA(pszStringBinding,
47 &hBinding);
48 if (status != RPC_S_OK)
49 {
50 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
51 }
52
53 status = RpcStringFreeA(&pszStringBinding);
54 if (status != RPC_S_OK)
55 {
56 ERR("RpcStringFree returned 0x%x\n", status);
57 }
58
59 return hBinding;
60 }
61
62
63 void __RPC_USER
64 SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName,
65 handle_t hBinding)
66 {
67 RPC_STATUS status;
68
69 TRACE("SVCCTL_HANDLEA_unbind() called\n");
70
71 status = RpcBindingFree(&hBinding);
72 if (status != RPC_S_OK)
73 {
74 ERR("RpcBindingFree returned 0x%x\n", status);
75 }
76 }
77
78
79 handle_t __RPC_USER
80 SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName)
81 {
82 handle_t hBinding = NULL;
83 LPWSTR pszStringBinding;
84 RPC_STATUS status;
85
86 TRACE("SVCCTL_HANDLEW_bind() called\n");
87
88 status = RpcStringBindingComposeW(NULL,
89 L"ncacn_np",
90 szMachineName,
91 L"\\pipe\\ntsvcs",
92 NULL,
93 &pszStringBinding);
94 if (status != RPC_S_OK)
95 {
96 ERR("RpcStringBindingCompose returned 0x%x\n", status);
97 return NULL;
98 }
99
100 /* Set the binding handle that will be used to bind to the server. */
101 status = RpcBindingFromStringBindingW(pszStringBinding,
102 &hBinding);
103 if (status != RPC_S_OK)
104 {
105 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
106 }
107
108 status = RpcStringFreeW(&pszStringBinding);
109 if (status != RPC_S_OK)
110 {
111 ERR("RpcStringFree returned 0x%x\n", status);
112 }
113
114 return hBinding;
115 }
116
117
118 void __RPC_USER
119 SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName,
120 handle_t hBinding)
121 {
122 RPC_STATUS status;
123
124 TRACE("SVCCTL_HANDLEW_unbind() called\n");
125
126 status = RpcBindingFree(&hBinding);
127 if (status != RPC_S_OK)
128 {
129 ERR("RpcBindingFree returned 0x%x\n", status);
130 }
131 }
132
133
134 handle_t __RPC_USER
135 RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
136 {
137 handle_t hBinding = NULL;
138 LPWSTR pszStringBinding;
139 RPC_STATUS status;
140
141 TRACE("RPC_SERVICE_STATUS_HANDLE_bind() called\n");
142
143 status = RpcStringBindingComposeW(NULL,
144 L"ncacn_np",
145 NULL,
146 L"\\pipe\\ntsvcs",
147 NULL,
148 &pszStringBinding);
149 if (status != RPC_S_OK)
150 {
151 ERR("RpcStringBindingCompose returned 0x%x\n", status);
152 return NULL;
153 }
154
155 /* Set the binding handle that will be used to bind to the server. */
156 status = RpcBindingFromStringBindingW(pszStringBinding,
157 &hBinding);
158 if (status != RPC_S_OK)
159 {
160 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
161 }
162
163 status = RpcStringFreeW(&pszStringBinding);
164 if (status != RPC_S_OK)
165 {
166 ERR("RpcStringFree returned 0x%x\n", status);
167 }
168
169 return hBinding;
170 }
171
172
173 void __RPC_USER
174 RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus,
175 handle_t hBinding)
176 {
177 RPC_STATUS status;
178
179 TRACE("RPC_SERVICE_STATUS_HANDLE_unbind() called\n");
180
181 status = RpcBindingFree(&hBinding);
182 if (status != RPC_S_OK)
183 {
184 ERR("RpcBindingFree returned 0x%x\n", status);
185 }
186 }
187
188
189 DWORD
190 ScmRpcStatusToWinError(RPC_STATUS Status)
191 {
192 switch (Status)
193 {
194 case RPC_S_INVALID_BINDING:
195 case RPC_X_SS_IN_NULL_CONTEXT:
196 return ERROR_INVALID_HANDLE;
197
198 case RPC_X_ENUM_VALUE_OUT_OF_RANGE:
199 case RPC_X_BYTE_COUNT_TOO_SMALL:
200 return ERROR_INVALID_PARAMETER;
201
202 case RPC_X_NULL_REF_POINTER:
203 return ERROR_INVALID_ADDRESS;
204
205 default:
206 return (DWORD)Status;
207 }
208 }
209
210
211 /**********************************************************************
212 * ChangeServiceConfig2A
213 *
214 * @implemented
215 */
216 BOOL WINAPI
217 ChangeServiceConfig2A(SC_HANDLE hService,
218 DWORD dwInfoLevel,
219 LPVOID lpInfo)
220 {
221 SC_RPC_CONFIG_INFOA Info;
222 DWORD dwError;
223
224 TRACE("ChangeServiceConfig2A() called\n");
225
226 /* Fill relevent field of the Info structure */
227 Info.dwInfoLevel = dwInfoLevel;
228 switch (dwInfoLevel)
229 {
230 case SERVICE_CONFIG_DESCRIPTION:
231 Info.psd = (LPSERVICE_DESCRIPTIONA)&lpInfo;
232 Info.lpDescription = ((LPSERVICE_DESCRIPTIONA)lpInfo)->lpDescription; //HACK
233 break;
234
235 case SERVICE_CONFIG_FAILURE_ACTIONS:
236 Info.psfa = (LPSERVICE_FAILURE_ACTIONSA)lpInfo;
237 break;
238
239 default:
240 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
241 SetLastError(ERROR_INVALID_PARAMETER);
242 return FALSE;
243 }
244
245 if (lpInfo == NULL)
246 return TRUE;
247
248 RpcTryExcept
249 {
250 dwError = RChangeServiceConfig2A((SC_RPC_HANDLE)hService,
251 Info);
252 }
253 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
254 {
255 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
256 }
257 RpcEndExcept;
258
259 if (dwError != ERROR_SUCCESS)
260 {
261 ERR("RChangeServiceConfig2A() failed (Error %lu)\n", dwError);
262 SetLastError(dwError);
263 return FALSE;
264 }
265
266 return TRUE;
267 }
268
269
270 /**********************************************************************
271 * ChangeServiceConfig2W
272 *
273 * @implemented
274 */
275 BOOL WINAPI
276 ChangeServiceConfig2W(SC_HANDLE hService,
277 DWORD dwInfoLevel,
278 LPVOID lpInfo)
279 {
280 SC_RPC_CONFIG_INFOW Info;
281 DWORD dwError;
282
283 TRACE("ChangeServiceConfig2W() called\n");
284
285 /* Fill relevent field of the Info structure */
286 Info.dwInfoLevel = dwInfoLevel;
287 switch (dwInfoLevel)
288 {
289 case SERVICE_CONFIG_DESCRIPTION:
290 {
291 Info.psd = (LPSERVICE_DESCRIPTIONW)&lpInfo;
292 break;
293 }
294
295 case SERVICE_CONFIG_FAILURE_ACTIONS:
296 Info.psfa = (LPSERVICE_FAILURE_ACTIONSW)&lpInfo;
297 break;
298
299 default:
300 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
301 SetLastError(ERROR_INVALID_PARAMETER);
302 return FALSE;
303 }
304
305 if (lpInfo == NULL)
306 return TRUE;
307
308 RpcTryExcept
309 {
310 dwError = RChangeServiceConfig2W((SC_RPC_HANDLE)hService,
311 Info);
312 }
313 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
314 {
315 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
316 }
317 RpcEndExcept;
318
319 if (dwError != ERROR_SUCCESS)
320 {
321 ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError);
322 SetLastError(dwError);
323 return FALSE;
324 }
325
326 return TRUE;
327 }
328
329
330 /**********************************************************************
331 * ChangeServiceConfigA
332 *
333 * @implemented
334 */
335 BOOL WINAPI
336 ChangeServiceConfigA(SC_HANDLE hService,
337 DWORD dwServiceType,
338 DWORD dwStartType,
339 DWORD dwErrorControl,
340 LPCSTR lpBinaryPathName,
341 LPCSTR lpLoadOrderGroup,
342 LPDWORD lpdwTagId,
343 LPCSTR lpDependencies,
344 LPCSTR lpServiceStartName,
345 LPCSTR lpPassword,
346 LPCSTR lpDisplayName)
347 {
348 DWORD dwError;
349 DWORD dwDependenciesLength = 0;
350 DWORD dwLength;
351 LPSTR lpStr;
352
353 TRACE("ChangeServiceConfigA() called\n");
354
355 /* Calculate the Dependencies length*/
356 if (lpDependencies != NULL)
357 {
358 lpStr = (LPSTR)lpDependencies;
359 while (*lpStr)
360 {
361 dwLength = strlen(lpStr) + 1;
362 dwDependenciesLength += dwLength;
363 lpStr = lpStr + dwLength;
364 }
365 dwDependenciesLength++;
366 }
367
368 /* FIXME: Encrypt the password */
369
370 RpcTryExcept
371 {
372 /* Call to services.exe using RPC */
373 dwError = RChangeServiceConfigA((SC_RPC_HANDLE)hService,
374 dwServiceType,
375 dwStartType,
376 dwErrorControl,
377 (LPSTR)lpBinaryPathName,
378 (LPSTR)lpLoadOrderGroup,
379 lpdwTagId,
380 (LPSTR)lpDependencies,
381 dwDependenciesLength,
382 (LPSTR)lpServiceStartName,
383 NULL, /* FIXME: lpPassword */
384 0, /* FIXME: dwPasswordLength */
385 (LPSTR)lpDisplayName);
386 }
387 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
388 {
389 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
390 }
391 RpcEndExcept;
392
393 if (dwError != ERROR_SUCCESS)
394 {
395 ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
396 SetLastError(dwError);
397 return FALSE;
398 }
399
400 return TRUE;
401 }
402
403
404 /**********************************************************************
405 * ChangeServiceConfigW
406 *
407 * @implemented
408 */
409 BOOL WINAPI
410 ChangeServiceConfigW(SC_HANDLE hService,
411 DWORD dwServiceType,
412 DWORD dwStartType,
413 DWORD dwErrorControl,
414 LPCWSTR lpBinaryPathName,
415 LPCWSTR lpLoadOrderGroup,
416 LPDWORD lpdwTagId,
417 LPCWSTR lpDependencies,
418 LPCWSTR lpServiceStartName,
419 LPCWSTR lpPassword,
420 LPCWSTR lpDisplayName)
421 {
422 DWORD dwError;
423 DWORD dwDependenciesLength = 0;
424 DWORD dwLength;
425 LPWSTR lpStr;
426
427 TRACE("ChangeServiceConfigW() called\n");
428
429 /* Calculate the Dependencies length*/
430 if (lpDependencies != NULL)
431 {
432 lpStr = (LPWSTR)lpDependencies;
433 while (*lpStr)
434 {
435 dwLength = wcslen(lpStr) + 1;
436 dwDependenciesLength += dwLength;
437 lpStr = lpStr + dwLength;
438 }
439 dwDependenciesLength++;
440 }
441
442 /* FIXME: Encrypt the password */
443
444 RpcTryExcept
445 {
446 /* Call to services.exe using RPC */
447 dwError = RChangeServiceConfigW((SC_RPC_HANDLE)hService,
448 dwServiceType,
449 dwStartType,
450 dwErrorControl,
451 (LPWSTR)lpBinaryPathName,
452 (LPWSTR)lpLoadOrderGroup,
453 lpdwTagId,
454 (LPBYTE)lpDependencies,
455 dwDependenciesLength,
456 (LPWSTR)lpServiceStartName,
457 NULL, /* FIXME: lpPassword */
458 0, /* FIXME: dwPasswordLength */
459 (LPWSTR)lpDisplayName);
460 }
461 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
462 {
463 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
464 }
465 RpcEndExcept;
466
467 if (dwError != ERROR_SUCCESS)
468 {
469 ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError);
470 SetLastError(dwError);
471 return FALSE;
472 }
473
474 return TRUE;
475 }
476
477
478 /**********************************************************************
479 * CloseServiceHandle
480 *
481 * @implemented
482 */
483 BOOL WINAPI
484 CloseServiceHandle(SC_HANDLE hSCObject)
485 {
486 DWORD dwError;
487
488 TRACE("CloseServiceHandle() called\n");
489
490 if (!hSCObject)
491 {
492 SetLastError(ERROR_INVALID_HANDLE);
493 return FALSE;
494 }
495
496 RpcTryExcept
497 {
498 /* Call to services.exe using RPC */
499 dwError = RCloseServiceHandle((LPSC_RPC_HANDLE)&hSCObject);
500 }
501 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
502 {
503 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
504 }
505 RpcEndExcept;
506
507 if (dwError)
508 {
509 ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError);
510 SetLastError(dwError);
511 return FALSE;
512 }
513
514 TRACE("CloseServiceHandle() done\n");
515
516 return TRUE;
517 }
518
519
520 /**********************************************************************
521 * ControlService
522 *
523 * @implemented
524 */
525 BOOL WINAPI
526 ControlService(SC_HANDLE hService,
527 DWORD dwControl,
528 LPSERVICE_STATUS lpServiceStatus)
529 {
530 DWORD dwError;
531
532 TRACE("ControlService(%x, %x, %p)\n",
533 hService, dwControl, lpServiceStatus);
534
535 RpcTryExcept
536 {
537 /* Call to services.exe using RPC */
538 dwError = RControlService((SC_RPC_HANDLE)hService,
539 dwControl,
540 lpServiceStatus);
541 }
542 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
543 {
544 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
545 }
546 RpcEndExcept;
547
548 if (dwError != ERROR_SUCCESS)
549 {
550 ERR("RControlService() failed (Error %lu)\n", dwError);
551 SetLastError(dwError);
552 return FALSE;
553 }
554
555 TRACE("ControlService() done\n");
556
557 return TRUE;
558 }
559
560
561 /**********************************************************************
562 * ControlServiceEx
563 *
564 * @unimplemented
565 */
566 BOOL WINAPI
567 ControlServiceEx(IN SC_HANDLE hService,
568 IN DWORD dwControl,
569 IN DWORD dwInfoLevel,
570 IN OUT PVOID pControlParams)
571 {
572 FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
573 hService, dwControl, dwInfoLevel, pControlParams);
574 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
575 return FALSE;
576 }
577
578
579 /**********************************************************************
580 * CreateServiceA
581 *
582 * @implemented
583 */
584 SC_HANDLE WINAPI
585 CreateServiceA(SC_HANDLE hSCManager,
586 LPCSTR lpServiceName,
587 LPCSTR lpDisplayName,
588 DWORD dwDesiredAccess,
589 DWORD dwServiceType,
590 DWORD dwStartType,
591 DWORD dwErrorControl,
592 LPCSTR lpBinaryPathName,
593 LPCSTR lpLoadOrderGroup,
594 LPDWORD lpdwTagId,
595 LPCSTR lpDependencies,
596 LPCSTR lpServiceStartName,
597 LPCSTR lpPassword)
598 {
599 SC_HANDLE RetVal = NULL;
600 LPWSTR lpServiceNameW = NULL;
601 LPWSTR lpDisplayNameW = NULL;
602 LPWSTR lpBinaryPathNameW = NULL;
603 LPWSTR lpLoadOrderGroupW = NULL;
604 LPWSTR lpDependenciesW = NULL;
605 LPWSTR lpServiceStartNameW = NULL;
606 LPWSTR lpPasswordW = NULL;
607 DWORD dwDependenciesLength = 0;
608 DWORD dwLength;
609 int len;
610 LPSTR lpStr;
611
612 if (!hSCManager)
613 {
614 SetLastError(ERROR_INVALID_HANDLE);
615 return NULL;
616 }
617
618 if (lpServiceName)
619 {
620 len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
621 lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
622 if (!lpServiceNameW)
623 {
624 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
625 goto cleanup;
626 }
627 MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
628 }
629
630 if (lpDisplayName)
631 {
632 len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
633 lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
634 if (!lpDisplayNameW)
635 {
636 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
637 goto cleanup;
638 }
639 MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
640 }
641
642 if (lpBinaryPathName)
643 {
644 len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
645 lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
646 if (!lpBinaryPathNameW)
647 {
648 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
649 goto cleanup;
650 }
651 MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
652 }
653
654 if (lpLoadOrderGroup)
655 {
656 len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
657 lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
658 if (!lpLoadOrderGroupW)
659 {
660 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
661 goto cleanup;
662 }
663 MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
664 }
665
666 if (lpDependencies)
667 {
668 lpStr = (LPSTR)lpDependencies;
669 while (*lpStr)
670 {
671 dwLength = strlen(lpStr) + 1;
672 dwDependenciesLength += dwLength;
673 lpStr = lpStr + dwLength;
674 }
675 dwDependenciesLength++;
676
677 lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
678 if (!lpDependenciesW)
679 {
680 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
681 goto cleanup;
682 }
683 MultiByteToWideChar(CP_ACP, 0, lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
684 }
685
686 if (lpServiceStartName)
687 {
688 len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
689 lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
690 if (!lpServiceStartNameW)
691 {
692 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
693 goto cleanup;
694 }
695 MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
696 }
697
698 if (lpPassword)
699 {
700 len = MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, NULL, 0);
701 lpPasswordW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
702 if (!lpPasswordW)
703 {
704 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
705 goto cleanup;
706 }
707 MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
708 }
709
710 RetVal = CreateServiceW(hSCManager,
711 lpServiceNameW,
712 lpDisplayNameW,
713 dwDesiredAccess,
714 dwServiceType,
715 dwStartType,
716 dwErrorControl,
717 lpBinaryPathNameW,
718 lpLoadOrderGroupW,
719 lpdwTagId,
720 lpDependenciesW,
721 lpServiceStartNameW,
722 lpPasswordW);
723
724 cleanup:
725 if (lpServiceNameW !=NULL)
726 HeapFree(GetProcessHeap(), 0, lpServiceNameW);
727
728 if (lpDisplayNameW != NULL)
729 HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
730
731 if (lpBinaryPathNameW != NULL)
732 HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
733
734 if (lpLoadOrderGroupW != NULL)
735 HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
736
737 if (lpDependenciesW != NULL)
738 HeapFree(GetProcessHeap(), 0, lpDependenciesW);
739
740 if (lpServiceStartNameW != NULL)
741 HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
742
743 if (lpPasswordW != NULL)
744 HeapFree(GetProcessHeap(), 0, lpPasswordW);
745
746 return RetVal;
747 }
748
749
750 /**********************************************************************
751 * CreateServiceW
752 *
753 * @implemented
754 */
755 SC_HANDLE WINAPI
756 CreateServiceW(SC_HANDLE hSCManager,
757 LPCWSTR lpServiceName,
758 LPCWSTR lpDisplayName,
759 DWORD dwDesiredAccess,
760 DWORD dwServiceType,
761 DWORD dwStartType,
762 DWORD dwErrorControl,
763 LPCWSTR lpBinaryPathName,
764 LPCWSTR lpLoadOrderGroup,
765 LPDWORD lpdwTagId,
766 LPCWSTR lpDependencies,
767 LPCWSTR lpServiceStartName,
768 LPCWSTR lpPassword)
769 {
770 SC_HANDLE hService = NULL;
771 DWORD dwDependenciesLength = 0;
772 DWORD dwError;
773 DWORD dwLength;
774 LPWSTR lpStr;
775
776 TRACE("CreateServiceW() called\n");
777 TRACE("%p %S %S\n", hSCManager,
778 lpServiceName, lpDisplayName);
779
780 if (!hSCManager)
781 {
782 SetLastError(ERROR_INVALID_HANDLE);
783 return NULL;
784 }
785
786 /* Calculate the Dependencies length*/
787 if (lpDependencies != NULL)
788 {
789 lpStr = (LPWSTR)lpDependencies;
790 while (*lpStr)
791 {
792 dwLength = wcslen(lpStr) + 1;
793 dwDependenciesLength += dwLength;
794 lpStr = lpStr + dwLength;
795 }
796 dwDependenciesLength++;
797
798 dwDependenciesLength *= sizeof(WCHAR);
799 }
800
801 /* FIXME: Encrypt the password */
802
803 RpcTryExcept
804 {
805 /* Call to services.exe using RPC */
806 dwError = RCreateServiceW((SC_RPC_HANDLE)hSCManager,
807 lpServiceName,
808 lpDisplayName,
809 dwDesiredAccess,
810 dwServiceType,
811 dwStartType,
812 dwErrorControl,
813 lpBinaryPathName,
814 lpLoadOrderGroup,
815 lpdwTagId,
816 (LPBYTE)lpDependencies,
817 dwDependenciesLength,
818 lpServiceStartName,
819 NULL, /* FIXME: lpPassword */
820 0, /* FIXME: dwPasswordLength */
821 (SC_RPC_HANDLE *)&hService);
822 }
823 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
824 {
825 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
826 }
827 RpcEndExcept;
828
829 if (dwError != ERROR_SUCCESS)
830 {
831 ERR("RCreateServiceW() failed (Error %lu)\n", dwError);
832 SetLastError(dwError);
833 return NULL;
834 }
835
836 return hService;
837 }
838
839
840 /**********************************************************************
841 * DeleteService
842 *
843 * @implemented
844 */
845 BOOL WINAPI
846 DeleteService(SC_HANDLE hService)
847 {
848 DWORD dwError;
849
850 TRACE("DeleteService(%x)\n", hService);
851
852 RpcTryExcept
853 {
854 /* Call to services.exe using RPC */
855 dwError = RDeleteService((SC_RPC_HANDLE)hService);
856 }
857 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
858 {
859 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
860 }
861 RpcEndExcept;
862
863 if (dwError != ERROR_SUCCESS)
864 {
865 ERR("RDeleteService() failed (Error %lu)\n", dwError);
866 SetLastError(dwError);
867 return FALSE;
868 }
869
870 return TRUE;
871 }
872
873
874 /**********************************************************************
875 * EnumDependentServicesA
876 *
877 * @implemented
878 */
879 BOOL WINAPI
880 EnumDependentServicesA(SC_HANDLE hService,
881 DWORD dwServiceState,
882 LPENUM_SERVICE_STATUSA lpServices,
883 DWORD cbBufSize,
884 LPDWORD pcbBytesNeeded,
885 LPDWORD lpServicesReturned)
886 {
887 LPENUM_SERVICE_STATUSA lpStatusPtr;
888 DWORD dwError;
889 DWORD dwCount;
890
891 TRACE("EnumServicesStatusA() called\n");
892
893 RpcTryExcept
894 {
895 dwError = REnumDependentServicesA((SC_RPC_HANDLE)hService,
896 dwServiceState,
897 (LPBYTE)lpServices,
898 cbBufSize,
899 pcbBytesNeeded,
900 lpServicesReturned);
901 }
902 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
903 {
904 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
905 }
906 RpcEndExcept;
907
908 if (dwError != ERROR_SUCCESS)
909 {
910 ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError);
911 SetLastError(dwError);
912 return FALSE;
913 }
914
915 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
916 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
917 {
918 if (lpStatusPtr->lpServiceName)
919 lpStatusPtr->lpServiceName =
920 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
921
922 if (lpStatusPtr->lpDisplayName)
923 lpStatusPtr->lpDisplayName =
924 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
925
926 lpStatusPtr++;
927 }
928
929 TRACE("EnumDependentServicesA() done\n");
930
931 return TRUE;
932 }
933
934
935 /**********************************************************************
936 * EnumDependentServicesW
937 *
938 * @implemented
939 */
940 BOOL WINAPI
941 EnumDependentServicesW(SC_HANDLE hService,
942 DWORD dwServiceState,
943 LPENUM_SERVICE_STATUSW lpServices,
944 DWORD cbBufSize,
945 LPDWORD pcbBytesNeeded,
946 LPDWORD lpServicesReturned)
947 {
948 LPENUM_SERVICE_STATUSW lpStatusPtr;
949 DWORD dwError;
950 DWORD dwCount;
951
952 TRACE("EnumServicesStatusW() called\n");
953
954 RpcTryExcept
955 {
956 dwError = REnumDependentServicesW((SC_RPC_HANDLE)hService,
957 dwServiceState,
958 (LPBYTE)lpServices,
959 cbBufSize,
960 pcbBytesNeeded,
961 lpServicesReturned);
962 }
963 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
964 {
965 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
966 }
967 RpcEndExcept;
968
969 if (dwError != ERROR_SUCCESS)
970 {
971 ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError);
972 SetLastError(dwError);
973 return FALSE;
974 }
975
976 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
977 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
978 {
979 if (lpStatusPtr->lpServiceName)
980 lpStatusPtr->lpServiceName =
981 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
982
983 if (lpStatusPtr->lpDisplayName)
984 lpStatusPtr->lpDisplayName =
985 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
986
987 lpStatusPtr++;
988 }
989
990 TRACE("EnumDependentServicesW() done\n");
991
992 return TRUE;
993 }
994
995
996 /**********************************************************************
997 * EnumServiceGroupW
998 *
999 * @unimplemented
1000 */
1001 BOOL
1002 WINAPI
1003 EnumServiceGroupW(
1004 SC_HANDLE hSCManager,
1005 DWORD dwServiceType,
1006 DWORD dwServiceState,
1007 LPENUM_SERVICE_STATUSW lpServices,
1008 DWORD cbBufSize,
1009 LPDWORD pcbBytesNeeded,
1010 LPDWORD lpServicesReturned,
1011 LPDWORD lpResumeHandle,
1012 LPCWSTR lpGroup)
1013 {
1014 FIXME("EnumServiceGroupW is unimplemented\n");
1015 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1016 return FALSE;
1017 }
1018
1019
1020 /**********************************************************************
1021 * EnumServicesStatusA
1022 *
1023 * @implemented
1024 */
1025 BOOL WINAPI
1026 EnumServicesStatusA(SC_HANDLE hSCManager,
1027 DWORD dwServiceType,
1028 DWORD dwServiceState,
1029 LPENUM_SERVICE_STATUSA lpServices,
1030 DWORD cbBufSize,
1031 LPDWORD pcbBytesNeeded,
1032 LPDWORD lpServicesReturned,
1033 LPDWORD lpResumeHandle)
1034 {
1035 LPENUM_SERVICE_STATUSA lpStatusPtr;
1036 DWORD dwError;
1037 DWORD dwCount;
1038
1039 TRACE("EnumServicesStatusA() called\n");
1040
1041 if (!hSCManager)
1042 {
1043 SetLastError(ERROR_INVALID_HANDLE);
1044 return FALSE;
1045 }
1046
1047 if (dwServiceType != SERVICE_DRIVER && dwServiceType != SERVICE_WIN32)
1048 {
1049 if (pcbBytesNeeded && lpServicesReturned)
1050 {
1051 *pcbBytesNeeded = 0;
1052 *lpServicesReturned = 0;
1053 }
1054
1055 SetLastError(ERROR_INVALID_PARAMETER);
1056 return FALSE;
1057 }
1058
1059 if (dwServiceState != SERVICE_ACTIVE && dwServiceState != SERVICE_INACTIVE && dwServiceState != SERVICE_STATE_ALL)
1060 {
1061 if (pcbBytesNeeded)
1062 *pcbBytesNeeded = 0;
1063
1064 if (lpServicesReturned)
1065 *lpServicesReturned = 0;
1066
1067 SetLastError(ERROR_INVALID_PARAMETER);
1068 return FALSE;
1069 }
1070
1071 if (!pcbBytesNeeded || !lpServicesReturned)
1072 {
1073 SetLastError(ERROR_INVALID_ADDRESS);
1074 return FALSE;
1075 }
1076
1077 if (!lpServices && cbBufSize != 0)
1078 {
1079 SetLastError(ERROR_INVALID_ADDRESS);
1080 return FALSE;
1081 }
1082
1083 RpcTryExcept
1084 {
1085 dwError = REnumServicesStatusA((SC_RPC_HANDLE)hSCManager,
1086 dwServiceType,
1087 dwServiceState,
1088 (LPBYTE)lpServices,
1089 cbBufSize,
1090 pcbBytesNeeded,
1091 lpServicesReturned,
1092 lpResumeHandle);
1093 }
1094 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1095 {
1096 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1097 }
1098 RpcEndExcept;
1099
1100 if (dwError != ERROR_SUCCESS)
1101 {
1102 ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError);
1103 SetLastError(dwError);
1104 return FALSE;
1105 }
1106
1107 lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
1108 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1109 {
1110 if (lpStatusPtr->lpServiceName)
1111 lpStatusPtr->lpServiceName =
1112 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1113
1114 if (lpStatusPtr->lpDisplayName)
1115 lpStatusPtr->lpDisplayName =
1116 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1117
1118 lpStatusPtr++;
1119 }
1120
1121 TRACE("EnumServicesStatusA() done\n");
1122
1123 return TRUE;
1124 }
1125
1126
1127 /**********************************************************************
1128 * EnumServicesStatusW
1129 *
1130 * @implemented
1131 */
1132 BOOL WINAPI
1133 EnumServicesStatusW(SC_HANDLE hSCManager,
1134 DWORD dwServiceType,
1135 DWORD dwServiceState,
1136 LPENUM_SERVICE_STATUSW lpServices,
1137 DWORD cbBufSize,
1138 LPDWORD pcbBytesNeeded,
1139 LPDWORD lpServicesReturned,
1140 LPDWORD lpResumeHandle)
1141 {
1142 LPENUM_SERVICE_STATUSW lpStatusPtr;
1143 DWORD dwError;
1144 DWORD dwCount;
1145
1146 TRACE("EnumServicesStatusW() called\n");
1147
1148 if (!hSCManager)
1149 {
1150 SetLastError(ERROR_INVALID_HANDLE);
1151 return FALSE;
1152 }
1153
1154 RpcTryExcept
1155 {
1156 dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager,
1157 dwServiceType,
1158 dwServiceState,
1159 (LPBYTE)lpServices,
1160 cbBufSize,
1161 pcbBytesNeeded,
1162 lpServicesReturned,
1163 lpResumeHandle);
1164 }
1165 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1166 {
1167 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1168 }
1169 RpcEndExcept;
1170
1171 if (dwError != ERROR_SUCCESS)
1172 {
1173 ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError);
1174 SetLastError(dwError);
1175 return FALSE;
1176 }
1177
1178 lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
1179 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1180 {
1181 if (lpStatusPtr->lpServiceName)
1182 lpStatusPtr->lpServiceName =
1183 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1184
1185 if (lpStatusPtr->lpDisplayName)
1186 lpStatusPtr->lpDisplayName =
1187 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1188
1189 lpStatusPtr++;
1190 }
1191
1192 TRACE("EnumServicesStatusW() done\n");
1193
1194 return TRUE;
1195 }
1196
1197
1198 /**********************************************************************
1199 * EnumServicesStatusExA
1200 *
1201 * @implemented
1202 */
1203 BOOL WINAPI
1204 EnumServicesStatusExA(SC_HANDLE hSCManager,
1205 SC_ENUM_TYPE InfoLevel,
1206 DWORD dwServiceType,
1207 DWORD dwServiceState,
1208 LPBYTE lpServices,
1209 DWORD cbBufSize,
1210 LPDWORD pcbBytesNeeded,
1211 LPDWORD lpServicesReturned,
1212 LPDWORD lpResumeHandle,
1213 LPCSTR pszGroupName)
1214 {
1215 LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
1216 DWORD dwError;
1217 DWORD dwCount;
1218
1219 TRACE("EnumServicesStatusExA() called\n");
1220
1221 if (InfoLevel != SC_ENUM_PROCESS_INFO)
1222 {
1223 SetLastError(ERROR_INVALID_LEVEL);
1224 return FALSE;
1225 }
1226
1227 if (!hSCManager)
1228 {
1229 SetLastError(ERROR_INVALID_HANDLE);
1230 return FALSE;
1231 }
1232
1233
1234 RpcTryExcept
1235 {
1236 dwError = REnumServicesStatusExA((SC_RPC_HANDLE)hSCManager,
1237 InfoLevel,
1238 dwServiceType,
1239 dwServiceState,
1240 (LPBYTE)lpServices,
1241 cbBufSize,
1242 pcbBytesNeeded,
1243 lpServicesReturned,
1244 lpResumeHandle,
1245 (LPSTR)pszGroupName);
1246 }
1247 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1248 {
1249 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1250 }
1251 RpcEndExcept;
1252
1253 if (dwError == ERROR_MORE_DATA)
1254 {
1255 WARN("Required buffer size %ul\n", *pcbBytesNeeded);
1256 SetLastError(dwError);
1257 return FALSE;
1258 }
1259 else if (dwError == ERROR_SUCCESS)
1260 {
1261 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
1262 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1263 {
1264 if (lpStatusPtr->lpServiceName)
1265 lpStatusPtr->lpServiceName =
1266 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1267
1268 if (lpStatusPtr->lpDisplayName)
1269 lpStatusPtr->lpDisplayName =
1270 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1271
1272 lpStatusPtr++;
1273 }
1274 }
1275 else
1276 {
1277 ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError);
1278 SetLastError(dwError);
1279 return FALSE;
1280 }
1281
1282 TRACE("EnumServicesStatusExA() done\n");
1283
1284 return TRUE;
1285 }
1286
1287
1288 /**********************************************************************
1289 * EnumServicesStatusExW
1290 *
1291 * @implemented
1292 */
1293 BOOL WINAPI
1294 EnumServicesStatusExW(SC_HANDLE hSCManager,
1295 SC_ENUM_TYPE InfoLevel,
1296 DWORD dwServiceType,
1297 DWORD dwServiceState,
1298 LPBYTE lpServices,
1299 DWORD cbBufSize,
1300 LPDWORD pcbBytesNeeded,
1301 LPDWORD lpServicesReturned,
1302 LPDWORD lpResumeHandle,
1303 LPCWSTR pszGroupName)
1304 {
1305 LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
1306 DWORD dwError;
1307 DWORD dwCount;
1308
1309 TRACE("EnumServicesStatusExW() called\n");
1310
1311 RpcTryExcept
1312 {
1313 dwError = REnumServicesStatusExW((SC_RPC_HANDLE)hSCManager,
1314 InfoLevel,
1315 dwServiceType,
1316 dwServiceState,
1317 (LPBYTE)lpServices,
1318 cbBufSize,
1319 pcbBytesNeeded,
1320 lpServicesReturned,
1321 lpResumeHandle,
1322 (LPWSTR)pszGroupName);
1323 }
1324 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1325 {
1326 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1327 }
1328 RpcEndExcept;
1329
1330 if (dwError == ERROR_MORE_DATA)
1331 {
1332 WARN("Required buffer size %ul\n", *pcbBytesNeeded);
1333 SetLastError(dwError);
1334 return FALSE;
1335 }
1336 else if (dwError == ERROR_SUCCESS)
1337 {
1338 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
1339 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1340 {
1341 if (lpStatusPtr->lpServiceName)
1342 lpStatusPtr->lpServiceName =
1343 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1344
1345 if (lpStatusPtr->lpDisplayName)
1346 lpStatusPtr->lpDisplayName =
1347 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1348
1349 lpStatusPtr++;
1350 }
1351 }
1352 else
1353 {
1354 ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError);
1355 SetLastError(dwError);
1356 return FALSE;
1357 }
1358
1359 TRACE("EnumServicesStatusExW() done\n");
1360
1361 return TRUE;
1362 }
1363
1364
1365 /**********************************************************************
1366 * GetServiceDisplayNameA
1367 *
1368 * @implemented
1369 */
1370 BOOL WINAPI
1371 GetServiceDisplayNameA(SC_HANDLE hSCManager,
1372 LPCSTR lpServiceName,
1373 LPSTR lpDisplayName,
1374 LPDWORD lpcchBuffer)
1375 {
1376 DWORD dwError;
1377
1378 TRACE("GetServiceDisplayNameA() called\n");
1379 TRACE("%p %s %p %p\n", hSCManager,
1380 debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer);
1381
1382 if (!hSCManager)
1383 {
1384 SetLastError(ERROR_INVALID_HANDLE);
1385 return FALSE;
1386 }
1387
1388 if (!lpDisplayName)
1389 *lpcchBuffer = 0;
1390
1391 RpcTryExcept
1392 {
1393 dwError = RGetServiceDisplayNameA((SC_RPC_HANDLE)hSCManager,
1394 lpServiceName,
1395 lpDisplayName,
1396 lpcchBuffer);
1397 }
1398 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1399 {
1400 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1401 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1402 }
1403
1404
1405 RpcEndExcept;
1406
1407 if (dwError != ERROR_SUCCESS)
1408 {
1409 ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
1410 SetLastError(dwError);
1411 return FALSE;
1412 }
1413
1414 return TRUE;
1415 }
1416
1417
1418 /**********************************************************************
1419 * GetServiceDisplayNameW
1420 *
1421 * @implemented
1422 */
1423 BOOL WINAPI
1424 GetServiceDisplayNameW(SC_HANDLE hSCManager,
1425 LPCWSTR lpServiceName,
1426 LPWSTR lpDisplayName,
1427 LPDWORD lpcchBuffer)
1428 {
1429 DWORD dwError;
1430
1431 TRACE("GetServiceDisplayNameW() called\n");
1432
1433 if (!hSCManager)
1434 {
1435 SetLastError(ERROR_INVALID_HANDLE);
1436 return FALSE;
1437 }
1438
1439 if (!lpDisplayName)
1440 *lpcchBuffer = 0;
1441
1442 RpcTryExcept
1443 {
1444 dwError = RGetServiceDisplayNameW((SC_RPC_HANDLE)hSCManager,
1445 lpServiceName,
1446 lpDisplayName,
1447 lpcchBuffer);
1448 }
1449 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1450 {
1451 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1452 }
1453 RpcEndExcept;
1454
1455 if (dwError != ERROR_SUCCESS)
1456 {
1457 ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
1458 SetLastError(dwError);
1459 return FALSE;
1460 }
1461
1462 return TRUE;
1463 }
1464
1465
1466 /**********************************************************************
1467 * GetServiceKeyNameA
1468 *
1469 * @implemented
1470 */
1471 BOOL WINAPI
1472 GetServiceKeyNameA(SC_HANDLE hSCManager,
1473 LPCSTR lpDisplayName,
1474 LPSTR lpServiceName,
1475 LPDWORD lpcchBuffer)
1476 {
1477 DWORD dwError;
1478
1479 TRACE("GetServiceKeyNameA() called\n");
1480
1481 if (!hSCManager)
1482 {
1483 SetLastError(ERROR_INVALID_HANDLE);
1484 return FALSE;
1485 }
1486
1487 if (!lpDisplayName)
1488 {
1489 SetLastError(ERROR_INVALID_ADDRESS);
1490
1491 if (!lpServiceName)
1492 *lpcchBuffer = 1;
1493 return FALSE;
1494 }
1495
1496 if (!lpServiceName)
1497 *lpcchBuffer = 0;
1498
1499 RpcTryExcept
1500 {
1501 dwError = RGetServiceKeyNameA((SC_RPC_HANDLE)hSCManager,
1502 lpDisplayName,
1503 lpServiceName,
1504 lpcchBuffer);
1505 }
1506 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1507 {
1508 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1509 }
1510 RpcEndExcept;
1511
1512 if (dwError != ERROR_SUCCESS)
1513 {
1514 ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
1515 SetLastError(dwError);
1516 return FALSE;
1517 }
1518
1519 return TRUE;
1520 }
1521
1522
1523 /**********************************************************************
1524 * GetServiceKeyNameW
1525 *
1526 * @implemented
1527 */
1528 BOOL WINAPI
1529 GetServiceKeyNameW(SC_HANDLE hSCManager,
1530 LPCWSTR lpDisplayName,
1531 LPWSTR lpServiceName,
1532 LPDWORD lpcchBuffer)
1533 {
1534 DWORD dwError;
1535
1536 TRACE("GetServiceKeyNameW() called\n");
1537
1538 if (!hSCManager)
1539 {
1540 SetLastError(ERROR_INVALID_HANDLE);
1541 return FALSE;
1542 }
1543
1544 if (!lpDisplayName)
1545 {
1546 SetLastError(ERROR_INVALID_ADDRESS);
1547
1548 if (!lpServiceName)
1549 *lpcchBuffer = 1;
1550 return FALSE;
1551 }
1552
1553 if (!lpServiceName)
1554 *lpcchBuffer = 0;
1555
1556 RpcTryExcept
1557 {
1558 dwError = RGetServiceKeyNameW((SC_RPC_HANDLE)hSCManager,
1559 lpDisplayName,
1560 lpServiceName,
1561 lpcchBuffer);
1562 }
1563 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1564 {
1565 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1566 }
1567 RpcEndExcept;
1568
1569 if (dwError != ERROR_SUCCESS)
1570 {
1571 ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
1572 SetLastError(dwError);
1573 return FALSE;
1574 }
1575
1576 return TRUE;
1577 }
1578
1579
1580 /**********************************************************************
1581 * LockServiceDatabase
1582 *
1583 * @implemented
1584 */
1585 SC_LOCK WINAPI
1586 LockServiceDatabase(SC_HANDLE hSCManager)
1587 {
1588 SC_LOCK hLock;
1589 DWORD dwError;
1590
1591 TRACE("LockServiceDatabase(%x)\n", hSCManager);
1592
1593 RpcTryExcept
1594 {
1595 /* Call to services.exe using RPC */
1596 dwError = RLockServiceDatabase((SC_RPC_HANDLE)hSCManager,
1597 (SC_RPC_LOCK *)&hLock);
1598 }
1599 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1600 {
1601 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1602 }
1603 RpcEndExcept;
1604
1605 if (dwError != ERROR_SUCCESS)
1606 {
1607 ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError);
1608 SetLastError(dwError);
1609 return NULL;
1610 }
1611
1612 TRACE("hLock = %p\n", hLock);
1613
1614 return hLock;
1615 }
1616
1617
1618 static VOID
1619 WaitForSCManager(VOID)
1620 {
1621 HANDLE hEvent;
1622
1623 TRACE("WaitForSCManager() called\n");
1624
1625 /* Try to open the existing event */
1626 hEvent = OpenEventW(SYNCHRONIZE,
1627 FALSE,
1628 L"SvcctrlStartEvent_A3752DX");
1629 if (hEvent == NULL)
1630 {
1631 if (GetLastError() != ERROR_FILE_NOT_FOUND)
1632 return;
1633
1634 /* Try to create a new event */
1635 hEvent = CreateEventW(NULL,
1636 TRUE,
1637 FALSE,
1638 L"SvcctrlStartEvent_A3752DX");
1639 if (hEvent == NULL)
1640 {
1641 /* Try to open the existing event again */
1642 hEvent = OpenEventW(SYNCHRONIZE,
1643 FALSE,
1644 L"SvcctrlStartEvent_A3752DX");
1645 if (hEvent == NULL)
1646 return;
1647 }
1648 }
1649
1650 /* Wait for 3 minutes */
1651 WaitForSingleObject(hEvent, 180000);
1652 CloseHandle(hEvent);
1653
1654 TRACE("ScmWaitForSCManager() done\n");
1655 }
1656
1657
1658 /**********************************************************************
1659 * OpenSCManagerA
1660 *
1661 * @implemented
1662 */
1663 SC_HANDLE WINAPI
1664 OpenSCManagerA(LPCSTR lpMachineName,
1665 LPCSTR lpDatabaseName,
1666 DWORD dwDesiredAccess)
1667 {
1668 SC_HANDLE hScm = NULL;
1669 DWORD dwError;
1670
1671 TRACE("OpenSCManagerA(%s, %s, %lx)\n",
1672 lpMachineName, lpDatabaseName, dwDesiredAccess);
1673
1674 WaitForSCManager();
1675
1676 RpcTryExcept
1677 {
1678 /* Call to services.exe using RPC */
1679 dwError = ROpenSCManagerA((LPSTR)lpMachineName,
1680 (LPSTR)lpDatabaseName,
1681 dwDesiredAccess,
1682 (SC_RPC_HANDLE *)&hScm);
1683 }
1684 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1685 {
1686 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1687 }
1688 RpcEndExcept;
1689
1690 if (dwError != ERROR_SUCCESS)
1691 {
1692 ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError);
1693 SetLastError(dwError);
1694 return NULL;
1695 }
1696
1697 TRACE("hScm = %p\n", hScm);
1698
1699 return hScm;
1700 }
1701
1702
1703 /**********************************************************************
1704 * OpenSCManagerW
1705 *
1706 * @implemented
1707 */
1708 SC_HANDLE WINAPI
1709 OpenSCManagerW(LPCWSTR lpMachineName,
1710 LPCWSTR lpDatabaseName,
1711 DWORD dwDesiredAccess)
1712 {
1713 SC_HANDLE hScm = NULL;
1714 DWORD dwError;
1715
1716 TRACE("OpenSCManagerW(%S, %S, %lx)\n",
1717 lpMachineName, lpDatabaseName, dwDesiredAccess);
1718
1719 WaitForSCManager();
1720
1721 RpcTryExcept
1722 {
1723 /* Call to services.exe using RPC */
1724 dwError = ROpenSCManagerW((LPWSTR)lpMachineName,
1725 (LPWSTR)lpDatabaseName,
1726 dwDesiredAccess,
1727 (SC_RPC_HANDLE *)&hScm);
1728 }
1729 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1730 {
1731 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1732 }
1733 RpcEndExcept;
1734
1735 if (dwError != ERROR_SUCCESS)
1736 {
1737 ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError);
1738 SetLastError(dwError);
1739 return NULL;
1740 }
1741
1742 TRACE("hScm = %p\n", hScm);
1743
1744 return hScm;
1745 }
1746
1747
1748 /**********************************************************************
1749 * OpenServiceA
1750 *
1751 * @implemented
1752 */
1753 SC_HANDLE WINAPI
1754 OpenServiceA(SC_HANDLE hSCManager,
1755 LPCSTR lpServiceName,
1756 DWORD dwDesiredAccess)
1757 {
1758 SC_HANDLE hService = NULL;
1759 DWORD dwError;
1760
1761 TRACE("OpenServiceA(%p, %s, %lx)\n",
1762 hSCManager, lpServiceName, dwDesiredAccess);
1763
1764 if (!hSCManager)
1765 {
1766 SetLastError(ERROR_INVALID_HANDLE);
1767 return NULL;
1768 }
1769
1770 RpcTryExcept
1771 {
1772 /* Call to services.exe using RPC */
1773 dwError = ROpenServiceA((SC_RPC_HANDLE)hSCManager,
1774 (LPSTR)lpServiceName,
1775 dwDesiredAccess,
1776 (SC_RPC_HANDLE *)&hService);
1777 }
1778 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1779 {
1780 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1781 }
1782 RpcEndExcept;
1783
1784 if (dwError != ERROR_SUCCESS)
1785 {
1786 ERR("ROpenServiceA() failed (Error %lu)\n", dwError);
1787 SetLastError(dwError);
1788 return NULL;
1789 }
1790
1791 TRACE("hService = %p\n", hService);
1792
1793 return hService;
1794 }
1795
1796
1797 /**********************************************************************
1798 * OpenServiceW
1799 *
1800 * @implemented
1801 */
1802 SC_HANDLE WINAPI
1803 OpenServiceW(SC_HANDLE hSCManager,
1804 LPCWSTR lpServiceName,
1805 DWORD dwDesiredAccess)
1806 {
1807 SC_HANDLE hService = NULL;
1808 DWORD dwError;
1809
1810 TRACE("OpenServiceW(%p, %S, %lx)\n",
1811 hSCManager, lpServiceName, dwDesiredAccess);
1812
1813 if (!hSCManager)
1814 {
1815 SetLastError(ERROR_INVALID_HANDLE);
1816 return NULL;
1817 }
1818
1819 RpcTryExcept
1820 {
1821 /* Call to services.exe using RPC */
1822 dwError = ROpenServiceW((SC_RPC_HANDLE)hSCManager,
1823 (LPWSTR)lpServiceName,
1824 dwDesiredAccess,
1825 (SC_RPC_HANDLE *)&hService);
1826 }
1827 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1828 {
1829 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1830 }
1831 RpcEndExcept;
1832
1833 if (dwError != ERROR_SUCCESS)
1834 {
1835 if (dwError == ERROR_SERVICE_DOES_NOT_EXIST)
1836 WARN("ROpenServiceW() failed (Error %lu)\n", dwError);
1837 else
1838 ERR("ROpenServiceW() failed (Error %lu)\n", dwError);
1839 SetLastError(dwError);
1840 return NULL;
1841 }
1842
1843 TRACE("hService = %p\n", hService);
1844
1845 return hService;
1846 }
1847
1848
1849 /**********************************************************************
1850 * QueryServiceConfigA
1851 *
1852 * @implemented
1853 */
1854 BOOL WINAPI
1855 QueryServiceConfigA(SC_HANDLE hService,
1856 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
1857 DWORD cbBufSize,
1858 LPDWORD pcbBytesNeeded)
1859 {
1860 DWORD dwError;
1861
1862 TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
1863 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1864
1865 RpcTryExcept
1866 {
1867 /* Call to services.exe using RPC */
1868 dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
1869 (LPBYTE)lpServiceConfig,
1870 cbBufSize,
1871 pcbBytesNeeded);
1872 }
1873 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1874 {
1875 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1876 }
1877 RpcEndExcept;
1878
1879 if (dwError != ERROR_SUCCESS)
1880 {
1881 ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
1882 SetLastError(dwError);
1883 return FALSE;
1884 }
1885
1886 /* Adjust the pointers */
1887 if (lpServiceConfig->lpBinaryPathName)
1888 lpServiceConfig->lpBinaryPathName =
1889 (LPSTR)((ULONG_PTR)lpServiceConfig +
1890 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1891
1892 if (lpServiceConfig->lpLoadOrderGroup)
1893 lpServiceConfig->lpLoadOrderGroup =
1894 (LPSTR)((ULONG_PTR)lpServiceConfig +
1895 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1896
1897 if (lpServiceConfig->lpDependencies)
1898 lpServiceConfig->lpDependencies =
1899 (LPSTR)((ULONG_PTR)lpServiceConfig +
1900 (ULONG_PTR)lpServiceConfig->lpDependencies);
1901
1902 if (lpServiceConfig->lpServiceStartName)
1903 lpServiceConfig->lpServiceStartName =
1904 (LPSTR)((ULONG_PTR)lpServiceConfig +
1905 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1906
1907 if (lpServiceConfig->lpDisplayName)
1908 lpServiceConfig->lpDisplayName =
1909 (LPSTR)((ULONG_PTR)lpServiceConfig +
1910 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1911
1912 TRACE("QueryServiceConfigA() done\n");
1913
1914 return TRUE;
1915 }
1916
1917
1918 /**********************************************************************
1919 * QueryServiceConfigW
1920 *
1921 * @implemented
1922 */
1923 BOOL WINAPI
1924 QueryServiceConfigW(SC_HANDLE hService,
1925 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
1926 DWORD cbBufSize,
1927 LPDWORD pcbBytesNeeded)
1928 {
1929 DWORD dwError;
1930
1931 TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
1932 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
1933
1934 RpcTryExcept
1935 {
1936 /* Call to services.exe using RPC */
1937 dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
1938 (LPBYTE)lpServiceConfig,
1939 cbBufSize,
1940 pcbBytesNeeded);
1941 }
1942 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1943 {
1944 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
1945 }
1946 RpcEndExcept;
1947
1948 if (dwError != ERROR_SUCCESS)
1949 {
1950 if (dwError == ERROR_INSUFFICIENT_BUFFER)
1951 WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1952 else
1953 ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
1954 SetLastError(dwError);
1955 return FALSE;
1956 }
1957
1958 /* Adjust the pointers */
1959 if (lpServiceConfig->lpBinaryPathName)
1960 lpServiceConfig->lpBinaryPathName =
1961 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1962 (ULONG_PTR)lpServiceConfig->lpBinaryPathName);
1963
1964 if (lpServiceConfig->lpLoadOrderGroup)
1965 lpServiceConfig->lpLoadOrderGroup =
1966 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1967 (ULONG_PTR)lpServiceConfig->lpLoadOrderGroup);
1968
1969 if (lpServiceConfig->lpDependencies)
1970 lpServiceConfig->lpDependencies =
1971 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1972 (ULONG_PTR)lpServiceConfig->lpDependencies);
1973
1974 if (lpServiceConfig->lpServiceStartName)
1975 lpServiceConfig->lpServiceStartName =
1976 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1977 (ULONG_PTR)lpServiceConfig->lpServiceStartName);
1978
1979 if (lpServiceConfig->lpDisplayName)
1980 lpServiceConfig->lpDisplayName =
1981 (LPWSTR)((ULONG_PTR)lpServiceConfig +
1982 (ULONG_PTR)lpServiceConfig->lpDisplayName);
1983
1984 TRACE("QueryServiceConfigW() done\n");
1985
1986 return TRUE;
1987 }
1988
1989
1990 /**********************************************************************
1991 * QueryServiceConfig2A
1992 *
1993 * @implemented
1994 */
1995 BOOL WINAPI
1996 QueryServiceConfig2A(SC_HANDLE hService,
1997 DWORD dwInfoLevel,
1998 LPBYTE lpBuffer,
1999 DWORD cbBufSize,
2000 LPDWORD pcbBytesNeeded)
2001 {
2002 DWORD dwError;
2003
2004 DbgPrint("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
2005 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
2006
2007 if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
2008 dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
2009 {
2010 SetLastError(ERROR_INVALID_LEVEL);
2011 return FALSE;
2012 }
2013
2014 if ((lpBuffer == NULL && cbBufSize != 0) ||
2015 pcbBytesNeeded == NULL)
2016 {
2017 SetLastError(ERROR_INVALID_ADDRESS);
2018 return FALSE;
2019 }
2020
2021 RpcTryExcept
2022 {
2023 /* Call to services.exe using RPC */
2024 dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService,
2025 dwInfoLevel,
2026 lpBuffer,
2027 cbBufSize,
2028 pcbBytesNeeded);
2029 }
2030 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2031 {
2032 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2033 }
2034 RpcEndExcept;
2035
2036 if (dwError != ERROR_SUCCESS)
2037 {
2038 ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
2039 SetLastError(dwError);
2040 return FALSE;
2041 }
2042
2043 switch (dwInfoLevel)
2044 {
2045 case SERVICE_CONFIG_DESCRIPTION:
2046 {
2047 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpBuffer;
2048
2049 if (lpPtr->lpDescription != NULL)
2050 lpPtr->lpDescription =
2051 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
2052 }
2053 break;
2054
2055 case SERVICE_CONFIG_FAILURE_ACTIONS:
2056 {
2057 LPSERVICE_FAILURE_ACTIONSA lpPtr = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
2058
2059 if (lpPtr->lpRebootMsg != NULL)
2060 lpPtr->lpRebootMsg =
2061 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
2062
2063 if (lpPtr->lpCommand != NULL)
2064 lpPtr->lpCommand =
2065 (LPSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
2066
2067 if (lpPtr->lpsaActions != NULL)
2068 lpPtr->lpsaActions =
2069 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
2070 }
2071 break;
2072
2073 default:
2074 ERR("Unknown info level 0x%lx\n", dwInfoLevel);
2075 SetLastError(ERROR_INVALID_PARAMETER);
2076 return FALSE;
2077 }
2078
2079 TRACE("QueryServiceConfig2A() done\n");
2080
2081 return TRUE;
2082 }
2083
2084
2085 /**********************************************************************
2086 * QueryServiceConfig2W
2087 *
2088 * @implemented
2089 */
2090 BOOL WINAPI
2091 QueryServiceConfig2W(SC_HANDLE hService,
2092 DWORD dwInfoLevel,
2093 LPBYTE lpBuffer,
2094 DWORD cbBufSize,
2095 LPDWORD pcbBytesNeeded)
2096 {
2097 DWORD dwError;
2098
2099 TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
2100 hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
2101
2102 if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
2103 dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
2104 {
2105 SetLastError(ERROR_INVALID_LEVEL);
2106 return FALSE;
2107 }
2108
2109 if ((lpBuffer == NULL && cbBufSize != 0) ||
2110 pcbBytesNeeded == NULL)
2111 {
2112 SetLastError(ERROR_INVALID_ADDRESS);
2113 return FALSE;
2114 }
2115
2116 RpcTryExcept
2117 {
2118 /* Call to services.exe using RPC */
2119 dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService,
2120 dwInfoLevel,
2121 lpBuffer,
2122 cbBufSize,
2123 pcbBytesNeeded);
2124 }
2125 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2126 {
2127 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2128 }
2129 RpcEndExcept;
2130
2131 if (dwError != ERROR_SUCCESS)
2132 {
2133 ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
2134 SetLastError(dwError);
2135 return FALSE;
2136 }
2137
2138 switch (dwInfoLevel)
2139 {
2140 case SERVICE_CONFIG_DESCRIPTION:
2141 {
2142 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpBuffer;
2143
2144 if (lpPtr->lpDescription != NULL)
2145 lpPtr->lpDescription =
2146 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpDescription);
2147 }
2148 break;
2149
2150 case SERVICE_CONFIG_FAILURE_ACTIONS:
2151 {
2152 LPSERVICE_FAILURE_ACTIONSW lpPtr = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
2153
2154 if (lpPtr->lpRebootMsg != NULL)
2155 lpPtr->lpRebootMsg =
2156 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpRebootMsg);
2157
2158 if (lpPtr->lpCommand != NULL)
2159 lpPtr->lpCommand =
2160 (LPWSTR)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpCommand);
2161
2162 if (lpPtr->lpsaActions != NULL)
2163 lpPtr->lpsaActions =
2164 (SC_ACTION*)((UINT_PTR)lpPtr + (UINT_PTR)lpPtr->lpsaActions);
2165 }
2166 break;
2167
2168 default:
2169 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
2170 SetLastError(ERROR_INVALID_PARAMETER);
2171 return FALSE;
2172 }
2173
2174 TRACE("QueryServiceConfig2W() done\n");
2175
2176 return TRUE;
2177 }
2178
2179
2180 /**********************************************************************
2181 * QueryServiceLockStatusA
2182 *
2183 * @implemented
2184 */
2185 BOOL WINAPI
2186 QueryServiceLockStatusA(SC_HANDLE hSCManager,
2187 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
2188 DWORD cbBufSize,
2189 LPDWORD pcbBytesNeeded)
2190 {
2191 DWORD dwError;
2192
2193 TRACE("QueryServiceLockStatusA() called\n");
2194
2195 RpcTryExcept
2196 {
2197 /* Call to services.exe using RPC */
2198 dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager,
2199 lpLockStatus,
2200 cbBufSize,
2201 pcbBytesNeeded);
2202 }
2203 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2204 {
2205 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2206 }
2207 RpcEndExcept;
2208
2209 if (dwError != ERROR_SUCCESS)
2210 {
2211 ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
2212 SetLastError(dwError);
2213 return FALSE;
2214 }
2215
2216 if (lpLockStatus->lpLockOwner != NULL)
2217 {
2218 lpLockStatus->lpLockOwner =
2219 (LPSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2220 }
2221
2222 TRACE("QueryServiceLockStatusA() done\n");
2223
2224 return TRUE;
2225 }
2226
2227
2228 /**********************************************************************
2229 * QueryServiceLockStatusW
2230 *
2231 * @implemented
2232 */
2233 BOOL WINAPI
2234 QueryServiceLockStatusW(SC_HANDLE hSCManager,
2235 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
2236 DWORD cbBufSize,
2237 LPDWORD pcbBytesNeeded)
2238 {
2239 DWORD dwError;
2240
2241 TRACE("QueryServiceLockStatusW() called\n");
2242
2243 RpcTryExcept
2244 {
2245 /* Call to services.exe using RPC */
2246 dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager,
2247 lpLockStatus,
2248 cbBufSize,
2249 pcbBytesNeeded);
2250 }
2251 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2252 {
2253 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2254 }
2255 RpcEndExcept;
2256
2257 if (dwError != ERROR_SUCCESS)
2258 {
2259 ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
2260 SetLastError(dwError);
2261 return FALSE;
2262 }
2263
2264 if (lpLockStatus->lpLockOwner != NULL)
2265 {
2266 lpLockStatus->lpLockOwner =
2267 (LPWSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
2268 }
2269
2270 TRACE("QueryServiceLockStatusW() done\n");
2271
2272 return TRUE;
2273 }
2274
2275
2276 /**********************************************************************
2277 * QueryServiceObjectSecurity
2278 *
2279 * @implemented
2280 */
2281 BOOL WINAPI
2282 QueryServiceObjectSecurity(SC_HANDLE hService,
2283 SECURITY_INFORMATION dwSecurityInformation,
2284 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
2285 DWORD cbBufSize,
2286 LPDWORD pcbBytesNeeded)
2287 {
2288 DWORD dwError;
2289
2290 TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
2291 hService, dwSecurityInformation, lpSecurityDescriptor);
2292
2293 RpcTryExcept
2294 {
2295 /* Call to services.exe using RPC */
2296 dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService,
2297 dwSecurityInformation,
2298 (LPBYTE)lpSecurityDescriptor,
2299 cbBufSize,
2300 pcbBytesNeeded);
2301 }
2302 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2303 {
2304 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2305 }
2306 RpcEndExcept;
2307
2308 if (dwError != ERROR_SUCCESS)
2309 {
2310 ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
2311 SetLastError(dwError);
2312 return FALSE;
2313 }
2314
2315 return TRUE;
2316 }
2317
2318 /**********************************************************************
2319 * SetServiceObjectSecurity
2320 *
2321 * @implemented
2322 */
2323 BOOL WINAPI
2324 SetServiceObjectSecurity(SC_HANDLE hService,
2325 SECURITY_INFORMATION dwSecurityInformation,
2326 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
2327 {
2328 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
2329 ULONG Length;
2330 NTSTATUS Status;
2331 DWORD dwError;
2332
2333 Length = 0;
2334 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2335 SelfRelativeSD,
2336 &Length);
2337 if (Status != STATUS_BUFFER_TOO_SMALL)
2338 {
2339 SetLastError(ERROR_INVALID_PARAMETER);
2340 return FALSE;
2341 }
2342
2343 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
2344 if (SelfRelativeSD == NULL)
2345 {
2346 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2347 return FALSE;
2348 }
2349
2350 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2351 SelfRelativeSD,
2352 &Length);
2353 if (!NT_SUCCESS(Status))
2354 {
2355 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2356 SetLastError(RtlNtStatusToDosError(Status));
2357 return FALSE;
2358 }
2359
2360 RpcTryExcept
2361 {
2362 /* Call to services.exe using RPC */
2363 dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService,
2364 dwSecurityInformation,
2365 (LPBYTE)SelfRelativeSD,
2366 Length);
2367 }
2368 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2369 {
2370 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2371 }
2372 RpcEndExcept;
2373
2374 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2375
2376 if (dwError != ERROR_SUCCESS)
2377 {
2378 ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
2379 SetLastError(dwError);
2380 return FALSE;
2381 }
2382
2383 return TRUE;
2384 }
2385
2386
2387 /**********************************************************************
2388 * QueryServiceStatus
2389 *
2390 * @implemented
2391 */
2392 BOOL WINAPI
2393 QueryServiceStatus(SC_HANDLE hService,
2394 LPSERVICE_STATUS lpServiceStatus)
2395 {
2396 DWORD dwError;
2397
2398 TRACE("QueryServiceStatus(%p, %p)\n",
2399 hService, lpServiceStatus);
2400
2401 if (!hService)
2402 {
2403 SetLastError(ERROR_INVALID_HANDLE);
2404 return FALSE;
2405 }
2406
2407 RpcTryExcept
2408 {
2409 /* Call to services.exe using RPC */
2410 dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService,
2411 lpServiceStatus);
2412 }
2413 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2414 {
2415 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2416 }
2417 RpcEndExcept;
2418
2419 if (dwError != ERROR_SUCCESS)
2420 {
2421 ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError);
2422 SetLastError(dwError);
2423 return FALSE;
2424 }
2425
2426 return TRUE;
2427 }
2428
2429
2430 /**********************************************************************
2431 * QueryServiceStatusEx
2432 *
2433 * @implemented
2434 */
2435 BOOL WINAPI
2436 QueryServiceStatusEx(SC_HANDLE hService,
2437 SC_STATUS_TYPE InfoLevel,
2438 LPBYTE lpBuffer,
2439 DWORD cbBufSize,
2440 LPDWORD pcbBytesNeeded)
2441 {
2442 DWORD dwError;
2443
2444 TRACE("QueryServiceStatusEx() called\n");
2445
2446 if (InfoLevel != SC_STATUS_PROCESS_INFO)
2447 {
2448 SetLastError(ERROR_INVALID_LEVEL);
2449 return FALSE;
2450 }
2451
2452 RpcTryExcept
2453 {
2454 /* Call to services.exe using RPC */
2455 dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService,
2456 InfoLevel,
2457 lpBuffer,
2458 cbBufSize,
2459 pcbBytesNeeded);
2460 }
2461 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2462 {
2463 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2464 }
2465 RpcEndExcept;
2466
2467 if (dwError != ERROR_SUCCESS)
2468 {
2469 ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
2470 SetLastError(dwError);
2471 return FALSE;
2472 }
2473
2474 return TRUE;
2475 }
2476
2477
2478 /**********************************************************************
2479 * StartServiceA
2480 *
2481 * @implemented
2482 */
2483 BOOL WINAPI
2484 StartServiceA(SC_HANDLE hService,
2485 DWORD dwNumServiceArgs,
2486 LPCSTR *lpServiceArgVectors)
2487 {
2488 DWORD dwError;
2489
2490 RpcTryExcept
2491 {
2492 dwError = RStartServiceA((SC_RPC_HANDLE)hService,
2493 dwNumServiceArgs,
2494 (LPSTRING_PTRSA)lpServiceArgVectors);
2495 }
2496 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2497 {
2498 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2499 }
2500 RpcEndExcept;
2501
2502 if (dwError != ERROR_SUCCESS)
2503 {
2504 ERR("RStartServiceA() failed (Error %lu)\n", dwError);
2505 SetLastError(dwError);
2506 return FALSE;
2507 }
2508
2509 return TRUE;
2510 }
2511
2512
2513 /**********************************************************************
2514 * StartServiceW
2515 *
2516 * @implemented
2517 */
2518 BOOL WINAPI
2519 StartServiceW(SC_HANDLE hService,
2520 DWORD dwNumServiceArgs,
2521 LPCWSTR *lpServiceArgVectors)
2522 {
2523 DWORD dwError;
2524
2525 RpcTryExcept
2526 {
2527 dwError = RStartServiceW((SC_RPC_HANDLE)hService,
2528 dwNumServiceArgs,
2529 (LPSTRING_PTRSW)lpServiceArgVectors);
2530 }
2531 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2532 {
2533 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2534 }
2535 RpcEndExcept;
2536
2537 if (dwError != ERROR_SUCCESS)
2538 {
2539 ERR("RStartServiceW() failed (Error %lu)\n", dwError);
2540 SetLastError(dwError);
2541 return FALSE;
2542 }
2543
2544 return TRUE;
2545 }
2546
2547
2548 /**********************************************************************
2549 * UnlockServiceDatabase
2550 *
2551 * @implemented
2552 */
2553 BOOL WINAPI
2554 UnlockServiceDatabase(SC_LOCK ScLock)
2555 {
2556 DWORD dwError;
2557
2558 TRACE("UnlockServiceDatabase(%x)\n", ScLock);
2559
2560 RpcTryExcept
2561 {
2562 /* Call to services.exe using RPC */
2563 dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock);
2564 }
2565 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2566 {
2567 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2568 }
2569 RpcEndExcept;
2570
2571 if (dwError != ERROR_SUCCESS)
2572 {
2573 ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
2574 SetLastError(dwError);
2575 return FALSE;
2576 }
2577
2578 return TRUE;
2579 }
2580
2581
2582 /**********************************************************************
2583 * NotifyBootConfigStatus
2584 *
2585 * @implemented
2586 */
2587 BOOL WINAPI
2588 NotifyBootConfigStatus(BOOL BootAcceptable)
2589 {
2590 DWORD dwError;
2591
2592 TRACE("NotifyBootConfigStatus()\n");
2593
2594 RpcTryExcept
2595 {
2596 /* Call to services.exe using RPC */
2597 dwError = RNotifyBootConfigStatus(NULL,
2598 BootAcceptable);
2599 }
2600 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2601 {
2602 dwError = ScmRpcStatusToWinError(RpcExceptionCode());
2603 }
2604 RpcEndExcept;
2605
2606 if (dwError != ERROR_SUCCESS)
2607 {
2608 ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
2609 SetLastError(dwError);
2610 return FALSE;
2611 }
2612
2613 return TRUE;
2614 }
2615
2616 /* EOF */