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.

580 lines
15 KiB

  1. /*
  2. * boot - Dialog box property sheet for "boot-time parameters"
  3. */
  4. #include "tweakui.h"
  5. #ifdef _X86_
  6. #pragma BEGIN_CONST_DATA
  7. #ifdef BOOTMENUDEFAULT
  8. ConstString(c_tszNetwork, "Network");
  9. ConstString(c_tszBootMenuDefault, "BootMenuDefault");
  10. #endif
  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('\0');
  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. * NOTE: BootKeys is meaningless if BootMenu is on -- if you
  275. * have the BootMenu enabled, then the menu just comes up even without
  276. * pressing a key. Fortunately, nobody yet has complained about the
  277. * interaction so I'm not gonna try to expose it in the UI.
  278. *
  279. *****************************************************************************/
  280. void PASCAL
  281. Boot_OnBootKeysChange(HWND hdlg)
  282. {
  283. BOOL f = IsDlgButtonChecked(hdlg, IDC_BOOTKEYS);
  284. HWND hwnd;
  285. hwnd = GetDlgItem(hdlg, IDC_BOOTDELAY);
  286. if (hwnd) {
  287. EnableWindow(hwnd, f);
  288. }
  289. EnableDlgItem(hdlg, IDC_BOOTMULTI, f);
  290. EnableDlgItem(hdlg, IDC_BOOTMENU, f);
  291. EnableDlgItem(hdlg, IDC_BOOTMENUDELAY, f);
  292. }
  293. /*****************************************************************************
  294. *
  295. * Boot_SetDlgOption
  296. *
  297. * Set the value of a dialog box item.
  298. *
  299. *****************************************************************************/
  300. void PASCAL
  301. Boot_SetDlgOption(HWND hdlg, PMSIO pmsio, UINT ui)
  302. {
  303. HWND hwnd = GetDlgItem(hdlg, pmsio->id);
  304. if (hwnd) {
  305. switch (pmsio->msiot) {
  306. case msiotUint:
  307. SetDlgItemInt(hdlg, pmsio->id, ui, 0);
  308. break;
  309. case msiotBool:
  310. CheckDlgButton(hdlg, pmsio->id, ui);
  311. break;
  312. case msiotCombo:
  313. ComboBox_SetCurSel(hwnd, ui);
  314. }
  315. }
  316. }
  317. /*****************************************************************************
  318. *
  319. * Boot_FactoryReset
  320. *
  321. * Restore to original factory settings.
  322. *
  323. * The weird one is IDC_BOOTLOGO, which
  324. * varies depending on the system configuration.
  325. *
  326. *****************************************************************************/
  327. BOOL PASCAL
  328. Boot_FactoryReset(HWND hdlg)
  329. {
  330. PMSIO pmsio;
  331. for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
  332. Boot_SetDlgOption(hdlg, pmsio, pmsio->uiDefault);
  333. }
  334. CheckDlgButton(hdlg, IDC_LOGO, Boot_fLogo());
  335. #ifdef BOOTMENUDEFAULT
  336. SendDlgItemMessage(hdlg, IDC_BOOTMENUDEFAULT, CB_SETCURSEL,
  337. (WPARAM)Boot_GetDefaultBootMenuDefault() - 1, 0L);
  338. #endif
  339. Boot_OnBootKeysChange(hdlg);
  340. Common_SetDirty(hdlg);
  341. return 1;
  342. }
  343. /*****************************************************************************
  344. *
  345. * Boot_OnCommand
  346. *
  347. * Ooh, we got a command.
  348. *
  349. *****************************************************************************/
  350. BOOL PASCAL
  351. Boot_OnCommand(HWND hdlg, int id, UINT codeNotify)
  352. {
  353. switch (id) {
  354. case IDC_RESET: /* Reset to factory default */
  355. if (codeNotify == BN_CLICKED) return Boot_FactoryReset(hdlg);
  356. break;
  357. case IDC_BOOTKEYS:
  358. if (codeNotify == BN_CLICKED) Boot_OnBootKeysChange(hdlg);
  359. /* FALLTHROUGH */
  360. case IDC_BOOTGUI:
  361. case IDC_BOOTMENU:
  362. case IDC_LOGO:
  363. case IDC_BOOTMULTI:
  364. if (codeNotify == BN_CLICKED) Common_SetDirty(hdlg);
  365. break;
  366. case IDC_BOOTDELAY:
  367. case IDC_BOOTMENUDELAY:
  368. if (codeNotify == EN_CHANGE) Common_SetDirty(hdlg);
  369. break;
  370. #ifdef BOOTMENUDEFAULT
  371. case IDC_BOOTMENUDEFAULT:
  372. if (codeNotify == CBN_SELCHANGE) Common_SetDirty(hdlg);
  373. break;
  374. #endif
  375. case IDC_SCANDISK:
  376. if (codeNotify == CBN_SELCHANGE) Common_SetDirty(hdlg);
  377. break;
  378. }
  379. return 0;
  380. }
  381. /*****************************************************************************
  382. *
  383. * Boot_OnNotify
  384. *
  385. * Ooh, we got a notification.
  386. *
  387. *****************************************************************************/
  388. BOOL PASCAL
  389. Boot_OnNotify(HWND hdlg, NMHDR FAR *pnm)
  390. {
  391. switch (pnm->code) {
  392. case PSN_APPLY:
  393. Boot_Apply(hdlg);
  394. break;
  395. }
  396. return 0;
  397. }
  398. /*****************************************************************************
  399. *
  400. * Boot_InitDlgInt
  401. *
  402. * Initialize a paired edit control / updown control.
  403. *
  404. * hdlg is the dialog box itself.
  405. *
  406. * idc is the edit control identifier. It is assumed that idc+didcUd is
  407. * the identifier for the updown control.
  408. *
  409. * iMin and iMax are the limits of the control.
  410. *
  411. *****************************************************************************/
  412. void PASCAL
  413. Boot_InitDlgInt(HWND hdlg, UINT idc, int iMin, int iMax)
  414. {
  415. HWND hwnd = GetDlgItem(hdlg, idc + didcEdit);
  416. if (hwnd) {
  417. Edit_LimitText(hwnd, 2);
  418. SendDlgItemMessage(hdlg, idc+didcUd,
  419. UDM_SETRANGE, 0, MAKELPARAM(iMax, iMin));
  420. }
  421. }
  422. /*****************************************************************************
  423. *
  424. * Boot_OnInitDialog
  425. *
  426. * Initialize the controls.
  427. *
  428. *****************************************************************************/
  429. BOOL NEAR PASCAL
  430. Boot_OnInitDialog(HWND hdlg)
  431. {
  432. PMSIO pmsio;
  433. HWND hwnd;
  434. UINT dids;
  435. TCH tsz[96];
  436. /*
  437. * Init the Scandisk gizmo. We need to do this even if not OPK2,
  438. * so that we don't confuse the Apply. But show it only if OPK2.
  439. */
  440. hwnd = GetDlgItem(hdlg, IDC_SCANDISK);
  441. for (dids = 0; dids < 3; dids++) {
  442. LoadString(hinstCur, IDS_SCANDISKFIRST + dids, tsz, cA(tsz));
  443. ComboBox_AddString(hwnd, tsz);
  444. }
  445. if (g_fOPK2) {
  446. ShowWindow(hwnd, 1);
  447. ShowWindow(GetDlgItem(hdlg, IDC_SCANDISKTEXT), 1);
  448. }
  449. for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
  450. Boot_SetDlgOption(hdlg, pmsio,
  451. Boot_GetOption(pmsio->ptszName, pmsio->uiDefault));
  452. }
  453. #ifdef BOOTMENUDEFAULT
  454. hwnd = GetDlgItem(hdlg, IDC_BOOTMENUDEFAULT);
  455. for (ids = IDS_BOOTMENU; ids <= IDS_BOOTMENULAST; ids++) {
  456. if (ids != IDS_BOOTMENUSAFENET || Boot_GetOption(c_tszNetwork, 0)) {
  457. LoadString(hinstCur, ids, tsz, cA(tsz));
  458. ComboBox_AddString(hwnd, tsz);
  459. }
  460. }
  461. ComboBox_SetCurSel(hwnd, Boot_GetBootMenuDefault() - 1);
  462. #endif
  463. Boot_InitDlgInt(hdlg, IDC_BOOTDELAY, 0, 99);
  464. Boot_InitDlgInt(hdlg, IDC_BOOTMENUDELAY, 0, 99);
  465. Boot_OnBootKeysChange(hdlg);
  466. if (g_fMemphis) {
  467. DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYTEXT));
  468. DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAY));
  469. DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYUD));
  470. DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYTEXT2));
  471. }
  472. return 1;
  473. }
  474. /*****************************************************************************
  475. *
  476. * Our window procedure.
  477. *
  478. *****************************************************************************/
  479. /*
  480. * The HANDLE_WM_* macros weren't designed to be used from a dialog
  481. * proc, so we need to handle the messages manually. (But carefully.)
  482. */
  483. INT_PTR EXPORT
  484. Boot_DlgProc(HWND hdlg, UINT wm, WPARAM wParam, LPARAM lParam)
  485. {
  486. switch (wm) {
  487. case WM_INITDIALOG: return Boot_OnInitDialog(hdlg);
  488. case WM_COMMAND:
  489. return Boot_OnCommand(hdlg,
  490. (int)GET_WM_COMMAND_ID(wParam, lParam),
  491. (UINT)GET_WM_COMMAND_CMD(wParam, lParam));
  492. case WM_NOTIFY:
  493. return Boot_OnNotify(hdlg, (NMHDR FAR *)lParam);
  494. case WM_HELP: Common_OnHelp(lParam, &rgdwHelp[0]); break;
  495. case WM_CONTEXTMENU: Common_OnContextMenu(wParam, &rgdwHelp[0]); break;
  496. default: return 0; /* Unhandled */
  497. }
  498. return 1; /* Handled */
  499. }
  500. #endif // _X86_ only