[SC]
[reactos.git] / reactos / base / applications / sc / failure.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/sc/failure.c
5 * PURPOSE: Query/Set the service failure actions
6 * COPYRIGHT: Copyright 2016 Eric Kohl
7 */
8
9 #include "sc.h"
10
11 BOOL QueryFailure(LPCTSTR ServiceName)
12 {
13 SC_HANDLE hManager = NULL;
14 SC_HANDLE hService = NULL;
15 BOOL bResult = TRUE;
16 DWORD cbBytesNeeded = 0;
17 LPSERVICE_FAILURE_ACTIONS pServiceFailure = NULL;
18 INT i;
19
20 #ifdef SCDBG
21 _tprintf(_T("service to show failure action - %s\n\n"), ServiceName);
22 #endif
23
24 hManager = OpenSCManager(NULL,
25 NULL,
26 SC_MANAGER_CONNECT);
27 if (hManager == NULL)
28 {
29 bResult = FALSE;
30 goto done;
31 }
32
33 hService = OpenService(hManager, ServiceName, SERVICE_QUERY_CONFIG);
34 if (hService == NULL)
35 {
36 bResult = FALSE;
37 goto done;
38 }
39
40 if (!QueryServiceConfig2(hService,
41 SERVICE_CONFIG_FAILURE_ACTIONS,
42 NULL,
43 0,
44 &cbBytesNeeded))
45 {
46 if (cbBytesNeeded == 0)
47 {
48 bResult = FALSE;
49 goto done;
50 }
51 }
52
53 pServiceFailure = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
54 if (pServiceFailure == NULL)
55 {
56 SetLastError(ERROR_OUTOFMEMORY);
57 bResult = FALSE;
58 goto done;
59 }
60
61 if (!QueryServiceConfig2(hService,
62 SERVICE_CONFIG_FAILURE_ACTIONS,
63 (LPBYTE)pServiceFailure,
64 cbBytesNeeded,
65 &cbBytesNeeded))
66 {
67 bResult = FALSE;
68 goto done;
69 }
70
71 _tprintf(_T("SERVICE_NAME: %s\n"), ServiceName);
72 _tprintf(_T(" RESET_PERIOD : %lu seconds\n"), pServiceFailure->dwResetPeriod);
73 _tprintf(_T(" REBOOT_MESSAGE : %s\n"), (pServiceFailure->lpRebootMsg) ? pServiceFailure->lpRebootMsg : _T(""));
74 _tprintf(_T(" COMMAND_LINE : %s\n"), (pServiceFailure->lpCommand) ? pServiceFailure->lpCommand : _T(""));
75 _tprintf(_T(" FAILURE_ACTIONS : "));
76 for (i = 0; i < pServiceFailure->cActions; i++)
77 {
78 if (i != 0)
79 _tprintf(_T(" "));
80 switch (pServiceFailure->lpsaActions[i].Type)
81 {
82 case SC_ACTION_NONE:
83 continue;
84
85 case SC_ACTION_RESTART:
86 _tprintf(_T("RESTART -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay);
87 break;
88
89 case SC_ACTION_REBOOT:
90 _tprintf(_T("REBOOT -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay);
91 break;
92
93 case SC_ACTION_RUN_COMMAND:
94 _tprintf(_T("RUN_COMMAND -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay);
95 break;
96
97 default:
98 _tprintf(_T("\n"));
99 break;
100 }
101 }
102
103 done:
104 if (bResult == FALSE)
105 ReportLastError();
106
107 if (pServiceFailure != NULL)
108 HeapFree(GetProcessHeap(), 0, pServiceFailure);
109
110 if (hService)
111 CloseServiceHandle(hService);
112
113 if (hManager)
114 CloseServiceHandle(hManager);
115
116 return bResult;
117 }
118
119 BOOL
120 SetFailure(
121 LPCTSTR *ServiceArgs,
122 INT ArgCount)
123 {
124 SC_HANDLE hManager = NULL;
125 SC_HANDLE hService = NULL;
126 BOOL bResult = TRUE;
127 SERVICE_FAILURE_ACTIONS FailureActions;
128 LPCTSTR lpServiceName = NULL;
129 BOOLEAN Old = FALSE;
130
131 ZeroMemory(&FailureActions, sizeof(SERVICE_FAILURE_ACTIONS));
132
133 if (!ParseFailureArguments(ServiceArgs, ArgCount, &lpServiceName, &FailureActions))
134 {
135 SetFailureUsage();
136 return FALSE;
137 }
138
139 hManager = OpenSCManager(NULL,
140 NULL,
141 SC_MANAGER_CONNECT);
142 if (hManager == NULL)
143 {
144 _tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError());
145 bResult = FALSE;
146 goto done;
147 }
148
149 hService = OpenService(hManager,
150 lpServiceName,
151 SERVICE_CHANGE_CONFIG | SERVICE_START);
152 if (hService == NULL)
153 {
154 _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError());
155 bResult = FALSE;
156 goto done;
157 }
158
159 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old);
160
161 if (!ChangeServiceConfig2(hService,
162 SERVICE_CONFIG_FAILURE_ACTIONS,
163 (LPBYTE)&FailureActions))
164 {
165 _tprintf(_T("[SC] ChangeServiceConfig2 FAILED %lu:\n\n"), GetLastError());
166 bResult = FALSE;
167 goto done;
168 }
169
170 _tprintf(_T("[SC] ChangeServiceConfig2 SUCCESS\n\n"));
171
172 done:
173 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, Old, FALSE, &Old);
174
175 if (bResult == FALSE)
176 ReportLastError();
177
178 if (FailureActions.lpsaActions != NULL)
179 HeapFree(GetProcessHeap(), 0, FailureActions.lpsaActions);
180
181 if (hService)
182 CloseServiceHandle(hService);
183
184 if (hManager)
185 CloseServiceHandle(hManager);
186
187 return bResult;
188 }