You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1272 lines
38 KiB
1272 lines
38 KiB
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
#include "precomp.h"
|
|
|
|
#ifdef EXT_DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#include "StartupPage.h"
|
|
|
|
// avoid some warnings.
|
|
#undef HDS_HORZ
|
|
#undef HDS_BUTTONS
|
|
#undef HDS_HIDDEN
|
|
#include "resource.h"
|
|
#include <stdlib.h>
|
|
#include <TCHAR.h>
|
|
#include "..\Common\util.h"
|
|
#include <windowsx.h>
|
|
#include <commctrl.h>
|
|
#include <shellapi.h>
|
|
#include "RebootPage.h"
|
|
#include "helpid.h"
|
|
#include "NetUtility.h"
|
|
|
|
// Reboot switch for crashdump dlg
|
|
#define RET_ERROR (-1)
|
|
#define RET_NO_CHANGE 0x00
|
|
#define RET_VIRTUAL_CHANGE 0x01
|
|
#define RET_RECOVER_CHANGE 0x02
|
|
#define RET_CHANGE_NO_REBOOT 0x04
|
|
#define RET_CONTINUE 0x08
|
|
#define RET_BREAK 0x10
|
|
#define RET_VIRT_AND_RECOVER (RET_VIRTUAL_CHANGE | RET_RECOVER_CHANGE)
|
|
|
|
|
|
#define FORMIN 0
|
|
#define FORMAX 999
|
|
// Length of WCHAR buffer needed to hold "Display startup list for..." value
|
|
#define FOR_MAX_LENGTH 20
|
|
|
|
// Default "Display startup list for..." value
|
|
#define FORDEF 30
|
|
|
|
#define NO_DUMP_OPTION 0
|
|
#define COMPLETE_DUMP_OPTION 1
|
|
#define KERNEL_DUMP_OPTION 2
|
|
#define SMALL_DUMP_OPTION 3
|
|
|
|
//
|
|
// Help ID's
|
|
//
|
|
|
|
DWORD aStartupHelpIds[] = {
|
|
IDC_STARTUP_SYS_OS, (IDH_STARTUP + 0),
|
|
IDC_STARTUP_SYS_ENABLECOUNTDOWN, (IDH_STARTUP + 1),
|
|
IDC_STARTUP_SYS_SECONDS, (IDH_STARTUP + 2),
|
|
IDC_STARTUP_SYS_SECONDS_LABEL, (IDH_STARTUP + 2),
|
|
IDC_STARTUP_CDMP_TXT1, (IDH_STARTUP + 3),
|
|
IDC_STARTUP_CDMP_LOG, (IDH_STARTUP + 4),
|
|
IDC_STARTUP_CDMP_SEND, (IDH_STARTUP + 5),
|
|
IDC_STARTUP_CDMP_FILENAME, (IDH_STARTUP + 7),
|
|
IDC_STARTUP_CDMP_OVERWRITE, (IDH_STARTUP + 13),
|
|
IDC_STARTUP_CDMP_AUTOREBOOT, (IDH_STARTUP + 9),
|
|
IDC_STARTUP_SYSTEM_GRP, (IDH_STARTUP + 10),
|
|
IDC_STARTUP_SYS_SECSCROLL, (IDH_STARTUP + 11),
|
|
IDC_STARTUP_CDMP_GRP, (IDH_STARTUP + 12),
|
|
IDC_STARTUP_SYSTEM_GRP2, (IDH_STARTUP + 14),
|
|
IDC_STARTUP_CDMP_OPTIONS, (IDH_STARTUP + 8),
|
|
IDC_EDIT_BOOT_INI_LABEL, (IDH_STARTUP + 15),
|
|
IDC_EDIT_BOOT_INI, (IDH_STARTUP + 16),
|
|
IDC_REBOOT, IDH_WBEM_ADVANCED_STARTRECOVER_REMOTE_REBOOT,
|
|
0, 0
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
INT_PTR CALLBACK StaticStartupDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// if this is the initDlg msg...
|
|
if(message == WM_INITDIALOG)
|
|
{
|
|
// transfer the 'this' ptr to the extraBytes.
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
|
|
}
|
|
|
|
// DWL_USER is the 'this' ptr.
|
|
StartupPage *me = (StartupPage *)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
if(me != NULL)
|
|
{
|
|
// call into the DlgProc() that has some context.
|
|
return me->DlgProc(hwndDlg, message, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
//--------------------------------------------------------------
|
|
StartupPage::StartupPage(WbemServiceThread *serviceThread)
|
|
: WBEMPageHelper(serviceThread)
|
|
{
|
|
IWbemClassObject *pInst = NULL;
|
|
|
|
m_WbemServices.SetPriv();
|
|
|
|
if((pInst = FirstInstanceOf("Win32_ComputerSystem")) != NULL)
|
|
{
|
|
m_computer = pInst;
|
|
}
|
|
|
|
if((pInst = FirstInstanceOf("Win32_OperatingSystem")) != NULL)
|
|
{
|
|
m_OS = pInst;
|
|
}
|
|
|
|
if((pInst = FirstInstanceOf("Win32_OSRecoveryConfiguration")) != NULL)
|
|
{
|
|
m_recovery = pInst;
|
|
}
|
|
|
|
if((pInst = FirstInstanceOf("Win32_LogicalMemoryConfiguration")) != NULL)
|
|
{
|
|
m_memory = pInst;
|
|
}
|
|
|
|
|
|
m_WbemServices.ClearPriv();
|
|
|
|
m_writable = TRUE;
|
|
m_lBound = 1;
|
|
m_bDownlevelTarget = TRUE; // Assume downlevel until proven otherwise.
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
INT_PTR StartupPage::DoModal(HWND hDlg)
|
|
{
|
|
return DialogBoxParam(HINST_THISDLL,
|
|
(LPTSTR) MAKEINTRESOURCE(IDD_STARTUP),
|
|
hDlg, StaticStartupDlgProc, (LPARAM)this);
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
StartupPage::~StartupPage()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
BOOL StartupPage::CheckVal( HWND hDlg, WORD wID, WORD wMin, WORD wMax, WORD wMsgID )
|
|
{
|
|
WORD nVal;
|
|
BOOL bOK;
|
|
HWND hVal;
|
|
WCHAR szTemp[FOR_MAX_LENGTH];
|
|
|
|
if( wMin > wMax )
|
|
{
|
|
nVal = wMin;
|
|
wMin = wMax;
|
|
wMax = nVal;
|
|
}
|
|
|
|
nVal = (WORD) GetDlgItemInt( hDlg, wID, &bOK, FALSE );
|
|
|
|
//
|
|
// This is a hack to make the null string act equivalent to zero
|
|
//
|
|
if (!bOK) {
|
|
bOK = !GetDlgItemTextW( hDlg, wID, szTemp, FOR_MAX_LENGTH );
|
|
}
|
|
|
|
if( !bOK || ( nVal < wMin ) || ( nVal > wMax ) )
|
|
{
|
|
TCHAR megBuf[30] = {0};
|
|
|
|
MsgBoxParam( hDlg, wMsgID, IDS_DISPLAY_NAME,
|
|
MB_OK | MB_ICONERROR);
|
|
|
|
SendMessage( hDlg, WM_NEXTDLGCTL,
|
|
(WPARAM) ( hVal = GetDlgItem( hDlg, wID ) ), 1L );
|
|
|
|
// SendMessage(hVal, EM_SETSEL, NULL, MAKELONG(0, 32767));
|
|
|
|
SendMessage( hVal, EM_SETSEL, 0, 32767 );
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
INT_PTR CALLBACK StartupPage::DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
m_hDlg = hwndDlg;
|
|
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
Init(hwndDlg);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(HIWORD(wParam))
|
|
{
|
|
case EN_CHANGE:
|
|
case BN_CLICKED:
|
|
case CBN_SELCHANGE:
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
}
|
|
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_STARTUP_SYS_ENABLECOUNTDOWN:
|
|
if (HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
BOOL bChecking = (WORD) !IsDlgButtonChecked(m_hDlg, IDC_STARTUP_SYS_ENABLECOUNTDOWN);
|
|
CheckDlgButton(m_hDlg, IDC_STARTUP_SYS_ENABLECOUNTDOWN, bChecking);
|
|
EnableWindow(GetDlgItem(m_hDlg, IDC_STARTUP_SYS_SECONDS), bChecking);
|
|
EnableWindow(GetDlgItem(m_hDlg, IDC_STARTUP_SYS_SECSCROLL), bChecking);
|
|
|
|
if(bChecking)
|
|
{
|
|
Edit_SetText(GetDlgItem(m_hDlg, IDC_STARTUP_SYS_SECONDS), _T("30"));
|
|
}
|
|
else //unchecking it.
|
|
{
|
|
Edit_SetText(GetDlgItem(m_hDlg, IDC_STARTUP_SYS_SECONDS), _T("0"));
|
|
}
|
|
SendMessage((HWND) lParam, EM_SETSEL, 0, -1);
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_STARTUP_SYS_SECONDS:
|
|
if(HIWORD(wParam) == EN_UPDATE)
|
|
{
|
|
if(!CheckVal(m_hDlg, IDC_STARTUP_SYS_SECONDS, FORMIN, FORMAX, SYSTEM+4))
|
|
{
|
|
SetDlgItemInt(m_hDlg, IDC_STARTUP_SYS_SECONDS, FORDEF, FALSE);
|
|
SendMessage((HWND) lParam, EM_SETSEL, 0, -1);
|
|
|
|
} // endif (!CheckVal()
|
|
|
|
} // endif
|
|
break;
|
|
|
|
case IDC_REBOOT:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
RebootPage dlg(m_serviceThread);
|
|
if(dlg.DoModal(hwndDlg) == IDOK)
|
|
{
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_REBOOT), FALSE);
|
|
m_serviceThread->DisconnectServer();
|
|
EndDialog(m_hDlg, CLOSE_SNAPIN);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDOK:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
if(Save())
|
|
{
|
|
EndDialog(m_hDlg, IDOK);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(m_hDlg, IDCANCEL);
|
|
break;
|
|
|
|
case IDC_STARTUP_CDMP_OPTIONS:
|
|
OnCDMPOptionUpdate();
|
|
break;
|
|
|
|
case IDC_EDIT_BOOT_INI:
|
|
if (m_serviceThread && m_serviceThread->LocalConnection())
|
|
{
|
|
//
|
|
// Local-only option. The button has been disabled but
|
|
// perform this anyway.
|
|
//
|
|
OnBootEdit();
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_HELP: // F1
|
|
::WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
|
|
L"sysdm.hlp",
|
|
HELP_WM_HELP,
|
|
(ULONG_PTR)(LPSTR)aStartupHelpIds);
|
|
break;
|
|
|
|
case WM_CONTEXTMENU: // right mouse click
|
|
WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
|
|
(ULONG_PTR)(LPSTR) aStartupHelpIds);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void StartupPage::OnCDMPOptionUpdate(void)
|
|
{
|
|
HWND ComboHwnd = GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_OPTIONS);
|
|
DWORD dwDumpOption = ComboBox_GetCurSel(ComboHwnd);
|
|
|
|
EnableWindow(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_FILENAME),
|
|
dwDumpOption != NO_DUMP_OPTION);
|
|
EnableWindow(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_OVERWRITE),
|
|
dwDumpOption != NO_DUMP_OPTION);
|
|
|
|
bstr_t debugPath;
|
|
if (dwDumpOption == SMALL_DUMP_OPTION)
|
|
{
|
|
debugPath = m_recovery.GetString("MiniDumpDirectory");
|
|
}
|
|
else
|
|
{
|
|
debugPath = m_recovery.GetString("DebugFilePath");
|
|
}
|
|
|
|
Edit_SetText(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_FILENAME), debugPath);
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
#define BOOT_INI _T("boot.ini")
|
|
|
|
void StartupPage::OnBootEdit(void)
|
|
{
|
|
HKEY hReg;
|
|
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE,
|
|
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup"),
|
|
&hReg) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR szBootDir[4];
|
|
DWORD dwType = REG_SZ;
|
|
DWORD cbBootDir = sizeof(szBootDir);
|
|
|
|
if (RegQueryValueEx(hReg,
|
|
_T("BootDir"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szBootDir,
|
|
&cbBootDir) == ERROR_SUCCESS)
|
|
{
|
|
if (dwType == REG_SZ)
|
|
{
|
|
TCHAR szBootIni[ARRAYSIZE(szBootDir) + ARRAYSIZE(BOOT_INI)];
|
|
|
|
lstrcpy(szBootIni, szBootDir);
|
|
lstrcat(szBootIni, BOOT_INI);
|
|
|
|
ShellExecute(m_hDlg,
|
|
NULL, // Default verb.
|
|
szBootIni, // boot.ini path.
|
|
NULL, // No parameters.
|
|
NULL, // Default working dir.
|
|
SW_SHOWNORMAL);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hReg);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
#define ONE_MEG 1048576
|
|
long StartupPage::GetRAMSizeMB(void)
|
|
{
|
|
IWbemClassObject *pInst = NULL;
|
|
CWbemClassObject memory;
|
|
long RAMsize = 0;
|
|
|
|
if((pInst = FirstInstanceOf("Win32_LogicalMemoryConfiguration")) != NULL)
|
|
{
|
|
memory = pInst;
|
|
long dwTotalPhys = memory.GetLong("TotalPhysicalMemory");
|
|
RAMsize = (dwTotalPhys / ONE_MEG) + 1;
|
|
}
|
|
return RAMsize;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
bool StartupPage::IsWorkstationProduct()
|
|
{
|
|
bool retval = true;
|
|
|
|
bstr_t name = m_OS.GetString("Name");
|
|
|
|
if(name.length() > 0)
|
|
{
|
|
TCHAR sName[200] = {0};
|
|
wcscpy(sName, name);
|
|
if(wcsstr(sName, L"Server") != NULL)
|
|
{
|
|
retval = false;
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
TCHAR szCrashKey[] = TEXT("System\\CurrentControlSet\\Control\\CrashControl");
|
|
|
|
void StartupPage::Init(HWND hDlg)
|
|
{
|
|
HWND ComboHwnd;
|
|
variant_t array;
|
|
DWORD dwDebugInfoType;
|
|
|
|
// load the startup combobox.
|
|
//
|
|
// Must enable SE_SYSTEM_ENVIRONMENT_NAME privilege on ia64.
|
|
//
|
|
#if defined(_IA64_)
|
|
m_WbemServices.SetPriv();
|
|
#endif // IA64
|
|
|
|
m_computer.Get("SystemStartupOptions", (variant_t &)array);
|
|
|
|
#if defined(_IA64_)
|
|
m_WbemServices.ClearPriv();
|
|
#endif // IA64
|
|
|
|
if(array.vt & VT_ARRAY)
|
|
{
|
|
SAFEARRAY *startupArray = V_ARRAY(&array);
|
|
long uBound = 1;
|
|
BSTR temp;
|
|
ComboHwnd = GetDlgItem(hDlg, IDC_STARTUP_SYS_OS);
|
|
|
|
SafeArrayGetLBound(startupArray, 1, &m_lBound);
|
|
SafeArrayGetUBound(startupArray, 1, &uBound);
|
|
|
|
for (long i = m_lBound; i <= uBound; i++)
|
|
{
|
|
SafeArrayGetElement(startupArray, &i, &temp);
|
|
ComboBox_AddString(ComboHwnd, temp);
|
|
}
|
|
|
|
// the first one is the selection we want (watch out for 'lBound' values)
|
|
long idx = m_computer.GetLong("SystemStartupSetting");
|
|
ComboBox_SetCurSel(ComboHwnd, idx - m_lBound);
|
|
|
|
// 3 chars in the second's edit box.
|
|
Edit_LimitText(GetDlgItem(hDlg, IDC_STARTUP_SYS_SECONDS), 3);
|
|
|
|
// limit spinner to 0 - 999.
|
|
SendDlgItemMessage (hDlg, IDC_STARTUP_SYS_SECSCROLL,
|
|
UDM_SETRANGE, 0, (LPARAM)MAKELONG(999,0));
|
|
|
|
|
|
WCHAR buf[30] = {0};
|
|
m_delay = 0;
|
|
m_delay = (short)m_computer.GetLong("SystemStartupDelay");
|
|
BOOL bChecked = (m_delay != 0);
|
|
|
|
CheckDlgButton(m_hDlg, IDC_STARTUP_SYS_ENABLECOUNTDOWN, bChecked);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_SECONDS), bChecked);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_SECSCROLL), bChecked);
|
|
Edit_SetText(GetDlgItem(hDlg, IDC_STARTUP_SYS_SECONDS), _itow(m_delay, buf, 10));
|
|
}
|
|
|
|
if( !(array.vt & VT_ARRAY) || !IsCurrentUserAdministrator())
|
|
{
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_OS), FALSE);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_ENABLECOUNTDOWN), FALSE);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_SECSCROLL), FALSE);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_SECONDS), FALSE);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_STARTUP_SYS_SECONDS_LABEL), FALSE);
|
|
|
|
} // endif VT_ARRAY failure.
|
|
|
|
// set all the recovery controls.
|
|
// Special Case: Server Product does not want ability to disable logging
|
|
// of crashdumps.
|
|
WPARAM checkState;
|
|
|
|
if(IsWorkstationProduct() == true)
|
|
{
|
|
checkState = (m_recovery.GetBool("WriteToSystemLog") ? BST_CHECKED : BST_UNCHECKED);
|
|
Button_SetCheck(GetDlgItem(hDlg, IDC_STARTUP_CDMP_LOG), checkState);
|
|
}
|
|
else
|
|
{
|
|
Button_SetCheck(GetDlgItem(hDlg, IDC_STARTUP_CDMP_LOG), BST_CHECKED);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_LOG),FALSE);
|
|
}
|
|
|
|
//
|
|
// Load the dump options combo box.
|
|
//
|
|
dwDebugInfoType = GetDebugInfoType();
|
|
|
|
TCHAR szBuf[MAX_PATH]; // The largest string loaded here is 24 chars.
|
|
|
|
szBuf[0] = _T('\0');
|
|
ComboHwnd = GetDlgItem(hDlg, IDC_STARTUP_CDMP_OPTIONS);
|
|
LoadString(HINST_THISDLL,
|
|
IDS_NO_DUMP,
|
|
szBuf,
|
|
sizeof(szBuf) / sizeof(TCHAR));
|
|
ComboBox_AddString(ComboHwnd, szBuf);
|
|
szBuf[0] = _T('\0');
|
|
LoadString(HINST_THISDLL,
|
|
IDS_COMPLETE_DUMP,
|
|
szBuf,
|
|
sizeof(szBuf) / sizeof(TCHAR));
|
|
|
|
ComboBox_AddString(ComboHwnd, szBuf);
|
|
szBuf[0] = _T('\0');
|
|
LoadString(HINST_THISDLL,
|
|
IDS_KERNEL_DUMP,
|
|
szBuf,
|
|
sizeof(szBuf) / sizeof(TCHAR));
|
|
ComboBox_AddString(ComboHwnd, szBuf);
|
|
|
|
if (!m_bDownlevelTarget)
|
|
{
|
|
szBuf[0] = _T('\0');
|
|
LoadString(HINST_THISDLL,
|
|
IDS_SMALL_DUMP,
|
|
szBuf,
|
|
sizeof(szBuf) / sizeof(TCHAR));
|
|
ComboBox_AddString(ComboHwnd, szBuf);
|
|
}
|
|
|
|
ComboBox_SetCurSel(ComboHwnd, dwDebugInfoType);
|
|
|
|
checkState = (m_recovery.GetBool("SendAdminAlert") ? BST_CHECKED : BST_UNCHECKED);
|
|
Button_SetCheck(GetDlgItem(hDlg, IDC_STARTUP_CDMP_SEND), checkState);
|
|
|
|
bstr_t debugPath;
|
|
if (dwDebugInfoType == SMALL_DUMP_OPTION)
|
|
{
|
|
debugPath = m_recovery.GetString("MiniDumpDirectory");
|
|
}
|
|
else
|
|
{
|
|
debugPath = m_recovery.GetString("DebugFilePath");
|
|
}
|
|
Edit_SetText(GetDlgItem(hDlg, IDC_STARTUP_CDMP_FILENAME), debugPath);
|
|
|
|
checkState = (m_recovery.GetBool("OverwriteExistingDebugFile") ? BST_CHECKED : BST_UNCHECKED);
|
|
Button_SetCheck(GetDlgItem(hDlg, IDC_STARTUP_CDMP_OVERWRITE), checkState);
|
|
|
|
checkState = (m_recovery.GetBool("AutoReboot") ? BST_CHECKED : BST_UNCHECKED);
|
|
Button_SetCheck(GetDlgItem(hDlg, IDC_STARTUP_CDMP_AUTOREBOOT), checkState);
|
|
|
|
//
|
|
// Special case disable the overwrite and logfile controls if no debug
|
|
// info option specified.
|
|
//
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_FILENAME),
|
|
dwDebugInfoType != NO_DUMP_OPTION);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_OVERWRITE),
|
|
dwDebugInfoType != NO_DUMP_OPTION);
|
|
|
|
//
|
|
// Test to determine if the user is an admin.
|
|
//
|
|
RemoteRegWriteable(szCrashKey, m_writable);
|
|
|
|
if (!m_writable)
|
|
{
|
|
// Non-admin - disable controls.
|
|
//
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_LOG ), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_SEND ), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_FILENAME), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_OVERWRITE), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_OPTIONS), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_CDMP_AUTOREBOOT), FALSE);
|
|
}
|
|
|
|
|
|
BOOL hasPriv = true, hasMethExecute = false;
|
|
if(m_serviceThread && m_serviceThread->LocalConnection())
|
|
{
|
|
hasPriv = HasPriv(SE_SHUTDOWN_NAME);
|
|
}
|
|
|
|
hasMethExecute = HasPerm(WBEM_METHOD_EXECUTE);
|
|
|
|
//
|
|
// Enable the edit button for local-only.
|
|
// Disable boot options label and edit button on i64.
|
|
//
|
|
#if defined(_IA64_)
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_EDIT_BOOT_INI), FALSE);
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_EDIT_BOOT_INI_LABEL), FALSE);
|
|
#else
|
|
EnableWindow(GetDlgItem (m_hDlg, IDC_EDIT_BOOT_INI_LABEL),
|
|
m_writable ?
|
|
(m_serviceThread && m_serviceThread->LocalConnection()) :
|
|
FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_BOOT_INI),
|
|
m_writable ?
|
|
(m_serviceThread && m_serviceThread->LocalConnection()) :
|
|
FALSE);
|
|
#endif // IA64
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_REBOOT),
|
|
m_writable ? (hasPriv && hasMethExecute) : FALSE);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
DWORD StartupPage::GetDebugInfoType(void)
|
|
{
|
|
// NB: Whistler on, the win32 provider supports new DebugInfoType
|
|
// (none,complete,kernel,small) and MiniDumpDirectory properties.
|
|
// Logic is needed to compensate for downlevel machines.
|
|
//
|
|
// *Important note* The small dump option cannot be supported
|
|
// on Win2K since the provider doesn't.
|
|
//
|
|
DWORD dwDebugInfoType = 0;
|
|
|
|
if (FAILED(m_recovery.Get("DebugInfoType", (long&)dwDebugInfoType)))
|
|
{
|
|
// Downlevel or error case.
|
|
//
|
|
if (!m_bDownlevelTarget)
|
|
{
|
|
// Bail. We've previously established this isn't downlevel
|
|
// but now fail to read the property.
|
|
//
|
|
return NO_DUMP_OPTION;
|
|
}
|
|
|
|
m_bDownlevelTarget = TRUE;
|
|
bool bWriteDebugInfo = FALSE;
|
|
|
|
if (FAILED(m_recovery.Get("WriteDebugInfo", bWriteDebugInfo)))
|
|
{
|
|
// Now we're clueless; default to (none).
|
|
//
|
|
bWriteDebugInfo = FALSE;
|
|
dwDebugInfoType = NO_DUMP_OPTION;
|
|
}
|
|
|
|
if (bWriteDebugInfo)
|
|
{
|
|
bool bKernelDumpOnly;
|
|
|
|
if (FAILED(m_recovery.Get("KernelDumpOnly", bKernelDumpOnly)))
|
|
{
|
|
// If we fail to get KernelDumpOnly we must assume complete,
|
|
// since they've elected to write debugging info.
|
|
//
|
|
bKernelDumpOnly = FALSE;
|
|
}
|
|
|
|
if (bKernelDumpOnly)
|
|
{
|
|
dwDebugInfoType = KERNEL_DUMP_OPTION;
|
|
}
|
|
else
|
|
{
|
|
dwDebugInfoType = COMPLETE_DUMP_OPTION;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_bDownlevelTarget = FALSE;
|
|
}
|
|
|
|
return dwDebugInfoType;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
HRESULT StartupPage::PutDebugInfoType(DWORD dwDebugInfoType)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (m_bDownlevelTarget)
|
|
{
|
|
switch (dwDebugInfoType) // Intentionally verbose - compiler will
|
|
// optimize.
|
|
{
|
|
case NO_DUMP_OPTION:
|
|
hr = m_recovery.Put("WriteDebugInfo", (bool)FALSE);
|
|
break;
|
|
|
|
case COMPLETE_DUMP_OPTION:
|
|
hr = m_recovery.Put("WriteDebugInfo", (bool)TRUE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = m_recovery.Put("KernelDumpOnly", (bool)FALSE);
|
|
}
|
|
break;
|
|
|
|
case KERNEL_DUMP_OPTION:
|
|
hr = m_recovery.Put("WriteDebugInfo", (bool)TRUE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = m_recovery.Put("KernelDumpOnly", (bool)TRUE);
|
|
}
|
|
break;
|
|
|
|
case SMALL_DUMP_OPTION:
|
|
ATLASSERT(!"Downlevel small dump option!");
|
|
hr = E_FAIL;
|
|
break;
|
|
|
|
default:
|
|
ATLASSERT(!"Downlevel unknown dump option!");
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = m_recovery.Put("DebugInfoType", (long)dwDebugInfoType);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
#define MIN_SWAPSIZE 2 // Min swap file size.
|
|
|
|
int StartupPage::CoreDumpHandleOk(HWND hDlg)
|
|
{
|
|
DWORD requiredFileSize = 0;
|
|
int iRet = RET_NO_CHANGE;
|
|
|
|
// Validate core dump filename
|
|
if(!CoreDumpValidFile(hDlg))
|
|
{
|
|
SetFocus(GetDlgItem(hDlg, IDC_STARTUP_CDMP_FILENAME));
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
|
iRet = RET_ERROR;
|
|
return(iRet);
|
|
}
|
|
|
|
// If we are to write the dump file, it must be >= sizeof
|
|
// phyical memory.
|
|
// writing debug info?
|
|
HWND ComboHwnd = GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_OPTIONS);
|
|
|
|
if (ComboBox_GetCurSel(ComboHwnd) != NO_DUMP_OPTION)
|
|
{
|
|
// go figure my pagefile requirements.
|
|
requiredFileSize = ((DWORD)m_memory.GetLong("TotalPhysicalMemory") / 1024) + 1;
|
|
}
|
|
else if(IsDlgButtonChecked(hDlg, IDC_STARTUP_CDMP_LOG) ||
|
|
IsDlgButtonChecked(hDlg, IDC_STARTUP_CDMP_SEND))
|
|
{
|
|
// I'll need this much to write a reminder to myself to send an
|
|
// alert or write to event log once I come back up.
|
|
requiredFileSize = MIN_SWAPSIZE;
|
|
}
|
|
|
|
// size of swapfile on the boot partition.
|
|
TCHAR bootDrv[4] = {0};
|
|
DWORD bootPartitionPageFileSize = GetPageFileSize(bootDrv);
|
|
|
|
// is it too small?
|
|
if(bootPartitionPageFileSize < requiredFileSize)
|
|
{
|
|
DWORD Ret;
|
|
TCHAR szTemp[30] = {0};
|
|
|
|
// Warn that the dump file may be truncated.
|
|
Ret = MsgBoxParam(hDlg, SYSTEM + 29, IDS_TITLE,
|
|
MB_ICONEXCLAMATION | MB_YESNO,
|
|
bootDrv, _itow(requiredFileSize, szTemp, 10));
|
|
|
|
if(Ret == IDNO)
|
|
{
|
|
return RET_ERROR;
|
|
}
|
|
}
|
|
|
|
return(iRet);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
BOOL StartupPage::CoreDumpValidFile(HWND hDlg)
|
|
{
|
|
TCHAR szInputPath[MAX_PATH] = {0};
|
|
TCHAR * pszPath = NULL;
|
|
HWND ComboHwnd;
|
|
|
|
ComboHwnd = GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_OPTIONS);
|
|
|
|
if (ComboBox_GetCurSel(ComboHwnd) != NO_DUMP_OPTION)
|
|
{
|
|
/*
|
|
* get the filename
|
|
*/
|
|
if(GetDlgItemText(hDlg, IDC_STARTUP_CDMP_FILENAME, szInputPath,
|
|
ARRAYSIZE(szInputPath)) == 0)
|
|
{
|
|
//ERR: enter a filename for the dumpfile.
|
|
MsgBoxParam(hDlg, SYSTEM+30, IDS_DISPLAY_NAME, MB_ICONSTOP | MB_OK);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// For local paths only, confirm/validate the path. Remote validation
|
|
// can be done later - too complicated, if not possible in the
|
|
// Whistler timeframe.
|
|
//
|
|
|
|
if (m_serviceThread != NULL && m_serviceThread->LocalConnection())
|
|
{
|
|
/*
|
|
* Expand any environment vars, and then check to make sure it
|
|
* is a fully quallified path
|
|
*/
|
|
// if it has a '%' in it, then try to expand it
|
|
if (_tcschr(szInputPath, _T('%')) != NULL)
|
|
{
|
|
TCHAR szExpandedPath[MAX_PATH] = {0};
|
|
DWORD cExpanded;
|
|
cExpanded = ExpandEnvironmentStrings(szInputPath,
|
|
szExpandedPath,
|
|
sizeof(szExpandedPath) / sizeof(TCHAR));
|
|
|
|
if (cExpanded == 0 || _tcschr(szExpandedPath, _T('%')) != NULL)
|
|
{
|
|
//
|
|
// Environment variable name(s) undefined or an error
|
|
// occurred during replacement.
|
|
//
|
|
MsgBoxParam(hDlg, SYSTEM+40, IDS_DISPLAY_NAME,
|
|
MB_ICONSTOP | MB_OK );
|
|
return FALSE;
|
|
}
|
|
else if (cExpanded > (sizeof(szExpandedPath) / sizeof(TCHAR)))
|
|
{
|
|
TCHAR buf[10];
|
|
MsgBoxParam(hDlg, SYSTEM+33, IDS_DISPLAY_NAME,
|
|
MB_ICONSTOP | MB_OK, _ltow((DWORD)MAX_PATH,
|
|
buf,
|
|
10));
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
pszPath = szExpandedPath;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pszPath = szInputPath;
|
|
}
|
|
|
|
// check to see that it already was cannonicalized
|
|
|
|
TCHAR drv[_MAX_DRIVE] = {0};
|
|
TCHAR path[_MAX_PATH] = {0};
|
|
TCHAR fname[_MAX_FNAME] = {0};
|
|
|
|
// build the instance path.
|
|
_wsplitpath(pszPath, drv, path, fname, NULL);
|
|
|
|
if((_tcslen(drv) == 0) || (_tcslen(path) == 0) ||
|
|
(_tcslen(fname) == 0) )
|
|
{
|
|
// ERR: must be a full path.
|
|
MsgBoxParam(hDlg, SYSTEM+34, IDS_DISPLAY_NAME,
|
|
MB_ICONSTOP | MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* check the drive (don't allow remote)
|
|
*/
|
|
if(!LocalDrive(pszPath))
|
|
{
|
|
// ERR: Local drives only
|
|
MsgBoxParam(hDlg, SYSTEM+31, IDS_DISPLAY_NAME,
|
|
MB_ICONSTOP | MB_OK );
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* if path is non-existent, tell user and let him decide what to
|
|
* do
|
|
*/
|
|
if(!DirExists(pszPath))
|
|
{
|
|
if(MsgBoxParam(hDlg, SYSTEM+32, IDS_DISPLAY_NAME,
|
|
MB_ICONQUESTION | MB_YESNO ) == IDNO)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
DWORD StartupPage::GetPageFileSize(LPTSTR bootDrv)
|
|
{
|
|
IWbemClassObject *pInst = NULL;
|
|
CWbemClassObject OS;
|
|
bstr_t path;
|
|
DWORD cMegBootPF = 0;
|
|
TCHAR szBootPath[_MAX_PATH] = {0};
|
|
szBootPath[0] = 0;
|
|
|
|
if(m_OS)
|
|
{
|
|
// WATCH: what's the value if GetWindowsDirectory fails?
|
|
path = m_OS.GetString("WindowsDirectory");
|
|
if(path.length())
|
|
{
|
|
// build the instance path.
|
|
_tcscpy(szBootPath, _T("Win32_PageFileSetting=\""));
|
|
_tcsncat(szBootPath, path, 3);
|
|
_tcscat(szBootPath, _T("\\pagefile.sys\""));
|
|
|
|
// while we're here....
|
|
_tcsncpy(bootDrv, path, 3);
|
|
|
|
m_page = m_WbemServices.GetObject(szBootPath);
|
|
|
|
if(m_page)
|
|
{
|
|
// NOTE: We'll need this later to change the swapfile size.
|
|
/* long dwTotalPhys = m_page.GetLong("Size");
|
|
cMegBootPF = (dwTotalPhys / ONE_MEG) + 1;*/
|
|
long dwMinPageFileSize = m_page.GetLong("InitialSize");
|
|
cMegBootPF = dwMinPageFileSize;
|
|
}
|
|
}
|
|
}
|
|
return cMegBootPF;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
BOOL StartupPage::ExpandRemoteEnvPath(LPTSTR szPath, LPTSTR expPath, UINT size)
|
|
{
|
|
//TODO: really expand the vars.
|
|
_tcscpy(szPath, expPath);
|
|
return TRUE;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
BOOL StartupPage::LocalDrive(LPCTSTR szPath)
|
|
{
|
|
CWbemClassObject drive;
|
|
TCHAR ltr[_MAX_PATH] = {0};
|
|
long type = 0;
|
|
BOOL retval = FALSE;
|
|
__int64 free = 0;
|
|
|
|
// build the instance path.
|
|
_tcscpy(ltr, _T("win32_LogicalDisk=\""));
|
|
_tcsncat(ltr, szPath, 2);
|
|
_tcscat(ltr, _T("\""));
|
|
|
|
// save the drive letter for msgs.
|
|
_tcsncpy(m_DriveLtr, szPath, 2);
|
|
|
|
drive = m_WbemServices.GetObject(ltr);
|
|
if(drive)
|
|
{
|
|
type = drive.GetLong("DriveType");
|
|
retval = ((type == DRIVE_REMOVABLE) ||
|
|
(type == DRIVE_FIXED));
|
|
|
|
// WARNING: this is only here cuz the LocalDrive check happens
|
|
// to come before the freespace check and I didn't want to do
|
|
// another GetObject() over a potentially slow network.
|
|
free = drive.GetI64("FreeSpace");
|
|
m_freeSpace = (DWORD)(free / ONE_MEG);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
BOOL StartupPage::DirExists(LPCTSTR szPath)
|
|
{
|
|
BOOL exists = TRUE;
|
|
CWbemClassObject drive;
|
|
|
|
TCHAR objPath[_MAX_PATH] = {0}, drv[_MAX_DRIVE] = {0}, path[_MAX_PATH] = {0};
|
|
|
|
// build the instance path.
|
|
_wsplitpath(szPath, drv, path, NULL, NULL);
|
|
path[_tcslen(path) - 1] = _T('\0');
|
|
|
|
_tcscpy(objPath, _T("Win32_Directory=\""));
|
|
_tcscat(objPath, drv);
|
|
|
|
// double the whacks cuz wmi has bad syntax.
|
|
TCHAR cooked[_MAX_PATH] = {0};
|
|
TCHAR input[_MAX_PATH] = {0};
|
|
|
|
int len = _tcslen(path);
|
|
|
|
_tcscpy(input, path);
|
|
|
|
for(int x = 0; x < len; x++)
|
|
{
|
|
_tcsncat(cooked, &input[x], 1);
|
|
|
|
// if its a whack...
|
|
if(input[x] == _T('\\'))
|
|
{
|
|
// have another pleeb.
|
|
_tcscat(cooked, _T("\\"));
|
|
}
|
|
} //endfor
|
|
|
|
_tcscat(objPath, cooked);
|
|
|
|
_tcscat(objPath, _T("\""));
|
|
|
|
drive = m_WbemServices.GetObject(objPath);
|
|
exists = (drive.IsNull() ? FALSE : TRUE);
|
|
return exists;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
BOOL StartupPage::IsAlerterSvcStarted(HWND hDlg)
|
|
{
|
|
CWbemClassObject service;
|
|
bool started = false;
|
|
|
|
service = m_WbemServices.GetObject(_T("win32_Service=\"Alerter\""));
|
|
if(service)
|
|
{
|
|
started = service.GetBool("started");
|
|
|
|
if(!started)
|
|
{
|
|
// get the method signature. dummy wont actually be used.
|
|
CWbemClassObject paramCls, inSig, dummy, outSig;
|
|
|
|
// need to class def to get the method signature.
|
|
paramCls = m_WbemServices.GetObject("win32_Service");
|
|
|
|
if(paramCls)
|
|
{
|
|
HRESULT hr = paramCls.GetMethod(L"ChangeStartMode", inSig, outSig);
|
|
|
|
// if got a good signature....
|
|
if((bool)inSig)
|
|
{
|
|
bstr_t path = service.GetString(_T("__PATH"));
|
|
|
|
inSig.Put(L"StartMode", (const _bstr_t&) L"Automatic");
|
|
|
|
// make sure the service starts on bootup.
|
|
hr = m_WbemServices.ExecMethod(path, L"ChangeStartMode",
|
|
inSig, outSig);
|
|
|
|
// did it work?
|
|
if(SUCCEEDED(hr) && (bool)outSig)
|
|
{
|
|
// NOTE: this guy return STATUS codes.
|
|
DWORD autoStart = outSig.GetLong(L"ReturnValue");
|
|
|
|
if(autoStart == 0)
|
|
{
|
|
// now actually start the service.
|
|
outSig = (IWbemClassObject *)0;
|
|
|
|
// now call the method.
|
|
hr = m_WbemServices.ExecMethod(path, L"StartService",
|
|
dummy, outSig);
|
|
|
|
// did the caller want the ReturnValue.
|
|
if(SUCCEEDED(hr) && (bool)outSig)
|
|
{
|
|
// NOTE: this guy return STATUS codes.
|
|
DWORD rv = outSig.GetLong(L"ReturnValue");
|
|
started = ((rv == 0) ? true : false);
|
|
}
|
|
|
|
} //endif autoStart
|
|
|
|
} //endif SUCCEEDED() execmMethod
|
|
|
|
} //endif (bool)inSig
|
|
|
|
} //endif paramCls
|
|
|
|
} //endif !started
|
|
|
|
if(!started)
|
|
{
|
|
MsgBoxParam(hDlg, SYSTEM+35, IDS_DISPLAY_NAME, MB_ICONEXCLAMATION );
|
|
}
|
|
}
|
|
|
|
return started;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
bool StartupPage::Save(void)
|
|
{
|
|
HRESULT hr;
|
|
HWND ComboHwnd;
|
|
|
|
// if its writeable-- do the work.
|
|
if(m_writable)
|
|
{
|
|
bool computerDirty = false, recoveryDirty = false;
|
|
variant_t array;
|
|
SAFEARRAY *startupArray = NULL;
|
|
VARTYPE varType = VT_ARRAY;
|
|
ComboHwnd = GetDlgItem(m_hDlg, IDC_STARTUP_SYS_OS);
|
|
|
|
// see if the selection changed (watch out for 'lBound' values)
|
|
long oldIdx = m_computer.GetLong("SystemStartupSetting");
|
|
long newIdx = ComboBox_GetCurSel(ComboHwnd) + m_lBound;
|
|
if(oldIdx != newIdx)
|
|
{
|
|
hr = m_computer.Put("SystemStartupSetting", variant_t((BYTE)newIdx));
|
|
computerDirty = true;
|
|
}
|
|
|
|
// see if the delay changed.
|
|
WCHAR oldBuf[30], newBuf[30];
|
|
short delay = (short)m_computer.GetLong("SystemStartupDelay");
|
|
_ltow(delay, oldBuf, 10);
|
|
Edit_GetText(GetDlgItem(m_hDlg, IDC_STARTUP_SYS_SECONDS), newBuf, 30);
|
|
if(wcscmp(oldBuf, newBuf) != 0)
|
|
{
|
|
short newVal = (short)_wtol(newBuf);
|
|
hr = m_computer.Put("SystemStartupDelay", variant_t(newVal));
|
|
computerDirty = true;
|
|
}
|
|
|
|
// evaluate all the recovery controls.
|
|
WPARAM oldCheckState = (m_recovery.GetBool("WriteToSystemLog") ? BST_CHECKED : BST_UNCHECKED);
|
|
WPARAM newCheckState = Button_GetCheck(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_LOG));
|
|
if(oldCheckState != newCheckState)
|
|
{
|
|
m_recovery.Put("WriteToSystemLog", (newCheckState == BST_CHECKED? true : false));
|
|
recoveryDirty = true;
|
|
}
|
|
|
|
oldCheckState = (m_recovery.GetBool("SendAdminAlert") ? BST_CHECKED : BST_UNCHECKED);
|
|
newCheckState = Button_GetCheck(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_SEND));
|
|
// did the state change?
|
|
if(oldCheckState != newCheckState)
|
|
{
|
|
m_recovery.Put("SendAdminAlert", (newCheckState == BST_CHECKED? true : false));
|
|
recoveryDirty = true;
|
|
|
|
// turning ON
|
|
if(newCheckState == TRUE)
|
|
{
|
|
// NOTE: had to move this fragment up to avoid being trapped under the wcsicmp() condition.
|
|
// If the Alert button is checked, make sure the alerter service is started.
|
|
IsAlerterSvcStarted(m_hDlg);
|
|
}
|
|
}
|
|
|
|
ComboHwnd = GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_OPTIONS);
|
|
DWORD dwOldDebugInfoType = GetDebugInfoType();
|
|
DWORD dwNewDebugInfoType = ComboBox_GetCurSel(ComboHwnd);
|
|
|
|
if (dwOldDebugInfoType != dwNewDebugInfoType)
|
|
{
|
|
// I detest this code. You add a member with a return code yet
|
|
// nothing here checks them. At least keep the recover dirty
|
|
// flag from being set and don't set the modify bit on the
|
|
// filename edit control if the put fails.
|
|
//
|
|
hr = PutDebugInfoType(dwNewDebugInfoType);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
recoveryDirty = true;
|
|
Edit_SetModify(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_FILENAME),
|
|
TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Only bother with these if other than "none" debug options is
|
|
// specified.
|
|
//
|
|
if (dwNewDebugInfoType != NO_DUMP_OPTION)
|
|
{
|
|
oldCheckState = (m_recovery.GetBool("OverwriteExistingDebugFile") ? BST_CHECKED : BST_UNCHECKED);
|
|
newCheckState = Button_GetCheck(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_OVERWRITE));
|
|
if(oldCheckState != newCheckState)
|
|
{
|
|
m_recovery.Put("OverwriteExistingDebugFile", (newCheckState == BST_CHECKED? true : false));
|
|
recoveryDirty = true;
|
|
}
|
|
|
|
bstr_t oldDebugPath = m_recovery.GetString(
|
|
(dwOldDebugInfoType == SMALL_DUMP_OPTION) ?
|
|
"MiniDumpDirectory" : "DebugFilePath");
|
|
TCHAR newDebugPath[MAX_PATH];
|
|
Edit_GetText(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_FILENAME),
|
|
newDebugPath, sizeof(newDebugPath) / sizeof(TCHAR));
|
|
|
|
if(_tcsicmp(oldDebugPath,newDebugPath) != 0)
|
|
{
|
|
if(RET_ERROR != CoreDumpHandleOk(m_hDlg))
|
|
{
|
|
m_recovery.Put(
|
|
(dwNewDebugInfoType == SMALL_DUMP_OPTION) ?
|
|
"MiniDumpDirectory" : "DebugFilePath",
|
|
(bstr_t)newDebugPath);
|
|
recoveryDirty = true;
|
|
}
|
|
else
|
|
{
|
|
long wl = GetWindowLongPtr(m_hDlg, DWLP_MSGRESULT);
|
|
if(wl == PSNRET_INVALID_NOCHANGEPAGE)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
} //endif 'WriteDebugInfo'
|
|
|
|
oldCheckState = (m_recovery.GetBool("AutoReboot") ? BST_CHECKED : BST_UNCHECKED);
|
|
newCheckState = Button_GetCheck(GetDlgItem(m_hDlg, IDC_STARTUP_CDMP_AUTOREBOOT));
|
|
if(oldCheckState != newCheckState)
|
|
{
|
|
m_recovery.Put("AutoReboot", (newCheckState == BST_CHECKED? true : false));
|
|
recoveryDirty = true;
|
|
}
|
|
|
|
m_WbemServices.SetPriv();
|
|
|
|
// who needs to be written?
|
|
if(computerDirty)
|
|
{
|
|
hr = m_WbemServices.PutInstance(m_computer);
|
|
}
|
|
|
|
if(recoveryDirty)
|
|
{
|
|
//
|
|
// Apparently recovery options don't require reboot in Whistler...
|
|
//
|
|
/*
|
|
g_fRebootRequired = TRUE;
|
|
|
|
MsgBoxParam(m_hDlg, SYSTEM + 39, IDS_TITLE,
|
|
MB_OK | MB_ICONINFORMATION);
|
|
*/
|
|
|
|
hr = m_WbemServices.PutInstance(m_recovery);
|
|
}
|
|
|
|
m_WbemServices.ClearPriv();
|
|
|
|
} //endif m_writable
|
|
|
|
return true; // close the dialog.
|
|
}
|