ReactOS  0.4.12-dev-102-g4b7f1e0
propsheet_recovery.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Services
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: base/applications/mscutils/servman/propsheet_recovery.c
5  * PURPOSE: Recovery property page
6  * COPYRIGHT: Eric Kohl
7  */
8 
9 #include "precomp.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 typedef struct _RECOVERYDATA
15 {
20 
21 static
22 VOID
24  HWND hwndDlg)
25 {
26  LPWSTR lpAction;
27  INT id;
28 
29  for (id = IDS_NO_ACTION; id <= IDS_RESTART_COMPUTER; id++)
30  {
31  if (AllocAndLoadString(&lpAction,
32  hInstance,
33  id))
34  {
35  SendDlgItemMessageW(hwndDlg,
38  0,
39  (LPARAM)lpAction);
40 
41  SendDlgItemMessageW(hwndDlg,
44  0,
45  (LPARAM)lpAction);
46 
47  SendDlgItemMessageW(hwndDlg,
50  0,
51  (LPARAM)lpAction);
52 
53  LocalFree(lpAction);
54  }
55  }
56 
57  SendDlgItemMessageW(hwndDlg,
60  0,
61  0);
62 
63  SendDlgItemMessageW(hwndDlg,
66  0,
67  0);
68 
69  SendDlgItemMessageW(hwndDlg,
72  0,
73  0);
74 
75  SendDlgItemMessageW(hwndDlg,
77  WM_SETTEXT,
78  0,
79  (LPARAM)L"0");
80 
81  SendDlgItemMessageW(hwndDlg,
83  WM_SETTEXT,
84  0,
85  (LPARAM)L"1");
86 
87  for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_OPTIONS; id++)
88  EnableWindow(GetDlgItem(hwndDlg, id), FALSE);
89 }
90 
91 
92 static
93 BOOL
95  PRECOVERYDATA pRecoveryData)
96 {
98  SC_HANDLE hManager = NULL;
99  SC_HANDLE hService = NULL;
100  BOOL bResult = TRUE;
101  DWORD cbBytesNeeded = 0;
102 
103  hManager = OpenSCManager(NULL,
104  NULL,
106  if (hManager == NULL)
107  {
108  bResult = FALSE;
109  goto done;
110  }
111 
112  hService = OpenService(hManager, pRecoveryData->pService->lpServiceName, SERVICE_QUERY_CONFIG);
113  if (hService == NULL)
114  {
115  bResult = FALSE;
116  goto done;
117  }
118 
119  if (!QueryServiceConfig2(hService,
121  NULL,
122  0,
123  &cbBytesNeeded))
124  {
125  if (cbBytesNeeded == 0)
126  {
127  bResult = FALSE;
128  goto done;
129  }
130  }
131 
132  pServiceFailure = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
133  if (pServiceFailure == NULL)
134  {
136  bResult = FALSE;
137  goto done;
138  }
139 
140  if (!QueryServiceConfig2(hService,
142  (LPBYTE)pServiceFailure,
143  cbBytesNeeded,
144  &cbBytesNeeded))
145  {
146  bResult = FALSE;
147  goto done;
148  }
149 
150  pRecoveryData->pServiceFailure = pServiceFailure;
151 
152 done:
153  if (bResult == FALSE && pServiceFailure != NULL)
154  HeapFree(GetProcessHeap(), 0, pServiceFailure);
155 
156  if (hService)
157  CloseServiceHandle(hService);
158 
159  if (hManager)
160  CloseServiceHandle(hManager);
161 
162  return bResult;
163 }
164 
165 static
166 VOID
168  HWND hwndDlg,
169  PRECOVERYDATA pRecoveryData)
170 {
171  WCHAR szBuffer[256];
172  PWSTR startPtr, endPtr;
173  INT index, id, length;
174  DWORD i;
175 
176  for (i = 0; i < min(pRecoveryData->pServiceFailure->cActions, 3); i++)
177  {
178  index = -1;
179 
180  switch (pRecoveryData->pServiceFailure->lpsaActions[i].Type)
181  {
182  case SC_ACTION_NONE:
183  index = 0;
184  break;
185 
186  case SC_ACTION_RESTART:
187  index = 1;
188 
189  wsprintf(szBuffer, L"%lu", pRecoveryData->pServiceFailure->lpsaActions[i].Delay / 60000);
190  SendDlgItemMessageW(hwndDlg,
192  WM_SETTEXT,
193  0,
194  (LPARAM)szBuffer);
195 
196  for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_TEXT2; id++)
197  EnableWindow(GetDlgItem(hwndDlg, id), TRUE);
198  break;
199 
200  case SC_ACTION_REBOOT:
201  index = 3;
202 
204  break;
205 
207  index = 2;
208 
209  for (id = IDC_RUN_GROUPBOX; id <= IDC_ADD_FAILCOUNT; id++)
210  EnableWindow(GetDlgItem(hwndDlg, id), TRUE);
211  break;
212  }
213 
214  if (index != -1)
215  {
216  SendDlgItemMessageW(hwndDlg,
217  IDC_FIRST_FAILURE + i,
218  CB_SETCURSEL,
219  index,
220  0);
221  }
222  }
223 
224  wsprintf(szBuffer, L"%lu", pRecoveryData->pServiceFailure->dwResetPeriod / 86400);
225  SendDlgItemMessageW(hwndDlg,
227  WM_SETTEXT,
228  0,
229  (LPARAM)szBuffer);
230 
231  if (pRecoveryData->pServiceFailure->lpCommand != NULL)
232  {
233  ZeroMemory(szBuffer, sizeof(szBuffer));
234 
235  startPtr = pRecoveryData->pServiceFailure->lpCommand;
236  if (*startPtr == L'\"')
237  startPtr++;
238 
239  endPtr = wcschr(startPtr, L'\"');
240  if (endPtr != NULL)
241  {
242  length = (INT)((LONG_PTR)endPtr - (LONG_PTR)startPtr);
243  CopyMemory(szBuffer, startPtr, length);
244  }
245  else
246  {
247  wcscpy(szBuffer, startPtr);
248  }
249 
250  SendDlgItemMessageW(hwndDlg,
251  IDC_PROGRAM,
252  WM_SETTEXT,
253  0,
254  (LPARAM)szBuffer);
255 
256  ZeroMemory(szBuffer, sizeof(szBuffer));
257 
258  if (endPtr != NULL)
259  {
260  startPtr = endPtr + 1;
261  while (iswspace(*startPtr))
262  startPtr++;
263 
264  endPtr = wcsstr(pRecoveryData->pServiceFailure->lpCommand, L"/fail=%1%");
265  if (endPtr != NULL)
266  {
267  while (iswspace(*(endPtr - 1)))
268  endPtr--;
269 
270  length = (INT)((LONG_PTR)endPtr - (LONG_PTR)startPtr);
271  CopyMemory(szBuffer, startPtr, length);
272  }
273  else
274  {
275  wcscpy(szBuffer, startPtr);
276  }
277 
278  SendDlgItemMessageW(hwndDlg,
280  WM_SETTEXT,
281  0,
282  (LPARAM)szBuffer);
283 
284  endPtr = wcsstr(pRecoveryData->pServiceFailure->lpCommand, L"/fail=%1%");
285  if (endPtr != NULL)
286  {
287  SendDlgItemMessageW(hwndDlg,
289  BM_SETCHECK,
290  BST_CHECKED,
291  0);
292  }
293  }
294  }
295 }
296 
297 
298 static
299 VOID
301  HWND hwndDlg,
302  PRECOVERYDATA pRecoveryData)
303 {
304  INT id, index;
305  BOOL bRestartService = FALSE;
306  BOOL bRunProgram = FALSE;
307  BOOL bRebootComputer = FALSE;
308 
309  for (id = IDC_FIRST_FAILURE; id <= IDC_SUBSEQUENT_FAILURES; id++)
310  {
311  index = SendDlgItemMessageW(hwndDlg,
312  id,
313  CB_GETCURSEL,
314  0,
315  0);
316  switch (index)
317  {
318  case 1: /* Restart Service */
319  bRestartService = TRUE;
320  break;
321 
322  case 2: /* Run Program */
323  bRunProgram = TRUE;
324  break;
325 
326  case 3: /* Reboot Computer */
327  bRebootComputer = TRUE;
328  break;
329  }
330  }
331 
332  for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_TEXT2; id++)
333  EnableWindow(GetDlgItem(hwndDlg, id), bRestartService);
334 
335  for (id = IDC_RUN_GROUPBOX; id <= IDC_ADD_FAILCOUNT; id++)
336  EnableWindow(GetDlgItem(hwndDlg, id), bRunProgram);
337 
338  EnableWindow(GetDlgItem(hwndDlg, IDC_RESTART_OPTIONS), bRebootComputer);
339 }
340 
341 
342 static
343 VOID
345  HWND hwndDlg)
346 {
347  WCHAR szFile[MAX_PATH] = {'\0'};
348  PWCHAR pszFilter = L"Executable Files (*.exe;*.com;*.cmd;*.bat)\0*.exe;*.com;*.cmd;*.bat\0";
350 
351  ZeroMemory(&ofn, sizeof(ofn));
352 
353  ofn.lStructSize = sizeof(ofn);
355  ofn.hwndOwner = hwndDlg;
356  ofn.lpstrFilter = pszFilter;
357  ofn.lpstrFile = szFile;
358  ofn.nMaxFile = MAX_PATH;
359 
360  if (GetOpenFileName(&ofn))
361  {
362  SendDlgItemMessageW(hwndDlg,
363  IDC_PROGRAM,
364  WM_SETTEXT,
365  0,
366  (LPARAM)szFile);
367  }
368 }
369 
370 
371 static
372 VOID
374  HWND hwndDlg)
375 {
376  SERVICE_FAILURE_ACTIONS FailureActions;
377  BOOL bRestartService = FALSE;
378  BOOL bRunProgram = FALSE;
379  BOOL bRebootComputer = FALSE;
380  INT id, index;
381 
382  ZeroMemory(&FailureActions, sizeof(FailureActions));
383 
384  /* Count the number of valid failure actions */
385  for (id = IDC_FIRST_FAILURE; id <= IDC_SUBSEQUENT_FAILURES; id++)
386  {
387  index = SendDlgItemMessageW(hwndDlg,
388  id,
389  CB_GETCURSEL,
390  0,
391  0);
392  switch (index)
393  {
394  case 1: /* Restart Service */
395  bRestartService = TRUE;
396  FailureActions.cActions++;
397  break;
398 
399  case 2: /* Run Program */
400  bRunProgram = TRUE;
401  FailureActions.cActions++;
402  break;
403 
404  case 3: /* Reboot Computer */
405  bRebootComputer = TRUE;
406  FailureActions.cActions++;
407  break;
408  }
409  }
410 
411  if (bRestartService)
412  {
413  // IDC_RESTART_TIME
414  }
415 
416  if (bRunProgram)
417  {
418  // IDC_RESTART_TIME
419  }
420 
421  if (bRebootComputer)
422  {
423  // IDC_RESTART_TIME
424  }
425 
426 
427 #if 0
428 typedef struct _SERVICE_FAILURE_ACTIONS {
429  DWORD dwResetPeriod;
430  LPTSTR lpRebootMsg;
431  LPTSTR lpCommand;
432  DWORD cActions;
433  SC_ACTION *lpsaActions;
435 #endif
436 }
437 
438 
439 INT_PTR
440 CALLBACK
442  HWND hwndDlg,
443  UINT uMsg,
444  WPARAM wParam,
445  LPARAM lParam)
446 {
447  PRECOVERYDATA pRecoveryData;
448 
449  /* Get the window context */
450  pRecoveryData = (PRECOVERYDATA)GetWindowLongPtr(hwndDlg,
451  GWLP_USERDATA);
452  if (pRecoveryData == NULL && uMsg != WM_INITDIALOG)
453  return FALSE;
454 
455  switch (uMsg)
456  {
457  case WM_INITDIALOG:
458  pRecoveryData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RECOVERYDATA));
459  if (pRecoveryData != NULL)
460  {
461  SetWindowLongPtr(hwndDlg,
463  (LONG_PTR)pRecoveryData);
464 
465  pRecoveryData->pService = ((PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam))->pService;
466 
467  InitRecoveryPage(hwndDlg);
468 
469  if (GetServiceFailure(pRecoveryData))
470  {
471  ShowFailureActions(hwndDlg, pRecoveryData);
472  }
473  }
474  break;
475 
476  case WM_DESTROY:
477  if (pRecoveryData != NULL)
478  {
479  if (pRecoveryData->pServiceFailure != NULL)
480  HeapFree(GetProcessHeap(), 0, pRecoveryData->pServiceFailure);
481 
482  HeapFree(GetProcessHeap(), 0, pRecoveryData);
483  }
484  break;
485 
486  case WM_COMMAND:
487  switch(LOWORD(wParam))
488  {
489  case IDC_FIRST_FAILURE:
490  case IDC_SECOND_FAILURE:
492  if (HIWORD(wParam) == CBN_SELCHANGE)
493  {
494  UpdateFailureActions(hwndDlg, pRecoveryData);
495  pRecoveryData->bChanged = TRUE;
496  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
497  }
498  break;
499 
500  case IDC_RESET_TIME:
501  case IDC_RESTART_TIME:
502  case IDC_PROGRAM:
503  case IDC_PARAMETERS:
504  if (HIWORD(wParam) == EN_CHANGE)
505  {
506  pRecoveryData->bChanged = TRUE;
507  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
508  }
509  break;
510 
511  case IDC_ADD_FAILCOUNT:
512  if (HIWORD(wParam) == BN_CLICKED)
513  {
514  pRecoveryData->bChanged = TRUE;
515  PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
516  }
517  break;
518 
519  case IDC_BROWSE_PROGRAM:
520  BrowseFile(hwndDlg);
521  break;
522 
523  case IDC_RESTART_OPTIONS:
524  break;
525  }
526  break;
527 
528  case WM_NOTIFY:
529  switch (((LPNMHDR)lParam)->code)
530  {
531  case PSN_APPLY:
532  if (pRecoveryData->bChanged)
533  {
534  SetFailureActions(hwndDlg);
535  pRecoveryData->bChanged = FALSE;
536  }
537  break;
538  }
539  break;
540  }
541 
542  return FALSE;
543 }
#define OFN_FILEMUSTEXIST
Definition: commdlg.h:106
#define IDC_RUN_GROUPBOX
Definition: resource.h:166
#define IDC_BROWSE_PROGRAM
Definition: resource.h:169
#define LONG_PTR
Definition: treelist.c:79
#define TRUE
Definition: types.h:120
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define IDC_FIRST_FAILURE
Definition: resource.h:159
#define IDC_SUBSEQUENT_FAILURES
Definition: resource.h:161
HWND hwndOwner
Definition: commdlg.h:330
LPSERVICE_FAILURE_ACTIONS pServiceFailure
__wchar_t WCHAR
Definition: xmlstorage.h:180
static BOOL GetServiceFailure(PRECOVERYDATA pRecoveryData)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
uint16_t * PWSTR
Definition: typedefs.h:54
struct _RECOVERYDATA * PRECOVERYDATA
SC_ACTION_TYPE Type
Definition: winsvc.h:205
#define CALLBACK
Definition: compat.h:27
OPENFILENAME ofn
Definition: main.cpp:37
#define ZeroMemory
Definition: winbase.h:1635
static VOID UpdateFailureActions(HWND hwndDlg, PRECOVERYDATA pRecoveryData)
uint16_t * PWCHAR
Definition: typedefs.h:54
#define PSN_APPLY
Definition: prsht.h:117
int32_t INT_PTR
Definition: typedefs.h:62
static INT AllocAndLoadString(OUT LPTSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID)
Definition: misc.c:60
int32_t INT
Definition: typedefs.h:56
#define SetWindowLongPtr
Definition: treelist.c:70
#define GetOpenFileName
Definition: commdlg.h:665
#define CB_GETCURSEL
Definition: winuser.h:1904
#define OpenService
Definition: winsvc.h:576
WPARAM wParam
Definition: combotst.c:138
CHAR * LPTSTR
Definition: xmlstorage.h:192
DWORD Delay
Definition: winsvc.h:206
static VOID SetFailureActions(HWND hwndDlg)
DWORD nMaxFile
Definition: commdlg.h:337
UINT_PTR WPARAM
Definition: windef.h:207
GLenum GLclampf GLint i
Definition: glfuncs.h:14
HINSTANCE hInstance
Definition: charmap.c:20
#define IDC_SECOND_FAILURE
Definition: resource.h:160
unsigned char * LPBYTE
Definition: typedefs.h:52
LONG_PTR LPARAM
Definition: windef.h:208
#define INT(a)
Definition: assyntax.h:463
#define GWLP_USERDATA
Definition: treelist.c:63
#define CB_ADDSTRING
Definition: winuser.h:1897
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:576
#define LPPROPSHEETPAGE
Definition: prsht.h:372
smooth NULL
Definition: ftsmooth.c:416
#define QueryServiceConfig2
Definition: winsvc.h:581
#define IDC_RESTART_TEXT2
Definition: resource.h:165
#define IDC_RESET_TIME
Definition: resource.h:162
struct _RECOVERYDATA RECOVERYDATA
#define WM_SETTEXT
Definition: winuser.h:1599
#define WM_DESTROY
Definition: winuser.h:1591
#define IDC_RESTART_TEXT1
Definition: resource.h:163
#define OFN_PATHMUSTEXIST
Definition: commdlg.h:117
SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONS
Definition: winsvc.h:556
#define OpenSCManager
Definition: winsvc.h:575
#define BM_SETCHECK
Definition: winuser.h:1882
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
static VOID BrowseFile(HWND hwndDlg)
#define PropSheet_Changed(d, w)
Definition: prsht.h:326
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define MAX_PATH
Definition: compat.h:26
DWORD lStructSize
Definition: commdlg.h:329
unsigned int UINT
Definition: ndis.h:50
#define CopyMemory
Definition: winbase.h:1633
#define SERVICE_CONFIG_FAILURE_ACTIONS
Definition: winsvc.h:66
#define BN_CLICKED
Definition: winuser.h:1886
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IDC_RESTART_TIME
Definition: resource.h:164
#define SetLastError(x)
Definition: compat.h:409
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
INT_PTR CALLBACK RecoveryPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define iswspace(_c)
Definition: ctype.h:669
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1087
static VOID InitRecoveryPage(HWND hwndDlg)
#define OFN_HIDEREADONLY
Definition: commdlg.h:107
#define CB_SETCURSEL
Definition: winuser.h:1922
#define IDC_RESTART_OPTIONS
Definition: resource.h:173
#define WM_COMMAND
Definition: winuser.h:1716
#define IDC_PARAMETERS
Definition: resource.h:171
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
SC_ACTION * lpsaActions
Definition: winsvc.h:213
LPSERVICE_FAILURE_ACTIONSA LPSERVICE_FAILURE_ACTIONS
Definition: winsvc.h:557
HWND WINAPI GetParent(_In_ HWND)
#define IDC_PROGRAM
Definition: resource.h:168
#define IDS_NO_ACTION
Definition: resource.h:220
LPSTR lpstrFile
Definition: commdlg.h:336
ENUM_SERVICE_STATUS_PROCESS * pService
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
LPCSTR lpstrFilter
Definition: commdlg.h:332
#define min(a, b)
Definition: monoChain.cc:55
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define CBN_SELCHANGE
Definition: winuser.h:1940
#define IDC_ADD_FAILCOUNT
Definition: resource.h:172
#define BST_CHECKED
Definition: winuser.h:197
#define HIWORD(l)
Definition: typedefs.h:246
GLenum GLuint id
Definition: glext.h:5579
#define SERVICE_QUERY_CONFIG
Definition: winsvc.h:53
#define GetWindowLongPtr
Definition: treelist.c:73
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define wsprintf
Definition: winuser.h:5731
struct _SERVICEPROPSHEET * PSERVICEPROPSHEET
#define OFN_ENABLESIZING
Definition: commdlg.h:101
#define IDS_RESTART_COMPUTER
Definition: resource.h:223
static VOID ShowFailureActions(HWND hwndDlg, PRECOVERYDATA pRecoveryData)
#define WM_INITDIALOG
Definition: winuser.h:1715
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
#define WM_NOTIFY
Definition: richedit.h:61
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
DWORD Flags
Definition: commdlg.h:342
#define EN_CHANGE
Definition: winuser.h:1983