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