ReactOS 0.4.16-dev-1163-gec5b142
scm.c
Go to the documentation of this file.
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 * Pierre Schweitzer
9 */
10
11/* INCLUDES ******************************************************************/
12
13#include <advapi32.h>
15
19 const struct ustring *in,
20 const struct ustring *key,
21 struct ustring *out);
22
26 IN PVOID ContextHandle,
27 OUT LPBYTE SessionKey);
28
29/* FUNCTIONS *****************************************************************/
30
33{
35 RPC_CSTR pszStringBinding;
37
38 TRACE("SVCCTL_HANDLEA_bind(%s)\n",
39 debugstr_a(szMachineName));
40
42 (RPC_CSTR)"ncacn_np",
43 (RPC_CSTR)szMachineName,
44 (RPC_CSTR)"\\pipe\\ntsvcs",
45 NULL,
46 &pszStringBinding);
47 if (status != RPC_S_OK)
48 {
49 ERR("RpcStringBindingCompose returned 0x%x\n", status);
50 return NULL;
51 }
52
53 /* Set the binding handle that will be used to bind to the server. */
54 status = RpcBindingFromStringBindingA(pszStringBinding,
55 &hBinding);
56 if (status != RPC_S_OK)
57 {
58 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
59 }
60
61 status = RpcStringFreeA(&pszStringBinding);
62 if (status != RPC_S_OK)
63 {
64 ERR("RpcStringFree returned 0x%x\n", status);
65 }
66
67 return hBinding;
68}
69
70
71void __RPC_USER
74{
76
77 TRACE("SVCCTL_HANDLEA_unbind(%s %p)\n",
78 debugstr_a(szMachineName), hBinding);
79
81 if (status != RPC_S_OK)
82 {
83 ERR("RpcBindingFree returned 0x%x\n", status);
84 }
85}
86
87
90{
92 RPC_WSTR pszStringBinding;
94
95 TRACE("SVCCTL_HANDLEW_bind(%s)\n",
96 debugstr_w(szMachineName));
97
99 L"ncacn_np",
100 szMachineName,
101 L"\\pipe\\ntsvcs",
102 NULL,
103 &pszStringBinding);
104 if (status != RPC_S_OK)
105 {
106 ERR("RpcStringBindingCompose returned 0x%x\n", status);
107 return NULL;
108 }
109
110 /* Set the binding handle that will be used to bind to the server. */
111 status = RpcBindingFromStringBindingW(pszStringBinding,
112 &hBinding);
113 if (status != RPC_S_OK)
114 {
115 ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
116 }
117
118 status = RpcStringFreeW(&pszStringBinding);
119 if (status != RPC_S_OK)
120 {
121 ERR("RpcStringFree returned 0x%x\n", status);
122 }
123
124 return hBinding;
125}
126
127
128void __RPC_USER
131{
133
134 TRACE("SVCCTL_HANDLEW_unbind(%s %p)\n",
135 debugstr_w(szMachineName), hBinding);
136
138 if (status != RPC_S_OK)
139 {
140 ERR("RpcBindingFree returned 0x%x\n", status);
141 }
142}
143
144
145DWORD
147{
148 TRACE("ScmRpcStatusToWinError(%lx)\n",
149 Status);
150
151 switch (Status)
152 {
157
161
164
165 default:
166 return (DWORD)Status;
167 }
168}
169
170
171static
172DWORD
174 _In_ PVOID ContextHandle,
175 _In_ PCWSTR pClearTextPassword,
176 _Out_ PBYTE *pEncryptedPassword,
177 _Out_ PDWORD pEncryptedPasswordSize)
178{
179 struct ustring inData, keyData, outData;
180 BYTE SessionKey[16];
183
184 /* Get the session key */
185 Status = SystemFunction028(ContextHandle,
186 SessionKey);
187 if (!NT_SUCCESS(Status))
188 {
189 ERR("SystemFunction028 failed (Status 0x%08lx)\n", Status);
191 }
192
193 inData.Length = (wcslen(pClearTextPassword) + 1) * sizeof(WCHAR);
194 inData.MaximumLength = inData.Length;
195 inData.Buffer = (unsigned char *)pClearTextPassword;
196
197 keyData.Length = sizeof(SessionKey);
198 keyData.MaximumLength = keyData.Length;
199 keyData.Buffer = SessionKey;
200
201 outData.Length = 0;
202 outData.MaximumLength = 0;
203 outData.Buffer = NULL;
204
205 /* Get the required buffer size */
206 Status = SystemFunction004(&inData,
207 &keyData,
208 &outData);
210 {
211 ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status);
213 }
214
215 /* Allocate a buffer for the encrypted password */
216 pBuffer = HeapAlloc(GetProcessHeap(), 0, outData.Length);
217 if (pBuffer == NULL)
218 return ERROR_OUTOFMEMORY;
219
220 outData.MaximumLength = outData.Length;
221 outData.Buffer = pBuffer;
222
223 /* Encrypt the password */
224 Status = SystemFunction004(&inData,
225 &keyData,
226 &outData);
227 if (!NT_SUCCESS(Status))
228 {
229 ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status);
232 }
233
234 *pEncryptedPassword = outData.Buffer;
235 *pEncryptedPasswordSize = outData.Length;
236
237 return ERROR_SUCCESS;
238}
239
240
241/**********************************************************************
242 * ChangeServiceConfig2A
243 *
244 * @implemented
245 */
247ChangeServiceConfig2A(SC_HANDLE hService,
249 LPVOID lpInfo)
250{
252 DWORD dwError;
253
254 TRACE("ChangeServiceConfig2A(%p %lu %p)\n",
255 hService, dwInfoLevel, lpInfo);
256
257 if (lpInfo == NULL) return TRUE;
258
259 /* Fill relevant field of the Info structure */
260 Info.dwInfoLevel = dwInfoLevel;
261 switch (dwInfoLevel)
262 {
264 Info.psd = lpInfo;
265 break;
266
268 Info.psfa = lpInfo;
269 break;
270
271 default:
272 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
274 return FALSE;
275 }
276
278 {
279 dwError = RChangeServiceConfig2A((SC_RPC_HANDLE)hService,
280 Info);
281 }
283 {
285 }
287
288 if (dwError != ERROR_SUCCESS)
289 {
290 TRACE("RChangeServiceConfig2A() failed (Error %lu)\n", dwError);
291 SetLastError(dwError);
292 return FALSE;
293 }
294
295 return TRUE;
296}
297
298
299/**********************************************************************
300 * ChangeServiceConfig2W
301 *
302 * @implemented
303 */
305ChangeServiceConfig2W(SC_HANDLE hService,
307 LPVOID lpInfo)
308{
310 DWORD dwError;
311
312 TRACE("ChangeServiceConfig2W(%p %lu %p)\n",
313 hService, dwInfoLevel, lpInfo);
314
315 if (lpInfo == NULL) return TRUE;
316
317 /* Fill relevant field of the Info structure */
318 Info.dwInfoLevel = dwInfoLevel;
319 switch (dwInfoLevel)
320 {
322 Info.psd = lpInfo;
323 break;
324
326 Info.psfa = lpInfo;
327 break;
328
329 default:
330 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
332 return FALSE;
333 }
334
336 {
337 dwError = RChangeServiceConfig2W((SC_RPC_HANDLE)hService,
338 Info);
339 }
341 {
343 }
345
346 if (dwError != ERROR_SUCCESS)
347 {
348 TRACE("RChangeServiceConfig2W() failed (Error %lu)\n", dwError);
349 SetLastError(dwError);
350 return FALSE;
351 }
352
353 return TRUE;
354}
355
356
357/**********************************************************************
358 * ChangeServiceConfigA
359 *
360 * @implemented
361 */
363ChangeServiceConfigA(SC_HANDLE hService,
364 DWORD dwServiceType,
365 DWORD dwStartType,
366 DWORD dwErrorControl,
367 LPCSTR lpBinaryPathName,
368 LPCSTR lpLoadOrderGroup,
369 LPDWORD lpdwTagId,
370 LPCSTR lpDependencies,
371 LPCSTR lpServiceStartName,
372 LPCSTR lpPassword,
374{
375 DWORD dwError;
376 DWORD dwDependenciesLength = 0;
377 SIZE_T cchLength;
378 LPCSTR lpStr;
379 DWORD dwPasswordSize = 0;
380 LPWSTR lpPasswordW = NULL;
381 LPBYTE lpEncryptedPassword = NULL;
382
383 TRACE("ChangeServiceConfigA(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
384 hService, dwServiceType, dwStartType, dwErrorControl, debugstr_a(lpBinaryPathName),
385 debugstr_a(lpLoadOrderGroup), lpdwTagId, debugstr_a(lpDependencies),
386 debugstr_a(lpServiceStartName), debugstr_a(lpPassword), debugstr_a(lpDisplayName));
387
388 /* Calculate the Dependencies length*/
389 if (lpDependencies != NULL)
390 {
391 lpStr = lpDependencies;
392 while (*lpStr)
393 {
394 cchLength = strlen(lpStr) + 1;
395 dwDependenciesLength += (DWORD)cchLength;
396 lpStr = lpStr + cchLength;
397 }
398 dwDependenciesLength++;
399 }
400
401 if (lpPassword != NULL)
402 {
403 /* Convert the password to unicode */
404 lpPasswordW = HeapAlloc(GetProcessHeap(),
406 (strlen(lpPassword) + 1) * sizeof(WCHAR));
407 if (lpPasswordW == NULL)
408 {
410 return FALSE;
411 }
412
414 0,
415 lpPassword,
416 -1,
417 lpPasswordW,
418 (int)(strlen(lpPassword) + 1));
419
420 /* Encrypt the unicode password */
421 dwError = ScmEncryptPassword(hService,
422 lpPasswordW,
423 &lpEncryptedPassword,
424 &dwPasswordSize);
425 if (dwError != ERROR_SUCCESS)
426 goto done;
427 }
428
430 {
431 dwError = RChangeServiceConfigA((SC_RPC_HANDLE)hService,
432 dwServiceType,
433 dwStartType,
434 dwErrorControl,
435 (LPSTR)lpBinaryPathName,
436 (LPSTR)lpLoadOrderGroup,
437 lpdwTagId,
438 (LPBYTE)lpDependencies,
439 dwDependenciesLength,
440 (LPSTR)lpServiceStartName,
441 lpEncryptedPassword,
442 dwPasswordSize,
444 }
446 {
448 }
450
451done:
452 if (lpPasswordW != NULL)
453 {
454 /* Wipe and release the password buffers */
455 SecureZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
456 HeapFree(GetProcessHeap(), 0, lpPasswordW);
457
458 if (lpEncryptedPassword != NULL)
459 {
460 SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
461 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
462 }
463 }
464
465 if (dwError != ERROR_SUCCESS)
466 {
467 TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
468 SetLastError(dwError);
469 return FALSE;
470 }
471
472 return TRUE;
473}
474
475
476/**********************************************************************
477 * ChangeServiceConfigW
478 *
479 * @implemented
480 */
482ChangeServiceConfigW(SC_HANDLE hService,
483 DWORD dwServiceType,
484 DWORD dwStartType,
485 DWORD dwErrorControl,
486 LPCWSTR lpBinaryPathName,
487 LPCWSTR lpLoadOrderGroup,
488 LPDWORD lpdwTagId,
489 LPCWSTR lpDependencies,
490 LPCWSTR lpServiceStartName,
491 LPCWSTR lpPassword,
493{
494 DWORD dwError;
495 DWORD dwDependenciesLength = 0;
496 SIZE_T cchLength;
497 LPCWSTR lpStr;
498 DWORD dwPasswordSize = 0;
499 LPBYTE lpEncryptedPassword = NULL;
500
501 TRACE("ChangeServiceConfigW(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
502 hService, dwServiceType, dwStartType, dwErrorControl, debugstr_w(lpBinaryPathName),
503 debugstr_w(lpLoadOrderGroup), lpdwTagId, debugstr_w(lpDependencies),
504 debugstr_w(lpServiceStartName), debugstr_w(lpPassword), debugstr_w(lpDisplayName));
505
506 /* Calculate the Dependencies length*/
507 if (lpDependencies != NULL)
508 {
509 lpStr = lpDependencies;
510 while (*lpStr)
511 {
512 cchLength = wcslen(lpStr) + 1;
513 dwDependenciesLength += (DWORD)cchLength;
514 lpStr = lpStr + cchLength;
515 }
516 dwDependenciesLength++;
517 dwDependenciesLength *= sizeof(WCHAR);
518 }
519
520 if (lpPassword != NULL)
521 {
522 dwError = ScmEncryptPassword(hService,
523 lpPassword,
524 &lpEncryptedPassword,
525 &dwPasswordSize);
526 if (dwError != ERROR_SUCCESS)
527 {
528 ERR("ScmEncryptPassword failed (Error %lu)\n", dwError);
529 goto done;
530 }
531 }
532
534 {
535 dwError = RChangeServiceConfigW((SC_RPC_HANDLE)hService,
536 dwServiceType,
537 dwStartType,
538 dwErrorControl,
539 (LPWSTR)lpBinaryPathName,
540 (LPWSTR)lpLoadOrderGroup,
541 lpdwTagId,
542 (LPBYTE)lpDependencies,
543 dwDependenciesLength,
544 (LPWSTR)lpServiceStartName,
545 lpEncryptedPassword,
546 dwPasswordSize,
548 }
550 {
552 }
554
555done:
556 if (lpEncryptedPassword != NULL)
557 {
558 /* Wipe and release the password buffer */
559 SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
560 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
561 }
562
563 if (dwError != ERROR_SUCCESS)
564 {
565 TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError);
566 SetLastError(dwError);
567 return FALSE;
568 }
569
570 return TRUE;
571}
572
573
574/**********************************************************************
575 * CloseServiceHandle
576 *
577 * @implemented
578 */
580CloseServiceHandle(SC_HANDLE hSCObject)
581{
582 DWORD dwError;
583
584 TRACE("CloseServiceHandle(%p)\n",
585 hSCObject);
586
587 if (!hSCObject)
588 {
590 return FALSE;
591 }
592
594 {
595 dwError = RCloseServiceHandle((LPSC_RPC_HANDLE)&hSCObject);
596 }
598 {
600 }
602
603 if (dwError)
604 {
605 TRACE("RCloseServiceHandle() failed (Error %lu)\n", dwError);
606 SetLastError(dwError);
607 return FALSE;
608 }
609
610 TRACE("CloseServiceHandle() done\n");
611
612 return TRUE;
613}
614
615
616/**********************************************************************
617 * ControlService
618 *
619 * @implemented
620 */
622ControlService(SC_HANDLE hService,
623 DWORD dwControl,
624 LPSERVICE_STATUS lpServiceStatus)
625{
626 DWORD dwError;
627
628 TRACE("ControlService(%p %lu %p)\n",
629 hService, dwControl, lpServiceStatus);
630
632 {
633 dwError = RControlService((SC_RPC_HANDLE)hService,
634 dwControl,
635 lpServiceStatus);
636 }
638 {
640 }
642
643 if (dwError != ERROR_SUCCESS)
644 {
645 TRACE("RControlService() failed (Error %lu)\n", dwError);
646 SetLastError(dwError);
647 return FALSE;
648 }
649
650 TRACE("ControlService() done\n");
651
652 return TRUE;
653}
654
655
656/**********************************************************************
657 * ControlServiceEx
658 *
659 * @unimplemented
660 */
662ControlServiceEx(IN SC_HANDLE hService,
663 IN DWORD dwControl,
665 IN OUT PVOID pControlParams)
666{
667 FIXME("ControlServiceEx(%p %lu %lu %p)\n",
668 hService, dwControl, dwInfoLevel, pControlParams);
670 return FALSE;
671}
672
673
674/**********************************************************************
675 * CreateServiceA
676 *
677 * @implemented
678 */
679SC_HANDLE WINAPI
681 LPCSTR lpServiceName,
683 DWORD dwDesiredAccess,
684 DWORD dwServiceType,
685 DWORD dwStartType,
686 DWORD dwErrorControl,
687 LPCSTR lpBinaryPathName,
688 LPCSTR lpLoadOrderGroup,
689 LPDWORD lpdwTagId,
690 LPCSTR lpDependencies,
691 LPCSTR lpServiceStartName,
692 LPCSTR lpPassword)
693{
694 SC_HANDLE hService = NULL;
695 DWORD dwDependenciesLength = 0;
696 DWORD dwError;
697 SIZE_T cchLength;
698 LPCSTR lpStr;
699 DWORD dwPasswordSize = 0;
700 LPWSTR lpPasswordW = NULL;
701 LPBYTE lpEncryptedPassword = NULL;
702
703 TRACE("CreateServiceA(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
705 dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl,
706 debugstr_a(lpBinaryPathName), debugstr_a(lpLoadOrderGroup), lpdwTagId,
707 debugstr_a(lpDependencies), debugstr_a(lpServiceStartName), debugstr_a(lpPassword));
708
709 if (!hSCManager)
710 {
712 return NULL;
713 }
714
715 /* Calculate the Dependencies length */
716 if (lpDependencies != NULL)
717 {
718 lpStr = lpDependencies;
719 while (*lpStr)
720 {
721 cchLength = strlen(lpStr) + 1;
722 dwDependenciesLength += (DWORD)cchLength;
723 lpStr = lpStr + cchLength;
724 }
725 dwDependenciesLength++;
726 }
727
728 if (lpPassword != NULL)
729 {
730 /* Convert the password to unicode */
731 lpPasswordW = HeapAlloc(GetProcessHeap(),
733 (strlen(lpPassword) + 1) * sizeof(WCHAR));
734 if (lpPasswordW == NULL)
735 {
737 return FALSE;
738 }
739
741 0,
742 lpPassword,
743 -1,
744 lpPasswordW,
745 (int)(strlen(lpPassword) + 1));
746
747 /* Encrypt the password */
749 lpPasswordW,
750 &lpEncryptedPassword,
751 &dwPasswordSize);
752 if (dwError != ERROR_SUCCESS)
753 goto done;
754 }
755
757 {
759 (LPSTR)lpServiceName,
761 dwDesiredAccess,
762 dwServiceType,
763 dwStartType,
764 dwErrorControl,
765 (LPSTR)lpBinaryPathName,
766 (LPSTR)lpLoadOrderGroup,
767 lpdwTagId,
768 (LPBYTE)lpDependencies,
769 dwDependenciesLength,
770 (LPSTR)lpServiceStartName,
771 lpEncryptedPassword,
772 dwPasswordSize,
773 (SC_RPC_HANDLE *)&hService);
774 }
776 {
778 }
780
781done:
782 if (lpPasswordW != NULL)
783 {
784 /* Wipe and release the password buffers */
785 SecureZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
786 HeapFree(GetProcessHeap(), 0, lpPasswordW);
787
788 if (lpEncryptedPassword != NULL)
789 {
790 SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
791 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
792 }
793 }
794
795 SetLastError(dwError);
796 if (dwError != ERROR_SUCCESS)
797 {
798 TRACE("RCreateServiceA() failed (Error %lu)\n", dwError);
799 return NULL;
800 }
801
802 return hService;
803}
804
805
806/**********************************************************************
807 * CreateServiceW
808 *
809 * @implemented
810 */
811SC_HANDLE WINAPI
813 LPCWSTR lpServiceName,
815 DWORD dwDesiredAccess,
816 DWORD dwServiceType,
817 DWORD dwStartType,
818 DWORD dwErrorControl,
819 LPCWSTR lpBinaryPathName,
820 LPCWSTR lpLoadOrderGroup,
821 LPDWORD lpdwTagId,
822 LPCWSTR lpDependencies,
823 LPCWSTR lpServiceStartName,
824 LPCWSTR lpPassword)
825{
826 SC_HANDLE hService = NULL;
827 DWORD dwDependenciesLength = 0;
828 DWORD dwError;
829 SIZE_T cchLength;
830 LPCWSTR lpStr;
831 DWORD dwPasswordSize = 0;
832 LPBYTE lpEncryptedPassword = NULL;
833
834 TRACE("CreateServiceW(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
836 dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl,
837 debugstr_w(lpBinaryPathName), debugstr_w(lpLoadOrderGroup), lpdwTagId,
838 debugstr_w(lpDependencies), debugstr_w(lpServiceStartName), debugstr_w(lpPassword));
839
840 if (!hSCManager)
841 {
843 return NULL;
844 }
845
846 /* Calculate the Dependencies length */
847 if (lpDependencies != NULL)
848 {
849 lpStr = lpDependencies;
850 while (*lpStr)
851 {
852 cchLength = wcslen(lpStr) + 1;
853 dwDependenciesLength += (DWORD)cchLength;
854 lpStr = lpStr + cchLength;
855 }
856 dwDependenciesLength++;
857 dwDependenciesLength *= sizeof(WCHAR);
858 }
859
860 if (lpPassword != NULL)
861 {
862 /* Encrypt the password */
864 lpPassword,
865 &lpEncryptedPassword,
866 &dwPasswordSize);
867 if (dwError != ERROR_SUCCESS)
868 goto done;
869 }
870
872 {
874 lpServiceName,
876 dwDesiredAccess,
877 dwServiceType,
878 dwStartType,
879 dwErrorControl,
880 lpBinaryPathName,
881 lpLoadOrderGroup,
882 lpdwTagId,
883 (LPBYTE)lpDependencies,
884 dwDependenciesLength,
885 lpServiceStartName,
886 lpEncryptedPassword,
887 dwPasswordSize,
888 (SC_RPC_HANDLE *)&hService);
889 }
891 {
893 }
895
896done:
897 if (lpEncryptedPassword != NULL)
898 {
899 /* Wipe and release the password buffers */
900 SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
901 HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
902 }
903
904 SetLastError(dwError);
905 if (dwError != ERROR_SUCCESS)
906 {
907 TRACE("RCreateServiceW() failed (Error %lu)\n", dwError);
908 return NULL;
909 }
910
911 return hService;
912}
913
914
915/**********************************************************************
916 * DeleteService
917 *
918 * @implemented
919 */
921DeleteService(SC_HANDLE hService)
922{
923 DWORD dwError;
924
925 TRACE("DeleteService(%p)\n",
926 hService);
927
929 {
930 dwError = RDeleteService((SC_RPC_HANDLE)hService);
931 }
933 {
935 }
937
938 if (dwError != ERROR_SUCCESS)
939 {
940 TRACE("RDeleteService() failed (Error %lu)\n", dwError);
941 SetLastError(dwError);
942 return FALSE;
943 }
944
945 return TRUE;
946}
947
948
949/**********************************************************************
950 * EnumDependentServicesA
951 *
952 * @implemented
953 */
955EnumDependentServicesA(SC_HANDLE hService,
956 DWORD dwServiceState,
957 LPENUM_SERVICE_STATUSA lpServices,
960 LPDWORD lpServicesReturned)
961{
963 LPENUM_SERVICE_STATUSA lpStatusPtr;
964 DWORD dwBufferSize;
965 DWORD dwError;
966 DWORD dwCount;
967
968 TRACE("EnumDependentServicesA(%p %lu %p %lu %p %p)\n",
969 hService, dwServiceState, lpServices, cbBufSize,
970 pcbBytesNeeded, lpServicesReturned);
971
972 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSA))
973 {
974 lpStatusPtr = &ServiceStatus;
975 dwBufferSize = sizeof(ENUM_SERVICE_STATUSA);
976 }
977 else
978 {
979 lpStatusPtr = lpServices;
980 dwBufferSize = cbBufSize;
981 }
982
984 {
985 dwError = REnumDependentServicesA((SC_RPC_HANDLE)hService,
986 dwServiceState,
987 (LPBYTE)lpStatusPtr,
988 dwBufferSize,
990 lpServicesReturned);
991 }
993 {
995 }
997
998 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
999 {
1000 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1001 {
1002 if (lpStatusPtr->lpServiceName)
1003 lpStatusPtr->lpServiceName =
1004 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1005
1006 if (lpStatusPtr->lpDisplayName)
1007 lpStatusPtr->lpDisplayName =
1008 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1009
1010 lpStatusPtr++;
1011 }
1012 }
1013
1014 if (dwError != ERROR_SUCCESS)
1015 {
1016 TRACE("REnumDependentServicesA() failed (Error %lu)\n", dwError);
1017 SetLastError(dwError);
1018 return FALSE;
1019 }
1020
1021 TRACE("EnumDependentServicesA() done\n");
1022
1023 return TRUE;
1024}
1025
1026
1027/**********************************************************************
1028 * EnumDependentServicesW
1029 *
1030 * @implemented
1031 */
1033EnumDependentServicesW(SC_HANDLE hService,
1034 DWORD dwServiceState,
1035 LPENUM_SERVICE_STATUSW lpServices,
1038 LPDWORD lpServicesReturned)
1039{
1041 LPENUM_SERVICE_STATUSW lpStatusPtr;
1042 DWORD dwBufferSize;
1043 DWORD dwError;
1044 DWORD dwCount;
1045
1046 TRACE("EnumDependentServicesW(%p %lu %p %lu %p %p)\n",
1047 hService, dwServiceState, lpServices, cbBufSize,
1048 pcbBytesNeeded, lpServicesReturned);
1049
1050 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW))
1051 {
1052 lpStatusPtr = &ServiceStatus;
1053 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW);
1054 }
1055 else
1056 {
1057 lpStatusPtr = lpServices;
1058 dwBufferSize = cbBufSize;
1059 }
1060
1062 {
1063 dwError = REnumDependentServicesW((SC_RPC_HANDLE)hService,
1064 dwServiceState,
1065 (LPBYTE)lpStatusPtr,
1066 dwBufferSize,
1068 lpServicesReturned);
1069 }
1071 {
1073 }
1075
1076 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1077 {
1078 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1079 {
1080 if (lpStatusPtr->lpServiceName)
1081 lpStatusPtr->lpServiceName =
1082 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1083
1084 if (lpStatusPtr->lpDisplayName)
1085 lpStatusPtr->lpDisplayName =
1086 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1087
1088 lpStatusPtr++;
1089 }
1090 }
1091
1092 if (dwError != ERROR_SUCCESS)
1093 {
1094 TRACE("REnumDependentServicesW() failed (Error %lu)\n", dwError);
1095 SetLastError(dwError);
1096 return FALSE;
1097 }
1098
1099 TRACE("EnumDependentServicesW() done\n");
1100
1101 return TRUE;
1102}
1103
1104
1105/**********************************************************************
1106 * EnumServiceGroupW
1107 *
1108 * @implemented
1109 */
1112 DWORD dwServiceType,
1113 DWORD dwServiceState,
1114 LPENUM_SERVICE_STATUSW lpServices,
1117 LPDWORD lpServicesReturned,
1118 LPDWORD lpResumeHandle,
1119 LPCWSTR lpGroup)
1120{
1122 LPENUM_SERVICE_STATUSW lpStatusPtr;
1123 DWORD dwBufferSize;
1124 DWORD dwError;
1125 DWORD dwCount;
1126
1127 TRACE("EnumServiceGroupW(%p %lu %lu %p %lu %p %p %p %s)\n",
1128 hSCManager, dwServiceType, dwServiceState, lpServices,
1129 cbBufSize, pcbBytesNeeded, lpServicesReturned,
1130 lpResumeHandle, debugstr_w(lpGroup));
1131
1132 if (!hSCManager)
1133 {
1135 return FALSE;
1136 }
1137
1138 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
1139 {
1141 return FALSE;
1142 }
1143
1144 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW))
1145 {
1146 lpStatusPtr = &ServiceStatus;
1147 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW);
1148 }
1149 else
1150 {
1151 lpStatusPtr = lpServices;
1152 dwBufferSize = cbBufSize;
1153 }
1154
1156 {
1157 if (lpGroup == NULL)
1158 {
1160 dwServiceType,
1161 dwServiceState,
1162 (LPBYTE)lpStatusPtr,
1163 dwBufferSize,
1165 lpServicesReturned,
1166 lpResumeHandle);
1167 }
1168 else
1169 {
1171 dwServiceType,
1172 dwServiceState,
1173 (LPBYTE)lpStatusPtr,
1174 dwBufferSize,
1176 lpServicesReturned,
1177 lpResumeHandle,
1178 lpGroup);
1179 }
1180 }
1182 {
1184 }
1186
1187 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1188 {
1189 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1190 {
1191 if (lpStatusPtr->lpServiceName)
1192 lpStatusPtr->lpServiceName =
1193 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1194
1195 if (lpStatusPtr->lpDisplayName)
1196 lpStatusPtr->lpDisplayName =
1197 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1198
1199 lpStatusPtr++;
1200 }
1201 }
1202
1203 if (dwError != ERROR_SUCCESS)
1204 {
1205 TRACE("REnumServiceGroupW() failed (Error %lu)\n", dwError);
1206 SetLastError(dwError);
1207 return FALSE;
1208 }
1209
1210 TRACE("EnumServiceGroupW() done\n");
1211
1212 return TRUE;
1213}
1214
1215
1216/**********************************************************************
1217 * EnumServicesStatusA
1218 *
1219 * @implemented
1220 */
1223 DWORD dwServiceType,
1224 DWORD dwServiceState,
1225 LPENUM_SERVICE_STATUSA lpServices,
1228 LPDWORD lpServicesReturned,
1229 LPDWORD lpResumeHandle)
1230{
1232 LPENUM_SERVICE_STATUSA lpStatusPtr;
1233 DWORD dwBufferSize;
1234 DWORD dwError;
1235 DWORD dwCount;
1236
1237 TRACE("EnumServicesStatusA(%p %lu %lu %p %lu %p %p %p)\n",
1238 hSCManager, dwServiceType, dwServiceState, lpServices,
1239 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle);
1240
1241 if (!hSCManager)
1242 {
1244 return FALSE;
1245 }
1246
1247 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
1248 {
1250 return FALSE;
1251 }
1252
1253 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSA))
1254 {
1255 lpStatusPtr = &ServiceStatus;
1256 dwBufferSize = sizeof(ENUM_SERVICE_STATUSA);
1257 }
1258 else
1259 {
1260 lpStatusPtr = lpServices;
1261 dwBufferSize = cbBufSize;
1262 }
1263
1265 {
1267 dwServiceType,
1268 dwServiceState,
1269 (LPBYTE)lpStatusPtr,
1270 dwBufferSize,
1272 lpServicesReturned,
1273 lpResumeHandle);
1274 }
1276 {
1278 }
1280
1281 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1282 {
1283 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1284 {
1285 if (lpStatusPtr->lpServiceName)
1286 lpStatusPtr->lpServiceName =
1287 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1288
1289 if (lpStatusPtr->lpDisplayName)
1290 lpStatusPtr->lpDisplayName =
1291 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1292
1293 lpStatusPtr++;
1294 }
1295 }
1296
1297 if (dwError != ERROR_SUCCESS)
1298 {
1299 TRACE("REnumServicesStatusA() failed (Error %lu)\n", dwError);
1300 SetLastError(dwError);
1301 return FALSE;
1302 }
1303
1304 TRACE("EnumServicesStatusA() done\n");
1305
1306 return TRUE;
1307}
1308
1309
1310/**********************************************************************
1311 * EnumServicesStatusW
1312 *
1313 * @implemented
1314 */
1317 DWORD dwServiceType,
1318 DWORD dwServiceState,
1319 LPENUM_SERVICE_STATUSW lpServices,
1322 LPDWORD lpServicesReturned,
1323 LPDWORD lpResumeHandle)
1324{
1326 LPENUM_SERVICE_STATUSW lpStatusPtr;
1327 DWORD dwBufferSize;
1328 DWORD dwError;
1329 DWORD dwCount;
1330
1331 TRACE("EnumServicesStatusW(%p %lu %lu %p %lu %p %p %p)\n",
1332 hSCManager, dwServiceType, dwServiceState, lpServices,
1333 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle);
1334
1335 if (!hSCManager)
1336 {
1338 return FALSE;
1339 }
1340
1341 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
1342 {
1344 return FALSE;
1345 }
1346
1347 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUSW))
1348 {
1349 lpStatusPtr = &ServiceStatus;
1350 dwBufferSize = sizeof(ENUM_SERVICE_STATUSW);
1351 }
1352 else
1353 {
1354 lpStatusPtr = lpServices;
1355 dwBufferSize = cbBufSize;
1356 }
1357
1359 {
1361 dwServiceType,
1362 dwServiceState,
1363 (LPBYTE)lpStatusPtr,
1364 dwBufferSize,
1366 lpServicesReturned,
1367 lpResumeHandle);
1368 }
1370 {
1372 }
1374
1375 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1376 {
1377 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1378 {
1379 if (lpStatusPtr->lpServiceName)
1380 lpStatusPtr->lpServiceName =
1381 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1382
1383 if (lpStatusPtr->lpDisplayName)
1384 lpStatusPtr->lpDisplayName =
1385 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1386
1387 lpStatusPtr++;
1388 }
1389 }
1390
1391 if (dwError != ERROR_SUCCESS)
1392 {
1393 TRACE("REnumServicesStatusW() failed (Error %lu)\n", dwError);
1394 SetLastError(dwError);
1395 return FALSE;
1396 }
1397
1398 TRACE("EnumServicesStatusW() done\n");
1399
1400 return TRUE;
1401}
1402
1403
1404/**********************************************************************
1405 * EnumServicesStatusExA
1406 *
1407 * @implemented
1408 */
1411 SC_ENUM_TYPE InfoLevel,
1412 DWORD dwServiceType,
1413 DWORD dwServiceState,
1414 LPBYTE lpServices,
1417 LPDWORD lpServicesReturned,
1418 LPDWORD lpResumeHandle,
1419 LPCSTR pszGroupName)
1420{
1423 DWORD dwBufferSize;
1424 DWORD dwError;
1425 DWORD dwCount;
1426
1427 TRACE("EnumServicesStatusExA(%p %lu %lu %p %lu %p %p %p %s)\n",
1428 hSCManager, dwServiceType, dwServiceState, lpServices,
1429 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle,
1430 debugstr_a(pszGroupName));
1431
1432 if (InfoLevel != SC_ENUM_PROCESS_INFO)
1433 {
1435 return FALSE;
1436 }
1437
1438 if (!hSCManager)
1439 {
1441 return FALSE;
1442 }
1443
1444 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
1445 {
1447 return FALSE;
1448 }
1449
1450 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUS_PROCESSA))
1451 {
1452 lpStatusPtr = &ServiceStatus;
1453 dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSA);
1454 }
1455 else
1456 {
1457 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
1458 dwBufferSize = cbBufSize;
1459 }
1460
1462 {
1464 InfoLevel,
1465 dwServiceType,
1466 dwServiceState,
1467 (LPBYTE)lpStatusPtr,
1468 dwBufferSize,
1470 lpServicesReturned,
1471 lpResumeHandle,
1472 (LPSTR)pszGroupName);
1473 }
1475 {
1477 }
1479
1480 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1481 {
1482 if (InfoLevel == SC_ENUM_PROCESS_INFO)
1483 {
1484 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1485 {
1486 if (lpStatusPtr->lpServiceName)
1487 lpStatusPtr->lpServiceName =
1488 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1489
1490 if (lpStatusPtr->lpDisplayName)
1491 lpStatusPtr->lpDisplayName =
1492 (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1493
1494 lpStatusPtr++;
1495 }
1496 }
1497 }
1498
1499 if (dwError != ERROR_SUCCESS)
1500 {
1501 TRACE("REnumServicesStatusExA() failed (Error %lu)\n", dwError);
1502 SetLastError(dwError);
1503 return FALSE;
1504 }
1505
1506 TRACE("EnumServicesStatusExA() done\n");
1507
1508 return TRUE;
1509}
1510
1511
1512/**********************************************************************
1513 * EnumServicesStatusExW
1514 *
1515 * @implemented
1516 */
1519 SC_ENUM_TYPE InfoLevel,
1520 DWORD dwServiceType,
1521 DWORD dwServiceState,
1522 LPBYTE lpServices,
1525 LPDWORD lpServicesReturned,
1526 LPDWORD lpResumeHandle,
1527 LPCWSTR pszGroupName)
1528{
1531 DWORD dwBufferSize;
1532 DWORD dwError;
1533 DWORD dwCount;
1534
1535 TRACE("EnumServicesStatusExW(%p %lu %lu %p %lu %p %p %p %s)\n",
1536 hSCManager, dwServiceType, dwServiceState, lpServices,
1537 cbBufSize, pcbBytesNeeded, lpServicesReturned, lpResumeHandle,
1538 debugstr_w(pszGroupName));
1539
1540 if (InfoLevel != SC_ENUM_PROCESS_INFO)
1541 {
1543 return FALSE;
1544 }
1545
1546 if (!hSCManager)
1547 {
1549 return FALSE;
1550 }
1551
1552 if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
1553 {
1555 return FALSE;
1556 }
1557
1558 if (lpServices == NULL || cbBufSize < sizeof(ENUM_SERVICE_STATUS_PROCESSW))
1559 {
1560 lpStatusPtr = &ServiceStatus;
1561 dwBufferSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW);
1562 }
1563 else
1564 {
1565 lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
1566 dwBufferSize = cbBufSize;
1567 }
1568
1570 {
1572 InfoLevel,
1573 dwServiceType,
1574 dwServiceState,
1575 (LPBYTE)lpStatusPtr,
1576 dwBufferSize,
1578 lpServicesReturned,
1579 lpResumeHandle,
1580 (LPWSTR)pszGroupName);
1581 }
1583 {
1585 }
1587
1588 if (dwError == ERROR_SUCCESS || dwError == ERROR_MORE_DATA)
1589 {
1590 if (InfoLevel == SC_ENUM_PROCESS_INFO)
1591 {
1592 for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
1593 {
1594 if (lpStatusPtr->lpServiceName)
1595 lpStatusPtr->lpServiceName =
1596 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
1597
1598 if (lpStatusPtr->lpDisplayName)
1599 lpStatusPtr->lpDisplayName =
1600 (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
1601
1602 lpStatusPtr++;
1603 }
1604 }
1605 }
1606
1607 if (dwError != ERROR_SUCCESS)
1608 {
1609 TRACE("REnumServicesStatusExW() failed (Error %lu)\n", dwError);
1610 SetLastError(dwError);
1611 return FALSE;
1612 }
1613
1614 TRACE("EnumServicesStatusExW() done\n");
1615
1616 return TRUE;
1617}
1618
1619
1620/**********************************************************************
1621 * I_ScSendPnPMessage
1622 *
1623 * Undocumented
1624 *
1625 * @unimplemented
1626 */
1627BOOL
1628WINAPI
1631 _In_ DWORD dwControlCode,
1632 _In_ DWORD dwEventType,
1633 _In_ PVOID pEventData)
1634{
1635 BOOL bResult;
1636
1637 TRACE("I_ScSendPnPMessage(%p %lu %lu %p)\n",
1638 hServiceStatus, dwControlCode, dwEventType, pEventData);
1639
1641 {
1643 dwControlCode,
1644 dwEventType,
1645 ((PDEV_BROADCAST_HDR)pEventData)->dbch_size,
1646 pEventData);
1647 }
1649 {
1651 bResult = FALSE;
1652 }
1654
1655 return bResult;
1656}
1657
1658
1659/**********************************************************************
1660 * GetServiceDisplayNameA
1661 *
1662 * @implemented
1663 */
1666 LPCSTR lpServiceName,
1668 LPDWORD lpcchBuffer)
1669{
1670 DWORD dwError;
1672 CHAR szEmptyName[] = "";
1673
1674 TRACE("GetServiceDisplayNameA(%p %s %p %p)\n",
1675 hSCManager, debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer);
1676
1677 if (!hSCManager)
1678 {
1680 return FALSE;
1681 }
1682
1683 if (!lpDisplayName || *lpcchBuffer < sizeof(CHAR))
1684 {
1685 lpNameBuffer = szEmptyName;
1686 *lpcchBuffer = sizeof(CHAR);
1687 }
1688 else
1689 {
1691 }
1692
1694 {
1696 lpServiceName,
1698 lpcchBuffer);
1699 }
1701 {
1703 }
1705
1706 if (dwError != ERROR_SUCCESS)
1707 {
1708 TRACE("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
1709 SetLastError(dwError);
1710 return FALSE;
1711 }
1712
1713 return TRUE;
1714}
1715
1716
1717/**********************************************************************
1718 * GetServiceDisplayNameW
1719 *
1720 * @implemented
1721 */
1724 LPCWSTR lpServiceName,
1726 LPDWORD lpcchBuffer)
1727{
1728 DWORD dwError;
1730 WCHAR szEmptyName[] = L"";
1731
1732 TRACE("GetServiceDisplayNameW(%p %s %p %p)\n",
1733 hSCManager, debugstr_w(lpServiceName), lpDisplayName, lpcchBuffer);
1734
1735 if (!hSCManager)
1736 {
1738 return FALSE;
1739 }
1740
1741 /*
1742 * NOTE: A size of 1 character would be enough, but tests show that
1743 * Windows returns 2 characters instead, certainly due to a WCHAR/bytes
1744 * mismatch in their code.
1745 */
1746 if (!lpDisplayName || *lpcchBuffer < sizeof(WCHAR))
1747 {
1748 lpNameBuffer = szEmptyName;
1749 *lpcchBuffer = sizeof(WCHAR);
1750 }
1751 else
1752 {
1754 }
1755
1757 {
1759 lpServiceName,
1761 lpcchBuffer);
1762 }
1764 {
1766 }
1768
1769 if (dwError != ERROR_SUCCESS)
1770 {
1771 TRACE("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
1772 SetLastError(dwError);
1773 return FALSE;
1774 }
1775
1776 return TRUE;
1777}
1778
1779
1780/**********************************************************************
1781 * GetServiceKeyNameA
1782 *
1783 * @implemented
1784 */
1788 LPSTR lpServiceName,
1789 LPDWORD lpcchBuffer)
1790{
1791 DWORD dwError;
1793 CHAR szEmptyName[] = "";
1794
1795 TRACE("GetServiceKeyNameA(%p %s %p %p)\n",
1796 hSCManager, debugstr_a(lpDisplayName), lpServiceName, lpcchBuffer);
1797
1798 if (!hSCManager)
1799 {
1801 return FALSE;
1802 }
1803
1804 if (!lpServiceName || *lpcchBuffer < sizeof(CHAR))
1805 {
1806 lpNameBuffer = szEmptyName;
1807 *lpcchBuffer = sizeof(CHAR);
1808 }
1809 else
1810 {
1811 lpNameBuffer = lpServiceName;
1812 }
1813
1815 {
1819 lpcchBuffer);
1820 }
1822 {
1823 /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
1825 }
1827
1828 if (dwError != ERROR_SUCCESS)
1829 {
1830 TRACE("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
1831 SetLastError(dwError);
1832 return FALSE;
1833 }
1834
1835 return TRUE;
1836}
1837
1838
1839/**********************************************************************
1840 * GetServiceKeyNameW
1841 *
1842 * @implemented
1843 */
1847 LPWSTR lpServiceName,
1848 LPDWORD lpcchBuffer)
1849{
1850 DWORD dwError;
1852 WCHAR szEmptyName[] = L"";
1853
1854 TRACE("GetServiceKeyNameW(%p %s %p %p)\n",
1855 hSCManager, debugstr_w(lpDisplayName), lpServiceName, lpcchBuffer);
1856
1857 if (!hSCManager)
1858 {
1860 return FALSE;
1861 }
1862
1863 /*
1864 * NOTE: A size of 1 character would be enough, but tests show that
1865 * Windows returns 2 characters instead, certainly due to a WCHAR/bytes
1866 * mismatch in their code.
1867 */
1868 if (!lpServiceName || *lpcchBuffer < sizeof(WCHAR))
1869 {
1870 lpNameBuffer = szEmptyName;
1871 *lpcchBuffer = sizeof(WCHAR);
1872 }
1873 else
1874 {
1875 lpNameBuffer = lpServiceName;
1876 }
1877
1879 {
1883 lpcchBuffer);
1884 }
1886 {
1888 }
1890
1891 if (dwError != ERROR_SUCCESS)
1892 {
1893 TRACE("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
1894 SetLastError(dwError);
1895 return FALSE;
1896 }
1897
1898 return TRUE;
1899}
1900
1901
1902/**********************************************************************
1903 * I_ScGetCurrentGroupStateW
1904 *
1905 * @implemented
1906 */
1909 LPWSTR pszGroupName,
1910 LPDWORD pdwGroupState)
1911{
1912 DWORD dwError;
1913
1914 TRACE("I_ScGetCurrentGroupStateW(%p %s %p)\n",
1915 hSCManager, debugstr_w(pszGroupName), pdwGroupState);
1916
1918 {
1920 pszGroupName,
1921 pdwGroupState);
1922 }
1924 {
1926 }
1928
1929 if (dwError != ERROR_SUCCESS)
1930 {
1931 TRACE("RI_ScGetCurrentGroupStateW() failed (Error %lu)\n", dwError);
1932 SetLastError(dwError);
1933 }
1934
1935 return dwError;
1936}
1937
1938
1939/**********************************************************************
1940 * I_ScValidatePnpService
1941 *
1942 * Undocumented
1943 *
1944 * @implemented
1945 */
1946DWORD
1947WINAPI
1949 _In_ LPCWSTR pszMachineName,
1950 _In_ LPCWSTR pszServiceName,
1951 _Out_ SERVICE_STATUS_HANDLE *phServiceStatus)
1952{
1955 DWORD dwError;
1956
1957 TRACE("I_ScValidatePnpService(%S %S %p)\n",
1958 pszMachineName, pszServiceName, phServiceStatus);
1959
1960 hSCManager = OpenSCManagerW(pszMachineName,
1963 if (hSCManager == NULL)
1964 {
1965 dwError = GetLastError();
1966 goto done;
1967 }
1968
1970 {
1972 (LPWSTR)pszServiceName,
1974 }
1976 {
1978 }
1980
1981 *phServiceStatus = hServiceStatus;
1982
1983done:
1984 if (hSCManager != NULL)
1986
1987 return dwError;
1988}
1989
1990
1991/**********************************************************************
1992 * LockServiceDatabase
1993 *
1994 * @implemented
1995 */
1998{
1999 SC_LOCK hLock;
2000 DWORD dwError;
2001
2002 TRACE("LockServiceDatabase(%p)\n",
2003 hSCManager);
2004
2006 {
2008 (SC_RPC_LOCK *)&hLock);
2009 }
2011 {
2013 }
2015
2016 if (dwError != ERROR_SUCCESS)
2017 {
2018 TRACE("RLockServiceDatabase() failed (Error %lu)\n", dwError);
2019 SetLastError(dwError);
2020 return NULL;
2021 }
2022
2023 TRACE("hLock = %p\n", hLock);
2024
2025 return hLock;
2026}
2027
2028
2029static VOID
2031{
2032 HANDLE hEvent;
2033
2034 TRACE("WaitForSCManager()\n");
2035
2036 /* Try to open the existing event */
2038 if (hEvent == NULL)
2039 {
2041 return;
2042
2043 /* Try to create a new event */
2045 if (hEvent == NULL)
2046 return;
2047 }
2048
2049 /* Wait for 3 minutes */
2050 WaitForSingleObject(hEvent, 180000);
2052
2053 TRACE("ScmWaitForSCManager() done\n");
2054}
2055
2056
2057/**********************************************************************
2058 * OpenSCManagerA
2059 *
2060 * @implemented
2061 */
2062SC_HANDLE WINAPI
2064 LPCSTR lpDatabaseName,
2065 DWORD dwDesiredAccess)
2066{
2067 SC_HANDLE hScm = NULL;
2068 DWORD dwError;
2069
2070 TRACE("OpenSCManagerA(%s %s %lx)\n",
2071 debugstr_a(lpMachineName), debugstr_a(lpDatabaseName), dwDesiredAccess);
2072
2074
2076 {
2077 dwError = ROpenSCManagerA((LPSTR)lpMachineName,
2078 (LPSTR)lpDatabaseName,
2079 dwDesiredAccess,
2080 (SC_RPC_HANDLE *)&hScm);
2081 }
2083 {
2085 }
2087
2088 SetLastError(dwError);
2089 if (dwError != ERROR_SUCCESS)
2090 {
2091 TRACE("ROpenSCManagerA() failed (Error %lu)\n", dwError);
2092 return NULL;
2093 }
2094
2095 TRACE("hScm = %p\n", hScm);
2096
2097 return hScm;
2098}
2099
2100
2101/**********************************************************************
2102 * OpenSCManagerW
2103 *
2104 * @implemented
2105 */
2106SC_HANDLE WINAPI
2108 LPCWSTR lpDatabaseName,
2109 DWORD dwDesiredAccess)
2110{
2111 SC_HANDLE hScm = NULL;
2112 DWORD dwError;
2113
2114 TRACE("OpenSCManagerW(%s %s %lx)\n",
2115 debugstr_w(lpMachineName), debugstr_w(lpDatabaseName), dwDesiredAccess);
2116
2118
2120 {
2121 dwError = ROpenSCManagerW((LPWSTR)lpMachineName,
2122 (LPWSTR)lpDatabaseName,
2123 dwDesiredAccess,
2124 (SC_RPC_HANDLE *)&hScm);
2125 }
2127 {
2129 }
2131
2132 SetLastError(dwError);
2133 if (dwError != ERROR_SUCCESS)
2134 {
2135 TRACE("ROpenSCManagerW() failed (Error %lu)\n", dwError);
2136 return NULL;
2137 }
2138
2139 TRACE("hScm = %p\n", hScm);
2140
2141 return hScm;
2142}
2143
2144
2145/**********************************************************************
2146 * OpenServiceA
2147 *
2148 * @implemented
2149 */
2150SC_HANDLE WINAPI
2152 LPCSTR lpServiceName,
2153 DWORD dwDesiredAccess)
2154{
2155 SC_HANDLE hService = NULL;
2156 DWORD dwError;
2157
2158 TRACE("OpenServiceA(%p %s %lx)\n",
2159 hSCManager, debugstr_a(lpServiceName), dwDesiredAccess);
2160
2161 if (!hSCManager)
2162 {
2164 return NULL;
2165 }
2166
2168 {
2170 (LPSTR)lpServiceName,
2171 dwDesiredAccess,
2172 (SC_RPC_HANDLE *)&hService);
2173 }
2175 {
2177 }
2179
2180 SetLastError(dwError);
2181 if (dwError != ERROR_SUCCESS)
2182 {
2183 TRACE("ROpenServiceA() failed (Error %lu)\n", dwError);
2184 return NULL;
2185 }
2186
2187 TRACE("hService = %p\n", hService);
2188
2189 return hService;
2190}
2191
2192
2193/**********************************************************************
2194 * OpenServiceW
2195 *
2196 * @implemented
2197 */
2198SC_HANDLE WINAPI
2200 LPCWSTR lpServiceName,
2201 DWORD dwDesiredAccess)
2202{
2203 SC_HANDLE hService = NULL;
2204 DWORD dwError;
2205
2206 TRACE("OpenServiceW(%p %s %lx)\n",
2207 hSCManager, debugstr_w(lpServiceName), dwDesiredAccess);
2208
2209 if (!hSCManager)
2210 {
2212 return NULL;
2213 }
2214
2216 {
2218 (LPWSTR)lpServiceName,
2219 dwDesiredAccess,
2220 (SC_RPC_HANDLE *)&hService);
2221 }
2223 {
2225 }
2227
2228 SetLastError(dwError);
2229 if (dwError != ERROR_SUCCESS)
2230 {
2231 TRACE("ROpenServiceW() failed (Error %lu)\n", dwError);
2232 return NULL;
2233 }
2234
2235 TRACE("hService = %p\n", hService);
2236
2237 return hService;
2238}
2239
2240
2241/**********************************************************************
2242 * QueryServiceConfigA
2243 *
2244 * @implemented
2245 */
2247QueryServiceConfigA(SC_HANDLE hService,
2248 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
2251{
2252 QUERY_SERVICE_CONFIGA ServiceConfig;
2253 LPQUERY_SERVICE_CONFIGA lpConfigPtr;
2254 DWORD dwBufferSize;
2255 DWORD dwError;
2256
2257 TRACE("QueryServiceConfigA(%p %p %lu %p)\n",
2258 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
2259
2260 if (lpServiceConfig == NULL ||
2262 {
2263 lpConfigPtr = &ServiceConfig;
2264 dwBufferSize = sizeof(QUERY_SERVICE_CONFIGA);
2265 }
2266 else
2267 {
2268 lpConfigPtr = lpServiceConfig;
2269 dwBufferSize = cbBufSize;
2270 }
2271
2273 {
2274 dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
2275 (LPBYTE)lpConfigPtr,
2276 dwBufferSize,
2278 }
2280 {
2282 }
2284
2285 if (dwError != ERROR_SUCCESS)
2286 {
2287 TRACE("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
2288 SetLastError(dwError);
2289 return FALSE;
2290 }
2291
2292 /* Adjust the pointers */
2293 if (lpConfigPtr->lpBinaryPathName)
2294 lpConfigPtr->lpBinaryPathName =
2295 (LPSTR)((ULONG_PTR)lpConfigPtr +
2296 (ULONG_PTR)lpConfigPtr->lpBinaryPathName);
2297
2298 if (lpConfigPtr->lpLoadOrderGroup)
2299 lpConfigPtr->lpLoadOrderGroup =
2300 (LPSTR)((ULONG_PTR)lpConfigPtr +
2301 (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup);
2302
2303 if (lpConfigPtr->lpDependencies)
2304 lpConfigPtr->lpDependencies =
2305 (LPSTR)((ULONG_PTR)lpConfigPtr +
2306 (ULONG_PTR)lpConfigPtr->lpDependencies);
2307
2308 if (lpConfigPtr->lpServiceStartName)
2309 lpConfigPtr->lpServiceStartName =
2310 (LPSTR)((ULONG_PTR)lpConfigPtr +
2311 (ULONG_PTR)lpConfigPtr->lpServiceStartName);
2312
2313 if (lpConfigPtr->lpDisplayName)
2314 lpConfigPtr->lpDisplayName =
2315 (LPSTR)((ULONG_PTR)lpConfigPtr +
2316 (ULONG_PTR)lpConfigPtr->lpDisplayName);
2317
2318 TRACE("QueryServiceConfigA() done\n");
2319
2320 return TRUE;
2321}
2322
2323
2324/**********************************************************************
2325 * QueryServiceConfigW
2326 *
2327 * @implemented
2328 */
2330QueryServiceConfigW(SC_HANDLE hService,
2331 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
2334{
2335 QUERY_SERVICE_CONFIGW ServiceConfig;
2336 LPQUERY_SERVICE_CONFIGW lpConfigPtr;
2337 DWORD dwBufferSize;
2338 DWORD dwError;
2339
2340 TRACE("QueryServiceConfigW(%p %p %lu %p)\n",
2341 hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
2342
2343 if (lpServiceConfig == NULL ||
2345 {
2346 lpConfigPtr = &ServiceConfig;
2347 dwBufferSize = sizeof(QUERY_SERVICE_CONFIGW);
2348 }
2349 else
2350 {
2351 lpConfigPtr = lpServiceConfig;
2352 dwBufferSize = cbBufSize;
2353 }
2354
2356 {
2357 dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
2358 (LPBYTE)lpConfigPtr,
2359 dwBufferSize,
2361 }
2363 {
2365 }
2367
2368 if (dwError != ERROR_SUCCESS)
2369 {
2370 TRACE("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
2371 SetLastError(dwError);
2372 return FALSE;
2373 }
2374
2375 /* Adjust the pointers */
2376 if (lpConfigPtr->lpBinaryPathName)
2377 lpConfigPtr->lpBinaryPathName =
2378 (LPWSTR)((ULONG_PTR)lpConfigPtr +
2379 (ULONG_PTR)lpConfigPtr->lpBinaryPathName);
2380
2381 if (lpConfigPtr->lpLoadOrderGroup)
2382 lpConfigPtr->lpLoadOrderGroup =
2383 (LPWSTR)((ULONG_PTR)lpConfigPtr +
2384 (ULONG_PTR)lpConfigPtr->lpLoadOrderGroup);
2385
2386 if (lpConfigPtr->lpDependencies)
2387 lpConfigPtr->lpDependencies =
2388 (LPWSTR)((ULONG_PTR)lpConfigPtr +
2389 (ULONG_PTR)lpConfigPtr->lpDependencies);
2390
2391 if (lpConfigPtr->lpServiceStartName)
2392 lpConfigPtr->lpServiceStartName =
2393 (LPWSTR)((ULONG_PTR)lpConfigPtr +
2394 (ULONG_PTR)lpConfigPtr->lpServiceStartName);
2395
2396 if (lpConfigPtr->lpDisplayName)
2397 lpConfigPtr->lpDisplayName =
2398 (LPWSTR)((ULONG_PTR)lpConfigPtr +
2399 (ULONG_PTR)lpConfigPtr->lpDisplayName);
2400
2401 TRACE("QueryServiceConfigW() done\n");
2402
2403 return TRUE;
2404}
2405
2406
2407/**********************************************************************
2408 * QueryServiceConfig2A
2409 *
2410 * @implemented
2411 */
2413QueryServiceConfig2A(SC_HANDLE hService,
2418{
2419 SERVICE_DESCRIPTIONA ServiceDescription;
2420 SERVICE_FAILURE_ACTIONSA ServiceFailureActions;
2421 LPBYTE lpTempBuffer;
2422 BOOL bUseTempBuffer = FALSE;
2423 DWORD dwBufferSize;
2424 DWORD dwError;
2425
2426 TRACE("QueryServiceConfig2A(%p %lu %p %lu %p)\n",
2428
2429 lpTempBuffer = lpBuffer;
2430 dwBufferSize = cbBufSize;
2431
2432 switch (dwInfoLevel)
2433 {
2435 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONA)))
2436 {
2437 lpTempBuffer = (LPBYTE)&ServiceDescription;
2438 dwBufferSize = sizeof(SERVICE_DESCRIPTIONA);
2439 bUseTempBuffer = TRUE;
2440 }
2441 break;
2442
2444 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSA)))
2445 {
2446 lpTempBuffer = (LPBYTE)&ServiceFailureActions;
2447 dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSA);
2448 bUseTempBuffer = TRUE;
2449 }
2450 break;
2451
2452 default:
2453 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
2455 return FALSE;
2456 }
2457
2459 {
2460 dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService,
2462 lpTempBuffer,
2463 dwBufferSize,
2465 }
2467 {
2469 }
2471
2472 if (dwError != ERROR_SUCCESS)
2473 {
2474 TRACE("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
2475 SetLastError(dwError);
2476 return FALSE;
2477 }
2478
2479 if (bUseTempBuffer != FALSE)
2480 {
2481 TRACE("RQueryServiceConfig2A() returns ERROR_INSUFFICIENT_BUFFER\n");
2482 *pcbBytesNeeded = dwBufferSize;
2484 return FALSE;
2485 }
2486
2487 switch (dwInfoLevel)
2488 {
2490 {
2491 LPSERVICE_DESCRIPTIONA lpPtr = (LPSERVICE_DESCRIPTIONA)lpTempBuffer;
2492
2493 if (lpPtr->lpDescription != NULL)
2494 lpPtr->lpDescription =
2495 (LPSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpDescription);
2496 }
2497 break;
2498
2500 {
2502
2503 if (lpPtr->lpRebootMsg != NULL)
2504 lpPtr->lpRebootMsg =
2505 (LPSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpRebootMsg);
2506
2507 if (lpPtr->lpCommand != NULL)
2508 lpPtr->lpCommand =
2509 (LPSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpCommand);
2510
2511 if (lpPtr->lpsaActions != NULL)
2512 lpPtr->lpsaActions =
2513 (LPSC_ACTION)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpsaActions);
2514 }
2515 break;
2516 }
2517
2518 TRACE("QueryServiceConfig2A() done\n");
2519
2520 return TRUE;
2521}
2522
2523
2524/**********************************************************************
2525 * QueryServiceConfig2W
2526 *
2527 * @implemented
2528 */
2530QueryServiceConfig2W(SC_HANDLE hService,
2535{
2536 SERVICE_DESCRIPTIONW ServiceDescription;
2537 SERVICE_FAILURE_ACTIONSW ServiceFailureActions;
2538 LPBYTE lpTempBuffer;
2539 BOOL bUseTempBuffer = FALSE;
2540 DWORD dwBufferSize;
2541 DWORD dwError;
2542
2543 TRACE("QueryServiceConfig2W(%p %lu %p %lu %p)\n",
2545
2546 lpTempBuffer = lpBuffer;
2547 dwBufferSize = cbBufSize;
2548
2549 switch (dwInfoLevel)
2550 {
2552 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_DESCRIPTIONW)))
2553 {
2554 lpTempBuffer = (LPBYTE)&ServiceDescription;
2555 dwBufferSize = sizeof(SERVICE_DESCRIPTIONW);
2556 bUseTempBuffer = TRUE;
2557 }
2558 break;
2559
2561 if ((lpBuffer == NULL) || (cbBufSize < sizeof(SERVICE_FAILURE_ACTIONSW)))
2562 {
2563 lpTempBuffer = (LPBYTE)&ServiceFailureActions;
2564 dwBufferSize = sizeof(SERVICE_FAILURE_ACTIONSW);
2565 bUseTempBuffer = TRUE;
2566 }
2567 break;
2568
2569 default:
2570 WARN("Unknown info level 0x%lx\n", dwInfoLevel);
2572 return FALSE;
2573 }
2574
2576 {
2577 dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService,
2579 lpTempBuffer,
2580 dwBufferSize,
2582 }
2584 {
2586 }
2588
2589 if (dwError != ERROR_SUCCESS)
2590 {
2591 TRACE("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
2592 SetLastError(dwError);
2593 return FALSE;
2594 }
2595
2596 if (bUseTempBuffer != FALSE)
2597 {
2598 TRACE("RQueryServiceConfig2W() returns ERROR_INSUFFICIENT_BUFFER\n");
2599 *pcbBytesNeeded = dwBufferSize;
2601 return FALSE;
2602 }
2603
2604 switch (dwInfoLevel)
2605 {
2607 {
2608 LPSERVICE_DESCRIPTIONW lpPtr = (LPSERVICE_DESCRIPTIONW)lpTempBuffer;
2609
2610 if (lpPtr->lpDescription != NULL)
2611 lpPtr->lpDescription =
2612 (LPWSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpDescription);
2613 }
2614 break;
2615
2617 {
2619
2620 if (lpPtr->lpRebootMsg != NULL)
2621 lpPtr->lpRebootMsg =
2622 (LPWSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpRebootMsg);
2623
2624 if (lpPtr->lpCommand != NULL)
2625 lpPtr->lpCommand =
2626 (LPWSTR)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpCommand);
2627
2628 if (lpPtr->lpsaActions != NULL)
2629 lpPtr->lpsaActions =
2630 (LPSC_ACTION)((ULONG_PTR)lpPtr + (ULONG_PTR)lpPtr->lpsaActions);
2631 }
2632 break;
2633 }
2634
2635 TRACE("QueryServiceConfig2W() done\n");
2636
2637 return TRUE;
2638}
2639
2640
2641/**********************************************************************
2642 * QueryServiceLockStatusA
2643 *
2644 * @implemented
2645 */
2648 LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
2651{
2652 QUERY_SERVICE_LOCK_STATUSA LockStatus;
2653 LPQUERY_SERVICE_LOCK_STATUSA lpStatusPtr;
2654 DWORD dwBufferSize;
2655 DWORD dwError;
2656
2657 TRACE("QueryServiceLockStatusA(%p %p %lu %p)\n",
2658 hSCManager, lpLockStatus, cbBufSize, pcbBytesNeeded);
2659
2660 if (lpLockStatus == NULL || cbBufSize < sizeof(QUERY_SERVICE_LOCK_STATUSA))
2661 {
2662 lpStatusPtr = &LockStatus;
2663 dwBufferSize = sizeof(QUERY_SERVICE_LOCK_STATUSA);
2664 }
2665 else
2666 {
2667 lpStatusPtr = lpLockStatus;
2668 dwBufferSize = cbBufSize;
2669 }
2670
2672 {
2674 (LPBYTE)lpStatusPtr,
2675 dwBufferSize,
2677 }
2679 {
2681 }
2683
2684 if (dwError != ERROR_SUCCESS)
2685 {
2686 TRACE("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
2687 SetLastError(dwError);
2688 return FALSE;
2689 }
2690
2691 if (lpStatusPtr->lpLockOwner != NULL)
2692 {
2693 lpStatusPtr->lpLockOwner =
2694 (LPSTR)((ULONG_PTR)lpStatusPtr + (ULONG_PTR)lpStatusPtr->lpLockOwner);
2695 }
2696
2697 TRACE("QueryServiceLockStatusA() done\n");
2698
2699 return TRUE;
2700}
2701
2702
2703/**********************************************************************
2704 * QueryServiceLockStatusW
2705 *
2706 * @implemented
2707 */
2710 LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
2713{
2714 QUERY_SERVICE_LOCK_STATUSW LockStatus;
2715 LPQUERY_SERVICE_LOCK_STATUSW lpStatusPtr;
2716 DWORD dwBufferSize;
2717 DWORD dwError;
2718
2719 TRACE("QueryServiceLockStatusW(%p %p %lu %p)\n",
2720 hSCManager, lpLockStatus, cbBufSize, pcbBytesNeeded);
2721
2722 if (lpLockStatus == NULL || cbBufSize < sizeof(QUERY_SERVICE_LOCK_STATUSW))
2723 {
2724 lpStatusPtr = &LockStatus;
2725 dwBufferSize = sizeof(QUERY_SERVICE_LOCK_STATUSW);
2726 }
2727 else
2728 {
2729 lpStatusPtr = lpLockStatus;
2730 dwBufferSize = cbBufSize;
2731 }
2732
2734 {
2736 (LPBYTE)lpStatusPtr,
2737 dwBufferSize,
2739 }
2741 {
2743 }
2745
2746 if (dwError != ERROR_SUCCESS)
2747 {
2748 TRACE("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
2749 SetLastError(dwError);
2750 return FALSE;
2751 }
2752
2753 if (lpStatusPtr->lpLockOwner != NULL)
2754 {
2755 lpStatusPtr->lpLockOwner =
2756 (LPWSTR)((ULONG_PTR)lpStatusPtr + (ULONG_PTR)lpStatusPtr->lpLockOwner);
2757 }
2758
2759 TRACE("QueryServiceLockStatusW() done\n");
2760
2761 return TRUE;
2762}
2763
2764
2765/**********************************************************************
2766 * QueryServiceObjectSecurity
2767 *
2768 * @implemented
2769 */
2772 SECURITY_INFORMATION dwSecurityInformation,
2773 PSECURITY_DESCRIPTOR lpSecurityDescriptor,
2776{
2777 DWORD dwError;
2778
2779 TRACE("QueryServiceObjectSecurity(%p %lu %p)\n",
2780 hService, dwSecurityInformation, lpSecurityDescriptor);
2781
2783 {
2784 dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService,
2785 dwSecurityInformation,
2786 (LPBYTE)lpSecurityDescriptor,
2787 cbBufSize,
2789 }
2791 {
2793 }
2795
2796 if (dwError != ERROR_SUCCESS)
2797 {
2798 TRACE("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
2799 SetLastError(dwError);
2800 return FALSE;
2801 }
2802
2803 return TRUE;
2804}
2805
2806
2807/**********************************************************************
2808 * SetServiceObjectSecurity
2809 *
2810 * @implemented
2811 */
2813SetServiceObjectSecurity(SC_HANDLE hService,
2814 SECURITY_INFORMATION dwSecurityInformation,
2815 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
2816{
2817 PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
2818 ULONG Length;
2820 DWORD dwError;
2821
2822 TRACE("SetServiceObjectSecurity(%p %lu %p)\n",
2823 hService, dwSecurityInformation, lpSecurityDescriptor);
2824
2825 Length = 0;
2826 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2827 SelfRelativeSD,
2828 &Length);
2830 {
2832 return FALSE;
2833 }
2834
2835 SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
2836 if (SelfRelativeSD == NULL)
2837 {
2839 return FALSE;
2840 }
2841
2842 Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
2843 SelfRelativeSD,
2844 &Length);
2845 if (!NT_SUCCESS(Status))
2846 {
2847 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2849 return FALSE;
2850 }
2851
2853 {
2854 dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService,
2855 dwSecurityInformation,
2856 (LPBYTE)SelfRelativeSD,
2857 Length);
2858 }
2860 {
2862 }
2864
2865 HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
2866
2867 if (dwError != ERROR_SUCCESS)
2868 {
2869 TRACE("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
2870 SetLastError(dwError);
2871 return FALSE;
2872 }
2873
2874 return TRUE;
2875}
2876
2877
2878/**********************************************************************
2879 * QueryServiceStatus
2880 *
2881 * @implemented
2882 */
2884QueryServiceStatus(SC_HANDLE hService,
2885 LPSERVICE_STATUS lpServiceStatus)
2886{
2887 DWORD dwError;
2888
2889 TRACE("QueryServiceStatus(%p %p)\n",
2890 hService, lpServiceStatus);
2891
2892 if (!hService)
2893 {
2895 return FALSE;
2896 }
2897
2899 {
2900 dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService,
2901 lpServiceStatus);
2902 }
2904 {
2906 }
2908
2909 if (dwError != ERROR_SUCCESS)
2910 {
2911 TRACE("RQueryServiceStatus() failed (Error %lu)\n", dwError);
2912 SetLastError(dwError);
2913 return FALSE;
2914 }
2915
2916 return TRUE;
2917}
2918
2919
2920/**********************************************************************
2921 * QueryServiceStatusEx
2922 *
2923 * @implemented
2924 */
2926QueryServiceStatusEx(SC_HANDLE hService,
2927 SC_STATUS_TYPE InfoLevel,
2931{
2932 DWORD dwError;
2933
2934 TRACE("QueryServiceStatusEx(%p %lu %p %lu %p)\n",
2935 hService, InfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
2936
2937 if (InfoLevel != SC_STATUS_PROCESS_INFO)
2938 {
2940 return FALSE;
2941 }
2942
2943 if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
2944 {
2947 return FALSE;
2948 }
2949
2951 {
2952 dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService,
2953 InfoLevel,
2954 lpBuffer,
2955 cbBufSize,
2957 }
2959 {
2961 }
2963
2964 if (dwError != ERROR_SUCCESS)
2965 {
2966 TRACE("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
2967 SetLastError(dwError);
2968 return FALSE;
2969 }
2970
2971 return TRUE;
2972}
2973
2974
2975/**********************************************************************
2976 * StartServiceA
2977 *
2978 * @implemented
2979 */
2981StartServiceA(SC_HANDLE hService,
2982 DWORD dwNumServiceArgs,
2983 LPCSTR *lpServiceArgVectors)
2984{
2985 DWORD dwError;
2986
2987 TRACE("StartServiceA(%p %lu %p)\n",
2988 hService, dwNumServiceArgs, lpServiceArgVectors);
2989
2991 {
2992 dwError = RStartServiceA((SC_RPC_HANDLE)hService,
2993 dwNumServiceArgs,
2994 (LPSTRING_PTRSA)lpServiceArgVectors);
2995 }
2997 {
2999 }
3001
3002 if (dwError != ERROR_SUCCESS)
3003 {
3004 ERR("RStartServiceA() failed (Error %lu)\n", dwError);
3005 SetLastError(dwError);
3006 return FALSE;
3007 }
3008
3009 return TRUE;
3010}
3011
3012
3013/**********************************************************************
3014 * StartServiceW
3015 *
3016 * @implemented
3017 */
3019StartServiceW(SC_HANDLE hService,
3020 DWORD dwNumServiceArgs,
3021 LPCWSTR *lpServiceArgVectors)
3022{
3023 DWORD dwError;
3024
3025 TRACE("StartServiceW(%p %lu %p)\n",
3026 hService, dwNumServiceArgs, lpServiceArgVectors);
3027
3029 {
3030 dwError = RStartServiceW((SC_RPC_HANDLE)hService,
3031 dwNumServiceArgs,
3032 (LPSTRING_PTRSW)lpServiceArgVectors);
3033 }
3035 {
3037 }
3039
3040 if (dwError != ERROR_SUCCESS)
3041 {
3042 ERR("RStartServiceW() failed (Error %lu)\n", dwError);
3043 SetLastError(dwError);
3044 return FALSE;
3045 }
3046
3047 return TRUE;
3048}
3049
3050
3051/**********************************************************************
3052 * UnlockServiceDatabase
3053 *
3054 * @implemented
3055 */
3058{
3059 DWORD dwError;
3060
3061 TRACE("UnlockServiceDatabase(%x)\n",
3062 ScLock);
3063
3065 {
3066 dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock);
3067 }
3069 {
3071 }
3073
3074 if (dwError == ERROR_INVALID_HANDLE)
3076
3077 if (dwError != ERROR_SUCCESS)
3078 {
3079 TRACE("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
3080 SetLastError(dwError);
3081 return FALSE;
3082 }
3083
3084 return TRUE;
3085}
3086
3087
3088/**********************************************************************
3089 * NotifyBootConfigStatus
3090 *
3091 * @implemented
3092 */
3095{
3096 DWORD dwError;
3097
3098 TRACE("NotifyBootConfigStatus(%u)\n",
3099 BootAcceptable);
3100
3102 {
3103 dwError = RNotifyBootConfigStatus(NULL,
3104 BootAcceptable);
3105 }
3107 {
3109 }
3111
3112 if (dwError != ERROR_SUCCESS)
3113 {
3114 TRACE("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
3115 SetLastError(dwError);
3116 return FALSE;
3117 }
3118
3119 return TRUE;
3120}
3121
3122DWORD
3125 PTAG_INFO_NAME_FROM_TAG InOutParams)
3126{
3127 SC_HANDLE hScm;
3128 DWORD dwError;
3131 LPWSTR lpszName;
3132
3133 /* We only support one class */
3135 {
3136 return ERROR_RETRY;
3137 }
3138
3139 /* Validate input structure */
3140 if (InOutParams->InParams.dwPid == 0 || InOutParams->InParams.dwTag == 0)
3141 {
3143 }
3144
3145 /* Validate output structure */
3146 if (InOutParams->OutParams.pszName != NULL)
3147 {
3149 }
3150
3151 /* Open service manager */
3153 if (hScm == NULL)
3154 {
3155 return GetLastError();
3156 }
3157
3158 /* Setup call parameters */
3159 InParams = &InOutParams->InParams;
3160 OutParams = NULL;
3161
3162 /* Call SCM to query tag information */
3164 {
3165 dwError = RI_ScQueryServiceTagInfo(hScm, TagInfoLevelNameFromTag, &InParams, &OutParams);
3166 }
3168 {
3170 }
3172
3173 /* Quit if not a success */
3174 if (dwError != ERROR_SUCCESS)
3175 {
3176 goto Cleanup;
3177 }
3178
3179 /* OutParams must be set now and we must have a name */
3180 if (OutParams == NULL ||
3181 OutParams->pszName == NULL)
3182 {
3183 dwError = ERROR_INVALID_DATA;
3184 goto Cleanup;
3185 }
3186
3187 /* Copy back what SCM returned */
3188 lpszName = LocalAlloc(LPTR,
3189 sizeof(WCHAR) * wcslen(OutParams->pszName) + sizeof(UNICODE_NULL));
3190 if (lpszName == NULL)
3191 {
3192 dwError = GetLastError();
3193 goto Cleanup;
3194 }
3195
3196 wcscpy(lpszName, OutParams->pszName);
3197 InOutParams->OutParams.pszName = lpszName;
3198 InOutParams->OutParams.TagType = OutParams->TagType;
3199
3200Cleanup:
3201 CloseServiceHandle(hScm);
3202
3203 /* Free memory allocated by SCM */
3204 if (OutParams != NULL)
3205 {
3206 if (OutParams->pszName != NULL)
3207 {
3208 midl_user_free(OutParams->pszName);
3209 }
3210
3211 midl_user_free(OutParams);
3212 }
3213
3214 return dwError;
3215}
3216
3217/**********************************************************************
3218 * I_QueryTagInformation
3219 *
3220 * @implemented
3221 */
3225 PTAG_INFO_NAME_FROM_TAG InOutParams)
3226{
3227 /*
3228 * We only support one information class and it
3229 * needs parameters
3230 */
3232 InOutParams == NULL)
3233 {
3235 }
3236
3237 /* Validate input structure */
3238 if (InOutParams->InParams.dwPid == 0 || InOutParams->InParams.dwTag == 0)
3239 {
3241 }
3242
3243 /* Validate output structure */
3244 if (InOutParams->OutParams.pszName != NULL)
3245 {
3247 }
3248
3249 /* Call internal function for the RPC call */
3251}
3252
3253/* EOF */
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
static SERVICE_STATUS ServiceStatus
Definition: browser.c:22
#define CHAR(Char)
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
DWORD WINAPI RCloseServiceHandle(LPSC_RPC_HANDLE hSCObject)
Definition: rpcserver.c:935
DWORD WINAPI RChangeServiceConfig2W(SC_RPC_HANDLE hService, SC_RPC_CONFIG_INFOW Info)
Definition: rpcserver.c:5435
DWORD WINAPI RDeleteService(SC_RPC_HANDLE hService)
Definition: rpcserver.c:1240
DWORD WINAPI RQueryServiceLockStatusW(SC_RPC_HANDLE hSCManager, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_4K pcbBytesNeeded)
Definition: rpcserver.c:3226
DWORD WINAPI RQueryServiceObjectSecurity(SC_RPC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, LPBYTE lpSecurityDescriptor, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded)
Definition: rpcserver.c:1326
DWORD WINAPI RChangeServiceConfig2A(SC_RPC_HANDLE hService, SC_RPC_CONFIG_INFOA Info)
Definition: rpcserver.c:5034
DWORD WINAPI ROpenSCManagerW(LPWSTR lpMachineName, LPWSTR lpDatabaseName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpScHandle)
Definition: rpcserver.c:2883
DWORD WINAPI RNotifyBootConfigStatus(SVCCTL_HANDLEW lpMachineName, DWORD BootAcceptable)
Definition: rpcserver.c:1864
DWORD WINAPI RStartServiceW(SC_RPC_HANDLE hService, DWORD argc, LPSTRING_PTRSW argv)
Definition: rpcserver.c:3269
DWORD WINAPI RGetServiceKeyNameA(SC_RPC_HANDLE hSCManager, LPCSTR lpDisplayName, LPSTR lpServiceName, LPBOUNDED_DWORD_4K lpcchBuffer)
Definition: rpcserver.c:4597
DWORD WINAPI RCreateServiceW(SC_RPC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPCWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:2287
DWORD WINAPI RUnlockServiceDatabase(LPSC_RPC_LOCK Lock)
Definition: rpcserver.c:1853
DWORD WINAPI ROpenServiceW(SC_RPC_HANDLE hSCManager, LPWSTR lpServiceName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:2935
DWORD WINAPI RChangeServiceConfigW(SC_RPC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPWSTR lpBinaryPathName, LPWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPWSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPWSTR lpDisplayName)
Definition: rpcserver.c:1935
DWORD WINAPI REnumServicesStatusA(SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD dwBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeHandle)
Definition: rpcserver.c:3914
DWORD WINAPI RLockServiceDatabase(SC_RPC_HANDLE hSCManager, LPSC_RPC_LOCK lpLock)
Definition: rpcserver.c:1298
DWORD WINAPI RQueryServiceConfig2A(SC_RPC_HANDLE hService, DWORD dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
Definition: rpcserver.c:5567
DWORD WINAPI RQueryServiceStatus(SC_RPC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: rpcserver.c:1544
DWORD WINAPI ROpenServiceA(SC_RPC_HANDLE hSCManager, LPSTR lpServiceName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:4059
DWORD WINAPI RStartServiceA(SC_RPC_HANDLE hService, DWORD argc, LPSTRING_PTRSA argv)
Definition: rpcserver.c:4373
DWORD WINAPI RGetServiceDisplayNameW(SC_RPC_HANDLE hSCManager, LPCWSTR lpServiceName, LPWSTR lpDisplayName, DWORD *lpcchBuffer)
Definition: rpcserver.c:3332
DWORD WINAPI RQueryServiceLockStatusA(SC_RPC_HANDLE hSCManager, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_4K pcbBytesNeeded)
Definition: rpcserver.c:4330
DWORD WINAPI RGetServiceKeyNameW(SC_RPC_HANDLE hSCManager, LPCWSTR lpDisplayName, LPWSTR lpServiceName, DWORD *lpcchBuffer)
Definition: rpcserver.c:3395
DWORD WINAPI RControlService(SC_RPC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: rpcserver.c:1005
DWORD WINAPI RCreateServiceA(SC_RPC_HANDLE hSCManager, LPSTR lpServiceName, LPSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPSTR lpBinaryPathName, LPSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSC_RPC_HANDLE lpServiceHandle)
Definition: rpcserver.c:3607
DWORD WINAPI REnumServiceGroupW(SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
Definition: rpcserver.c:4768
DWORD WINAPI RQueryServiceStatusEx(SC_RPC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
Definition: rpcserver.c:6038
DWORD WINAPI RI_ScQueryServiceTagInfo(SC_RPC_HANDLE hSCManager, TAG_INFO_LEVEL dwInfoLevel, PTAG_INFO_NAME_FROM_TAG_IN_PARAMS *lpInParams, PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS *lpOutParams)
Definition: rpcserver.c:6608
DWORD WINAPI RQueryServiceConfigW(SC_RPC_HANDLE hService, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
Definition: rpcserver.c:3018
DWORD WINAPI RQueryServiceConfig2W(SC_RPC_HANDLE hService, DWORD dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
Definition: rpcserver.c:5814
DWORD WINAPI RI_ScValidatePnPService(_In_ SC_RPC_HANDLE hSCManager, _In_ LPWSTR pszServiceName, _Out_ RPC_SERVICE_STATUS_HANDLE *phServiceStatus)
Definition: rpcserver.c:6735
DWORD WINAPI REnumServicesStatusExA(SC_RPC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCSTR pszGroupName)
Definition: rpcserver.c:6111
DWORD WINAPI REnumDependentServicesW(SC_RPC_HANDLE hService, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned)
Definition: rpcserver.c:2722
DWORD WINAPI RGetServiceDisplayNameA(SC_RPC_HANDLE hSCManager, LPCSTR lpServiceName, LPSTR lpDisplayName, LPBOUNDED_DWORD_4K lpcchBuffer)
Definition: rpcserver.c:4475
DWORD WINAPI RI_ScGetCurrentGroupStateW(SC_RPC_HANDLE hSCManager, LPWSTR lpLoadOrderGroup, LPDWORD lpState)
Definition: rpcserver.c:4711
DWORD WINAPI ROpenSCManagerA(LPSTR lpMachineName, LPSTR lpDatabaseName, DWORD dwDesiredAccess, LPSC_RPC_HANDLE lpScHandle)
Definition: rpcserver.c:4021
DWORD WINAPI RSetServiceObjectSecurity(SC_RPC_HANDLE hService, DWORD dwSecurityInformation, LPBYTE lpSecurityDescriptor, DWORD dwSecurityDescriptorSize)
Definition: rpcserver.c:1410
DWORD WINAPI RI_ScSendPnPMessage(_In_ RPC_SERVICE_STATUS_HANDLE hServiceStatus, _In_ DWORD dwControl, _In_ DWORD dwEventType, _In_ DWORD dwEventSize, _In_ LPBYTE pEventData)
Definition: rpcserver.c:6718
DWORD WINAPI RChangeServiceConfigA(SC_RPC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPSTR lpBinaryPathName, LPSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPBYTE lpDependencies, DWORD dwDependSize, LPSTR lpServiceStartName, LPBYTE lpPassword, DWORD dwPwSize, LPSTR lpDisplayName)
Definition: rpcserver.c:3476
DWORD WINAPI RQueryServiceConfigA(SC_RPC_HANDLE hService, LPBYTE lpBuf, DWORD cbBufSize, LPBOUNDED_DWORD_8K pcbBytesNeeded)
Definition: rpcserver.c:4089
DWORD WINAPI REnumDependentServicesA(SC_RPC_HANDLE hService, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned)
Definition: rpcserver.c:3760
DWORD WINAPI REnumServicesStatusExW(SC_RPC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD cbBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeIndex, LPCWSTR pszGroupName)
Definition: rpcserver.c:6250
DWORD WINAPI REnumServicesStatusW(SC_RPC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpBuffer, DWORD dwBufSize, LPBOUNDED_DWORD_256K pcbBytesNeeded, LPBOUNDED_DWORD_256K lpServicesReturned, LPBOUNDED_DWORD_256K lpResumeHandle)
Definition: rpcserver.c:2857
wcscpy
handle_t hBinding
Definition: ctx_c.c:54
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Cleanup[]
Definition: register.c:80
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLuint in
Definition: glext.h:9616
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define Unused(x)
Definition: atlwin.h:28
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HANDLE hEvent
Definition: comm.c:54
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
NTSYSAPI NTSTATUS NTAPI RtlMakeSelfRelativeSD(_In_ PSECURITY_DESCRIPTOR AbsoluteSD, _Out_ PSECURITY_DESCRIPTOR SelfRelativeSD, _Inout_ PULONG BufferLength)
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define SYNCHRONIZE
Definition: nt_native.h:61
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
PVOID pBuffer
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:880
RPC_STATUS WINAPI RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:510
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:787
RPC_STATUS WINAPI RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, RPC_CSTR NetworkAddr, RPC_CSTR Endpoint, RPC_CSTR Options, RPC_CSTR *StringBinding)
Definition: rpc_binding.c:457
RPC_STATUS WINAPI RpcBindingFromStringBindingA(RPC_CSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:840
unsigned short * RPC_WSTR
Definition: rpcdce.h:46
unsigned char * RPC_CSTR
Definition: rpcdce.h:45
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:175
RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR *String)
Definition: rpcrt4_main.c:158
SC_HANDLE hSCManager
Definition: sc.c:12
NTSTATUS WINAPI SystemFunction028(IN PVOID ContextHandle, OUT LPBYTE SessionKey)
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2884
BOOL WINAPI NotifyBootConfigStatus(BOOL BootAcceptable)
Definition: scm.c:3094
BOOL WINAPI EnumServicesStatusExA(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCSTR pszGroupName)
Definition: scm.c:1410
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
DWORD ScmRpcStatusToWinError(RPC_STATUS Status)
Definition: scm.c:146
void __RPC_USER SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName, handle_t hBinding)
Definition: scm.c:129
handle_t __RPC_USER SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName)
Definition: scm.c:89
BOOL WINAPI StartServiceA(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCSTR *lpServiceArgVectors)
Definition: scm.c:2981
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2107
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:622
handle_t __RPC_USER SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName)
Definition: scm.c:32
BOOL WINAPI UnlockServiceDatabase(SC_LOCK ScLock)
Definition: scm.c:3057
void __RPC_USER SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName, handle_t hBinding)
Definition: scm.c:72
DWORD WINAPI I_ScGetCurrentGroupStateW(SC_HANDLE hSCManager, LPWSTR pszGroupName, LPDWORD pdwGroupState)
Definition: scm.c:1908
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2926
SC_HANDLE WINAPI OpenServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2151
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2199
BOOL WINAPI QueryServiceConfigW(SC_HANDLE hService, LPQUERY_SERVICE_CONFIGW lpServiceConfig, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2330
BOOL WINAPI QueryServiceLockStatusA(SC_HANDLE hSCManager, LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2647
BOOL WINAPI GetServiceDisplayNameW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPWSTR lpDisplayName, LPDWORD lpcchBuffer)
Definition: scm.c:1723
BOOL WINAPI ChangeServiceConfig2A(SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo)
Definition: scm.c:247
BOOL WINAPI QueryServiceConfig2A(SC_HANDLE hService, DWORD dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2413
BOOL WINAPI GetServiceKeyNameA(SC_HANDLE hSCManager, LPCSTR lpDisplayName, LPSTR lpServiceName, LPDWORD lpcchBuffer)
Definition: scm.c:1786
BOOL WINAPI EnumServiceGroupW(SC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPENUM_SERVICE_STATUSW lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCWSTR lpGroup)
Definition: scm.c:1111
BOOL WINAPI EnumDependentServicesA(SC_HANDLE hService, DWORD dwServiceState, LPENUM_SERVICE_STATUSA lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: scm.c:955
BOOL WINAPI GetServiceDisplayNameA(SC_HANDLE hSCManager, LPCSTR lpServiceName, LPSTR lpDisplayName, LPDWORD lpcchBuffer)
Definition: scm.c:1665
BOOL WINAPI ChangeServiceConfigW(SC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName)
Definition: scm.c:482
SC_HANDLE WINAPI CreateServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword)
Definition: scm.c:812
static DWORD ScmEncryptPassword(_In_ PVOID ContextHandle, _In_ PCWSTR pClearTextPassword, _Out_ PBYTE *pEncryptedPassword, _Out_ PDWORD pEncryptedPasswordSize)
Definition: scm.c:173
BOOL WINAPI ControlServiceEx(IN SC_HANDLE hService, IN DWORD dwControl, IN DWORD dwInfoLevel, IN OUT PVOID pControlParams)
Definition: scm.c:662
static VOID WaitForSCManager(VOID)
Definition: scm.c:2030
BOOL WINAPI QueryServiceObjectSecurity(SC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR lpSecurityDescriptor, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2771
BOOL WINAPI SetServiceObjectSecurity(SC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR lpSecurityDescriptor)
Definition: scm.c:2813
BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2530
DWORD I_ScQueryServiceTagInfo(PVOID Unused, TAG_INFO_LEVEL dwInfoLevel, PTAG_INFO_NAME_FROM_TAG InOutParams)
Definition: scm.c:3123
NTSTATUS WINAPI SystemFunction004(const struct ustring *in, const struct ustring *key, struct ustring *out)
Definition: sysfunc.c:119
BOOL WINAPI QueryServiceLockStatusW(SC_HANDLE hSCManager, LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2709
BOOL WINAPI QueryServiceConfigA(SC_HANDLE hService, LPQUERY_SERVICE_CONFIGA lpServiceConfig, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2247
BOOL WINAPI ChangeServiceConfigA(SC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCSTR lpDependencies, LPCSTR lpServiceStartName, LPCSTR lpPassword, LPCSTR lpDisplayName)
Definition: scm.c:363
BOOL WINAPI EnumServicesStatusExW(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCWSTR pszGroupName)
Definition: scm.c:1518
BOOL WINAPI I_ScSendPnPMessage(_In_ SERVICE_STATUS_HANDLE hServiceStatus, _In_ DWORD dwControlCode, _In_ DWORD dwEventType, _In_ PVOID pEventData)
Definition: scm.c:1629
BOOL WINAPI StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:3019
BOOL WINAPI EnumServicesStatusA(SC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPENUM_SERVICE_STATUSA lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle)
Definition: scm.c:1222
SC_HANDLE WINAPI CreateServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, LPCSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCSTR lpDependencies, LPCSTR lpServiceStartName, LPCSTR lpPassword)
Definition: scm.c:680
DWORD WINAPI I_QueryTagInformation(PVOID Unused, TAG_INFO_LEVEL dwInfoLevel, PTAG_INFO_NAME_FROM_TAG InOutParams)
Definition: scm.c:3223
DWORD WINAPI I_ScValidatePnpService(_In_ LPCWSTR pszMachineName, _In_ LPCWSTR pszServiceName, _Out_ SERVICE_STATUS_HANDLE *phServiceStatus)
Definition: scm.c:1948
BOOL WINAPI ChangeServiceConfig2W(SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo)
Definition: scm.c:305
SC_LOCK WINAPI LockServiceDatabase(SC_HANDLE hSCManager)
Definition: scm.c:1997
SC_HANDLE WINAPI OpenSCManagerA(LPCSTR lpMachineName, LPCSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2063
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
BOOL WINAPI GetServiceKeyNameW(SC_HANDLE hSCManager, LPCWSTR lpDisplayName, LPWSTR lpServiceName, LPDWORD lpcchBuffer)
Definition: scm.c:1845
BOOL WINAPI EnumServicesStatusW(SC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPENUM_SERVICE_STATUSW lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle)
Definition: scm.c:1316
BOOL WINAPI EnumDependentServicesW(SC_HANDLE hService, DWORD dwServiceState, LPENUM_SERVICE_STATUSW lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: scm.c:1033
#define RpcEndExcept
Definition: rpc.h:123
#define midl_user_free
Definition: rpc.h:41
#define RpcTryExcept
Definition: rpc.h:121
#define RpcExcept(expr)
Definition: rpc.h:122
long RPC_STATUS
Definition: rpc.h:48
#define __RPC_USER
Definition: rpc.h:61
#define RpcExceptionCode()
Definition: rpc.h:127
#define SCM_START_EVENT
Definition: services.h:26
static LPSTR lpNameBuffer
Definition: secur32.c:50
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR lpDisplayName
Definition: winsvc.h:131
LPWSTR lpServiceName
Definition: winsvc.h:130
LPSTR lpServiceStartName
Definition: winsvc.h:152
LPWSTR lpServiceStartName
Definition: winsvc.h:163
LPWSTR lpBinaryPathName
Definition: winsvc.h:159
LPWSTR lpLoadOrderGroup
Definition: winsvc.h:160
LPWSTR lpDescription
Definition: winsvc.h:196
SC_ACTION * lpsaActions
Definition: winsvc.h:213
SC_ACTION * lpsaActions
Definition: winsvc.h:220
TAG_INFO_NAME_FROM_TAG_OUT_PARAMS OutParams
Definition: svcctl.idl:320
TAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams
Definition: svcctl.idl:319
Definition: copy.c:22
Definition: ps.c:97
Definition: config.c:19
DWORD Length
Definition: config.c:20
DWORD MaximumLength
Definition: config.c:21
unsigned char * Buffer
Definition: config.c:22
LPSTR SVCCTL_HANDLEA
Definition: svcctl.idl:18
ULONG_PTR RPC_SERVICE_STATUS_HANDLE
Definition: svcctl.idl:20
LPWSTR SVCCTL_HANDLEW
Definition: svcctl.idl:19
enum _TAG_INFO_LEVEL TAG_INFO_LEVEL
@ TagInfoLevelNameFromTag
Definition: svcctl.idl:300
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
SERVICE_STATUS_HANDLE hServiceStatus
Definition: main.c:10
#define SecureZeroMemory
Definition: winbase.h:1745
_In_ LPCSTR _Out_writes_to_opt_ cchDisplayName LPSTR lpDisplayName
Definition: winbase.h:2822
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LPTR
Definition: winbase.h:408
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define RPC_X_ENUM_VALUE_OUT_OF_RANGE
Definition: winerror.h:1088
#define RPC_X_SS_IN_NULL_CONTEXT
Definition: winerror.h:1083
#define ERROR_RETRY
Definition: winerror.h:740
#define RPC_X_NULL_REF_POINTER
Definition: winerror.h:1087
#define ERROR_INVALID_SERVICE_LOCK
Definition: winerror.h:622
#define RPC_X_BYTE_COUNT_TOO_SMALL
Definition: winerror.h:1089
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1013
#define ERROR_INVALID_DATA
Definition: winerror.h:116
struct _QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUSW
struct _SERVICE_DESCRIPTIONA SERVICE_DESCRIPTIONA
struct _ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESSA
_In_ DWORD _In_ DWORD _Out_ LPDWORD pcbBytesNeeded
Definition: winsvc.h:425
struct _SERVICE_FAILURE_ACTIONSW SERVICE_FAILURE_ACTIONSW
struct _QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUSA
@ SC_STATUS_PROCESS_INFO
Definition: winsvc.h:119
_In_ DWORD _In_ DWORD cbBufSize
Definition: winsvc.h:424
struct _ENUM_SERVICE_STATUS_PROCESSW * LPENUM_SERVICE_STATUS_PROCESSW
#define SERVICE_CONFIG_DESCRIPTION
Definition: winsvc.h:65
struct _SERVICE_DESCRIPTIONW SERVICE_DESCRIPTIONW
#define SC_MANAGER_ENUMERATE_SERVICE
Definition: winsvc.h:16
struct _ENUM_SERVICE_STATUS_PROCESSA * LPENUM_SERVICE_STATUS_PROCESSA
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
struct _QUERY_SERVICE_CONFIGW QUERY_SERVICE_CONFIGW
struct _SERVICE_DESCRIPTIONW * LPSERVICE_DESCRIPTIONW
struct _ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUSW
struct _ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESSW
struct _SERVICE_FAILURE_ACTIONSA * LPSERVICE_FAILURE_ACTIONSA
_In_ DWORD dwInfoLevel
Definition: winsvc.h:422
struct _SC_ACTION * LPSC_ACTION
enum _SC_STATUS_TYPE SC_STATUS_TYPE
struct _SERVICE_DESCRIPTIONA * LPSERVICE_DESCRIPTIONA
struct _SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONSA
#define SERVICES_ACTIVE_DATABASEW
Definition: winsvc.h:8
#define SERVICE_CONFIG_FAILURE_ACTIONS
Definition: winsvc.h:66
@ SC_ENUM_PROCESS_INFO
Definition: winsvc.h:122
struct _SERVICE_FAILURE_ACTIONSW * LPSERVICE_FAILURE_ACTIONSW
struct _SERVICE_STATUS_PROCESS SERVICE_STATUS_PROCESS
struct _ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUSA
enum _SC_ENUM_TYPE SC_ENUM_TYPE
Definition: service.c:43
struct _QUERY_SERVICE_CONFIGA QUERY_SERVICE_CONFIGA
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193