Source code of Windows XP (NT5)
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.

477 lines
16 KiB

  1. // PageBootIni.h : Declaration of the CPageBootIni
  2. #ifndef __PAGEBOOTINI_H_
  3. #define __PAGEBOOTINI_H_
  4. #include "resource.h" // main symbols
  5. #include <atlhost.h>
  6. #include "msconfigstate.h"
  7. /////////////////////////////////////////////////////////////////////////////
  8. // CPageBootIni
  9. class CPageBootIni : public CAxDialogImpl<CPageBootIni>
  10. {
  11. public:
  12. CPageBootIni() : m_fIgnoreEdit(FALSE)
  13. {
  14. }
  15. ~CPageBootIni()
  16. {
  17. }
  18. enum { IDD = IDD_PAGEBOOTINI };
  19. BEGIN_MSG_MAP(CPageBootIni)
  20. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  21. COMMAND_HANDLER(IDC_BOOTMOVEDOWN, BN_CLICKED, OnClickedMoveDown)
  22. COMMAND_HANDLER(IDC_BOOTMOVEUP, BN_CLICKED, OnClickedMoveUp)
  23. COMMAND_HANDLER(IDC_LISTBOOTINI, LBN_SELCHANGE, OnSelChangeList)
  24. COMMAND_HANDLER(IDC_BASEVIDEO, BN_CLICKED, OnClickedBaseVideo)
  25. COMMAND_HANDLER(IDC_BOOTLOG, BN_CLICKED, OnClickedBootLog)
  26. COMMAND_HANDLER(IDC_NOGUIBOOT, BN_CLICKED, OnClickedNoGUIBoot)
  27. COMMAND_HANDLER(IDC_SAFEBOOT, BN_CLICKED, OnClickedSafeBoot)
  28. COMMAND_HANDLER(IDC_SOS, BN_CLICKED, OnClickedSOS)
  29. COMMAND_HANDLER(IDC_SBDSREPAIR, BN_CLICKED, OnClickedSBDSRepair)
  30. COMMAND_HANDLER(IDC_SBMINIMAL, BN_CLICKED, OnClickedSBMinimal)
  31. COMMAND_HANDLER(IDC_SBMINIMALALT, BN_CLICKED, OnClickedSBMinimalAlt)
  32. COMMAND_HANDLER(IDC_SBNETWORK, BN_CLICKED, OnClickedSBNetwork)
  33. COMMAND_HANDLER(IDC_SBNORMAL, BN_CLICKED, OnClickedSBNormal)
  34. COMMAND_HANDLER(IDC_EDITTIMEOUT, EN_CHANGE, OnChangeEditTimeOut)
  35. END_MSG_MAP()
  36. // Handler prototypes:
  37. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  38. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  39. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  40. //-------------------------------------------------------------------------
  41. // Initialize the boot.ini page. Read in the INI file, set up internal
  42. // structures to represent the file, and update the controls to reflect
  43. // the internal structures.
  44. //-------------------------------------------------------------------------
  45. LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  46. {
  47. ::EnableWindow(GetDlgItem(IDC_CHECKBOOTPATHS), FALSE);
  48. ::EnableWindow(GetDlgItem(IDC_BOOTADVANCED), FALSE);
  49. ::EnableWindow(GetDlgItem(IDC_SETASDEFAULT), FALSE);
  50. if (LoadBootIni())
  51. {
  52. SyncControlsToIni();
  53. if (m_nMinOSIndex != -1)
  54. {
  55. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, m_nMinOSIndex, 0);
  56. SelectLine(m_nMinOSIndex);
  57. }
  58. }
  59. return 1; // Let the system set the focus
  60. }
  61. //-------------------------------------------------------------------------
  62. // Load the contents of the BOOT.INI file into our local structures.
  63. //
  64. // TBD - boot.ini always on the C:\ drive?
  65. // TBD - unicode issues?
  66. //-------------------------------------------------------------------------
  67. BOOL LoadBootIni()
  68. {
  69. // Read the contents of the boot.ini file into a string.
  70. HANDLE h = ::CreateFile(_T("c:\\boot.ini"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  71. if (INVALID_HANDLE_VALUE == h)
  72. return FALSE;
  73. CString strContents;
  74. DWORD dwNumberBytesRead, dwNumberBytesToRead = ::GetFileSize(h, NULL);
  75. if (!::ReadFile(h, (LPVOID)strContents.GetBuffer(dwNumberBytesToRead/sizeof(TCHAR)), dwNumberBytesToRead, &dwNumberBytesRead, NULL))
  76. strContents.Empty();
  77. strContents.ReleaseBuffer();
  78. ::CloseHandle(h);
  79. if (dwNumberBytesToRead != dwNumberBytesRead || strContents.IsEmpty())
  80. return FALSE;
  81. // Parse the contents of the string into an array of strings (one for each line
  82. // of the file).
  83. m_arrayIniLines.RemoveAll();
  84. m_arrayIniLines.SetSize(10, 10);
  85. CString strLine;
  86. int nIndex = 0;
  87. while (!strContents.IsEmpty())
  88. {
  89. strLine = strContents.SpanExcluding(_T("\r\n"));
  90. if (!strLine.IsEmpty())
  91. {
  92. m_arrayIniLines.SetAtGrow(nIndex, strLine);
  93. nIndex += 1;
  94. }
  95. strContents = strContents.Mid(strLine.GetLength());
  96. strContents.TrimLeft(_T("\r\n"));
  97. }
  98. // Look through the lines read from the INI file, searching for particular
  99. // ones we'll want to make a note of.
  100. m_nTimeoutIndex = m_nDefaultIndex = m_nMinOSIndex = m_nMaxOSIndex = -1;
  101. for (int i = 0; i < m_arrayIniLines.GetUpperBound(); i++)
  102. {
  103. CString strScanLine = m_arrayIniLines[i];
  104. strScanLine.MakeLower();
  105. if (strScanLine.Find(_T("timeout=")) != -1)
  106. m_nTimeoutIndex = i;
  107. else if (strScanLine.Find(_T("default=")) != -1)
  108. m_nDefaultIndex = i;
  109. if (m_nMinOSIndex != -1 && m_nMaxOSIndex == -1 && (strScanLine.IsEmpty() || strScanLine[0] == _T('[')))
  110. m_nMaxOSIndex = i - 1;
  111. else if (strScanLine.Find(_T("[operating systems]")) != -1)
  112. m_nMinOSIndex = i + 1;
  113. }
  114. if (m_nMinOSIndex != -1 && m_nMaxOSIndex == -1)
  115. m_nMaxOSIndex = i - 1;
  116. return TRUE;
  117. }
  118. //----------------------------------------------------------------------------
  119. // Update the state of the controls on this tab to match the contents of the
  120. // internal representation of the INI file.
  121. //----------------------------------------------------------------------------
  122. void SyncControlsToIni(BOOL fSyncEditField = TRUE)
  123. {
  124. // First, add the lines from the boot ini into the list control.
  125. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_RESETCONTENT, 0, 0);
  126. for (int i = 0; i < m_arrayIniLines.GetUpperBound(); i++)
  127. if (!m_arrayIniLines[i].IsEmpty())
  128. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_ADDSTRING, 0, (LPARAM)(LPCTSTR)m_arrayIniLines[i]);
  129. // Set the timeout value based on the boot.ini.
  130. if (m_nTimeoutIndex != -1 && fSyncEditField)
  131. {
  132. CString strTimeout = m_arrayIniLines[m_nTimeoutIndex];
  133. strTimeout.TrimLeft(_T("timeout="));
  134. m_fIgnoreEdit = TRUE;
  135. SetDlgItemText(IDC_EDITTIMEOUT, strTimeout);
  136. m_fIgnoreEdit = FALSE;
  137. }
  138. }
  139. //----------------------------------------------------------------------------
  140. // Update the controls based on the user's selection of a line.
  141. //----------------------------------------------------------------------------
  142. void SelectLine(int index)
  143. {
  144. if (index < m_nMinOSIndex)
  145. {
  146. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, m_nMinOSIndex, 0);
  147. SelectLine(m_nMinOSIndex);
  148. return;
  149. }
  150. if (index > m_nMaxOSIndex)
  151. {
  152. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, m_nMaxOSIndex, 0);
  153. SelectLine(m_nMaxOSIndex);
  154. return;
  155. }
  156. ::EnableWindow(GetDlgItem(IDC_BOOTMOVEUP), (index > m_nMinOSIndex));
  157. ::EnableWindow(GetDlgItem(IDC_BOOTMOVEDOWN), (index < m_nMaxOSIndex));
  158. CString strOS = m_arrayIniLines[index];
  159. strOS.MakeLower();
  160. CheckDlgButton(IDC_SAFEBOOT, (strOS.Find(_T("/safeboot")) != -1));
  161. CheckDlgButton(IDC_NOGUIBOOT, (strOS.Find(_T("/noguiboot")) != -1));
  162. CheckDlgButton(IDC_BOOTLOG, (strOS.Find(_T("/bootlog")) != -1));
  163. CheckDlgButton(IDC_BASEVIDEO, (strOS.Find(_T("/basevideo")) != -1));
  164. CheckDlgButton(IDC_SOS, (strOS.Find(_T("/sos")) != -1));
  165. BOOL fSafeboot = (strOS.Find(_T("/safeboot")) != -1);
  166. ::EnableWindow(GetDlgItem(IDC_SBNETWORK), fSafeboot);
  167. ::EnableWindow(GetDlgItem(IDC_SBDSREPAIR), fSafeboot);
  168. ::EnableWindow(GetDlgItem(IDC_SBMINIMAL), fSafeboot);
  169. ::EnableWindow(GetDlgItem(IDC_SBMINIMALALT), fSafeboot);
  170. ::EnableWindow(GetDlgItem(IDC_SBNORMAL), fSafeboot);
  171. if (fSafeboot)
  172. {
  173. CheckDlgButton(IDC_SBNETWORK, (strOS.Find(_T("/safeboot:network")) != -1));
  174. CheckDlgButton(IDC_SBDSREPAIR, (strOS.Find(_T("/safeboot:dsrepair")) != -1));
  175. CheckDlgButton(IDC_SBMINIMAL, (strOS.Find(_T("/safeboot:minimal ")) != -1));
  176. CheckDlgButton(IDC_SBMINIMALALT, (strOS.Find(_T("/safeboot:minimal(alternateshell)")) != -1));
  177. CheckDlgButton(IDC_SBNORMAL, (strOS.Find(_T("/safeboot ")) != -1));
  178. }
  179. }
  180. //-------------------------------------------------------------------------
  181. // Called when the user clicks move up or down.
  182. //-------------------------------------------------------------------------
  183. LRESULT OnClickedMoveDown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  184. {
  185. int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0);
  186. ASSERT(iSelection >= m_nMinOSIndex && iSelection < m_nMaxOSIndex);
  187. if (iSelection >= m_nMinOSIndex && iSelection < m_nMaxOSIndex)
  188. {
  189. CString strTemp = m_arrayIniLines[iSelection + 1];
  190. m_arrayIniLines.SetAt(iSelection + 1, m_arrayIniLines[iSelection]);
  191. m_arrayIniLines.SetAt(iSelection, strTemp);
  192. SyncControlsToIni();
  193. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection + 1, 0);
  194. SelectLine(iSelection + 1);
  195. }
  196. return 0;
  197. }
  198. LRESULT OnClickedMoveUp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  199. {
  200. int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0);
  201. ASSERT(iSelection > m_nMinOSIndex && iSelection <= m_nMaxOSIndex);
  202. if (iSelection > m_nMinOSIndex && iSelection <= m_nMaxOSIndex)
  203. {
  204. CString strTemp = m_arrayIniLines[iSelection - 1];
  205. m_arrayIniLines.SetAt(iSelection - 1, m_arrayIniLines[iSelection]);
  206. m_arrayIniLines.SetAt(iSelection, strTemp);
  207. SyncControlsToIni();
  208. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection - 1, 0);
  209. SelectLine(iSelection - 1);
  210. }
  211. return 0;
  212. }
  213. //-------------------------------------------------------------------------
  214. // Called when the user clicks on a line in the list view.
  215. //-------------------------------------------------------------------------
  216. LRESULT OnSelChangeList(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  217. {
  218. SelectLine((int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0));
  219. return 0;
  220. }
  221. //-------------------------------------------------------------------------
  222. // The check boxes are handled uniformly - adding or removing a flag from
  223. // the currently selected OS line.
  224. //-------------------------------------------------------------------------
  225. LRESULT OnClickedBaseVideo(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  226. {
  227. ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_BASEVIDEO), _T("/basevideo"));
  228. return 0;
  229. }
  230. LRESULT OnClickedBootLog(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  231. {
  232. ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_BOOTLOG), _T("/bootlog"));
  233. return 0;
  234. }
  235. LRESULT OnClickedNoGUIBoot(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  236. {
  237. ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_NOGUIBOOT), _T("/noguiboot"));
  238. return 0;
  239. }
  240. LRESULT OnClickedSOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  241. {
  242. ChangeCurrentOSFlag(IsDlgButtonChecked(IDC_SOS), _T("/sos"));
  243. return 0;
  244. }
  245. //-------------------------------------------------------------------------
  246. // The safeboot flag is a little more complicated, since it has an extra
  247. // portion (from the radio buttons).
  248. //-------------------------------------------------------------------------
  249. LRESULT OnClickedSafeBoot(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  250. {
  251. CString strFlag(_T("/safeboot"));
  252. if (IsDlgButtonChecked(IDC_SBNETWORK))
  253. strFlag += _T(":network");
  254. else if (IsDlgButtonChecked(IDC_SBDSREPAIR))
  255. strFlag += _T(":dsrepair");
  256. else if (IsDlgButtonChecked(IDC_SBMINIMAL))
  257. strFlag += _T(":minimal");
  258. else if (IsDlgButtonChecked(IDC_SBMINIMALALT))
  259. strFlag += _T(":minimal(alternateshell)");
  260. else
  261. CheckDlgButton(IDC_SBNORMAL, 1);
  262. BOOL fSafeBoot = IsDlgButtonChecked(IDC_SAFEBOOT);
  263. ChangeCurrentOSFlag(fSafeBoot, strFlag);
  264. m_strSafeBoot = strFlag;
  265. ::EnableWindow(GetDlgItem(IDC_SBNETWORK), fSafeBoot);
  266. ::EnableWindow(GetDlgItem(IDC_SBDSREPAIR), fSafeBoot);
  267. ::EnableWindow(GetDlgItem(IDC_SBMINIMAL), fSafeBoot);
  268. ::EnableWindow(GetDlgItem(IDC_SBMINIMALALT), fSafeBoot);
  269. ::EnableWindow(GetDlgItem(IDC_SBNORMAL), fSafeBoot);
  270. return 0;
  271. }
  272. //-------------------------------------------------------------------------
  273. // Add or remove the specified flag from the currently selected OS line.
  274. //-------------------------------------------------------------------------
  275. void ChangeCurrentOSFlag(BOOL fAdd, LPCTSTR szFlag)
  276. {
  277. int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0);
  278. CString strFlagPlusSpace = CString(_T(" ")) + szFlag;
  279. CString strNewLine;
  280. if (fAdd)
  281. {
  282. if (m_arrayIniLines[iSelection].Find(szFlag) != -1)
  283. {
  284. ASSERT(0 && "the flag is already there");
  285. return;
  286. }
  287. strNewLine = m_arrayIniLines[iSelection] + strFlagPlusSpace;
  288. }
  289. else
  290. {
  291. int iIndex = m_arrayIniLines[iSelection].Find(strFlagPlusSpace);
  292. if (iIndex == -1)
  293. {
  294. ASSERT(0 && "there is no flag");
  295. return;
  296. }
  297. strNewLine = m_arrayIniLines[iSelection].Left(iIndex);
  298. strNewLine += m_arrayIniLines[iSelection].Mid(iIndex + strFlagPlusSpace.GetLength());
  299. }
  300. m_arrayIniLines.SetAt(iSelection, strNewLine);
  301. SyncControlsToIni();
  302. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection, 0);
  303. }
  304. //-------------------------------------------------------------------------
  305. // Clicking on one of the safeboot radio buttons requires a little extra
  306. // processing, to remove the existing flag and add the new one.
  307. //
  308. // TBD - make so they don't do a double update of the field
  309. //-------------------------------------------------------------------------
  310. LRESULT OnClickedSBDSRepair(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  311. {
  312. ChangeCurrentOSFlag(FALSE, m_strSafeBoot);
  313. m_strSafeBoot = _T("/safeboot:dsrepair");
  314. ChangeCurrentOSFlag(TRUE, m_strSafeBoot);
  315. return 0;
  316. }
  317. LRESULT OnClickedSBMinimal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  318. {
  319. ChangeCurrentOSFlag(FALSE, m_strSafeBoot);
  320. m_strSafeBoot = _T("/safeboot:minimal");
  321. ChangeCurrentOSFlag(TRUE, m_strSafeBoot);
  322. return 0;
  323. }
  324. LRESULT OnClickedSBMinimalAlt(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  325. {
  326. ChangeCurrentOSFlag(FALSE, m_strSafeBoot);
  327. m_strSafeBoot = _T("/safeboot:minimal(alternateshell)");
  328. ChangeCurrentOSFlag(TRUE, m_strSafeBoot);
  329. return 0;
  330. }
  331. LRESULT OnClickedSBNetwork(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  332. {
  333. ChangeCurrentOSFlag(FALSE, m_strSafeBoot);
  334. m_strSafeBoot = _T("/safeboot:network");
  335. ChangeCurrentOSFlag(TRUE, m_strSafeBoot);
  336. return 0;
  337. }
  338. LRESULT OnClickedSBNormal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  339. {
  340. ChangeCurrentOSFlag(FALSE, m_strSafeBoot);
  341. m_strSafeBoot = _T("/safeboot");
  342. ChangeCurrentOSFlag(TRUE, m_strSafeBoot);
  343. return 0;
  344. }
  345. //-------------------------------------------------------------------------
  346. // As the user enters text in the timeout field, update the line in the
  347. // ini file list box.
  348. //
  349. // TBD - do more sanity checking on this value
  350. //-------------------------------------------------------------------------
  351. LRESULT OnChangeEditTimeOut(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  352. {
  353. if (m_fIgnoreEdit)
  354. return 0;
  355. if (m_nTimeoutIndex == -1)
  356. return 0; // TBD - make this actually add the line
  357. CString strTimeout = m_arrayIniLines[m_nTimeoutIndex];
  358. int iEquals = strTimeout.Find(_T('='));
  359. if (iEquals == -1)
  360. return 0;
  361. TCHAR szValue[MAX_PATH];
  362. GetDlgItemText(IDC_EDITTIMEOUT, szValue, MAX_PATH);
  363. CString strNewTimeout = strTimeout.Left(iEquals + 1) + szValue;
  364. m_arrayIniLines.SetAt(m_nTimeoutIndex, strNewTimeout);
  365. int iSelection = (int)::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_GETCURSEL, 0, 0);
  366. SyncControlsToIni(FALSE);
  367. ::SendMessage(GetDlgItem(IDC_LISTBOOTINI), LB_SETCURSEL, iSelection, 0);
  368. return 0;
  369. }
  370. private:
  371. CStringArray m_arrayIniLines; // array of lines in the ini file
  372. int m_nTimeoutIndex; // list index of the "timeout=" line
  373. int m_nDefaultIndex; // list index of the "default=" line
  374. int m_nMinOSIndex; // first list index of an OS line
  375. int m_nMaxOSIndex; // last list index of an OS line
  376. CString m_strSafeBoot; // the current string for the safeboot flag
  377. BOOL m_fIgnoreEdit; // used to avoid a recursion problem
  378. private:
  379. CString m_strCaption; // contains the localized name of this page
  380. public:
  381. //-------------------------------------------------------------------------
  382. // Functions used by the parent dialog.
  383. //-------------------------------------------------------------------------
  384. BOOL IsValid(CMSConfigState * state)
  385. {
  386. return TRUE;
  387. }
  388. LPCTSTR GetCaption()
  389. {
  390. if (m_strCaption.IsEmpty())
  391. {
  392. ::AfxSetResourceHandle(_Module.GetResourceInstance());
  393. m_strCaption.LoadString(IDS_BOOTINI_CAPTION);
  394. }
  395. return m_strCaption;
  396. }
  397. };
  398. #endif //__PAGEBOOTINI_H_