boot.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 15k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * boot - Dialog box property sheet for "boot-time parameters"
  3.  */
  4. #include "tweakui.h"
  5. #pragma BEGIN_CONST_DATA
  6. #ifdef BOOTMENUDEFAULT
  7. ConstString(c_tszNetwork, "Network");
  8. ConstString(c_tszBootMenuDefault, "BootMenuDefault");
  9. #endif
  10. /* BUGBUG - use a dispatch table already */
  11. typedef BYTE MSIOT; /* msdos.sys ini option type */
  12. #define msiotUint 0
  13. #define msiotBool 1
  14. #define msiotCombo 2
  15. typedef const struct MSIO { /* msdos.sys ini option */
  16.     const TCH CODESEG *ptszName;
  17.     WORD id; /* Dialog id */
  18.     MSIOT msiot; /* Data type */
  19.     BYTE uiDefault; /* The default value */
  20. } MSIO;
  21. typedef MSIO CODESEG *PMSIO;
  22. MSIO CODESEG rgmsio[] = {
  23.     { c_tszBootKeys,  IDC_BOOTKEYS, msiotBool,  1 },
  24.     { c_tszBootDelay,  IDC_BOOTDELAY,  msiotUint,  2 },
  25.     { c_tszBootGUI,  IDC_BOOTGUI, msiotBool,  1 },
  26.     { c_tszBootMenu,  IDC_BOOTMENU, msiotBool,  0 },
  27.     { c_tszBootMenuDelay,IDC_BOOTMENUDELAY, msiotUint, 30 },
  28.     { c_tszLogo,  IDC_LOGO, msiotBool,  1 },
  29.     { c_tszBootMulti,  IDC_BOOTMULTI,  msiotBool,  0 },
  30.     { c_tszAutoScan,  IDC_SCANDISK, msiotCombo, 1 },
  31. };
  32. #define pmsioMax (&rgmsio[cA(rgmsio)])
  33. const static DWORD CODESEG rgdwHelp[] = {
  34. IDC_BOOTGROUP1, IDH_GROUP,
  35. IDC_BOOTKEYS, IDH_BOOTKEYS,
  36. IDC_BOOTDELAYTEXT, IDH_BOOTKEYS,
  37. IDC_BOOTDELAY, IDH_BOOTKEYS,
  38. IDC_BOOTDELAYUD, IDH_BOOTKEYS,
  39. IDC_BOOTDELAYTEXT2, IDH_BOOTKEYS,
  40. IDC_BOOTGUI, IDH_BOOTGUI,
  41. IDC_LOGO, IDH_LOGO,
  42. IDC_BOOTMULTI, IDH_BOOTMULTI,
  43. IDC_BOOTMENUGROUP, IDH_GROUP,
  44. IDC_BOOTMENU, IDH_BOOTMENU,
  45. IDC_BOOTMENUDELAYTEXT, IDH_BOOTMENUDELAY,
  46. IDC_BOOTMENUDELAY, IDH_BOOTMENUDELAY,
  47. IDC_BOOTMENUDELAYUD, IDH_BOOTMENUDELAY,
  48. IDC_BOOTMENUDELAYTEXT2, IDH_BOOTMENUDELAY,
  49. IDC_SCANDISKTEXT, IDH_AUTOSCAN,
  50. IDC_SCANDISK, IDH_AUTOSCAN,
  51. IDC_RESET, IDH_RESET,
  52. 0, 0,
  53. };
  54. #pragma END_CONST_DATA
  55. /*****************************************************************************
  56.  *
  57.  *  Boot_fLogo
  58.  *
  59.  * Nonzer if this machine should have the logo enabled by default.
  60.  *
  61.  * The answer is yes, unless the display driver is xga.drv,
  62.  * because XGA cards aren't really VGA compatible, and the logo
  63.  * code uses VGA mode X.
  64.  *
  65.  *****************************************************************************/
  66. BOOL PASCAL
  67. Boot_fLogo(void)
  68. {
  69.     TCH tsz[12];
  70.     return !(GetPrivateProfileString(c_tszBoot, c_tszDisplayDrv, c_tszNil,
  71.      tsz, cA(tsz), c_tszSysIni) &&
  72. lstrcmpi(tsz, c_tszXgaDrv) == 0);
  73. }
  74. /*****************************************************************************
  75.  *
  76.  *  Boot_GetOption
  77.  *
  78.  *****************************************************************************/
  79. int PASCAL
  80. Boot_GetOption(LPCTSTR ptszName, UINT uiDefault)
  81. {
  82.     return GetPrivateProfileInt(c_tszOptions, ptszName,
  83.         uiDefault, g_tszMsdosSys);
  84. }
  85. #ifdef BOOTMENUDEFAULT
  86. /*****************************************************************************
  87.  *
  88.  *  Boot_GetDefaultBootMenuDefault
  89.  *
  90.  * Get the default boot menu default.  This is 3 if no network, 
  91.  * or 4 if network.
  92.  *
  93.  *****************************************************************************/
  94. UINT PASCAL
  95. Boot_GetDefaultBootMenuDefault(void)
  96. {
  97.     return 3 + Boot_GetOption(c_tszNetwork, 0);
  98. }
  99. /*****************************************************************************
  100.  *
  101.  *  Boot_GetBootMenuDefault
  102.  *
  103.  * Get the boot menu default.
  104.  *
  105.  *****************************************************************************/
  106. int PASCAL
  107. Boot_GetBootMenuDefault(void)
  108. {
  109.     return Boot_GetOption(c_tszBootMenuDefault,
  110.   Boot_GetDefaultBootMenuDefault());
  111. }
  112. #endif
  113. /*****************************************************************************
  114.  *
  115.  *  Boot_FindMsdosSys
  116.  *
  117.  * Search the hard drives for the file X:MSDOS.SYS.
  118.  *
  119.  * There is no "Get boot drive" function in Win32, so this is the best
  120.  * I can do.
  121.  *
  122.  * (MS-DOS function 3305h returns the boot drive.)
  123.  *
  124.  *****************************************************************************/
  125. void PASCAL
  126. Boot_FindMsdosSys(void)
  127. {
  128.     TCH tsz[2]; /* scratch */
  129.     char szRoot[4]; /* Root directory thing */
  130.     (*(LPDWORD)szRoot) = 0x005C3A40; /* @: */
  131.     for (szRoot[0] = 'A'; szRoot[0] <= 'Z'; szRoot[0]++) {
  132. if (GetDriveTypeA(szRoot) == DRIVE_FIXED) {
  133.     DWORD fl;
  134.     if (GetVolumeInformation(szRoot, 0, 0, 0, 0, &fl, 0, 0) &&
  135. !(fl & FS_VOL_IS_COMPRESSED)) {
  136. g_tszMsdosSys[0] = (TCH)szRoot[0];
  137. if (GetPrivateProfileString(c_tszPaths, c_tszWinDir, 0,
  138.     tsz, cA(tsz), g_tszMsdosSys)) {
  139.     return;
  140. }
  141.     }
  142. }
  143.     }
  144.     g_tszMsdosSys[0] = TEXT('');
  145. }
  146. /*****************************************************************************
  147.  *
  148.  *  Boot_WriteOptionUint
  149.  *
  150.  * Write an option unsigned integer to the msdos.sys file.
  151.  *
  152.  *****************************************************************************/
  153. void PASCAL
  154. Boot_WriteOptionUint(LPCTSTR ptszName, UINT ui, UINT uiDefault)
  155. {
  156.     if (GetPrivateProfileInt(c_tszOptions, ptszName,
  157.      uiDefault, g_tszMsdosSys) != ui) {
  158. TCH tsz[32];
  159. wsprintf(tsz, c_tszPercentU, ui);
  160. WritePrivateProfileString(c_tszOptions, ptszName, tsz, g_tszMsdosSys);
  161. OutputDebugString(ptszName);
  162. OutputDebugString(tsz);
  163.     }
  164. }
  165. /*****************************************************************************
  166.  *
  167.  *  Boot_SetOptionBool
  168.  *
  169.  * Propagate an option boolean to the msdos.sys file.
  170.  *
  171.  *****************************************************************************/
  172. void PASCAL
  173. Boot_SetOptionBool(HWND hdlg, PMSIO pmsio)
  174. {
  175.     Boot_WriteOptionUint(pmsio->ptszName, IsDlgButtonChecked(hdlg, pmsio->id),
  176.  pmsio->uiDefault);
  177. }
  178. /*****************************************************************************
  179.  *
  180.  *  Boot_SetOptionUint
  181.  *
  182.  * Propagate an option unsigned integer to the msdos.sys file.
  183.  *
  184.  *****************************************************************************/
  185. void PASCAL
  186. Boot_SetOptionUint(HWND hdlg, PMSIO pmsio)
  187. {
  188.     UINT ui;
  189.     BOOL f;
  190.     ui = (int)GetDlgItemInt(hdlg, pmsio->id, &f, 0);
  191.     if (f) {
  192.         Boot_WriteOptionUint(pmsio->ptszName, ui, pmsio->uiDefault);
  193.     }
  194. }
  195. /*****************************************************************************
  196.  *
  197.  *  Boot_SetOptionCombo
  198.  *
  199.  * Propagate a combo option to the msdos.sys file.
  200.  *
  201.  * Not propagating the value that is already there means that we don't
  202.  * set AutoScan if not running OPK2.
  203.  *
  204.  *****************************************************************************/
  205. void PASCAL
  206. Boot_SetOptionCombo(HWND hdlg, PMSIO pmsio)
  207. {
  208.     Boot_WriteOptionUint(pmsio->ptszName,
  209.  SendDlgItemMessage(hdlg, pmsio->id,
  210.     CB_GETCURSEL, 0, 0),
  211.  pmsio->uiDefault);
  212. }
  213. /*****************************************************************************
  214.  *
  215.  *  Boot_FlushIniCache
  216.  *
  217.  *  Make sure all changes are committed to disk.
  218.  *
  219.  *****************************************************************************/
  220. INLINE void
  221. Boot_FlushIniCache(void)
  222. {
  223.     WritePrivateProfileString(0, 0, 0, g_tszMsdosSys);
  224. }
  225. /*****************************************************************************
  226.  *
  227.  *  Boot_Apply
  228.  *
  229.  * Write the changes to the msdos.sys file.
  230.  *
  231.  *****************************************************************************/
  232. BOOL PASCAL
  233. Boot_Apply(HWND hdlg)
  234. {
  235.     DWORD dwAttr = GetFileAttributes(g_tszMsdosSys);
  236.     if (dwAttr != 0xFFFFFFFF &&
  237. SetFileAttributes(g_tszMsdosSys, FILE_ATTRIBUTE_NORMAL)) {
  238. PMSIO pmsio;
  239. for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
  240.             HWND hwnd = GetDlgItem(hdlg, pmsio->id);
  241.             if (hwnd) {
  242.                 switch (pmsio->msiot) {
  243.                 case msiotUint:
  244.                     Boot_SetOptionUint(hdlg, pmsio);
  245.                     break;
  246.                 case msiotBool:
  247.                     Boot_SetOptionBool(hdlg, pmsio);
  248.                     break;
  249.                 case msiotCombo:
  250.                     Boot_SetOptionCombo(hdlg, pmsio);
  251.                     break;
  252.                 }
  253.             }
  254. }
  255. #ifdef BOOTMENUDEFAULT
  256. Boot_WriteOptionUint(c_tszBootMenuDefault,
  257.     (UINT)SendDlgItemMessage(hdlg, IDC_BOOTMENUDEFAULT, CB_GETCURSEL,
  258.      0, 0L) + 1);
  259. #endif
  260. Boot_FlushIniCache();
  261. SetFileAttributes(g_tszMsdosSys, dwAttr);
  262.     } else {
  263. MessageBoxId(hdlg, IDS_ERRMSDOSSYS, g_tszName, MB_OK);
  264.     }
  265.     return 1;
  266. }
  267. /*****************************************************************************
  268.  *
  269.  *  Boot_OnBootKeysChange
  270.  *
  271.  * When IDC_BOOTKEYS changes, enable or disable the boot delay,
  272.  * BootMulti, and BootMenu.
  273.  *
  274.  * BUGBUG -- Bootkeys and bootmenu are mutually exclusive.
  275.  *
  276.  *****************************************************************************/
  277. void PASCAL
  278. Boot_OnBootKeysChange(HWND hdlg)
  279. {
  280.     BOOL f = IsDlgButtonChecked(hdlg, IDC_BOOTKEYS);
  281.     HWND hwnd;
  282.     hwnd = GetDlgItem(hdlg, IDC_BOOTDELAY);
  283.     if (hwnd) {
  284.         EnableWindow(hwnd, f);
  285.     }
  286.     EnableDlgItem(hdlg, IDC_BOOTMULTI, f);
  287.     EnableDlgItem(hdlg, IDC_BOOTMENU, f);
  288.     EnableDlgItem(hdlg, IDC_BOOTMENUDELAY, f);
  289. }
  290. /*****************************************************************************
  291.  *
  292.  *  Boot_SetDlgOption
  293.  *
  294.  * Set the value of a dialog box item.
  295.  *
  296.  *****************************************************************************/
  297. void PASCAL
  298. Boot_SetDlgOption(HWND hdlg, PMSIO pmsio, UINT ui)
  299. {
  300.     HWND hwnd = GetDlgItem(hdlg, pmsio->id);
  301.     if (hwnd) {
  302.         switch (pmsio->msiot) {
  303.         case msiotUint:
  304.             SetDlgItemInt(hdlg, pmsio->id, ui, 0);
  305.             break;
  306.         case msiotBool:
  307.             CheckDlgButton(hdlg, pmsio->id, ui);
  308.             break;
  309.         case msiotCombo:
  310.             ComboBox_SetCurSel(hwnd, ui);
  311.         }
  312.     }
  313. }
  314. /*****************************************************************************
  315.  *
  316.  *  Boot_FactoryReset
  317.  *
  318.  * Restore to original factory settings.
  319.  *
  320.  * The weird one is IDC_BOOTLOGO, which
  321.  * varies depending on the system configuration.
  322.  *
  323.  *****************************************************************************/
  324. BOOL PASCAL
  325. Boot_FactoryReset(HWND hdlg)
  326. {
  327.     PMSIO pmsio;
  328.     for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
  329. Boot_SetDlgOption(hdlg, pmsio, pmsio->uiDefault);
  330.     }
  331.     CheckDlgButton(hdlg, IDC_LOGO, Boot_fLogo());
  332. #ifdef BOOTMENUDEFAULT
  333.     SendDlgItemMessage(hdlg, IDC_BOOTMENUDEFAULT, CB_SETCURSEL,
  334.        (WPARAM)Boot_GetDefaultBootMenuDefault() - 1, 0L);
  335. #endif
  336.     Boot_OnBootKeysChange(hdlg);
  337.     Common_SetDirty(hdlg);
  338.     return 1;
  339. }
  340. /*****************************************************************************
  341.  *
  342.  *  Boot_OnCommand
  343.  *
  344.  * Ooh, we got a command.
  345.  *
  346.  *****************************************************************************/
  347. BOOL PASCAL
  348. Boot_OnCommand(HWND hdlg, int id, UINT codeNotify)
  349. {
  350.     switch (id) {
  351.     case IDC_RESET: /* Reset to factory default */
  352. if (codeNotify == BN_CLICKED) return Boot_FactoryReset(hdlg);
  353. break;
  354.     case IDC_BOOTKEYS:
  355. if (codeNotify == BN_CLICKED) Boot_OnBootKeysChange(hdlg);
  356. /* FALLTHROUGH */
  357.     case IDC_BOOTGUI:
  358.     case IDC_BOOTMENU:
  359.     case IDC_LOGO:
  360.     case IDC_BOOTMULTI:
  361. if (codeNotify == BN_CLICKED) Common_SetDirty(hdlg);
  362. break;
  363.     case IDC_BOOTDELAY:
  364.     case IDC_BOOTMENUDELAY:
  365. if (codeNotify == EN_CHANGE) Common_SetDirty(hdlg);
  366. break;
  367. #ifdef BOOTMENUDEFAULT
  368.     case IDC_BOOTMENUDEFAULT:
  369. if (codeNotify == CBN_SELCHANGE) Common_SetDirty(hdlg);
  370. break;
  371. #endif
  372.     case IDC_SCANDISK:
  373. if (codeNotify == CBN_SELCHANGE) Common_SetDirty(hdlg);
  374. break;
  375.     }
  376.     return 0;
  377. }
  378. /*****************************************************************************
  379.  *
  380.  *  Boot_OnNotify
  381.  *
  382.  * Ooh, we got a notification.
  383.  *
  384.  *****************************************************************************/
  385. BOOL PASCAL
  386. Boot_OnNotify(HWND hdlg, NMHDR FAR *pnm)
  387. {
  388.     switch (pnm->code) {
  389.     case PSN_APPLY:
  390. Boot_Apply(hdlg);
  391. break;
  392.     }
  393.     return 0;
  394. }
  395. /*****************************************************************************
  396.  *
  397.  *  Boot_InitDlgInt
  398.  *
  399.  * Initialize a paired edit control / updown control.
  400.  *
  401.  * hdlg is the dialog box itself.
  402.  *
  403.  * idc is the edit control identifier.  It is assumed that idc+didcUd is
  404.  * the identifier for the updown control.
  405.  *
  406.  * iMin and iMax are the limits of the control.
  407.  *
  408.  *****************************************************************************/
  409. void PASCAL
  410. Boot_InitDlgInt(HWND hdlg, UINT idc, int iMin, int iMax)
  411. {
  412.     HWND hwnd = GetDlgItem(hdlg, idc + didcEdit);
  413.     if (hwnd) {
  414.         Edit_LimitText(hwnd, 2);
  415.         SendDlgItemMessage(hdlg, idc+didcUd,
  416.                            UDM_SETRANGE, 0, MAKELPARAM(iMax, iMin));
  417.     }
  418. }
  419. /*****************************************************************************
  420.  *
  421.  *  Boot_OnInitDialog
  422.  *
  423.  * Initialize the controls.
  424.  *
  425.  *****************************************************************************/
  426. BOOL NEAR PASCAL
  427. Boot_OnInitDialog(HWND hdlg)
  428. {
  429.     PMSIO pmsio;
  430.     HWND hwnd;
  431.     UINT dids;
  432.     TCH tsz[96];
  433.     /*
  434.      * Init the Scandisk gizmo.  We need to do this even if not OPK2,
  435.      * so that we don't freak out on the Apply.  But show it only if OPK2.
  436.      */
  437.     hwnd = GetDlgItem(hdlg, IDC_SCANDISK);
  438.     for (dids = 0; dids < 3; dids++) {
  439. LoadString(hinstCur, IDS_SCANDISKFIRST + dids, tsz, cA(tsz));
  440. ComboBox_AddString(hwnd, tsz);
  441.     }
  442.     if (g_fOPK2) {
  443. ShowWindow(hwnd, 1);
  444. ShowWindow(GetDlgItem(hdlg, IDC_SCANDISKTEXT), 1);
  445.     }
  446.     for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
  447. Boot_SetDlgOption(hdlg, pmsio,
  448.   Boot_GetOption(pmsio->ptszName, pmsio->uiDefault));
  449.     }
  450.     
  451. #ifdef BOOTMENUDEFAULT
  452.     hwnd = GetDlgItem(hdlg, IDC_BOOTMENUDEFAULT);
  453.     for (ids = IDS_BOOTMENU; ids <= IDS_BOOTMENULAST; ids++) {
  454. if (ids != IDS_BOOTMENUSAFENET || Boot_GetOption(c_tszNetwork, 0)) {
  455.     LoadString(hinstCur, ids, tsz, cA(tsz));
  456.     ComboBox_AddString(hwnd, tsz);
  457. }
  458.     }
  459.     ComboBox_SetCurSel(hwnd, Boot_GetBootMenuDefault() - 1);
  460. #endif
  461.     Boot_InitDlgInt(hdlg, IDC_BOOTDELAY, 0, 99);
  462.     Boot_InitDlgInt(hdlg, IDC_BOOTMENUDELAY, 0, 99);
  463.     Boot_OnBootKeysChange(hdlg);
  464.     if (g_fMemphis) {
  465.         DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYTEXT));
  466.         DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAY));
  467.         DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYUD));
  468.         DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYTEXT2));
  469.     }
  470.     return 1;
  471. }
  472. /*****************************************************************************
  473.  *
  474.  *  Our window procedure.
  475.  *
  476.  *****************************************************************************/
  477. /*
  478.  * The HANDLE_WM_* macros weren't designed to be used from a dialog
  479.  * proc, so we need to handle the messages manually.  (But carefully.)
  480.  */
  481. BOOL EXPORT
  482. Boot_DlgProc(HWND hdlg, UINT wm, WPARAM wParam, LPARAM lParam)
  483. {
  484.     switch (wm) {
  485.     case WM_INITDIALOG: return Boot_OnInitDialog(hdlg);
  486.     case WM_COMMAND:
  487. return Boot_OnCommand(hdlg,
  488.        (int)GET_WM_COMMAND_ID(wParam, lParam),
  489.        (UINT)GET_WM_COMMAND_CMD(wParam, lParam));
  490.     case WM_NOTIFY:
  491. return Boot_OnNotify(hdlg, (NMHDR FAR *)lParam);
  492.     case WM_HELP: Common_OnHelp(lParam, &rgdwHelp[0]); break;
  493.     case WM_CONTEXTMENU: Common_OnContextMenu(wParam, &rgdwHelp[0]); break;
  494.     default: return 0; /* Unhandled */
  495.     }
  496.     return 1; /* Handled */
  497. }