reactos/base/applications/mscutils/servman/propsheet_recovery.c
Katayama Hirofumi MZ bebdfda8b7
[NOTEPAD][WORDPAD][MSPAINT]... Use newer file open dialog (#3571)
Use new-style file open/save-as dialog.
- Add OFN_EXPLORER flag to OPENFILENAME structure in notepad, wordpad, mspaint, clipbrd, mmc, mplay32, mscutils, regedit, winhlp32, progman, shellbtrfs, cryptui, shell32, setupapi, vgafontedit, infinst, and vfdlib modules.
2021-04-01 22:50:32 +09:00

543 lines
14 KiB
C

/*
* PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/propsheet_recovery.c
* PURPOSE: Recovery property page
* COPYRIGHT: Eric Kohl
*/
#include "precomp.h"
#define NDEBUG
#include <debug.h>
typedef struct _RECOVERYDATA
{
ENUM_SERVICE_STATUS_PROCESS *pService;
LPSERVICE_FAILURE_ACTIONS pServiceFailure;
BOOL bChanged;
} RECOVERYDATA, *PRECOVERYDATA;
static
VOID
InitRecoveryPage(
HWND hwndDlg)
{
LPWSTR lpAction;
INT id;
for (id = IDS_NO_ACTION; id <= IDS_RESTART_COMPUTER; id++)
{
if (AllocAndLoadString(&lpAction,
hInstance,
id))
{
SendDlgItemMessageW(hwndDlg,
IDC_FIRST_FAILURE,
CB_ADDSTRING,
0,
(LPARAM)lpAction);
SendDlgItemMessageW(hwndDlg,
IDC_SECOND_FAILURE,
CB_ADDSTRING,
0,
(LPARAM)lpAction);
SendDlgItemMessageW(hwndDlg,
IDC_SUBSEQUENT_FAILURES,
CB_ADDSTRING,
0,
(LPARAM)lpAction);
LocalFree(lpAction);
}
}
SendDlgItemMessageW(hwndDlg,
IDC_FIRST_FAILURE,
CB_SETCURSEL,
0,
0);
SendDlgItemMessageW(hwndDlg,
IDC_SECOND_FAILURE,
CB_SETCURSEL,
0,
0);
SendDlgItemMessageW(hwndDlg,
IDC_SUBSEQUENT_FAILURES,
CB_SETCURSEL,
0,
0);
SendDlgItemMessageW(hwndDlg,
IDC_RESET_TIME,
WM_SETTEXT,
0,
(LPARAM)L"0");
SendDlgItemMessageW(hwndDlg,
IDC_RESTART_TIME,
WM_SETTEXT,
0,
(LPARAM)L"1");
for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_OPTIONS; id++)
EnableWindow(GetDlgItem(hwndDlg, id), FALSE);
}
static
BOOL
GetServiceFailure(
PRECOVERYDATA pRecoveryData)
{
LPSERVICE_FAILURE_ACTIONS pServiceFailure = NULL;
SC_HANDLE hManager = NULL;
SC_HANDLE hService = NULL;
BOOL bResult = TRUE;
DWORD cbBytesNeeded = 0;
hManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_CONNECT);
if (hManager == NULL)
{
bResult = FALSE;
goto done;
}
hService = OpenService(hManager, pRecoveryData->pService->lpServiceName, SERVICE_QUERY_CONFIG);
if (hService == NULL)
{
bResult = FALSE;
goto done;
}
if (!QueryServiceConfig2(hService,
SERVICE_CONFIG_FAILURE_ACTIONS,
NULL,
0,
&cbBytesNeeded))
{
if (cbBytesNeeded == 0)
{
bResult = FALSE;
goto done;
}
}
pServiceFailure = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
if (pServiceFailure == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
bResult = FALSE;
goto done;
}
if (!QueryServiceConfig2(hService,
SERVICE_CONFIG_FAILURE_ACTIONS,
(LPBYTE)pServiceFailure,
cbBytesNeeded,
&cbBytesNeeded))
{
bResult = FALSE;
goto done;
}
pRecoveryData->pServiceFailure = pServiceFailure;
done:
if (bResult == FALSE && pServiceFailure != NULL)
HeapFree(GetProcessHeap(), 0, pServiceFailure);
if (hService)
CloseServiceHandle(hService);
if (hManager)
CloseServiceHandle(hManager);
return bResult;
}
static
VOID
ShowFailureActions(
HWND hwndDlg,
PRECOVERYDATA pRecoveryData)
{
WCHAR szBuffer[256];
PWSTR startPtr, endPtr;
INT index, id, length;
DWORD i;
for (i = 0; i < min(pRecoveryData->pServiceFailure->cActions, 3); i++)
{
index = -1;
switch (pRecoveryData->pServiceFailure->lpsaActions[i].Type)
{
case SC_ACTION_NONE:
index = 0;
break;
case SC_ACTION_RESTART:
index = 1;
wsprintf(szBuffer, L"%lu", pRecoveryData->pServiceFailure->lpsaActions[i].Delay / 60000);
SendDlgItemMessageW(hwndDlg,
IDC_RESTART_TIME,
WM_SETTEXT,
0,
(LPARAM)szBuffer);
for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_TEXT2; id++)
EnableWindow(GetDlgItem(hwndDlg, id), TRUE);
break;
case SC_ACTION_REBOOT:
index = 3;
EnableWindow(GetDlgItem(hwndDlg, IDC_RESTART_OPTIONS), TRUE);
break;
case SC_ACTION_RUN_COMMAND:
index = 2;
for (id = IDC_RUN_GROUPBOX; id <= IDC_ADD_FAILCOUNT; id++)
EnableWindow(GetDlgItem(hwndDlg, id), TRUE);
break;
}
if (index != -1)
{
SendDlgItemMessageW(hwndDlg,
IDC_FIRST_FAILURE + i,
CB_SETCURSEL,
index,
0);
}
}
wsprintf(szBuffer, L"%lu", pRecoveryData->pServiceFailure->dwResetPeriod / 86400);
SendDlgItemMessageW(hwndDlg,
IDC_RESET_TIME,
WM_SETTEXT,
0,
(LPARAM)szBuffer);
if (pRecoveryData->pServiceFailure->lpCommand != NULL)
{
ZeroMemory(szBuffer, sizeof(szBuffer));
startPtr = pRecoveryData->pServiceFailure->lpCommand;
if (*startPtr == L'\"')
startPtr++;
endPtr = wcschr(startPtr, L'\"');
if (endPtr != NULL)
{
length = (INT)((LONG_PTR)endPtr - (LONG_PTR)startPtr);
CopyMemory(szBuffer, startPtr, length);
}
else
{
wcscpy(szBuffer, startPtr);
}
SendDlgItemMessageW(hwndDlg,
IDC_PROGRAM,
WM_SETTEXT,
0,
(LPARAM)szBuffer);
ZeroMemory(szBuffer, sizeof(szBuffer));
if (endPtr != NULL)
{
startPtr = endPtr + 1;
while (iswspace(*startPtr))
startPtr++;
endPtr = wcsstr(pRecoveryData->pServiceFailure->lpCommand, L"/fail=%1%");
if (endPtr != NULL)
{
while (iswspace(*(endPtr - 1)))
endPtr--;
length = (INT)((LONG_PTR)endPtr - (LONG_PTR)startPtr);
CopyMemory(szBuffer, startPtr, length);
}
else
{
wcscpy(szBuffer, startPtr);
}
SendDlgItemMessageW(hwndDlg,
IDC_PARAMETERS,
WM_SETTEXT,
0,
(LPARAM)szBuffer);
endPtr = wcsstr(pRecoveryData->pServiceFailure->lpCommand, L"/fail=%1%");
if (endPtr != NULL)
{
SendDlgItemMessageW(hwndDlg,
IDC_ADD_FAILCOUNT,
BM_SETCHECK,
BST_CHECKED,
0);
}
}
}
}
static
VOID
UpdateFailureActions(
HWND hwndDlg,
PRECOVERYDATA pRecoveryData)
{
INT id, index;
BOOL bRestartService = FALSE;
BOOL bRunProgram = FALSE;
BOOL bRebootComputer = FALSE;
for (id = IDC_FIRST_FAILURE; id <= IDC_SUBSEQUENT_FAILURES; id++)
{
index = SendDlgItemMessageW(hwndDlg,
id,
CB_GETCURSEL,
0,
0);
switch (index)
{
case 1: /* Restart Service */
bRestartService = TRUE;
break;
case 2: /* Run Program */
bRunProgram = TRUE;
break;
case 3: /* Reboot Computer */
bRebootComputer = TRUE;
break;
}
}
for (id = IDC_RESTART_TEXT1; id <= IDC_RESTART_TEXT2; id++)
EnableWindow(GetDlgItem(hwndDlg, id), bRestartService);
for (id = IDC_RUN_GROUPBOX; id <= IDC_ADD_FAILCOUNT; id++)
EnableWindow(GetDlgItem(hwndDlg, id), bRunProgram);
EnableWindow(GetDlgItem(hwndDlg, IDC_RESTART_OPTIONS), bRebootComputer);
}
static
VOID
BrowseFile(
HWND hwndDlg)
{
WCHAR szFile[MAX_PATH] = {'\0'};
PWCHAR pszFilter = L"Executable Files (*.exe;*.com;*.cmd;*.bat)\0*.exe;*.com;*.cmd;*.bat\0";
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ENABLESIZING;
ofn.hwndOwner = hwndDlg;
ofn.lpstrFilter = pszFilter;
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn))
{
SendDlgItemMessageW(hwndDlg,
IDC_PROGRAM,
WM_SETTEXT,
0,
(LPARAM)szFile);
}
}
static
VOID
SetFailureActions(
HWND hwndDlg)
{
SERVICE_FAILURE_ACTIONS FailureActions;
BOOL bRestartService = FALSE;
BOOL bRunProgram = FALSE;
BOOL bRebootComputer = FALSE;
INT id, index;
ZeroMemory(&FailureActions, sizeof(FailureActions));
/* Count the number of valid failure actions */
for (id = IDC_FIRST_FAILURE; id <= IDC_SUBSEQUENT_FAILURES; id++)
{
index = SendDlgItemMessageW(hwndDlg,
id,
CB_GETCURSEL,
0,
0);
switch (index)
{
case 1: /* Restart Service */
bRestartService = TRUE;
FailureActions.cActions++;
break;
case 2: /* Run Program */
bRunProgram = TRUE;
FailureActions.cActions++;
break;
case 3: /* Reboot Computer */
bRebootComputer = TRUE;
FailureActions.cActions++;
break;
}
}
if (bRestartService)
{
// IDC_RESTART_TIME
}
if (bRunProgram)
{
// IDC_RESTART_TIME
}
if (bRebootComputer)
{
// IDC_RESTART_TIME
}
#if 0
typedef struct _SERVICE_FAILURE_ACTIONS {
DWORD dwResetPeriod;
LPTSTR lpRebootMsg;
LPTSTR lpCommand;
DWORD cActions;
SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;
#endif
}
INT_PTR
CALLBACK
RecoveryPageProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PRECOVERYDATA pRecoveryData;
/* Get the window context */
pRecoveryData = (PRECOVERYDATA)GetWindowLongPtr(hwndDlg,
GWLP_USERDATA);
if (pRecoveryData == NULL && uMsg != WM_INITDIALOG)
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
pRecoveryData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RECOVERYDATA));
if (pRecoveryData != NULL)
{
SetWindowLongPtr(hwndDlg,
GWLP_USERDATA,
(LONG_PTR)pRecoveryData);
pRecoveryData->pService = ((PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam))->pService;
InitRecoveryPage(hwndDlg);
if (GetServiceFailure(pRecoveryData))
{
ShowFailureActions(hwndDlg, pRecoveryData);
}
}
break;
case WM_DESTROY:
if (pRecoveryData != NULL)
{
if (pRecoveryData->pServiceFailure != NULL)
HeapFree(GetProcessHeap(), 0, pRecoveryData->pServiceFailure);
HeapFree(GetProcessHeap(), 0, pRecoveryData);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_FIRST_FAILURE:
case IDC_SECOND_FAILURE:
case IDC_SUBSEQUENT_FAILURES:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
UpdateFailureActions(hwndDlg, pRecoveryData);
pRecoveryData->bChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_RESET_TIME:
case IDC_RESTART_TIME:
case IDC_PROGRAM:
case IDC_PARAMETERS:
if (HIWORD(wParam) == EN_CHANGE)
{
pRecoveryData->bChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_ADD_FAILCOUNT:
if (HIWORD(wParam) == BN_CLICKED)
{
pRecoveryData->bChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_BROWSE_PROGRAM:
BrowseFile(hwndDlg);
break;
case IDC_RESTART_OPTIONS:
break;
}
break;
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case PSN_APPLY:
if (pRecoveryData->bChanged)
{
SetFailureActions(hwndDlg);
pRecoveryData->bChanged = FALSE;
}
break;
}
break;
}
return FALSE;
}