windows-nt/Source/XPSP1/NT/sdktools/tweakui/boot.cpp
2020-09-26 16:20:57 +08:00

581 lines
15 KiB
C++

/*
* boot - Dialog box property sheet for "boot-time parameters"
*/
#include "tweakui.h"
#ifdef _X86_
#pragma BEGIN_CONST_DATA
#ifdef BOOTMENUDEFAULT
ConstString(c_tszNetwork, "Network");
ConstString(c_tszBootMenuDefault, "BootMenuDefault");
#endif
typedef BYTE MSIOT; /* msdos.sys ini option type */
#define msiotUint 0
#define msiotBool 1
#define msiotCombo 2
typedef const struct _MSIO { /* msdos.sys ini option */
const TCH CODESEG *ptszName;
WORD id; /* Dialog id */
MSIOT msiot; /* Data type */
BYTE uiDefault; /* The default value */
} MSIO;
typedef MSIO CODESEG *PMSIO;
MSIO CODESEG rgmsio[] = {
{ c_tszBootKeys, IDC_BOOTKEYS, msiotBool, 1 },
{ c_tszBootDelay, IDC_BOOTDELAY, msiotUint, 2 },
{ c_tszBootGUI, IDC_BOOTGUI, msiotBool, 1 },
{ c_tszBootMenu, IDC_BOOTMENU, msiotBool, 0 },
{ c_tszBootMenuDelay,IDC_BOOTMENUDELAY, msiotUint, 30 },
{ c_tszLogo, IDC_LOGO, msiotBool, 1 },
{ c_tszBootMulti, IDC_BOOTMULTI, msiotBool, 0 },
{ c_tszAutoScan, IDC_SCANDISK, msiotCombo, 1 },
};
#define pmsioMax (&rgmsio[cA(rgmsio)])
const static DWORD CODESEG rgdwHelp[] = {
IDC_BOOTGROUP1, IDH_GROUP,
IDC_BOOTKEYS, IDH_BOOTKEYS,
IDC_BOOTDELAYTEXT, IDH_BOOTKEYS,
IDC_BOOTDELAY, IDH_BOOTKEYS,
IDC_BOOTDELAYUD, IDH_BOOTKEYS,
IDC_BOOTDELAYTEXT2, IDH_BOOTKEYS,
IDC_BOOTGUI, IDH_BOOTGUI,
IDC_LOGO, IDH_LOGO,
IDC_BOOTMULTI, IDH_BOOTMULTI,
IDC_BOOTMENUGROUP, IDH_GROUP,
IDC_BOOTMENU, IDH_BOOTMENU,
IDC_BOOTMENUDELAYTEXT, IDH_BOOTMENUDELAY,
IDC_BOOTMENUDELAY, IDH_BOOTMENUDELAY,
IDC_BOOTMENUDELAYUD, IDH_BOOTMENUDELAY,
IDC_BOOTMENUDELAYTEXT2, IDH_BOOTMENUDELAY,
IDC_SCANDISKTEXT, IDH_AUTOSCAN,
IDC_SCANDISK, IDH_AUTOSCAN,
IDC_RESET, IDH_RESET,
0, 0,
};
#pragma END_CONST_DATA
/*****************************************************************************
*
* Boot_fLogo
*
* Nonzer if this machine should have the logo enabled by default.
*
* The answer is yes, unless the display driver is xga.drv,
* because XGA cards aren't really VGA compatible, and the logo
* code uses VGA mode X.
*
*****************************************************************************/
BOOL PASCAL
Boot_fLogo(void)
{
TCH tsz[12];
return !(GetPrivateProfileString(c_tszBoot, c_tszDisplayDrv, c_tszNil,
tsz, cA(tsz), c_tszSysIni) &&
lstrcmpi(tsz, c_tszXgaDrv) == 0);
}
/*****************************************************************************
*
* Boot_GetOption
*
*****************************************************************************/
int PASCAL
Boot_GetOption(LPCTSTR ptszName, UINT uiDefault)
{
return GetPrivateProfileInt(c_tszOptions, ptszName,
uiDefault, g_tszMsdosSys);
}
#ifdef BOOTMENUDEFAULT
/*****************************************************************************
*
* Boot_GetDefaultBootMenuDefault
*
* Get the default boot menu default. This is 3 if no network,
* or 4 if network.
*
*****************************************************************************/
UINT PASCAL
Boot_GetDefaultBootMenuDefault(void)
{
return 3 + Boot_GetOption(c_tszNetwork, 0);
}
/*****************************************************************************
*
* Boot_GetBootMenuDefault
*
* Get the boot menu default.
*
*****************************************************************************/
int PASCAL
Boot_GetBootMenuDefault(void)
{
return Boot_GetOption(c_tszBootMenuDefault,
Boot_GetDefaultBootMenuDefault());
}
#endif
/*****************************************************************************
*
* Boot_FindMsdosSys
*
* Search the hard drives for the file X:\MSDOS.SYS.
*
* There is no "Get boot drive" function in Win32, so this is the best
* I can do.
*
* (MS-DOS function 3305h returns the boot drive.)
*
*****************************************************************************/
void PASCAL
Boot_FindMsdosSys(void)
{
TCH tsz[2]; /* scratch */
char szRoot[4]; /* Root directory thing */
(*(LPDWORD)szRoot) = 0x005C3A40; /* @:\ */
for (szRoot[0] = 'A'; szRoot[0] <= 'Z'; szRoot[0]++) {
if (GetDriveTypeA(szRoot) == DRIVE_FIXED) {
DWORD fl;
if (GetVolumeInformation(szRoot, 0, 0, 0, 0, &fl, 0, 0) &&
!(fl & FS_VOL_IS_COMPRESSED)) {
g_tszMsdosSys[0] = (TCH)szRoot[0];
if (GetPrivateProfileString(c_tszPaths, c_tszWinDir, 0,
tsz, cA(tsz), g_tszMsdosSys)) {
return;
}
}
}
}
g_tszMsdosSys[0] = TEXT('\0');
}
/*****************************************************************************
*
* Boot_WriteOptionUint
*
* Write an option unsigned integer to the msdos.sys file.
*
*****************************************************************************/
void PASCAL
Boot_WriteOptionUint(LPCTSTR ptszName, UINT ui, UINT uiDefault)
{
if (GetPrivateProfileInt(c_tszOptions, ptszName,
uiDefault, g_tszMsdosSys) != ui) {
TCH tsz[32];
wsprintf(tsz, c_tszPercentU, ui);
WritePrivateProfileString(c_tszOptions, ptszName, tsz, g_tszMsdosSys);
OutputDebugString(ptszName);
OutputDebugString(tsz);
}
}
/*****************************************************************************
*
* Boot_SetOptionBool
*
* Propagate an option boolean to the msdos.sys file.
*
*****************************************************************************/
void PASCAL
Boot_SetOptionBool(HWND hdlg, PMSIO pmsio)
{
Boot_WriteOptionUint(pmsio->ptszName, IsDlgButtonChecked(hdlg, pmsio->id),
pmsio->uiDefault);
}
/*****************************************************************************
*
* Boot_SetOptionUint
*
* Propagate an option unsigned integer to the msdos.sys file.
*
*****************************************************************************/
void PASCAL
Boot_SetOptionUint(HWND hdlg, PMSIO pmsio)
{
UINT ui;
BOOL f;
ui = (int)GetDlgItemInt(hdlg, pmsio->id, &f, 0);
if (f) {
Boot_WriteOptionUint(pmsio->ptszName, ui, pmsio->uiDefault);
}
}
/*****************************************************************************
*
* Boot_SetOptionCombo
*
* Propagate a combo option to the msdos.sys file.
*
* Not propagating the value that is already there means that we don't
* set AutoScan if not running OPK2.
*
*****************************************************************************/
void PASCAL
Boot_SetOptionCombo(HWND hdlg, PMSIO pmsio)
{
Boot_WriteOptionUint(pmsio->ptszName,
SendDlgItemMessage(hdlg, pmsio->id,
CB_GETCURSEL, 0, 0),
pmsio->uiDefault);
}
/*****************************************************************************
*
* Boot_FlushIniCache
*
* Make sure all changes are committed to disk.
*
*****************************************************************************/
INLINE void
Boot_FlushIniCache(void)
{
WritePrivateProfileString(0, 0, 0, g_tszMsdosSys);
}
/*****************************************************************************
*
* Boot_Apply
*
* Write the changes to the msdos.sys file.
*
*****************************************************************************/
BOOL PASCAL
Boot_Apply(HWND hdlg)
{
DWORD dwAttr = GetFileAttributes(g_tszMsdosSys);
if (dwAttr != 0xFFFFFFFF &&
SetFileAttributes(g_tszMsdosSys, FILE_ATTRIBUTE_NORMAL)) {
PMSIO pmsio;
for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
HWND hwnd = GetDlgItem(hdlg, pmsio->id);
if (hwnd) {
switch (pmsio->msiot) {
case msiotUint:
Boot_SetOptionUint(hdlg, pmsio);
break;
case msiotBool:
Boot_SetOptionBool(hdlg, pmsio);
break;
case msiotCombo:
Boot_SetOptionCombo(hdlg, pmsio);
break;
}
}
}
#ifdef BOOTMENUDEFAULT
Boot_WriteOptionUint(c_tszBootMenuDefault,
(UINT)SendDlgItemMessage(hdlg, IDC_BOOTMENUDEFAULT, CB_GETCURSEL,
0, 0L) + 1);
#endif
Boot_FlushIniCache();
SetFileAttributes(g_tszMsdosSys, dwAttr);
} else {
MessageBoxId(hdlg, IDS_ERRMSDOSSYS, g_tszName, MB_OK);
}
return 1;
}
/*****************************************************************************
*
* Boot_OnBootKeysChange
*
* When IDC_BOOTKEYS changes, enable or disable the boot delay,
* BootMulti, and BootMenu.
*
* NOTE: BootKeys is meaningless if BootMenu is on -- if you
* have the BootMenu enabled, then the menu just comes up even without
* pressing a key. Fortunately, nobody yet has complained about the
* interaction so I'm not gonna try to expose it in the UI.
*
*****************************************************************************/
void PASCAL
Boot_OnBootKeysChange(HWND hdlg)
{
BOOL f = IsDlgButtonChecked(hdlg, IDC_BOOTKEYS);
HWND hwnd;
hwnd = GetDlgItem(hdlg, IDC_BOOTDELAY);
if (hwnd) {
EnableWindow(hwnd, f);
}
EnableDlgItem(hdlg, IDC_BOOTMULTI, f);
EnableDlgItem(hdlg, IDC_BOOTMENU, f);
EnableDlgItem(hdlg, IDC_BOOTMENUDELAY, f);
}
/*****************************************************************************
*
* Boot_SetDlgOption
*
* Set the value of a dialog box item.
*
*****************************************************************************/
void PASCAL
Boot_SetDlgOption(HWND hdlg, PMSIO pmsio, UINT ui)
{
HWND hwnd = GetDlgItem(hdlg, pmsio->id);
if (hwnd) {
switch (pmsio->msiot) {
case msiotUint:
SetDlgItemInt(hdlg, pmsio->id, ui, 0);
break;
case msiotBool:
CheckDlgButton(hdlg, pmsio->id, ui);
break;
case msiotCombo:
ComboBox_SetCurSel(hwnd, ui);
}
}
}
/*****************************************************************************
*
* Boot_FactoryReset
*
* Restore to original factory settings.
*
* The weird one is IDC_BOOTLOGO, which
* varies depending on the system configuration.
*
*****************************************************************************/
BOOL PASCAL
Boot_FactoryReset(HWND hdlg)
{
PMSIO pmsio;
for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
Boot_SetDlgOption(hdlg, pmsio, pmsio->uiDefault);
}
CheckDlgButton(hdlg, IDC_LOGO, Boot_fLogo());
#ifdef BOOTMENUDEFAULT
SendDlgItemMessage(hdlg, IDC_BOOTMENUDEFAULT, CB_SETCURSEL,
(WPARAM)Boot_GetDefaultBootMenuDefault() - 1, 0L);
#endif
Boot_OnBootKeysChange(hdlg);
Common_SetDirty(hdlg);
return 1;
}
/*****************************************************************************
*
* Boot_OnCommand
*
* Ooh, we got a command.
*
*****************************************************************************/
BOOL PASCAL
Boot_OnCommand(HWND hdlg, int id, UINT codeNotify)
{
switch (id) {
case IDC_RESET: /* Reset to factory default */
if (codeNotify == BN_CLICKED) return Boot_FactoryReset(hdlg);
break;
case IDC_BOOTKEYS:
if (codeNotify == BN_CLICKED) Boot_OnBootKeysChange(hdlg);
/* FALLTHROUGH */
case IDC_BOOTGUI:
case IDC_BOOTMENU:
case IDC_LOGO:
case IDC_BOOTMULTI:
if (codeNotify == BN_CLICKED) Common_SetDirty(hdlg);
break;
case IDC_BOOTDELAY:
case IDC_BOOTMENUDELAY:
if (codeNotify == EN_CHANGE) Common_SetDirty(hdlg);
break;
#ifdef BOOTMENUDEFAULT
case IDC_BOOTMENUDEFAULT:
if (codeNotify == CBN_SELCHANGE) Common_SetDirty(hdlg);
break;
#endif
case IDC_SCANDISK:
if (codeNotify == CBN_SELCHANGE) Common_SetDirty(hdlg);
break;
}
return 0;
}
/*****************************************************************************
*
* Boot_OnNotify
*
* Ooh, we got a notification.
*
*****************************************************************************/
BOOL PASCAL
Boot_OnNotify(HWND hdlg, NMHDR FAR *pnm)
{
switch (pnm->code) {
case PSN_APPLY:
Boot_Apply(hdlg);
break;
}
return 0;
}
/*****************************************************************************
*
* Boot_InitDlgInt
*
* Initialize a paired edit control / updown control.
*
* hdlg is the dialog box itself.
*
* idc is the edit control identifier. It is assumed that idc+didcUd is
* the identifier for the updown control.
*
* iMin and iMax are the limits of the control.
*
*****************************************************************************/
void PASCAL
Boot_InitDlgInt(HWND hdlg, UINT idc, int iMin, int iMax)
{
HWND hwnd = GetDlgItem(hdlg, idc + didcEdit);
if (hwnd) {
Edit_LimitText(hwnd, 2);
SendDlgItemMessage(hdlg, idc+didcUd,
UDM_SETRANGE, 0, MAKELPARAM(iMax, iMin));
}
}
/*****************************************************************************
*
* Boot_OnInitDialog
*
* Initialize the controls.
*
*****************************************************************************/
BOOL NEAR PASCAL
Boot_OnInitDialog(HWND hdlg)
{
PMSIO pmsio;
HWND hwnd;
UINT dids;
TCH tsz[96];
/*
* Init the Scandisk gizmo. We need to do this even if not OPK2,
* so that we don't confuse the Apply. But show it only if OPK2.
*/
hwnd = GetDlgItem(hdlg, IDC_SCANDISK);
for (dids = 0; dids < 3; dids++) {
LoadString(hinstCur, IDS_SCANDISKFIRST + dids, tsz, cA(tsz));
ComboBox_AddString(hwnd, tsz);
}
if (g_fOPK2) {
ShowWindow(hwnd, 1);
ShowWindow(GetDlgItem(hdlg, IDC_SCANDISKTEXT), 1);
}
for (pmsio = rgmsio; pmsio < pmsioMax; pmsio++) {
Boot_SetDlgOption(hdlg, pmsio,
Boot_GetOption(pmsio->ptszName, pmsio->uiDefault));
}
#ifdef BOOTMENUDEFAULT
hwnd = GetDlgItem(hdlg, IDC_BOOTMENUDEFAULT);
for (ids = IDS_BOOTMENU; ids <= IDS_BOOTMENULAST; ids++) {
if (ids != IDS_BOOTMENUSAFENET || Boot_GetOption(c_tszNetwork, 0)) {
LoadString(hinstCur, ids, tsz, cA(tsz));
ComboBox_AddString(hwnd, tsz);
}
}
ComboBox_SetCurSel(hwnd, Boot_GetBootMenuDefault() - 1);
#endif
Boot_InitDlgInt(hdlg, IDC_BOOTDELAY, 0, 99);
Boot_InitDlgInt(hdlg, IDC_BOOTMENUDELAY, 0, 99);
Boot_OnBootKeysChange(hdlg);
if (g_fMemphis) {
DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYTEXT));
DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAY));
DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYUD));
DestroyWindow(GetDlgItem(hdlg, IDC_BOOTDELAYTEXT2));
}
return 1;
}
/*****************************************************************************
*
* Our window procedure.
*
*****************************************************************************/
/*
* The HANDLE_WM_* macros weren't designed to be used from a dialog
* proc, so we need to handle the messages manually. (But carefully.)
*/
INT_PTR EXPORT
Boot_DlgProc(HWND hdlg, UINT wm, WPARAM wParam, LPARAM lParam)
{
switch (wm) {
case WM_INITDIALOG: return Boot_OnInitDialog(hdlg);
case WM_COMMAND:
return Boot_OnCommand(hdlg,
(int)GET_WM_COMMAND_ID(wParam, lParam),
(UINT)GET_WM_COMMAND_CMD(wParam, lParam));
case WM_NOTIFY:
return Boot_OnNotify(hdlg, (NMHDR FAR *)lParam);
case WM_HELP: Common_OnHelp(lParam, &rgdwHelp[0]); break;
case WM_CONTEXTMENU: Common_OnContextMenu(wParam, &rgdwHelp[0]); break;
default: return 0; /* Unhandled */
}
return 1; /* Handled */
}
#endif // _X86_ only