|
|
// PageBootIni.h : Declaration of the CPageBootIni
#ifndef __PAGEBOOTINI_H_
#define __PAGEBOOTINI_H_
#include "resource.h" // main symbols
#include <atlhost.h>
#include "msconfigstate.h"
/////////////////////////////////////////////////////////////////////////////
// CPageBootIni
class CPageBootIni : public CAxDialogImpl<CPageBootIni> { public: CPageBootIni() : m_fIgnoreEdit(FALSE) { }
~CPageBootIni() { }
enum { IDD = IDD_PAGEBOOTINI };
BEGIN_MSG_MAP(CPageBootIni) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) COMMAND_HANDLER(IDC_BOOTMOVEDOWN, BN_CLICKED, OnClickedMoveDown) COMMAND_HANDLER(IDC_BOOTMOVEUP, BN_CLICKED, OnClickedMoveUp) COMMAND_HANDLER(IDC_LISTBOOTINI, LBN_SELCHANGE, OnSelChangeList) COMMAND_HANDLER(IDC_BASEVIDEO, BN_CLICKED, OnClickedBaseVideo) COMMAND_HANDLER(IDC_BOOTLOG, BN_CLICKED, OnClickedBootLog) COMMAND_HANDLER(IDC_NOGUIBOOT, BN_CLICKED, OnClickedNoGUIBoot) COMMAND_HANDLER(IDC_SAFEBOOT, BN_CLICKED, OnClickedSafeBoot) COMMAND_HANDLER(IDC_SOS, BN_CLICKED, OnClickedSOS) COMMAND_HANDLER(IDC_SBDSREPAIR, BN_CLICKED, OnClickedSBDSRepair) COMMAND_HANDLER(IDC_SBMINIMAL, BN_CLICKED, OnClickedSBMinimal) COMMAND_HANDLER(IDC_SBMINIMALALT, BN_CLICKED, OnClickedSBMinimalAlt) COMMAND_HANDLER(IDC_SBNETWORK, BN_CLICKED, OnClickedSBNetwork) COMMAND_HANDLER(IDC_SBNORMAL, BN_CLICKED, OnClickedSBNormal) COMMAND_HANDLER(IDC_EDITTIMEOUT, EN_CHANGE, OnChangeEditTimeOut) END_MSG_MAP() // Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
//-------------------------------------------------------------------------
// Initialize the boot.ini page. Read in the INI file, set up internal
// structures to represent the file, and update the controls to reflect
// the internal structures.
//-------------------------------------------------------------------------
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { ::EnableWindow(GetDlgItem(IDC_CHECKBOOTPATHS), FALSE); ::EnableWindow(GetDlgItem(IDC_BOOTADVANCED), FALSE); ::EnableWindow(GetDlgItem(IDC_SETASDEFAULT), FALSE);
if (LoadBootIni()) { SyncControlsToIni(); if (m_nMinOSIndex != -1) { ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, m_nMinOSIndex, 0); SelectLine(m_nMinOSIndex); } }
return 1; // Let the system set the focus
}
//-------------------------------------------------------------------------
// Load the contents of the BOOT.INI file into our local structures.
//
// TBD - boot.ini always on the C:\ drive?
// TBD - unicode issues?
//-------------------------------------------------------------------------
BOOL LoadBootIni() { // Read the contents of the boot.ini file into a string.
HANDLE h = ::CreateFile(_T("c:\\boot.ini"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == h) return FALSE;
CString strContents; DWORD dwNumberBytesRead, dwNumberBytesToRead = ::GetFileSize(h, NULL); if (!::ReadFile(h, (LPVOID)strContents.GetBuffer(dwNumberBytesToRead/sizeof(TCHAR)), dwNumberBytesToRead, &dwNumberBytesRead, NULL)) strContents.Empty(); strContents.ReleaseBuffer();
::CloseHandle(h);
if (dwNumberBytesToRead != dwNumberBytesRead || strContents.IsEmpty()) return FALSE;
// Parse the contents of the string into an array of strings (one for each line
// of the file).
m_arrayIniLines.RemoveAll(); m_arrayIniLines.SetSize(10, 10);
CString strLine; int nIndex = 0;
while (!strContents.IsEmpty()) { strLine = strContents.SpanExcluding(_T("\r\n")); if (!strLine.IsEmpty()) { m_arrayIniLines.SetAtGrow(nIndex, strLine); nIndex += 1; } strContents = strContents.Mid(strLine.GetLength()); strContents.TrimLeft(_T("\r\n")); }
// Look through the lines read from the INI file, searching for particular
// ones we'll want to make a note of.
m_nTimeoutIndex = m_nDefaultIndex = m_nMinOSIndex = m_nMaxOSIndex = -1; for (int i = 0; i < m_arrayIniLines.GetUpperBound(); i++) { CString strScanLine = m_arrayIniLines[i]; strScanLine.MakeLower();
if (strScanLine.Find(_T("timeout=")) != -1) m_nTimeoutIndex = i; else if (strScanLine.Find(_T("default=")) != -1) m_nDefaultIndex = i;
if (m_nMinOSIndex != -1 && m_nMaxOSIndex == -1 && (strScanLine.IsEmpty() || strScanLine[0] == _T('['))) m_nMaxOSIndex = i - 1; else if (strScanLine.Find(_T("[operating systems]")) != -1) m_nMinOSIndex = i + 1; } if (m_nMinOSIndex != -1 && m_nMaxOSIndex == -1) m_nMaxOSIndex = i - 1;
return TRUE; }
//----------------------------------------------------------------------------
// Update the state of the controls on this tab to match the contents of the
// internal representation of the INI file.
//----------------------------------------------------------------------------
void SyncControlsToIni(BOOL fSyncEditField = TRUE) { // First, add the lines from the boot ini into the list control.
::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_RESETCONTENT, 0, 0); for (int i = 0; i < m_arrayIniLines.GetUpperBound(); i++) if (!m_arrayIniLines[i].IsEmpty()) ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)m_arrayIniLines[i]);
// Set the timeout value based on the boot.ini.
if (m_nTimeoutIndex != -1 && fSyncEditField) { CString strTimeout = m_arrayIniLines[m_nTimeoutIndex]; strTimeout.TrimLeft(_T("timeout=")); m_fIgnoreEdit = TRUE; SetDlgItemText(IDC_EDITTIMEOUT, strTimeout); m_fIgnoreEdit = FALSE; } }
//----------------------------------------------------------------------------
// Update the controls based on the user's selection of a line.
//----------------------------------------------------------------------------
void SelectLine(int index) { if (index < m_nMinOSIndex) { ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, m_nMinOSIndex, 0); SelectLine(m_nMinOSIndex); return; }
if (index > m_nMaxOSIndex) { ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, m_nMaxOSIndex, 0); SelectLine(m_nMaxOSIndex); return; }
::EnableWindow(GetDlgItem(IDC_BOOTMOVEUP), (index > m_nMinOSIndex)); ::EnableWindow(GetDlgItem(IDC_BOOTMOVEDOWN), (index < m_nMaxOSIndex));
CString strOS = m_arrayIniLines[index]; strOS.MakeLower();
CheckDlgButton(IDC_SAFEBOOT, (strOS.Find(_T("/safeboot")) != -1)); CheckDlgButton(IDC_NOGUIBOOT, (strOS.Find(_T("/noguiboot")) != -1)); CheckDlgButton(IDC_BOOTLOG, (strOS.Find(_T("/bootlog")) != -1)); CheckDlgButton(IDC_BASEVIDEO, (strOS.Find(_T("/basevideo")) != -1)); CheckDlgButton(IDC_SOS, (strOS.Find(_T("/sos")) != -1));
BOOL fSafeboot = (strOS.Find(_T("/safeboot")) != -1); ::EnableWindow(GetDlgItem(IDC_SBNETWORK), fSafeboot); ::EnableWindow(GetDlgItem(IDC_SBDSREPAIR), fSafeboot); ::EnableWindow(GetDlgItem(IDC_SBMINIMAL), fSafeboot); ::EnableWindow(GetDlgItem(IDC_SBMINIMALALT), fSafeboot); ::EnableWindow(GetDlgItem(IDC_SBNORMAL), fSafeboot); if (fSafeboot) { CheckDlgButton(IDC_SBNETWORK, (strOS.Find(_T("/safeboot:network")) != -1)); CheckDlgButton(IDC_SBDSREPAIR, (strOS.Find(_T("/safeboot:dsrepair")) != -1)); CheckDlgButton(IDC_SBMINIMAL, (strOS.Find(_T("/safeboot:minimal ")) != -1)); CheckDlgButton(IDC_SBMINIMALALT, (strOS.Find(_T("/safeboot:minimal(alternateshell)")) != -1)); CheckDlgButton(IDC_SBNORMAL, (strOS.Find(_T("/safeboot ")) != -1)); } }
//-------------------------------------------------------------------------
// Called when the user clicks move up or down.
//-------------------------------------------------------------------------
LRESULT OnClickedMoveDown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0); ASSERT(iSelection >= m_nMinOSIndex && iSelection < m_nMaxOSIndex); if (iSelection >= m_nMinOSIndex && iSelection < m_nMaxOSIndex) { CString strTemp = m_arrayIniLines[iSelection + 1]; m_arrayIniLines.SetAt(iSelection + 1, m_arrayIniLines[iSelection]); m_arrayIniLines.SetAt(iSelection, strTemp); SyncControlsToIni(); ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection + 1, 0); SelectLine(iSelection + 1); } return 0; }
LRESULT OnClickedMoveUp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0); ASSERT(iSelection > m_nMinOSIndex && iSelection <= m_nMaxOSIndex); if (iSelection > m_nMinOSIndex && iSelection <= m_nMaxOSIndex) { CString strTemp = m_arrayIniLines[iSelection - 1]; m_arrayIniLines.SetAt(iSelection - 1, m_arrayIniLines[iSelection]); m_arrayIniLines.SetAt(iSelection, strTemp); SyncControlsToIni(); ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection - 1, 0); SelectLine(iSelection - 1); } return 0; }
//-------------------------------------------------------------------------
// Called when the user clicks on a line in the list view.
//-------------------------------------------------------------------------
LRESULT OnSelChangeList(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { SelectLine((int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0)); return 0; }
//-------------------------------------------------------------------------
// The check boxes are handled uniformly - adding or removing a flag from
// the currently selected OS line.
//-------------------------------------------------------------------------
LRESULT OnClickedBaseVideo(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_BASEVIDEO), _T("/basevideo")); return 0; }
LRESULT OnClickedBootLog(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_BOOTLOG), _T("/bootlog")); return 0; } LRESULT OnClickedNoGUIBoot(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_NOGUIBOOT), _T("/noguiboot")); return 0; } LRESULT OnClickedSOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_SOS), _T("/sos")); return 0; }
//-------------------------------------------------------------------------
// The safeboot flag is a little more complicated, since it has an extra
// portion (from the radio buttons).
//-------------------------------------------------------------------------
LRESULT OnClickedSafeBoot(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { CString strFlag(_T("/safeboot"));
if (IsDlgButtonChecked(IDC_SBNETWORK)) strFlag += _T(":network"); else if (IsDlgButtonChecked(IDC_SBDSREPAIR)) strFlag += _T(":dsrepair"); else if (IsDlgButtonChecked(IDC_SBMINIMAL)) strFlag += _T(":minimal"); else if (IsDlgButtonChecked(IDC_SBMINIMALALT)) strFlag += _T(":minimal(alternateshell)"); else CheckDlgButton(IDC_SBNORMAL, 1);
BOOL fSafeBoot = IsDlgButtonChecked(IDC_SAFEBOOT); ChangeCurrentOSFlag(fSafeBoot, strFlag); m_strSafeBoot = strFlag; ::EnableWindow(GetDlgItem(IDC_SBNETWORK), fSafeBoot); ::EnableWindow(GetDlgItem(IDC_SBDSREPAIR), fSafeBoot); ::EnableWindow(GetDlgItem(IDC_SBMINIMAL), fSafeBoot); ::EnableWindow(GetDlgItem(IDC_SBMINIMALALT), fSafeBoot); ::EnableWindow(GetDlgItem(IDC_SBNORMAL), fSafeBoot); return 0; }
//-------------------------------------------------------------------------
// Add or remove the specified flag from the currently selected OS line.
//-------------------------------------------------------------------------
void ChangeCurrentOSFlag(BOOL fAdd, LPCTSTR szFlag) { int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0); CString strFlagPlusSpace = CString(_T(" ")) + szFlag; CString strNewLine;
if (fAdd) { if (m_arrayIniLines[iSelection].Find(szFlag) != -1) { ASSERT(0 && "the flag is already there"); return; } strNewLine = m_arrayIniLines[iSelection] + strFlagPlusSpace; } else { int iIndex = m_arrayIniLines[iSelection].Find(strFlagPlusSpace); if (iIndex == -1) { ASSERT(0 && "there is no flag"); return; } strNewLine = m_arrayIniLines[iSelection].Left(iIndex); strNewLine += m_arrayIniLines[iSelection].Mid(iIndex + strFlagPlusSpace.GetLength()); }
m_arrayIniLines.SetAt(iSelection, strNewLine); SyncControlsToIni(); ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection, 0); }
//-------------------------------------------------------------------------
// Clicking on one of the safeboot radio buttons requires a little extra
// processing, to remove the existing flag and add the new one.
//
// TBD - make so they don't do a double update of the field
//-------------------------------------------------------------------------
LRESULT OnClickedSBDSRepair(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(FALSE, m_strSafeBoot); m_strSafeBoot = _T("/safeboot:dsrepair"); ChangeCurrentOSFlag(TRUE, m_strSafeBoot); return 0; }
LRESULT OnClickedSBMinimal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(FALSE, m_strSafeBoot); m_strSafeBoot = _T("/safeboot:minimal"); ChangeCurrentOSFlag(TRUE, m_strSafeBoot); return 0; }
LRESULT OnClickedSBMinimalAlt(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(FALSE, m_strSafeBoot); m_strSafeBoot = _T("/safeboot:minimal(alternateshell)"); ChangeCurrentOSFlag(TRUE, m_strSafeBoot); return 0; }
LRESULT OnClickedSBNetwork(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(FALSE, m_strSafeBoot); m_strSafeBoot = _T("/safeboot:network"); ChangeCurrentOSFlag(TRUE, m_strSafeBoot); return 0; }
LRESULT OnClickedSBNormal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChangeCurrentOSFlag(FALSE, m_strSafeBoot); m_strSafeBoot = _T("/safeboot"); ChangeCurrentOSFlag(TRUE, m_strSafeBoot); return 0; }
//-------------------------------------------------------------------------
// As the user enters text in the timeout field, update the line in the
// ini file list box.
//
// TBD - do more sanity checking on this value
//-------------------------------------------------------------------------
LRESULT OnChangeEditTimeOut(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { if (m_fIgnoreEdit) return 0;
if (m_nTimeoutIndex == -1) return 0; // TBD - make this actually add the line
CString strTimeout = m_arrayIniLines[m_nTimeoutIndex]; int iEquals = strTimeout.Find(_T('=')); if (iEquals == -1) return 0;
TCHAR szValue[MAX_PATH]; GetDlgItemText(IDC_EDITTIMEOUT, szValue, MAX_PATH); CString strNewTimeout = strTimeout.Left(iEquals + 1) + szValue; m_arrayIniLines.SetAt(m_nTimeoutIndex, strNewTimeout); int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0); SyncControlsToIni(FALSE); ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection, 0); return 0; }
private: CStringArray m_arrayIniLines; // array of lines in the ini file
int m_nTimeoutIndex; // list index of the "timeout=" line
int m_nDefaultIndex; // list index of the "default=" line
int m_nMinOSIndex; // first list index of an OS line
int m_nMaxOSIndex; // last list index of an OS line
CString m_strSafeBoot; // the current string for the safeboot flag
BOOL m_fIgnoreEdit; // used to avoid a recursion problem
private: CString m_strCaption; // contains the localized name of this page
public: //-------------------------------------------------------------------------
// Functions used by the parent dialog.
//-------------------------------------------------------------------------
BOOL IsValid(CMSConfigState * state) { return TRUE; }
LPCTSTR GetCaption() { if (m_strCaption.IsEmpty()) { ::AfxSetResourceHandle(_Module.GetResourceInstance()); m_strCaption.LoadString(IDS_BOOTINI_CAPTION); } return m_strCaption; } };
#endif //__PAGEBOOTINI_H_
|