xref: /reactos/base/applications/sc/failure.c (revision 40462c92)
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 }
189