Leaked source code of windows server 2003
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.

896 lines
26 KiB

  1. /*++
  2. Copyright (c) 1992-2002 Microsoft Corporation
  3. Module Name:
  4. Memwin.cpp
  5. Abstract:
  6. This module contains the main line code for display of multiple memory
  7. windows and the subclassed win proc to handle editing, display, etc.
  8. --*/
  9. #include "precomp.hxx"
  10. #pragma hdrstop
  11. _INTERFACE_TYPE_NAMES rgInterfaceTypeNames[MaximumInterfaceType] =
  12. {
  13. { Internal, "Internal" },
  14. { Isa, "Isa" },
  15. { Eisa, "Eisa" },
  16. { MicroChannel, "MicroChannel" },
  17. { TurboChannel, "TurboChannel" },
  18. { PCIBus, "PCIBus" },
  19. { VMEBus, "VMEBus" },
  20. { NuBus, "NuBus" },
  21. { PCMCIABus, "PCMCIABus" },
  22. { CBus, "CBus" },
  23. { MPIBus, "MPIBus" },
  24. { MPSABus, "MPSABus" },
  25. { ProcessorInternal, "ProcessorInternal" },
  26. { InternalPowerBus, "InternalPowerBus" },
  27. { PNPISABus, "PNPISABus" },
  28. { PNPBus, "PNPBus" }
  29. };
  30. _BUS_TYPE_NAMES rgBusTypeNames[MaximumBusDataType] =
  31. {
  32. { Cmos, "Cmos" },
  33. { EisaConfiguration, "EisaConfiguration" },
  34. { Pos, "Pos" },
  35. { CbusConfiguration, "CbusConfiguration" },
  36. { PCIConfiguration, "PCIConfiguration" },
  37. { VMEConfiguration, "VMEConfiguration" },
  38. { NuBusConfiguration, "NuBusConfiguration" },
  39. { PCMCIAConfiguration, "PCMCIAConfiguration" },
  40. { MPIConfiguration, "MPIConfiguration" },
  41. { MPSAConfiguration, "MPSAConfiguration" },
  42. { PNPISAConfiguration, "PNPISAConfiguration" },
  43. { SgiInternalConfiguration, "SgiInternalConfiguration" }
  44. };
  45. PSTR g_MemTypeNames[] =
  46. {
  47. "Virtual:", "Physical:", "Control:", "I/O:", "MSR:", "Bus data:"
  48. };
  49. //
  50. //
  51. //
  52. MEMWIN_DATA::MEMWIN_DATA()
  53. : EDITWIN_DATA(512)
  54. {
  55. m_enumType = MEM_WINDOW;
  56. ZeroMemory(&m_GenMemData, sizeof(m_GenMemData));
  57. strcpy(m_OffsetExpr, FormatAddr64(g_EventIp));
  58. m_GenMemData.memtype = VIRTUAL_MEM_TYPE;
  59. m_GenMemData.nDisplayFormat = 3;
  60. m_Columns = 4;
  61. m_WindowDataSize = 0;
  62. }
  63. void
  64. MEMWIN_DATA::Validate()
  65. {
  66. EDITWIN_DATA::Validate();
  67. Assert(MEM_WINDOW == m_enumType);
  68. }
  69. HRESULT
  70. MEMWIN_DATA::ReadState(void)
  71. {
  72. HRESULT Status;
  73. ULONG DataNeeded;
  74. PVOID Data;
  75. ULONG64 Offset;
  76. DEBUG_VALUE Value;
  77. ULONG i;
  78. // Evaluate offset expression.
  79. if ((Status = g_pDbgControl->Evaluate(m_OffsetExpr, DEBUG_VALUE_INT64,
  80. &Value, NULL)) != S_OK)
  81. {
  82. return Status;
  83. }
  84. Offset = Value.I64;
  85. // Compute how much data to retrieve. We don't want to
  86. // create a big matrix of memtype/display format so just
  87. // ask for a chunk of data big enough for any display format.
  88. DataNeeded = m_LineHeight * m_Columns * 2 * sizeof(ULONG64);
  89. Empty();
  90. Data = AddData(DataNeeded);
  91. if (Data == NULL)
  92. {
  93. return E_OUTOFMEMORY;
  94. }
  95. ULONG Read;
  96. switch(m_GenMemData.memtype)
  97. {
  98. default:
  99. Assert(!"Unhandled condition");
  100. Status = E_FAIL;
  101. break;
  102. case PHYSICAL_MEM_TYPE:
  103. Status = g_pDbgData->ReadPhysical(Offset,
  104. Data,
  105. DataNeeded,
  106. &Read
  107. );
  108. break;
  109. case VIRTUAL_MEM_TYPE:
  110. Status = g_pDbgData->ReadVirtual(Offset,
  111. Data,
  112. DataNeeded,
  113. &Read
  114. );
  115. break;
  116. case CONTROL_MEM_TYPE:
  117. Status = g_pDbgData->ReadControl(m_GenMemData.any.control.Processor,
  118. Offset,
  119. Data,
  120. DataNeeded,
  121. &Read
  122. );
  123. break;
  124. case IO_MEM_TYPE:
  125. Status = g_pDbgData->ReadIo(m_GenMemData.any.io.interface_type,
  126. m_GenMemData.any.io.BusNumber,
  127. m_GenMemData.any.io.AddressSpace,
  128. Offset,
  129. Data,
  130. DataNeeded,
  131. &Read
  132. );
  133. break;
  134. case MSR_MEM_TYPE:
  135. Read = 0;
  136. for (i = 0; i < DataNeeded / sizeof(ULONG64); i++)
  137. {
  138. if ((Status = g_pDbgData->ReadMsr((ULONG)Offset + i,
  139. (PULONG64)Data + i
  140. )) != S_OK)
  141. {
  142. // Assume an error means we've run out of MSRs to
  143. // read. If some were read, don't consider it an error.
  144. if (Read > 0)
  145. {
  146. Status = S_OK;
  147. }
  148. break;
  149. }
  150. Read += sizeof(ULONG64);
  151. }
  152. break;
  153. case BUS_MEM_TYPE:
  154. Status = g_pDbgData->ReadBusData(m_GenMemData.any.bus.bus_type,
  155. m_GenMemData.any.bus.BusNumber,
  156. m_GenMemData.any.bus.SlotNumber,
  157. (ULONG)Offset,
  158. Data,
  159. DataNeeded,
  160. &Read
  161. );
  162. break;
  163. }
  164. if (Status == S_OK)
  165. {
  166. // Trim data back if read didn't get everything.
  167. RemoveTail(DataNeeded - Read);
  168. m_OffsetRead = Offset;
  169. }
  170. return Status;
  171. }
  172. BOOL
  173. MEMWIN_DATA::HasEditableProperties()
  174. {
  175. return TRUE;
  176. }
  177. BOOL
  178. MEMWIN_DATA::EditProperties()
  179. /*++
  180. Returns
  181. TRUE - If properties were edited
  182. FALSE - If nothing was changed
  183. --*/
  184. {
  185. if (g_TargetClass != DEBUG_CLASS_UNINITIALIZED)
  186. {
  187. INT_PTR Res = DisplayOptionsPropSheet(GetParent(m_hwndChild),
  188. g_hInst,
  189. m_GenMemData.memtype
  190. );
  191. if (IDOK == Res)
  192. {
  193. UpdateOptions();
  194. return TRUE; // Properties have been changed
  195. }
  196. }
  197. MessageBeep(0);
  198. return FALSE; // No Debuggee or User Cancel out.
  199. }
  200. BOOL
  201. MEMWIN_DATA::OnCreate(void)
  202. {
  203. RECT Rect;
  204. int i;
  205. ULONG Height;
  206. Height = GetSystemMetrics(SM_CYVSCROLL) + 4 * GetSystemMetrics(SM_CYEDGE);
  207. m_Toolbar = CreateWindowEx(0, REBARCLASSNAME, NULL,
  208. WS_VISIBLE | WS_CHILD |
  209. WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  210. CCS_NODIVIDER | CCS_NOPARENTALIGN |
  211. RBS_VARHEIGHT | RBS_BANDBORDERS,
  212. 0, 0, m_Size.cx, Height, m_Win,
  213. (HMENU)ID_TOOLBAR,
  214. g_hInst, NULL);
  215. if (m_Toolbar == NULL)
  216. {
  217. return FALSE;
  218. }
  219. REBARINFO BarInfo;
  220. BarInfo.cbSize = sizeof(BarInfo);
  221. BarInfo.fMask = 0;
  222. BarInfo.himl = NULL;
  223. SendMessage(m_Toolbar, RB_SETBARINFO, 0, (LPARAM)&BarInfo);
  224. REBARBANDINFO BandInfo;
  225. BandInfo.cbSize = sizeof(BandInfo);
  226. BandInfo.fMask = RBBIM_TEXT | RBBIM_CHILD | RBBIM_CHILDSIZE;
  227. m_ToolbarEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL,
  228. WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL,
  229. 0, 0, 18 *
  230. m_Font->Metrics.tmAveCharWidth,
  231. Height, m_Toolbar, (HMENU)IDC_EDIT_OFFSET,
  232. g_hInst, NULL);
  233. if (m_ToolbarEdit == NULL)
  234. {
  235. return FALSE;
  236. }
  237. SendMessage(m_ToolbarEdit, WM_SETFONT, (WPARAM)m_Font->Font, 0);
  238. SendMessage(m_ToolbarEdit, EM_LIMITTEXT, sizeof(m_OffsetExpr) - 1, 0);
  239. GetClientRect(m_ToolbarEdit, &Rect);
  240. BandInfo.lpText = "Offset:";
  241. BandInfo.hwndChild = m_ToolbarEdit;
  242. BandInfo.cxMinChild = Rect.right - Rect.left;
  243. BandInfo.cyMinChild = Rect.bottom - Rect.top;
  244. SendMessage(m_Toolbar, RB_INSERTBAND, -1, (LPARAM)&BandInfo);
  245. m_FormatCombo = CreateWindowEx(0, "COMBOBOX", NULL,
  246. WS_VISIBLE | WS_CHILD | WS_VSCROLL |
  247. CBS_SORT | CBS_DROPDOWNLIST, 0, 0,
  248. 15 * m_Font->Metrics.tmAveCharWidth,
  249. (g_nMaxNumFormatsMemWin *
  250. m_Font->Metrics.tmHeight / 2),
  251. m_Toolbar, (HMENU)IDC_COMBO_DISPLAY_FORMAT,
  252. g_hInst, NULL);
  253. if (m_FormatCombo == NULL)
  254. {
  255. return FALSE;
  256. }
  257. SendMessage(m_FormatCombo, WM_SETFONT, (WPARAM)m_Font->Font, 0);
  258. for (i = 0; i < g_nMaxNumFormatsMemWin; i++)
  259. {
  260. LRESULT Idx;
  261. // The format strings will be sorted so mark them with
  262. // their true index for retrieval when selected.
  263. Idx = SendMessage(m_FormatCombo, CB_ADDSTRING,
  264. 0, (LPARAM)g_FormatsMemWin[i].lpszDescription);
  265. SendMessage(m_FormatCombo, CB_SETITEMDATA, (WPARAM)Idx, i);
  266. }
  267. GetClientRect(m_FormatCombo, &Rect);
  268. BandInfo.lpText = "Display format:";
  269. BandInfo.hwndChild = m_FormatCombo;
  270. BandInfo.cxMinChild = Rect.right - Rect.left;
  271. BandInfo.cyMinChild = Rect.bottom - Rect.top;
  272. SendMessage(m_Toolbar, RB_INSERTBAND, -1, (LPARAM)&BandInfo);
  273. PSTR PrevText = "Previous";
  274. m_PreviousButton =
  275. AddButtonBand(m_Toolbar, PrevText, PrevText, IDC_MEM_PREVIOUS);
  276. m_NextButton =
  277. AddButtonBand(m_Toolbar, "Next", PrevText, IDC_MEM_NEXT);
  278. if (m_PreviousButton == NULL || m_NextButton == NULL)
  279. {
  280. return FALSE;
  281. }
  282. // Maximize the space for the offset expression.
  283. SendMessage(m_Toolbar, RB_MAXIMIZEBAND, 0, FALSE);
  284. GetClientRect(m_Toolbar, &Rect);
  285. m_ToolbarHeight = Rect.bottom - Rect.top + GetSystemMetrics(SM_CYEDGE);
  286. m_ShowToolbar = TRUE;
  287. if (!EDITWIN_DATA::OnCreate())
  288. {
  289. return FALSE;
  290. }
  291. SendMessage(m_hwndChild, EM_SETBKGNDCOLOR, FALSE,
  292. g_Colors[COL_PLAIN].Color);
  293. SendMessage(m_hwndChild, EM_SETEVENTMASK, 0, ENM_KEYEVENTS);
  294. UpdateOptions();
  295. return TRUE;
  296. }
  297. LRESULT
  298. MEMWIN_DATA::OnCommand(
  299. WPARAM wParam,
  300. LPARAM lParam
  301. )
  302. {
  303. switch(LOWORD(wParam))
  304. {
  305. case IDC_EDIT_OFFSET:
  306. if (HIWORD(wParam) == EN_CHANGE)
  307. {
  308. // This message is sent on every keystroke
  309. // which causes a bit too much updating.
  310. // Set up a timer to trigger the actual
  311. // update in half a second.
  312. SetTimer(m_Win, IDC_EDIT_OFFSET, EDIT_DELAY, NULL);
  313. m_UpdateExpr = TRUE;
  314. }
  315. break;
  316. case IDC_COMBO_DISPLAY_FORMAT:
  317. if (HIWORD(wParam) == CBN_SELCHANGE)
  318. {
  319. LRESULT Sel = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
  320. if (Sel != CB_ERR)
  321. {
  322. m_GenMemData.nDisplayFormat = (int)
  323. SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)Sel, 0);
  324. UpdateOptions();
  325. UiRequestRead();
  326. }
  327. }
  328. break;
  329. case IDC_MEM_PREVIOUS:
  330. ScrollLower();
  331. break;
  332. case IDC_MEM_NEXT:
  333. ScrollHigher();
  334. break;
  335. }
  336. return 0;
  337. }
  338. void
  339. MEMWIN_DATA::OnSize(void)
  340. {
  341. EDITWIN_DATA::OnSize();
  342. // Force buffer to refill for new line count.
  343. UiRequestRead();
  344. }
  345. void
  346. MEMWIN_DATA::OnTimer(WPARAM TimerId)
  347. {
  348. if (TimerId == IDC_EDIT_OFFSET && m_UpdateExpr)
  349. {
  350. m_UpdateExpr = FALSE;
  351. if (SendMessage(m_ToolbarEdit, EM_GETMODIFY, 0,0))
  352. {
  353. GetWindowText(m_ToolbarEdit, m_OffsetExpr, sizeof(m_OffsetExpr));
  354. SendMessage(m_ToolbarEdit, EM_SETMODIFY, 0,0);
  355. UiRequestRead();
  356. }
  357. // KillTimer(m_Win, IDC_EDIT_OFFSET);
  358. }
  359. }
  360. LRESULT
  361. MEMWIN_DATA::OnNotify(WPARAM Wpm, LPARAM Lpm)
  362. {
  363. LPNMHDR Hdr = (LPNMHDR)Lpm;
  364. switch(Hdr->code)
  365. {
  366. case RBN_HEIGHTCHANGE:
  367. PostMessage(m_Win, WU_RECONFIGURE, 0, 0);
  368. break;
  369. case EN_MSGFILTER:
  370. MSGFILTER* Filter = (MSGFILTER*)Lpm;
  371. if (Filter->msg == WM_KEYDOWN)
  372. {
  373. switch(Filter->wParam)
  374. {
  375. case VK_UP:
  376. {
  377. CHARRANGE range;
  378. SendMessage(m_hwndChild, EM_EXGETSEL, 0, (LPARAM) &range);
  379. if (!SendMessage(m_hwndChild, EM_LINEFROMCHAR,
  380. range.cpMin, 0))
  381. {
  382. // up arrow on top line, scroll
  383. ScrollLower();
  384. return TRUE;
  385. }
  386. break;
  387. }
  388. case VK_DOWN:
  389. {
  390. CHARRANGE range;
  391. int MaxLine;
  392. SendMessage(m_hwndChild, EM_EXGETSEL, 0, (LPARAM) &range);
  393. MaxLine = (int)SendMessage(m_hwndChild, EM_GETLINECOUNT, 0, 0);
  394. if (MaxLine == (1 + SendMessage(m_hwndChild, EM_LINEFROMCHAR,
  395. range.cpMin, 0)))
  396. {
  397. // down arrow on bottom line, scroll
  398. ScrollHigher();
  399. return TRUE;
  400. }
  401. break;
  402. }
  403. case VK_PRIOR:
  404. ScrollLower();
  405. return TRUE;
  406. case VK_NEXT:
  407. ScrollHigher();
  408. return TRUE;
  409. case VK_LEFT: case VK_RIGHT:
  410. break;
  411. case VK_DELETE:
  412. MessageBeep(0);
  413. return TRUE;
  414. default:
  415. // Allow default processing of everything else
  416. return TRUE;
  417. }
  418. }
  419. else if (Filter->msg == WM_KEYUP)
  420. {
  421. return TRUE;
  422. }
  423. if (ES_READONLY & GetWindowLongPtr(m_hwndChild, GWL_STYLE))
  424. {
  425. break;
  426. }
  427. if (Filter->msg == WM_CHAR)
  428. {
  429. switch(Filter->wParam)
  430. {
  431. case '0': case '1': case '2': case '3': case '4':
  432. case '5': case '6': case '7': case '8': case '9':
  433. case 'a': case 'A': case 'b': case 'B': case 'c':
  434. case 'C': case 'd': case 'D': case 'e': case 'E':
  435. case 'f': case 'F':
  436. {
  437. CHARRANGE value;
  438. ULONG charIndex;
  439. ULONG64 Address;
  440. CHAR writeval[2] = {0};
  441. writeval[0] = (CHAR) tolower((CHAR) Filter->wParam);
  442. Address = GetAddressOfCurValue(&charIndex, &value);
  443. if (Address)
  444. {
  445. TEXTRANGE textRange;
  446. SendMessage(m_hwndChild, EM_SETSEL,
  447. charIndex, charIndex+1);
  448. SendMessage(m_hwndChild, EM_REPLACESEL,
  449. FALSE, (LPARAM) writeval);
  450. textRange.chrg = value;
  451. textRange.lpstrText = &m_ValueExpr[0];
  452. if (SendMessage(m_hwndChild, EM_GETTEXTRANGE,
  453. 0, (LPARAM) &textRange))
  454. {
  455. m_ValueExpr[charIndex - value.cpMin] = writeval[0];
  456. WriteValue(Address);
  457. SendMessage(m_hwndChild, EM_SETSEL,
  458. charIndex+1, charIndex+1);
  459. return TRUE;
  460. }
  461. }
  462. }
  463. default:
  464. MessageBeep(0);
  465. return TRUE;
  466. }
  467. }
  468. break;
  469. }
  470. return EDITWIN_DATA::OnNotify(Wpm, Lpm);
  471. }
  472. void
  473. MEMWIN_DATA::OnUpdate(
  474. UpdateType Type
  475. )
  476. {
  477. if (Type != UPDATE_BUFFER)
  478. {
  479. return;
  480. }
  481. HRESULT Status;
  482. Status = UiLockForRead();
  483. if (Status == S_OK)
  484. {
  485. ULONG charIndex;
  486. SendMessage(m_hwndChild, EM_GETSEL, (WPARAM) &charIndex, NULL);
  487. SendMessage(m_hwndChild, WM_SETREDRAW, FALSE, 0);
  488. CHARRANGE Sel;
  489. // Select everything so it's all replaced.
  490. Sel.cpMin = 0;
  491. Sel.cpMax = -1;
  492. SendMessage(m_hwndChild, EM_EXSETSEL, 0, (LPARAM)&Sel);
  493. TCHAR Buf[64];
  494. TCHAR CharBuf[64];
  495. TCHAR* ColChar;
  496. ULONG Row, Col;
  497. ULONG64 Offset;
  498. ULONG64 DataEnd;
  499. PUCHAR Data;
  500. ULONG Bytes;
  501. _FORMATS_MEM_WIN* Fmt = g_FormatsMemWin + m_GenMemData.nDisplayFormat;
  502. Offset = m_OffsetRead;
  503. Data = (PUCHAR)m_Data;
  504. DataEnd = Offset + m_DataUsed;
  505. Bytes = (Fmt->cBits + 7) / 8;
  506. for (Row = 0; Row < m_LineHeight; Row++)
  507. {
  508. SendMessage(m_hwndChild, EM_REPLACESEL, FALSE,
  509. (LPARAM)FormatAddr64(Offset));
  510. ColChar = CharBuf;
  511. *ColChar++ = ' ';
  512. *ColChar++ = ' ';
  513. for (Col = 0; Col < m_Columns; Col++)
  514. {
  515. if (Offset < DataEnd)
  516. {
  517. _tcscpy(Buf, _T(" "));
  518. // If the formatting succeeds,
  519. // Buf contains the formatted data.
  520. if (!CPFormatMemory(Buf + 1,
  521. (DWORD)min(_tsizeof(Buf) - 1,
  522. Fmt->cchMax + 1),
  523. Data,
  524. Fmt->cBits,
  525. Fmt->fmtType,
  526. Fmt->radix))
  527. {
  528. // Else we don't know what to format
  529. for (UINT uTmp = 0; uTmp < Bytes; uTmp++)
  530. {
  531. m_AllowWrite = FALSE;
  532. _tcscat(Buf + 1, _T("??"));
  533. }
  534. }
  535. if (Fmt->fTwoFields)
  536. {
  537. if (!CPFormatMemory(ColChar, 1, Data, 8,
  538. fmtAscii, 0))
  539. {
  540. *ColChar = '?';
  541. }
  542. ColChar++;
  543. }
  544. }
  545. else
  546. {
  547. m_AllowWrite = FALSE;
  548. _tcscpy(Buf, _T(" ????????"));
  549. *ColChar++ = '?';
  550. }
  551. SendMessage(m_hwndChild, EM_REPLACESEL, FALSE, (LPARAM)Buf);
  552. Data += Bytes;
  553. Offset += Bytes;
  554. }
  555. if (Fmt->fTwoFields)
  556. {
  557. *ColChar = 0;
  558. SendMessage(m_hwndChild, EM_REPLACESEL,
  559. FALSE, (LPARAM)CharBuf);
  560. }
  561. // Don't complete the last line to avoid leaving
  562. // a blank line at the bottom.
  563. if (Row < m_LineHeight - 1)
  564. {
  565. SendMessage(m_hwndChild, EM_REPLACESEL, FALSE, (LPARAM)"\n");
  566. }
  567. }
  568. m_WindowDataSize = (ULONG)(Offset - m_OffsetRead);
  569. UnlockStateBuffer(this);
  570. SendMessage(m_hwndChild, WM_SETREDRAW, TRUE, 0);
  571. InvalidateRect(m_hwndChild, NULL, TRUE);
  572. SendMessage(m_hwndChild, EM_SETSEL, charIndex, charIndex);
  573. }
  574. else
  575. {
  576. SendLockStatusMessage(m_hwndChild, WM_SETTEXT, Status);
  577. }
  578. }
  579. void
  580. MEMWIN_DATA::ScrollLower(void)
  581. {
  582. ULONG64 Offs = m_OffsetRead;
  583. if (Offs >= m_WindowDataSize)
  584. {
  585. Offs -= m_WindowDataSize;
  586. }
  587. else
  588. {
  589. Offs = 0;
  590. }
  591. sprintf(m_OffsetExpr, "0x%I64x", Offs);
  592. UiRequestRead();
  593. }
  594. void
  595. MEMWIN_DATA::ScrollHigher(void)
  596. {
  597. ULONG64 Offs = m_OffsetRead;
  598. if (Offs + m_WindowDataSize > Offs)
  599. {
  600. Offs += m_WindowDataSize;
  601. }
  602. else
  603. {
  604. Offs = (ULONG64)-1 - m_WindowDataSize;
  605. }
  606. sprintf(m_OffsetExpr, "0x%I64x", Offs);
  607. UiRequestRead();
  608. }
  609. void
  610. MEMWIN_DATA::UpdateOptions(void)
  611. {
  612. REBARBANDINFO BandInfo;
  613. BandInfo.cbSize = sizeof(BandInfo);
  614. BandInfo.fMask = RBBIM_TEXT;
  615. BandInfo.lpText = g_MemTypeNames[m_GenMemData.memtype];
  616. SendMessage(m_Toolbar, RB_SETBANDINFO, 0, (LPARAM)&BandInfo);
  617. SetWindowText(m_ToolbarEdit, m_OffsetExpr);
  618. m_AllowWrite = (m_GenMemData.memtype == PHYSICAL_MEM_TYPE ||
  619. m_GenMemData.memtype == VIRTUAL_MEM_TYPE) &&
  620. ((g_FormatsMemWin[m_GenMemData.nDisplayFormat].fmtType & fmtBasis) == fmtUInt ||
  621. (g_FormatsMemWin[m_GenMemData.nDisplayFormat].fmtType & fmtBasis) == fmtInt ||
  622. (g_FormatsMemWin[m_GenMemData.nDisplayFormat].fmtType & fmtBasis) == fmtAddress
  623. ) &&
  624. g_FormatsMemWin[m_GenMemData.nDisplayFormat].radix == 16;
  625. SendMessage(m_hwndChild, EM_SETREADONLY, !m_AllowWrite, 0);
  626. for (LONG Idx = 0; Idx < g_nMaxNumFormatsMemWin; Idx++)
  627. {
  628. if ((LONG)SendMessage(m_FormatCombo, CB_GETITEMDATA, Idx, 0) ==
  629. m_GenMemData.nDisplayFormat)
  630. {
  631. SendMessage(m_FormatCombo, CB_SETCURSEL, Idx, 0);
  632. break;
  633. }
  634. }
  635. switch(m_GenMemData.memtype)
  636. {
  637. case MSR_MEM_TYPE:
  638. m_Columns = 1;
  639. break;
  640. default:
  641. if ((g_FormatsMemWin[m_GenMemData.nDisplayFormat].fmtType &
  642. fmtBasis) == fmtBit)
  643. {
  644. m_Columns = 8;
  645. }
  646. else if ((g_FormatsMemWin[m_GenMemData.nDisplayFormat].fmtType &
  647. fmtBasis) == fmtAscii ||
  648. (g_FormatsMemWin[m_GenMemData.nDisplayFormat].fmtType &
  649. fmtBasis) == fmtUnicode ||
  650. g_FormatsMemWin[m_GenMemData.nDisplayFormat].cBits == 8)
  651. {
  652. m_Columns = 16;
  653. }
  654. else if (g_FormatsMemWin[m_GenMemData.nDisplayFormat].cBits == 16)
  655. {
  656. m_Columns = 8;
  657. }
  658. else if (g_FormatsMemWin[m_GenMemData.nDisplayFormat].cBits > 64)
  659. {
  660. m_Columns = 2;
  661. }
  662. else
  663. {
  664. m_Columns = 4;
  665. }
  666. break;
  667. }
  668. }
  669. void
  670. MEMWIN_DATA::WriteValue(
  671. ULONG64 Offset
  672. )
  673. {
  674. if (!m_AllowWrite)
  675. {
  676. return;
  677. }
  678. ULONG64 Data;
  679. ULONG Size;
  680. DEBUG_VALUE Value;
  681. // Evaluate value expression.
  682. if (g_pDbgControl->Evaluate(m_ValueExpr, DEBUG_VALUE_INT64,
  683. &Value, NULL) != S_OK)
  684. {
  685. return;
  686. }
  687. Data = Value.I64;
  688. Size = g_FormatsMemWin[m_GenMemData.nDisplayFormat].cBits / 8;
  689. UIC_WRITE_DATA_DATA* WriteData;
  690. WriteData = StartStructCommand(UIC_WRITE_DATA);
  691. if (WriteData == NULL)
  692. {
  693. return;
  694. }
  695. // Fill in WriteData members.
  696. memcpy(WriteData->Data, &Data, Size);
  697. WriteData->Length = Size;
  698. WriteData->Offset = Offset;
  699. WriteData->Type = m_GenMemData.memtype;
  700. WriteData->Any = m_GenMemData.any;
  701. FinishCommand();
  702. }
  703. ULONG64
  704. MEMWIN_DATA::GetAddressOfCurValue(
  705. PULONG pCharIndex,
  706. CHARRANGE *pCRange
  707. )
  708. {
  709. CHARRANGE range;
  710. ULONG CurLine, FirstLineChar, CurCol;
  711. SendMessage(m_hwndChild, EM_EXGETSEL, NULL, (LPARAM) &range);
  712. CurLine = (ULONG)SendMessage(m_hwndChild, EM_LINEFROMCHAR, range.cpMin, 0);
  713. FirstLineChar = (ULONG)SendMessage(m_hwndChild, EM_LINEINDEX, CurLine, 0);
  714. CurCol = range.cpMin - FirstLineChar;
  715. ULONG Length;
  716. PCHAR pLineTxt = (PCHAR)
  717. malloc(Length = ((ULONG)SendMessage(m_hwndChild, EM_LINELENGTH,
  718. FirstLineChar, 0) + 2));
  719. if (!pLineTxt)
  720. {
  721. return 0;
  722. }
  723. Assert(Length >= CurCol);
  724. ZeroMemory(pLineTxt, Length);
  725. // Assert (Length = (ULONG) SendMessage(m_hwndChild, EM_GETLINE, (WPARAM) CurLine, (LPARAM) pLineTxt));
  726. TEXTRANGE textrange;
  727. textrange.chrg.cpMin = FirstLineChar;
  728. textrange.chrg.cpMax = FirstLineChar + Length-2;
  729. textrange.lpstrText = (LPSTR) pLineTxt;
  730. SendMessage(m_hwndChild, EM_GETTEXTRANGE, 0, (LPARAM) &textrange);
  731. ULONG ValueCol=0, Index=0, ValueIndex=0;
  732. while (pLineTxt[CurCol] == ' ')
  733. {
  734. CurCol++;
  735. }
  736. while (Index < CurCol)
  737. {
  738. if (pLineTxt[Index] == ' ')
  739. {
  740. if (ValueIndex != Index)
  741. {
  742. ValueCol++;
  743. }
  744. ValueIndex = Index+1;
  745. }
  746. ++Index;
  747. }
  748. if (!ValueIndex || !pLineTxt[CurCol]) // cursor on address column
  749. {
  750. free (pLineTxt);
  751. return 0;
  752. }
  753. ULONG Bytes;
  754. Bytes = (g_FormatsMemWin[m_GenMemData.nDisplayFormat].cBits + 7) / 8;
  755. ULONG64 Offset;
  756. Offset = m_OffsetRead + (CurLine * Bytes * m_Columns) + (ValueCol - 1)*Bytes;
  757. for (Index = ValueIndex; pLineTxt[Index] && pLineTxt[Index] != ' '; Index++) ;
  758. memcpy(m_ValueExpr, pLineTxt+ValueIndex, Index - ValueIndex);
  759. m_ValueExpr[Index-ValueIndex]=0;
  760. free (pLineTxt);
  761. if (pCharIndex)
  762. {
  763. *pCharIndex = FirstLineChar + CurCol;
  764. }
  765. if (pCRange)
  766. {
  767. pCRange->cpMin = FirstLineChar + CurCol - (CurCol - ValueIndex);
  768. pCRange->cpMax = pCRange->cpMin + Index - ValueIndex;
  769. }
  770. return Offset;
  771. }