WindowsXP-SP1/shell/shell32/pifmem.c

310 lines
11 KiB
C

// Created 04-Jan-1993 1:10pm by Jeff Parsons
#include "shellprv.h"
#pragma hdrstop
BINF abinfMem[] = {
{IDC_HMA, BITNUM(MEMINIT_NOHMA) | 0x80},
{IDC_GLOBALPROTECT, BITNUM(MEMINIT_GLOBALPROTECT) },
};
VINF avinfMem[] = {
{FIELD_OFFSET(PROPMEM,wMinLow), VINF_AUTOMINMAX, IDC_LOWMEM, MEMLOW_MIN, MEMLOW_MAX, IDS_BAD_MEMLOW},
{FIELD_OFFSET(PROPMEM,wMinEMS), VINF_AUTOMINMAX, IDC_EMSMEM, MEMEMS_MIN, MEMEMS_MAX, IDS_BAD_MEMEMS},
{FIELD_OFFSET(PROPMEM,wMinXMS), VINF_AUTOMINMAX, IDC_XMSMEM, MEMXMS_MIN, MEMXMS_MAX, IDS_BAD_MEMXMS},
};
VINF avinfEnvMem[] = {
{FIELD_OFFSET(PROPENV,cbEnvironment), VINF_AUTO, IDC_ENVMEM, ENVSIZE_MIN, ENVSIZE_MAX, IDS_BAD_ENVIRONMENT},
{FIELD_OFFSET(PROPENV,wMaxDPMI), VINF_AUTO, IDC_DPMIMEM, ENVDPMI_MIN, ENVDPMI_MAX, IDS_BAD_MEMDPMI},
};
// Per-dialog data
#define MEMINFO_RELAUNCH 0x0001 // relaunch required to take effect
#define EMS_NOEMS 0x0001 // EMS no supported in protmode
#define EMS_EMM386 0x0002 // EM386 is installed
#define EMS_QEMM 0x0004 // Third-party mmgr installed
#define EMS_RMPAGEFRAME 0x0008 // Page frame present in real mode
#define EMS_SYSINIDISABLE 0x0010 // EMS forced off by system.ini
typedef struct MEMINFO { /* mi */
PPROPLINK ppl; // pointer to property info
DWORD flMemInfo; // initially zero thx to LocalAlloc(LPTR)
DWORD flEms; // EMS support flags
} MEMINFO;
typedef MEMINFO *PMEMINFO; /* pmi */
// Private function prototypes
BOOL GetSetMemProps(HWND hDlg, GETSETFN lpfn, PPROPLINK ppl, LPPROPMEM lpmem, LPPROPENV lpenv, int idError);
void InitMemDlg(HWND hDlg, PMEMINFO pmi);
void ApplyMemDlg(HWND hDlg, PMEMINFO pmi);
void AdjustEmsControls(HWND hDlg, PMEMINFO pmi);
void ExplainNoEms(HWND hDlg, PMEMINFO pmi);
// Context-sensitive help ids
const static DWORD rgdwHelp[] = {
IDC_CONVMEMLBL, IDH_DOS_MEMORY_CONV,
IDC_LOWMEM, IDH_DOS_MEMORY_CONV,
IDC_GLOBALPROTECT, IDH_DOS_MEMORY_CONV_GLOBAL,
IDC_EXPMEMGRP, IDH_COMM_GROUPBOX,
IDC_EXPMEMLBL, IDH_DOS_MEMORY_EXP,
IDC_EMSMEM, IDH_DOS_MEMORY_EXP,
IDC_EXTMEMGRP, IDH_COMM_GROUPBOX,
IDC_XMSMEM, IDH_DOS_MEMORY_EXT,
IDC_EXTMEMLBL, IDH_DOS_MEMORY_EXT,
IDC_DPMIMEMGRP, IDH_COMM_GROUPBOX,
IDC_DPMIMEM, IDH_DOS_MEMORY_DPMI,
IDC_DPMIMEMLBL, IDH_DOS_MEMORY_DPMI,
IDC_HMA, IDH_DOS_MEMORY_EXT_HMA,
IDC_CONVMEMGRP, IDH_COMM_GROUPBOX,
IDC_LOCALENVLBL, IDH_DOS_PROGRAM_ENVIRSZ,
IDC_ENVMEM, IDH_DOS_PROGRAM_ENVIRSZ,
IDC_REALMODEDISABLE, IDH_DOS_REALMODEPROPS,
IDC_NOEMSDETAILS, IDH_DOS_MEMORY_NOEMS_DETAILS,
0, 0
};
BOOL_PTR CALLBACK DlgMemProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fError;
PMEMINFO pmi;
FunctionName(DlgMemProc);
pmi = (PMEMINFO)GetWindowLongPtr(hDlg, DWLP_USER);
switch (uMsg) {
case WM_INITDIALOG:
// allocate dialog instance data
if (NULL != (pmi = (PMEMINFO)LocalAlloc(LPTR, SIZEOF(MEMINFO)))) {
pmi->ppl = (PPROPLINK)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pmi);
InitMemDlg(hDlg, pmi);
} else {
EndDialog(hDlg, FALSE); // fail the dialog create
}
break;
case WM_DESTROY:
// free the pmi
if (pmi) {
EVAL(LocalFree(pmi) == NULL);
SetWindowLongPtr(hDlg, DWLP_USER, 0);
}
break;
HELP_CASES(rgdwHelp) // Handle help messages
case WM_COMMAND:
if (LOWORD(lParam) == 0)
break; // message not from a control
switch (LOWORD(wParam)) {
case IDC_ENVMEM:
case IDC_LOWMEM:
case IDC_EMSMEM:
case IDC_XMSMEM:
case IDC_DPMIMEM:
if (HIWORD(wParam) == CBN_SELCHANGE ||
HIWORD(wParam) == CBN_EDITCHANGE) {
SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
pmi->flMemInfo |= MEMINFO_RELAUNCH;
}
break;
case IDC_HMA:
case IDC_GLOBALPROTECT:
if (HIWORD(wParam) == BN_CLICKED) {
SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
if (LOWORD(wParam) != IDC_GLOBALPROTECT)
pmi->flMemInfo |= MEMINFO_RELAUNCH;
}
break;
case IDC_NOEMSDETAILS:
if (HIWORD(wParam) == BN_CLICKED) {
ExplainNoEms(hDlg, pmi);
}
return FALSE; // return 0 if we process WM_COMMAND
}
break;
case WM_NOTIFY:
switch (((NMHDR *)lParam)->code) {
case PSN_SETACTIVE:
AdjustRealModeControls(pmi->ppl, hDlg);
AdjustEmsControls(hDlg, pmi);
// make sure DWL_MSGRESULT is zero,
// otherwise the prsht code thinks we
// "failed" this notify and switches
// to another (sometimes random) page -JTP
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
break;
case PSN_KILLACTIVE:
// This gives the current page a chance to validate itself
fError = ValidateDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem));
fError |= ValidateDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem));
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, fError);
break;
case PSN_APPLY:
// This happens on OK....
ApplyMemDlg(hDlg, pmi);
break;
case PSN_RESET:
// This happens on Cancel....
break;
}
break;
default:
return FALSE; // return 0 when not processing
}
return TRUE;
}
BOOL GetSetMemProps(HWND hDlg, GETSETFN lpfn, PPROPLINK ppl, LPPROPMEM lpmem, LPPROPENV lpenv, int idError)
{
if (!(*lpfn)(ppl, MAKELP(0,GROUP_MEM),
lpmem, SIZEOF(*lpmem), GETPROPS_NONE) ||
!(*lpfn)(ppl, MAKELP(0,GROUP_ENV),
lpenv, SIZEOF(*lpenv), GETPROPS_NONE)) {
Warning(hDlg, (WORD)idError, (WORD)MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
return TRUE;
}
void InitMemDlg(HWND hDlg, PMEMINFO pmi)
{
PROPMEM mem;
PROPENV env;
PPROPLINK ppl = pmi->ppl;
FunctionName(InitMemDlg);
if (!GetSetMemProps(hDlg, PifMgr_GetProperties, ppl, &mem, &env, IDS_QUERY_ERROR))
return;
SetDlgBits(hDlg, abinfMem, ARRAYSIZE(abinfMem), mem.flMemInit);
SetDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem), (LPVOID)&mem);
SetDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem), (LPVOID)&env);
/* Disallow "None" as a valid setting for "Conventional memory" */
SendDlgItemMessage(hDlg, IDC_LOWMEM, CB_DELETESTRING,
(WPARAM)SendDlgItemMessage(hDlg, IDC_LOWMEM, CB_FINDSTRING,
(WPARAM)-1, (LPARAM)(LPTSTR)g_szNone), 0L);
pmi->flEms = (EMS_EMM386 | EMS_RMPAGEFRAME);
AdjustEmsControls(hDlg, pmi);
}
void ApplyMemDlg(HWND hDlg, PMEMINFO pmi)
{
PROPMEM mem;
PROPENV env;
PPROPLINK ppl = pmi->ppl;
FunctionName(ApplyMemDlg);
if (!GetSetMemProps(hDlg, PifMgr_GetProperties, ppl, &mem, &env, IDS_UPDATE_ERROR))
return;
GetDlgBits(hDlg, abinfMem, ARRAYSIZE(abinfMem), &mem.flMemInit);
GetDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem), (LPVOID)&mem);
GetDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem), (LPVOID)&env);
if (GetSetMemProps(hDlg, PifMgr_SetProperties, ppl, &mem, &env, IDS_UPDATE_ERROR)) {
if (ppl->hwndNotify) {
ppl->flProp |= PROP_NOTIFY;
PostMessage(ppl->hwndNotify, ppl->uMsgNotify, SIZEOF(mem), (LPARAM)MAKELP(0,GROUP_MEM));
PostMessage(ppl->hwndNotify, ppl->uMsgNotify, SIZEOF(env), (LPARAM)MAKELP(0,GROUP_ENV));
}
if (ppl->hVM && (pmi->flMemInfo & MEMINFO_RELAUNCH)) {
pmi->flMemInfo &= ~MEMINFO_RELAUNCH;
Warning(hDlg, IDS_MEMORY_RELAUNCH, MB_ICONWARNING | MB_OK);
}
}
}
void HideAndDisable(HWND hwnd)
{
ShowWindow(hwnd, SW_HIDE);
EnableWindow(hwnd, FALSE);
}
void AdjustEmsControls(HWND hDlg, PMEMINFO pmi)
{
if (!(pmi->ppl->flProp & PROP_REALMODE)) {
/*
* When not marked as PROP_REALMODE, all the EMS-related controls
* are visible. We need to choose which set to disable.
*
* We cheat, because we know that there are only two controls
* in both cases, and they come right after each other.
*/
UINT uiHide;
if (pmi->flEms & EMS_NOEMS) {
uiHide = IDC_EXPMEMLBL;
CTASSERTF(IDC_EXPMEMLBL + 1 == IDC_EMSMEM);
} else {
uiHide = IDC_NOEMS;
CTASSERTF(IDC_NOEMS + 1 == IDC_NOEMSDETAILS);
}
HideAndDisable(GetDlgItem(hDlg, uiHide));
HideAndDisable(GetDlgItem(hDlg, uiHide+1));
}
}
void ExplainNoEms(HWND hDlg, PMEMINFO pmi)
{
WORD idsHelp;
TCHAR szMsg[MAX_STRING_SIZE];
/*
* Here is where we stare at all the bits to try to figure
* out what recommendation to make.
*/
ASSERTTRUE(pmi->flEms & EMS_NOEMS);
if (pmi->flEms & EMS_SYSINIDISABLE) {
/*
* System.ini contains the line NOEMMDRIVER=1.
*/
idsHelp = IDS_SYSINI_NOEMS;
} else if (pmi->flEms & EMS_RMPAGEFRAME) {
/*
* Had page-frame in real mode, which means that some protmode
* guy must've messed it up.
*/
idsHelp = IDS_RING0_NOEMS;
} else if (pmi->flEms & EMS_EMM386) {
/*
* No page-frame in real mode, and EMM386 was in charge,
* so it's EMM386's fault.
*/
idsHelp = IDS_EMM386_NOEMS;
} else {
/*
* No page-frame in real mode, and QEMM was in charge,
* so it's QEMM's fault.
*/
idsHelp = IDS_QEMM_NOEMS;
}
if (LoadStringSafe(hDlg, idsHelp+1, szMsg, ARRAYSIZE(szMsg))) {
Warning(hDlg, idsHelp, MB_OK, (LPCTSTR)szMsg);
}
}