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.

309 lines
10 KiB

  1. // Created 04-Jan-1993 1:10pm by Jeff Parsons
  2. #include "shellprv.h"
  3. #pragma hdrstop
  4. BINF abinfMem[] = {
  5. {IDC_HMA, BITNUM(MEMINIT_NOHMA) | 0x80},
  6. {IDC_GLOBALPROTECT, BITNUM(MEMINIT_GLOBALPROTECT) },
  7. };
  8. VINF avinfMem[] = {
  9. {FIELD_OFFSET(PROPMEM,wMinLow), VINF_AUTOMINMAX, IDC_LOWMEM, MEMLOW_MIN, MEMLOW_MAX, IDS_BAD_MEMLOW},
  10. {FIELD_OFFSET(PROPMEM,wMinEMS), VINF_AUTOMINMAX, IDC_EMSMEM, MEMEMS_MIN, MEMEMS_MAX, IDS_BAD_MEMEMS},
  11. {FIELD_OFFSET(PROPMEM,wMinXMS), VINF_AUTOMINMAX, IDC_XMSMEM, MEMXMS_MIN, MEMXMS_MAX, IDS_BAD_MEMXMS},
  12. };
  13. VINF avinfEnvMem[] = {
  14. {FIELD_OFFSET(PROPENV,cbEnvironment), VINF_AUTO, IDC_ENVMEM, ENVSIZE_MIN, ENVSIZE_MAX, IDS_BAD_ENVIRONMENT},
  15. {FIELD_OFFSET(PROPENV,wMaxDPMI), VINF_AUTO, IDC_DPMIMEM, ENVDPMI_MIN, ENVDPMI_MAX, IDS_BAD_MEMDPMI},
  16. };
  17. // Per-dialog data
  18. #define MEMINFO_RELAUNCH 0x0001 // relaunch required to take effect
  19. #define EMS_NOEMS 0x0001 // EMS no supported in protmode
  20. #define EMS_EMM386 0x0002 // EM386 is installed
  21. #define EMS_QEMM 0x0004 // Third-party mmgr installed
  22. #define EMS_RMPAGEFRAME 0x0008 // Page frame present in real mode
  23. #define EMS_SYSINIDISABLE 0x0010 // EMS forced off by system.ini
  24. typedef struct MEMINFO { /* mi */
  25. PPROPLINK ppl; // pointer to property info
  26. DWORD flMemInfo; // initially zero thx to LocalAlloc(LPTR)
  27. DWORD flEms; // EMS support flags
  28. } MEMINFO;
  29. typedef MEMINFO *PMEMINFO; /* pmi */
  30. // Private function prototypes
  31. BOOL GetSetMemProps(HWND hDlg, GETSETFN lpfn, PPROPLINK ppl, LPPROPMEM lpmem, LPPROPENV lpenv, int idError);
  32. void InitMemDlg(HWND hDlg, PMEMINFO pmi);
  33. void ApplyMemDlg(HWND hDlg, PMEMINFO pmi);
  34. void AdjustEmsControls(HWND hDlg, PMEMINFO pmi);
  35. void ExplainNoEms(HWND hDlg, PMEMINFO pmi);
  36. // Context-sensitive help ids
  37. const static DWORD rgdwHelp[] = {
  38. IDC_CONVMEMLBL, IDH_DOS_MEMORY_CONV,
  39. IDC_LOWMEM, IDH_DOS_MEMORY_CONV,
  40. IDC_GLOBALPROTECT, IDH_DOS_MEMORY_CONV_GLOBAL,
  41. IDC_EXPMEMGRP, IDH_COMM_GROUPBOX,
  42. IDC_EXPMEMLBL, IDH_DOS_MEMORY_EXP,
  43. IDC_EMSMEM, IDH_DOS_MEMORY_EXP,
  44. IDC_EXTMEMGRP, IDH_COMM_GROUPBOX,
  45. IDC_XMSMEM, IDH_DOS_MEMORY_EXT,
  46. IDC_EXTMEMLBL, IDH_DOS_MEMORY_EXT,
  47. IDC_DPMIMEMGRP, IDH_COMM_GROUPBOX,
  48. IDC_DPMIMEM, IDH_DOS_MEMORY_DPMI,
  49. IDC_DPMIMEMLBL, IDH_DOS_MEMORY_DPMI,
  50. IDC_HMA, IDH_DOS_MEMORY_EXT_HMA,
  51. IDC_CONVMEMGRP, IDH_COMM_GROUPBOX,
  52. IDC_LOCALENVLBL, IDH_DOS_PROGRAM_ENVIRSZ,
  53. IDC_ENVMEM, IDH_DOS_PROGRAM_ENVIRSZ,
  54. IDC_REALMODEDISABLE, IDH_DOS_REALMODEPROPS,
  55. IDC_NOEMSDETAILS, IDH_DOS_MEMORY_NOEMS_DETAILS,
  56. 0, 0
  57. };
  58. BOOL_PTR CALLBACK DlgMemProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  59. {
  60. BOOL fError;
  61. PMEMINFO pmi;
  62. FunctionName(DlgMemProc);
  63. pmi = (PMEMINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  64. switch (uMsg) {
  65. case WM_INITDIALOG:
  66. // allocate dialog instance data
  67. if (NULL != (pmi = (PMEMINFO)LocalAlloc(LPTR, SIZEOF(MEMINFO)))) {
  68. pmi->ppl = (PPROPLINK)((LPPROPSHEETPAGE)lParam)->lParam;
  69. SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pmi);
  70. InitMemDlg(hDlg, pmi);
  71. } else {
  72. EndDialog(hDlg, FALSE); // fail the dialog create
  73. }
  74. break;
  75. case WM_DESTROY:
  76. // free the pmi
  77. if (pmi) {
  78. EVAL(LocalFree(pmi) == NULL);
  79. SetWindowLongPtr(hDlg, DWLP_USER, 0);
  80. }
  81. break;
  82. HELP_CASES(rgdwHelp) // Handle help messages
  83. case WM_COMMAND:
  84. if (LOWORD(lParam) == 0)
  85. break; // message not from a control
  86. switch (LOWORD(wParam)) {
  87. case IDC_ENVMEM:
  88. case IDC_LOWMEM:
  89. case IDC_EMSMEM:
  90. case IDC_XMSMEM:
  91. case IDC_DPMIMEM:
  92. if (HIWORD(wParam) == CBN_SELCHANGE ||
  93. HIWORD(wParam) == CBN_EDITCHANGE) {
  94. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  95. pmi->flMemInfo |= MEMINFO_RELAUNCH;
  96. }
  97. break;
  98. case IDC_HMA:
  99. case IDC_GLOBALPROTECT:
  100. if (HIWORD(wParam) == BN_CLICKED) {
  101. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  102. if (LOWORD(wParam) != IDC_GLOBALPROTECT)
  103. pmi->flMemInfo |= MEMINFO_RELAUNCH;
  104. }
  105. break;
  106. case IDC_NOEMSDETAILS:
  107. if (HIWORD(wParam) == BN_CLICKED) {
  108. ExplainNoEms(hDlg, pmi);
  109. }
  110. return FALSE; // return 0 if we process WM_COMMAND
  111. }
  112. break;
  113. case WM_NOTIFY:
  114. switch (((NMHDR *)lParam)->code) {
  115. case PSN_SETACTIVE:
  116. AdjustRealModeControls(pmi->ppl, hDlg);
  117. AdjustEmsControls(hDlg, pmi);
  118. // make sure DWL_MSGRESULT is zero,
  119. // otherwise the prsht code thinks we
  120. // "failed" this notify and switches
  121. // to another (sometimes random) page -JTP
  122. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
  123. break;
  124. case PSN_KILLACTIVE:
  125. // This gives the current page a chance to validate itself
  126. fError = ValidateDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem));
  127. fError |= ValidateDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem));
  128. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, fError);
  129. break;
  130. case PSN_APPLY:
  131. // This happens on OK....
  132. ApplyMemDlg(hDlg, pmi);
  133. break;
  134. case PSN_RESET:
  135. // This happens on Cancel....
  136. break;
  137. }
  138. break;
  139. default:
  140. return FALSE; // return 0 when not processing
  141. }
  142. return TRUE;
  143. }
  144. BOOL GetSetMemProps(HWND hDlg, GETSETFN lpfn, PPROPLINK ppl, LPPROPMEM lpmem, LPPROPENV lpenv, int idError)
  145. {
  146. if (!(*lpfn)(ppl, MAKELP(0,GROUP_MEM),
  147. lpmem, SIZEOF(*lpmem), GETPROPS_NONE) ||
  148. !(*lpfn)(ppl, MAKELP(0,GROUP_ENV),
  149. lpenv, SIZEOF(*lpenv), GETPROPS_NONE)) {
  150. Warning(hDlg, (WORD)idError, (WORD)MB_ICONEXCLAMATION | MB_OK);
  151. return FALSE;
  152. }
  153. return TRUE;
  154. }
  155. void InitMemDlg(HWND hDlg, PMEMINFO pmi)
  156. {
  157. PROPMEM mem;
  158. PROPENV env;
  159. PPROPLINK ppl = pmi->ppl;
  160. FunctionName(InitMemDlg);
  161. if (!GetSetMemProps(hDlg, PifMgr_GetProperties, ppl, &mem, &env, IDS_QUERY_ERROR))
  162. return;
  163. SetDlgBits(hDlg, abinfMem, ARRAYSIZE(abinfMem), mem.flMemInit);
  164. SetDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem), (LPVOID)&mem);
  165. SetDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem), (LPVOID)&env);
  166. /* Disallow "None" as a valid setting for "Conventional memory" */
  167. SendDlgItemMessage(hDlg, IDC_LOWMEM, CB_DELETESTRING,
  168. (WPARAM)SendDlgItemMessage(hDlg, IDC_LOWMEM, CB_FINDSTRING,
  169. (WPARAM)-1, (LPARAM)(LPTSTR)g_szNone), 0L);
  170. pmi->flEms = (EMS_EMM386 | EMS_RMPAGEFRAME);
  171. AdjustEmsControls(hDlg, pmi);
  172. }
  173. void ApplyMemDlg(HWND hDlg, PMEMINFO pmi)
  174. {
  175. PROPMEM mem;
  176. PROPENV env;
  177. PPROPLINK ppl = pmi->ppl;
  178. FunctionName(ApplyMemDlg);
  179. if (!GetSetMemProps(hDlg, PifMgr_GetProperties, ppl, &mem, &env, IDS_UPDATE_ERROR))
  180. return;
  181. GetDlgBits(hDlg, abinfMem, ARRAYSIZE(abinfMem), &mem.flMemInit);
  182. GetDlgInts(hDlg, avinfMem, ARRAYSIZE(avinfMem), (LPVOID)&mem);
  183. GetDlgInts(hDlg, avinfEnvMem, ARRAYSIZE(avinfEnvMem), (LPVOID)&env);
  184. if (GetSetMemProps(hDlg, PifMgr_SetProperties, ppl, &mem, &env, IDS_UPDATE_ERROR)) {
  185. if (ppl->hwndNotify) {
  186. ppl->flProp |= PROP_NOTIFY;
  187. PostMessage(ppl->hwndNotify, ppl->uMsgNotify, SIZEOF(mem), (LPARAM)MAKELP(0,GROUP_MEM));
  188. PostMessage(ppl->hwndNotify, ppl->uMsgNotify, SIZEOF(env), (LPARAM)MAKELP(0,GROUP_ENV));
  189. }
  190. if (ppl->hVM && (pmi->flMemInfo & MEMINFO_RELAUNCH)) {
  191. pmi->flMemInfo &= ~MEMINFO_RELAUNCH;
  192. Warning(hDlg, IDS_MEMORY_RELAUNCH, MB_ICONWARNING | MB_OK);
  193. }
  194. }
  195. }
  196. void HideAndDisable(HWND hwnd)
  197. {
  198. ShowWindow(hwnd, SW_HIDE);
  199. EnableWindow(hwnd, FALSE);
  200. }
  201. void AdjustEmsControls(HWND hDlg, PMEMINFO pmi)
  202. {
  203. if (!(pmi->ppl->flProp & PROP_REALMODE)) {
  204. /*
  205. * When not marked as PROP_REALMODE, all the EMS-related controls
  206. * are visible. We need to choose which set to disable.
  207. *
  208. * We cheat, because we know that there are only two controls
  209. * in both cases, and they come right after each other.
  210. */
  211. UINT uiHide;
  212. if (pmi->flEms & EMS_NOEMS) {
  213. uiHide = IDC_EXPMEMLBL;
  214. CTASSERTF(IDC_EXPMEMLBL + 1 == IDC_EMSMEM);
  215. } else {
  216. uiHide = IDC_NOEMS;
  217. CTASSERTF(IDC_NOEMS + 1 == IDC_NOEMSDETAILS);
  218. }
  219. HideAndDisable(GetDlgItem(hDlg, uiHide));
  220. HideAndDisable(GetDlgItem(hDlg, uiHide+1));
  221. }
  222. }
  223. void ExplainNoEms(HWND hDlg, PMEMINFO pmi)
  224. {
  225. WORD idsHelp;
  226. TCHAR szMsg[MAX_STRING_SIZE];
  227. /*
  228. * Here is where we stare at all the bits to try to figure
  229. * out what recommendation to make.
  230. */
  231. ASSERTTRUE(pmi->flEms & EMS_NOEMS);
  232. if (pmi->flEms & EMS_SYSINIDISABLE) {
  233. /*
  234. * System.ini contains the line NOEMMDRIVER=1.
  235. */
  236. idsHelp = IDS_SYSINI_NOEMS;
  237. } else if (pmi->flEms & EMS_RMPAGEFRAME) {
  238. /*
  239. * Had page-frame in real mode, which means that some protmode
  240. * guy must've messed it up.
  241. */
  242. idsHelp = IDS_RING0_NOEMS;
  243. } else if (pmi->flEms & EMS_EMM386) {
  244. /*
  245. * No page-frame in real mode, and EMM386 was in charge,
  246. * so it's EMM386's fault.
  247. */
  248. idsHelp = IDS_EMM386_NOEMS;
  249. } else {
  250. /*
  251. * No page-frame in real mode, and QEMM was in charge,
  252. * so it's QEMM's fault.
  253. */
  254. idsHelp = IDS_QEMM_NOEMS;
  255. }
  256. if (LoadStringSafe(hDlg, idsHelp+1, szMsg, ARRAYSIZE(szMsg))) {
  257. Warning(hDlg, idsHelp, MB_OK, (LPCTSTR)szMsg);
  258. }
  259. }