reactos/dll/cpl/sysdm/startrec.c
Hermès Bélusca-Maïto a8e06d92e8
[SYSDM] Make ResourceMessageBox() support printf-like messages. (#4844)
+ Make usage of this new functionality.
+ Cleanup precomp.h.
2022-11-16 21:55:22 +01:00

840 lines
28 KiB
C

/*
* PROJECT: ReactOS System Control Panel Applet
* LICENSE: GPL - See COPYING in the top level directory
* FILE: dll/cpl/sysdm/startrec.c
* PURPOSE: Computer settings for startup and recovery
* COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
* Copyright 2006 Christoph von Wittich <Christoph@ApiViewer.de>
* Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org>
*/
#include "precomp.h"
#include <shlwapi.h>
typedef struct _BOOTRECORD
{
DWORD BootType;
WCHAR szSectionName[128];
WCHAR szBootPath[MAX_PATH];
WCHAR szOptions[512];
} BOOTRECORD, *PBOOTRECORD;
typedef struct _STARTINFO
{
WCHAR szFreeldrIni[MAX_PATH + 15];
WCHAR szDumpFile[MAX_PATH];
WCHAR szMinidumpDir[MAX_PATH];
DWORD dwCrashDumpEnabled;
INT iFreeLdrIni;
} STARTINFO, *PSTARTINFO;
BOOL SaveRecoveryOptions;
static VOID
SetTimeout(HWND hwndDlg, INT Timeout)
{
if (Timeout == 0)
{
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTUPDWN), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTEDIT), FALSE);
}
else
{
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTUPDWN), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTEDIT), TRUE);
}
SendDlgItemMessageW(hwndDlg, IDC_STRRECLISTUPDWN, UDM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELONG((short) 999, 0));
SendDlgItemMessageW(hwndDlg, IDC_STRRECLISTUPDWN, UDM_SETPOS, (WPARAM) 0, (LPARAM) MAKELONG((short) Timeout, 0));
}
static VOID
SetRecoveryTimeout(HWND hwndDlg, INT Timeout)
{
if (Timeout == 0)
{
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECUPDWN), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECEDIT), FALSE);
}
else
{
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECUPDWN), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECEDIT), TRUE);
}
SendDlgItemMessageW(hwndDlg, IDC_STRRECRECUPDWN, UDM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELONG((short) 999, 0));
SendDlgItemMessageW(hwndDlg, IDC_STRRECRECUPDWN, UDM_SETPOS, (WPARAM) 0, (LPARAM) MAKELONG((short) Timeout, 0));
}
static DWORD
GetSystemDrive(WCHAR **szSystemDrive)
{
DWORD dwBufSize;
/* Get Path to freeldr.ini or boot.ini */
*szSystemDrive = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
if (*szSystemDrive != NULL)
{
dwBufSize = GetEnvironmentVariableW(L"SystemDrive", *szSystemDrive, MAX_PATH);
if (dwBufSize > MAX_PATH)
{
WCHAR *szTmp;
DWORD dwBufSize2;
szTmp = HeapReAlloc(GetProcessHeap(), 0, *szSystemDrive, dwBufSize * sizeof(WCHAR));
if (szTmp == NULL)
goto FailGetSysDrive;
*szSystemDrive = szTmp;
dwBufSize2 = GetEnvironmentVariableW(L"SystemDrive", *szSystemDrive, dwBufSize);
if (dwBufSize2 > dwBufSize || dwBufSize2 == 0)
goto FailGetSysDrive;
}
else if (dwBufSize == 0)
{
FailGetSysDrive:
HeapFree(GetProcessHeap(), 0, *szSystemDrive);
*szSystemDrive = NULL;
return 0;
}
return dwBufSize;
}
return 0;
}
static PBOOTRECORD
ReadFreeldrSection(HINF hInf, WCHAR *szSectionName)
{
PBOOTRECORD pRecord;
INFCONTEXT InfContext;
WCHAR szName[MAX_PATH];
WCHAR szValue[MAX_PATH];
DWORD LineLength;
if (!SetupFindFirstLineW(hInf,
szSectionName,
NULL,
&InfContext))
{
/* Failed to find section */
return NULL;
}
pRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
if (pRecord == NULL)
{
return NULL;
}
wcscpy(pRecord->szSectionName, szSectionName);
do
{
if (!SetupGetStringFieldW(&InfContext,
0,
szName,
sizeof(szName) / sizeof(WCHAR),
&LineLength))
{
break;
}
if (!SetupGetStringFieldW(&InfContext,
1,
szValue,
sizeof(szValue) / sizeof(WCHAR),
&LineLength))
{
break;
}
if (!_wcsnicmp(szName, L"BootType", 8))
{
if (!_wcsnicmp(szValue, L"ReactOS", 7))
{
// FIXME: Store as enum
pRecord->BootType = 1;
}
else
{
pRecord->BootType = 0;
}
}
else if (!_wcsnicmp(szName, L"SystemPath", 10))
{
wcscpy(pRecord->szBootPath, szValue);
}
else if (!_wcsnicmp(szName, L"Options", 7))
{
// FIXME: Store flags as values
wcscpy(pRecord->szOptions, szValue);
}
}
while (SetupFindNextLine(&InfContext, &InfContext));
return pRecord;
}
static INT
LoadFreeldrSettings(HINF hInf, HWND hwndDlg)
{
INFCONTEXT InfContext;
PBOOTRECORD pRecord;
WCHAR szDefaultOs[MAX_PATH];
WCHAR szName[MAX_PATH];
WCHAR szValue[MAX_PATH];
DWORD LineLength;
DWORD TimeOut;
LRESULT lResult;
if (!SetupFindFirstLineW(hInf,
L"FREELOADER",
L"DefaultOS",
&InfContext))
{
/* Failed to find default os */
return FALSE;
}
if (!SetupGetStringFieldW(&InfContext,
1,
szDefaultOs,
sizeof(szDefaultOs) / sizeof(WCHAR),
&LineLength))
{
/* No key */
return FALSE;
}
if (!SetupFindFirstLineW(hInf,
L"FREELOADER",
L"TimeOut",
&InfContext))
{
/* Expected to find timeout value */
return FALSE;
}
if (!SetupGetIntField(&InfContext,
1,
(PINT)&TimeOut))
{
/* Failed to retrieve timeout */
return FALSE;
}
if (!SetupFindFirstLineW(hInf,
L"Operating Systems",
NULL,
&InfContext))
{
/* Expected list of operating systems */
return FALSE;
}
do
{
if (!SetupGetStringFieldW(&InfContext,
0,
szName,
sizeof(szName) / sizeof(WCHAR),
&LineLength))
{
/* The ini file is messed up */
return FALSE;
}
if (!SetupGetStringFieldW(&InfContext,
1,
szValue,
sizeof(szValue) / sizeof(WCHAR),
&LineLength))
{
/* The ini file is messed up */
return FALSE;
}
pRecord = ReadFreeldrSection(hInf, szName);
if (pRecord)
{
lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
if (lResult != CB_ERR)
{
SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord);
if (!wcscmp(szDefaultOs, szName))
{
/* We store the friendly name as key */
wcscpy(szDefaultOs, szValue);
}
}
else
{
HeapFree(GetProcessHeap(), 0, pRecord);
}
}
}
while (SetupFindNextLine(&InfContext, &InfContext));
/* Find default os in list */
lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)-1, (LPARAM)szDefaultOs);
if (lResult != CB_ERR)
{
/* Set cur sel */
SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
}
if(TimeOut)
{
SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
}
SetTimeout(hwndDlg, TimeOut);
return TRUE;
}
static INT
LoadBootSettings(HINF hInf, HWND hwndDlg)
{
INFCONTEXT InfContext;
WCHAR szName[MAX_PATH];
WCHAR szValue[MAX_PATH];
DWORD LineLength;
DWORD TimeOut = 0;
WCHAR szDefaultOS[MAX_PATH];
WCHAR szOptions[MAX_PATH];
PBOOTRECORD pRecord;
LRESULT lResult;
if(!SetupFindFirstLineW(hInf,
L"boot loader",
NULL,
&InfContext))
{
return FALSE;
}
do
{
if (!SetupGetStringFieldW(&InfContext,
0,
szName,
sizeof(szName) / sizeof(WCHAR),
&LineLength))
{
return FALSE;
}
if (!SetupGetStringFieldW(&InfContext,
1,
szValue,
sizeof(szValue) / sizeof(WCHAR),
&LineLength))
{
return FALSE;
}
if (!_wcsnicmp(szName, L"timeout", 7))
{
TimeOut = _wtoi(szValue);
}
if (!_wcsnicmp(szName, L"default", 7))
{
wcscpy(szDefaultOS, szValue);
}
}
while (SetupFindNextLine(&InfContext, &InfContext));
if (!SetupFindFirstLineW(hInf,
L"operating systems",
NULL,
&InfContext))
{
/* Failed to find operating systems section */
return FALSE;
}
do
{
if (!SetupGetStringFieldW(&InfContext,
0,
szName,
sizeof(szName) / sizeof(WCHAR),
&LineLength))
{
return FALSE;
}
if (!SetupGetStringFieldW(&InfContext,
1,
szValue,
sizeof(szValue) / sizeof(WCHAR),
&LineLength))
{
return FALSE;
}
SetupGetStringFieldW(&InfContext,
2,
szOptions,
sizeof(szOptions) / sizeof(WCHAR),
&LineLength);
pRecord = (PBOOTRECORD) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
if (pRecord)
{
pRecord->BootType = 0;
wcscpy(pRecord->szBootPath, szName);
wcscpy(pRecord->szSectionName, szValue);
wcscpy(pRecord->szOptions, szOptions);
if (!wcscmp(szName, szDefaultOS))
{
/* ms boot ini stores the path not the friendly name */
wcscpy(szDefaultOS, szValue);
}
lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
if (lResult != CB_ERR)
{
SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord);
}
else
{
HeapFree(GetProcessHeap(), 0, pRecord);
}
}
}
while (SetupFindNextLine(&InfContext, &InfContext));
/* Find default os in list */
lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)0, (LPARAM)szDefaultOS);
if (lResult != CB_ERR)
{
/* Set cur sel */
SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
}
if(TimeOut)
{
SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
}
SetTimeout(hwndDlg, TimeOut);
return TRUE;
}
static VOID
DeleteBootRecords(HWND hwndDlg)
{
LRESULT lIndex;
LONG index;
PBOOTRECORD pRecord;
lIndex = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
if (lIndex == CB_ERR)
return;
for (index = 0; index <lIndex; index++)
{
pRecord = (PBOOTRECORD) SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_GETITEMDATA, (WPARAM)index, (LPARAM)0);
if ((INT_PTR)pRecord != CB_ERR)
{
HeapFree(GetProcessHeap(), 0, pRecord);
}
}
SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
}
static LRESULT
LoadOSList(HWND hwndDlg, PSTARTINFO pStartInfo)
{
DWORD dwBufSize;
WCHAR *szSystemDrive;
HINF hInf;
dwBufSize = GetSystemDrive(&szSystemDrive);
if (dwBufSize == 0)
return FALSE;
wcscpy(pStartInfo->szFreeldrIni, szSystemDrive);
wcscat(pStartInfo->szFreeldrIni, L"\\freeldr.ini");
if (PathFileExistsW(pStartInfo->szFreeldrIni))
{
/* Free resource previously allocated by GetSystemDrive() */
HeapFree(GetProcessHeap(), 0, szSystemDrive);
/* freeldr.ini exists */
hInf = SetupOpenInfFileW(pStartInfo->szFreeldrIni,
NULL,
INF_STYLE_OLDNT,
NULL);
if (hInf != INVALID_HANDLE_VALUE)
{
LoadFreeldrSettings(hInf, hwndDlg);
SetupCloseInfFile(hInf);
pStartInfo->iFreeLdrIni = 1;
return TRUE;
}
return FALSE;
}
/* Try loading boot.ini settings */
wcscpy(pStartInfo->szFreeldrIni, szSystemDrive);
wcscat(pStartInfo->szFreeldrIni, L"\\boot.ini");
/* Free resource previously allocated by GetSystemDrive() */
HeapFree(GetProcessHeap(), 0, szSystemDrive);
if (PathFileExistsW(pStartInfo->szFreeldrIni))
{
/* Load boot.ini settings */
hInf = SetupOpenInfFileW(pStartInfo->szFreeldrIni,
NULL,
INF_STYLE_OLDNT,
NULL);
if (hInf != INVALID_HANDLE_VALUE)
{
LoadBootSettings(hInf, hwndDlg);
SetupCloseInfFile(hInf);
pStartInfo->iFreeLdrIni = 2;
return TRUE;
}
return FALSE;
}
return FALSE;
}
static VOID
SetCrashDlgItems(HWND hwnd, PSTARTINFO pStartInfo)
{
if (pStartInfo->dwCrashDumpEnabled == 0)
{
/* No crash information required */
EnableWindow(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), FALSE);
EnableWindow(GetDlgItem(hwnd, IDC_STRRECOVERWRITE), FALSE);
}
else if (pStartInfo->dwCrashDumpEnabled == 3)
{
/* Minidump type */
EnableWindow(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), TRUE);
EnableWindow(GetDlgItem(hwnd, IDC_STRRECOVERWRITE), FALSE);
SendMessageW(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), WM_SETTEXT, (WPARAM)0, (LPARAM)pStartInfo->szMinidumpDir);
}
else if (pStartInfo->dwCrashDumpEnabled == 1 || pStartInfo->dwCrashDumpEnabled == 2)
{
/* Kernel or complete dump */
EnableWindow(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), TRUE);
EnableWindow(GetDlgItem(hwnd, IDC_STRRECOVERWRITE), TRUE);
SendMessageW(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), WM_SETTEXT, (WPARAM)0, (LPARAM)pStartInfo->szDumpFile);
}
SendDlgItemMessageW(hwnd, IDC_STRRECDEBUGCOMBO, CB_SETCURSEL, (WPARAM)pStartInfo->dwCrashDumpEnabled, (LPARAM)0);
}
static VOID
WriteStartupRecoveryOptions(HWND hwndDlg, PSTARTINFO pStartInfo)
{
HKEY hKey;
DWORD lResult;
lResult = (DWORD)RegCreateKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\CrashControl",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&hKey,
NULL);
if (lResult != ERROR_SUCCESS)
{
/* Failed to open key */
SetLastError(lResult);
ShowLastWin32Error(hwndDlg);
return;
}
lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECWRITEEVENT, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
RegSetValueExW(hKey, L"LogEvent", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult));
lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECSENDALERT, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
RegSetValueExW(hKey, L"SendAlert", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult));
lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECRESTART, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
RegSetValueExW(hKey, L"AutoReboot", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult));
lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECOVERWRITE, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
RegSetValueExW(hKey, L"Overwrite", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult));
if (pStartInfo->dwCrashDumpEnabled == 1 || pStartInfo->dwCrashDumpEnabled == 2)
{
SendDlgItemMessage(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szDumpFile) / sizeof(WCHAR), (LPARAM)pStartInfo->szDumpFile);
RegSetValueExW(hKey, L"DumpFile", 0, REG_EXPAND_SZ, (LPBYTE)pStartInfo->szDumpFile, (wcslen(pStartInfo->szDumpFile) + 1) * sizeof(WCHAR));
}
else if (pStartInfo->dwCrashDumpEnabled == 3)
{
SendDlgItemMessage(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szDumpFile) / sizeof(WCHAR), (LPARAM)pStartInfo->szDumpFile);
RegSetValueExW(hKey, L"MinidumpDir", 0, REG_EXPAND_SZ, (LPBYTE)pStartInfo->szDumpFile, (wcslen(pStartInfo->szDumpFile) + 1) * sizeof(WCHAR));
}
RegSetValueExW(hKey, L"CrashDumpEnabled", 0, REG_DWORD, (LPBYTE)&pStartInfo->dwCrashDumpEnabled, sizeof(pStartInfo->dwCrashDumpEnabled));
RegCloseKey(hKey);
}
static VOID
LoadRecoveryOptions(HWND hwndDlg, PSTARTINFO pStartInfo)
{
HKEY hKey;
WCHAR szName[MAX_PATH];
DWORD dwValue, dwValueLength, dwType, dwResult;
dwResult = (DWORD)RegCreateKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\CrashControl",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ,
NULL,
&hKey,
NULL);
if (dwResult != ERROR_SUCCESS)
{
/* Failed to open key */
SetLastError(dwResult);
ShowLastWin32Error(hwndDlg);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECWRITEEVENT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECSENDALERT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRESTART), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECDEBUGCOMBO), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECDUMPFILE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECOVERWRITE), FALSE);
SaveRecoveryOptions = FALSE;
return;
}
dwValueLength = sizeof(DWORD);
if (RegQueryValueExW(hKey, L"LogEvent", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue)
SendDlgItemMessageW(hwndDlg, IDC_STRRECWRITEEVENT, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
dwValueLength = sizeof(DWORD);
if (RegQueryValueExW(hKey, L"SendAlert", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue)
SendDlgItemMessageW(hwndDlg, IDC_STRRECSENDALERT, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
dwValueLength = sizeof(DWORD);
if (RegQueryValueExW(hKey, L"AutoReboot", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue)
SendDlgItemMessageW(hwndDlg, IDC_STRRECRESTART, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
dwValueLength = sizeof(DWORD);
if (RegQueryValueExW(hKey, L"Overwrite", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue)
SendDlgItemMessageW(hwndDlg, IDC_STRRECOVERWRITE, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
dwValueLength = sizeof(DWORD);
if (RegQueryValueExW(hKey, L"CrashDumpEnabled", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue)
pStartInfo->dwCrashDumpEnabled = dwValue;
dwValueLength = sizeof(pStartInfo->szDumpFile);
if (RegQueryValueExW(hKey, L"DumpFile", NULL, &dwType, (LPBYTE)pStartInfo->szDumpFile, &dwValueLength) != ERROR_SUCCESS)
pStartInfo->szDumpFile[0] = L'\0';
dwValueLength = sizeof(pStartInfo->szMinidumpDir);
if (RegQueryValueExW(hKey, L"MinidumpDir", NULL, &dwType, (LPBYTE)pStartInfo->szMinidumpDir, &dwValueLength) != ERROR_SUCCESS)
pStartInfo->szMinidumpDir[0] = L'\0';
if (LoadStringW(hApplet, IDS_NO_DUMP, szName, sizeof(szName) / sizeof(WCHAR)))
{
szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName);
}
if (LoadStringW(hApplet, IDS_FULL_DUMP, szName, sizeof(szName) / sizeof(WCHAR)))
{
szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName);
}
if (LoadStringW(hApplet, IDS_KERNEL_DUMP, szName, sizeof(szName) / sizeof(WCHAR)))
{
szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName);
}
if (LoadStringW(hApplet, IDS_MINI_DUMP, szName, sizeof(szName) / sizeof(WCHAR)))
{
szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName);
}
SetCrashDlgItems(hwndDlg, pStartInfo);
RegCloseKey(hKey);
SaveRecoveryOptions = TRUE;
}
/* Property page dialog callback */
INT_PTR CALLBACK
StartRecDlgProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PSTARTINFO pStartInfo;
PBOOTRECORD pRecord;
int iTimeout;
LRESULT lResult;
WCHAR szTimeout[10];
UNREFERENCED_PARAMETER(lParam);
pStartInfo = (PSTARTINFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch(uMsg)
{
case WM_INITDIALOG:
pStartInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STARTINFO));
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pStartInfo);
LoadRecoveryOptions(hwndDlg, pStartInfo);
SetRecoveryTimeout(hwndDlg, 0);
return LoadOSList(hwndDlg, pStartInfo);
case WM_DESTROY:
DeleteBootRecords(hwndDlg);
HeapFree(GetProcessHeap(), 0, pStartInfo);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_STRRECEDIT:
ShellExecuteW(0, L"open", L"notepad", pStartInfo->szFreeldrIni, NULL, SW_SHOWNORMAL);
// FIXME: Use CreateProcess and wait untill finished
// DeleteBootRecords(hwndDlg);
// LoadOSList(hwndDlg);
break;
case IDOK:
/* Save timeout */
if (SendDlgItemMessage(hwndDlg, IDC_STRECLIST, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED)
iTimeout = SendDlgItemMessage(hwndDlg, IDC_STRRECLISTUPDWN, UDM_GETPOS, (WPARAM)0, (LPARAM)0);
else
iTimeout = 0;
swprintf(szTimeout, L"%i", iTimeout);
lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
if (lResult == CB_ERR)
{
/* ? */
DeleteBootRecords(hwndDlg);
return TRUE;
}
pRecord = (PBOOTRECORD) SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETITEMDATA, (WPARAM)lResult, (LPARAM)0);
if ((INT_PTR)pRecord != CB_ERR)
{
if (pStartInfo->iFreeLdrIni == 1) // FreeLdrIni style
{
/* Set default timeout */
WritePrivateProfileStringW(L"FREELOADER",
L"TimeOut",
szTimeout,
pStartInfo->szFreeldrIni);
/* Set default OS */
WritePrivateProfileStringW(L"FREELOADER",
L"DefaultOS",
pRecord->szSectionName,
pStartInfo->szFreeldrIni);
}
else if (pStartInfo->iFreeLdrIni == 2) // BootIni style
{
/* Set default timeout */
WritePrivateProfileStringW(L"boot loader",
L"timeout",
szTimeout,
pStartInfo->szFreeldrIni);
/* Set default OS */
WritePrivateProfileStringW(L"boot loader",
L"default",
pRecord->szBootPath,
pStartInfo->szFreeldrIni);
}
}
if (SaveRecoveryOptions)
{
WriteStartupRecoveryOptions(hwndDlg, pStartInfo);
}
EndDialog(hwndDlg,
LOWORD(wParam));
return TRUE;
case IDCANCEL:
EndDialog(hwndDlg,
LOWORD(wParam));
return TRUE;
case IDC_STRECLIST:
if (SendDlgItemMessage(hwndDlg, IDC_STRECLIST, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED)
SetTimeout(hwndDlg, 30);
else
SetTimeout(hwndDlg, 0);
break;
case IDC_STRRECREC:
if (SendDlgItemMessage(hwndDlg, IDC_STRRECREC, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED)
SetRecoveryTimeout(hwndDlg, 30);
else
SetRecoveryTimeout(hwndDlg, 0);
break;
case IDC_STRRECDEBUGCOMBO:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
LRESULT lResult;
lResult = SendDlgItemMessage(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
if (lResult != CB_ERR && lResult != (LRESULT)pStartInfo->dwCrashDumpEnabled)
{
if (pStartInfo->dwCrashDumpEnabled == 1 || pStartInfo->dwCrashDumpEnabled == 2)
{
SendDlgItemMessageW(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szDumpFile) / sizeof(WCHAR), (LPARAM)pStartInfo->szDumpFile);
}
else if (pStartInfo->dwCrashDumpEnabled == 3)
{
SendDlgItemMessageW(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szMinidumpDir) / sizeof(WCHAR), (LPARAM)pStartInfo->szMinidumpDir);
}
pStartInfo->dwCrashDumpEnabled = (DWORD)lResult;
SetCrashDlgItems(hwndDlg, pStartInfo);
}
}
break;
}
break;
}
return FALSE;
}