/[RomCheater]/trunk/RomCheater/Docking/UI/UIMemoryViewer.cs
ViewVC logotype

Contents of /trunk/RomCheater/Docking/UI/UIMemoryViewer.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 287 - (show annotations) (download)
Tue Jun 5 08:52:07 2012 UTC (8 years, 3 months ago) by william
File size: 24769 byte(s)

1 //#define DISABLE_GETFIRSTNONZEROBYTE_ONUPDATE_ACCEPTEDPROCESS // when defined will not call GetFirstNonZeroByte() when AcceptedProcess is updated and is not null
2 //#define DISABLE_GETFIRSTNONZERO_BYTE // when defined will make GetFirstNonZeroByte() an empty void method
3 using System;
4 using System.Collections.Generic;
5 using System.ComponentModel;
6 using System.Drawing;
7 using System.Data;
8 using System.Linq;
9 using System.Text;
10 using System.Windows.Forms;
11 using Be.Windows.Forms;
12 using RomCheater.Logging;
13 using RomCheater.PluginFramework.Interfaces;
14 using System.Diagnostics;
15 using Sojaner.MemoryScanner.MemoryProviers;
16 using System.Runtime.InteropServices;
17 using RomCheater.PluginFramework.Events;
18
19 namespace RomCheater.Docking.UI
20 {
21 public partial class UIMemoryViewer : UserControl,
22 IAcceptsPlugin<IConfigPlugin>,
23 IAcceptsProcess<Process>,
24 IAcceptsProcessAndConfig,
25 IAcceptsMemoryRange,
26 IBrowseMemoryRegion
27 {
28 public UIMemoryViewer()
29 {
30 InitializeComponent();
31 SetStyle(ControlStyles.UserPaint, true);
32 SetStyle(ControlStyles.DoubleBuffer, true);
33 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
34 SetStyle(ControlStyles.ResizeRedraw, true);
35 //this.OnPCSX2ProcessCallback = new UIEvents.PCSX2ProcessCallback(this.PCSX2ProcessCallback);
36 //if (this.OnPCSX2ProcessCallback != null) { this.OnPCSX2ProcessCallback.Invoke(out procdata); }
37 this.UpdateEnabled = false;
38 txtData.BytesPerLine = (int)max_address_width;
39 txtData.UseFixedBytesPerLine = true;
40 txtData.StringViewVisible = true;
41 ramScroll.Minimum = (int)MemoryRangeStart;
42 for (int i = MemoryRangeStart; i < (MemoryRangeStart + max_ram_view); i += max_address_width) { ramScroll.Maximum += (int)max_address_width; }
43 ramScroll.Value = ramScroll.Minimum;
44 this.CanChangeUpdateInterval = false;
45
46
47 lblAddressMarker.Text = "";
48 for (uint i = 0; i < max_address_width; i++)
49 {
50 lblAddressMarker.Text = lblAddressMarker.Text + string.Format("{0:X2} ", i);
51 }
52 this.AcceptedPlugin = null; this.AcceptedProcess = null;
53
54 txtAddresses.MouseWheel += new MouseEventHandler(txtAddresses_MouseWheel);
55 txtData.MouseWheel += new MouseEventHandler(txtData_MouseWheel);
56 }
57
58 private void GetFirstNonZeroByte()
59 {
60 #if !DISABLE_GETFIRSTNONZERO_BYTE
61 if (!DesignMode)
62 {
63 GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this);
64 provider.OpenProvider();
65 int addr = 0;
66 provider.ReadFirstNonZeroByte(MemoryRangeStart, MemoryRangeSize, out addr);
67 provider.CloseProvider();
68 GotoAddress(addr);
69 }
70 #endif
71 }
72 #region IBrowseMemoryRegion
73 public bool BrowseMemoryRegion(int MemoryRegion)
74 {
75 try
76 {
77 if (!((MemoryRangeStart <= MemoryRegion) && (MemoryRegion <= (MemoryRangeStart + MemoryRangeSize)))) { return false; }
78 GotoAddress(MemoryRegion);
79 return true;
80 }
81 catch(Exception ex)
82 {
83 logger.Error.WriteLine("UIMemoryViewer.BrowseMemoryRegion(int MemoryRegion): Failed to Browse Memory Region: 0x{0:x8}", MemoryRegion);
84 logger.Error.WriteLine(ex.ToString());
85 return false;
86 }
87 }
88 #endregion
89 #region IAcceptsProcess<Process> Members
90 private Process _AcceptedProcess;
91 public Process AcceptedProcess
92 {
93 get { return _AcceptedProcess; }
94 set
95 {
96 _AcceptedProcess = value;
97 update_timer.Enabled = (value != null);
98 UpdateEnabled = update_timer.Enabled;
99 #if !DISABLE_GETFIRSTNONZEROBYTE_ONUPDATE_ACCEPTEDPROCESS
100 if (value != null)
101 GetFirstNonZeroByte();
102 #endif
103 }
104 }
105 #endregion
106 #region IAcceptsPlugin<IConfigPlugin> Members
107 public IConfigPlugin AcceptedPlugin { get; set; }
108 #endregion
109 #region IAcceptsMemoryRange members
110 public int MemoryRangeStart { get { return MemorySizeConstants.MinimumAddress; } set { } }
111 public uint MemoryRangeSize { get { if (MemoryRangeStart > 0) { return (uint)(MemorySizeConstants.MaximumAddress - MemoryRangeStart); } return MemorySizeConstants.MaximumAddress; } set { } }
112 #endregion
113 public void GotoTop() { this.CURRENT_TOP_ADDR = 0; }
114 public void GotoBottom() { uint size = (uint)MemoryRangeSize; this.CURRENT_TOP_ADDR = (int)((size - 1) - max_ram_view); }
115 public void GotoAddress(int addr) { this.CURRENT_TOP_ADDR = (int)(addr & 0xFFFFFFF0); }
116 private bool _UpdateEnabled;
117 public bool UpdateEnabled
118 {
119 get { return _UpdateEnabled; }
120 set
121 {
122 _UpdateEnabled = value;
123 if (value) { this.update_timer.Enabled = true; }
124 else { this.update_timer.Enabled = false; }
125 }
126 }
127 private bool _CanChangeUpdateInterval;
128 public bool CanChangeUpdateInterval
129 {
130 get { return _CanChangeUpdateInterval; }
131 set { _CanChangeUpdateInterval = value; }
132 }
133
134 public int UpdateInterval
135 {
136 get { return this.update_timer.Interval; }
137 set { if (CanChangeUpdateInterval) this.update_timer.Interval = value; }
138 }
139 private string AddressList = "";
140 private string AsciiData = "";
141 private byte[] RamData = new byte[] { };
142
143 const int max_address_width = 16;
144 static int max_ram_view = max_address_width * 27;
145
146 static int small_scroll_change = max_address_width * 1; // scrolls one line (when you clikc the up or down arrows)
147 static int medium_scroll_change = max_ram_view / 2; // scrolls half a page
148 static int large_scroll_change = max_ram_view; // scrolls a full page
149 private int _CURRENT_TOP_ADDR;
150 int CURRENT_TOP_ADDR
151 {
152 get { return _CURRENT_TOP_ADDR; }
153 set { txthexGoto.Value = _CURRENT_TOP_ADDR = value; }
154 }
155 //uint CURRENT_BOITTOM_ADDR() { return CURRENT_TOP_ADDR + max_ram_view; }
156 private void UpdateMaxRamView()
157 {
158 if (this.IsDisposed) return;
159 Graphics g = this.CreateGraphics();
160 Size size = g.MeasureString("00", txtData.Font).ToSize();
161 int ByteHeight = size.Height;
162 int TotalHeight = txtData.Height;
163 int NumberOfBytes = (int)((TotalHeight / ByteHeight) * max_address_width);
164 int byte_width = (max_address_width * 2);
165 max_ram_view = NumberOfBytes + (byte_width);
166 }
167 private void btnGotoAddress_Click(object sender, EventArgs e)
168 {
169 this.GotoAddress(txthexGoto.ToInt32());
170 }
171
172 private void btnEditBytes_Click(object sender, EventArgs e)
173 {
174 bool reenable = false;
175 if (this.UpdateEnabled) reenable = true;
176 this.UpdateEnabled = false;
177 ByteEditor editor = new ByteEditor((txtData.ByteProvider as DynamicByteProvider).Bytes.ToArray(), this.CURRENT_TOP_ADDR);
178 editor.ShowDialog();
179 if (editor.BytesEdited)
180 {
181 //DynamicByteProvider _DynamicByteProvider = new DynamicByteProvider(editor.AsBytes);
182 //txtData.ByteProvider = _DynamicByteProvider;
183 //_DynamicByteProvider.Changed += new EventHandler(HexResourceViewerBytes_Changed);
184 this.WriteCurrentBytes(this.CURRENT_TOP_ADDR, editor.AsBytes);
185 }
186 this.UpdateEnabled = reenable;
187 }
188 private bool ForceUpdate = false;
189 private bool ShouldUpdateResults()
190 {
191 //if (ResultsUpdateWorkerThread.IsBusy) { return false; }
192 if (ForceUpdate) return true;
193 //else if (TextIsBeingSelected) return false;
194 //else if (NonHandledKeysAreBeingPressed) return false;
195 else if (this.UpdateEnabled) return true;
196 else { return false; }
197 }
198 private void UpdateGui(bool force)
199 {
200 if (AcceptedProcess == null) { return; }
201 if (AcceptedPlugin == null) { return; }
202
203 if (!this.ShouldUpdateResults()) { return; }// this.Logger.LogDebugMessage(string.Format("ShouldUpdateResults() -> returning false")); return; }
204 this.UpdateMaxRamView();
205 //if (!force)
206 //{
207 if (!ResultsUpdateWorkerThread.IsBusy)
208 ResultsUpdateWorkerThread.RunWorkerAsync();
209 //}
210 //else
211 //{
212 // while (!ResultsUpdateWorkerThread.IsBusy) { ResultsUpdateWorkerThread.CancelAsync(); Application.DoEvents(); }
213 // ResultsUpdateWorkerThread.RunWorkerAsync();
214 //}
215 }
216 private void UpdateGui()
217 {
218 this.UpdateGui(false);
219 }
220 private byte[] GetMemory()
221 {
222 byte[] data = new byte[] { };
223 try
224 {
225 GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this);
226 provider.OpenProvider();
227 int bytesReadSize;
228 provider.ReadProcessMemory(CURRENT_TOP_ADDR, (uint)max_ram_view, out bytesReadSize, out data);
229 try
230 {
231 provider.CloseProvider();
232 }
233 catch (SEHException ex)
234 {
235 logger.Error.WriteLine("UIMemoryViewer.GetMemory(): SEHException: (0x{0:x8} {1}", ex.ErrorCode, ex.Message);
236 logger.Error.WriteLine(ex.ToString());
237 }
238 catch (Exception ex)
239 {
240 logger.Error.WriteLine("UIMemoryViewer.GetMemory(): Exception: {0}", ex.Message);
241 logger.Error.WriteLine(ex.ToString());
242 }
243 }
244 catch (Exception ex)
245 {
246 logger.Error.WriteLine("{0}.GetMemory():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString());
247 }
248 finally
249 {
250 if (data.Length == 0)
251 {
252 data = new byte[max_ram_view];
253 for (int i = 0; i < data.Length; i++) { data[i] = 0x0; }
254 }
255 }
256 return data;
257 }
258 private void UpdateMemroyView() { this.UpdateMemroyView(this.CURRENT_TOP_ADDR); }
259 private void UpdateMemroyView(int address)
260 {
261 try
262 {
263 if (AcceptedProcess == null) { return; }
264 if (AcceptedPlugin == null) { return; }
265
266 byte[] data = GetMemory();
267 try
268 {
269 RamData = data;
270
271
272 AddressList = "";
273 AsciiData = "";
274 // write the addreses out
275 for (int i = address; i < (address + max_ram_view); i += max_address_width)
276 {
277 AddressList = AddressList + string.Format("{0:X8}:\n", i);
278 }
279 //// write out the ascii data
280 StringBuilder builder = new StringBuilder();
281 for (int i = address; i < (address + max_ram_view); i += max_address_width)
282 {
283 try
284 {
285 for (int j = 0; j < max_address_width; j++)
286 {
287 int current_addr = i + j;
288 if (current_addr >= MemoryRangeSize) break;
289 byte ascii_value_raw = data[j];
290 char ascii_value = (char)data[j];
291 if (ascii_value_raw >= 0x20 && ascii_value_raw <= 0x7e)
292 {
293 builder.Append(ascii_value.ToString());
294 }
295 else
296 {
297 builder.Append(".");
298 }
299 }
300 builder.AppendLine();
301 }
302 catch (Exception ex)
303 {
304 logger.Error.WriteLine("{0}.UpdateMemroyView().BuildingAsciiString:{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString());
305 return;
306 }
307 }
308 AsciiData = builder.ToString();
309
310
311 }
312 catch (Exception ex)
313 {
314 logger.Error.WriteLine("{0}.UpdateMemroyView():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString());
315 return;
316 }
317 }
318 catch (Exception ex) { logger.Error.WriteLine("{0}.UpdateMemroyView():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); }
319 }
320 //private void HexResourceViewerBytes_Changed(object sender, System.EventArgs e)
321 //{
322 // this.WriteCurrentBytes();
323 //}
324 private void WriteCurrentBytes(int start_address, byte[] data)
325 {
326 try
327 {
328 if (AcceptedProcess == null) { return; }
329 if (AcceptedPlugin == null) { return; }
330 // Byte changed
331 //byte[] data = (txtData.ByteProvider as DynamicByteProvider).Bytes.ToArray();
332 GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this);
333 provider.OpenProvider();
334 int bytesReadSize;
335
336 for (int i = 0; i < data.Length; i ++)
337 {
338 int addr = (int)(start_address + i);
339 byte data_to_write = data[i];
340 provider.WriteProcessMemory(addr, data_to_write, out bytesReadSize);
341 }
342 provider.CloseProvider();
343 }
344 catch (Exception ex) { logger.Error.WriteLine("{0}.WriteCurrentBytes():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); }
345 }
346
347 private void update_timer_Tick(object sender, EventArgs e) { this.UpdateGui(); }
348 private void ResultsUpdateWorkerThread_DoWork(object sender, DoWorkEventArgs e) { try { this.UpdateMemroyView(); } catch (Exception ex) { logger.Error.WriteLine("{0}.ResultsUpdateWorkerThread_DoWork():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); } }
349 private void ResultsUpdateWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
350 {
351 try
352 {
353 txtAddresses.Clear(); txtAddresses.Text = AddressList;
354 //txtAscii.Clear(); txtAscii.Text = AsciiData;
355 //this.Logger.LogDebugMessage(string.Format("RunWorkerCompeleted() -> Memory Size: {0}0x{2:X8}{1}", "{", "}", RamData.Length));
356 DynamicByteProvider _DynamicByteProvider = new DynamicByteProvider(RamData);
357 txtData.ByteProvider = _DynamicByteProvider;
358 //_DynamicByteProvider.Changed += new EventHandler(HexResourceViewerBytes_Changed);
359 }
360 catch (ObjectDisposedException) { } // ignore errors aobut disposed objects (usually only happens when the parent closes)
361 catch (Exception ex) { logger.Error.WriteLine("{0}.ResultsUpdateWorkerThread_RunWorkerCompleted():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); }
362 }
363 private void Handle_KeyDown(object sender, KeyEventArgs e)
364 {
365 //isScrolling = false;
366 //bool reenable = false;
367 //if (this.UpdateEnabled) reenable = true;
368 //this.UpdateEnabled = false;
369
370 this.UpdateMaxRamView();
371 int ORIGINAL_ADDR = this.CURRENT_TOP_ADDR;
372
373 ////if (e.Type == ScrollEventType.EndScroll) return;
374 //uint size = max_ram_view;
375
376 bool haveModifier = false;
377 switch (e.Modifiers)
378 {
379 case Keys.Control:
380 switch (e.KeyCode)
381 {
382 case Keys.Home:
383 this.CURRENT_TOP_ADDR = 0; //NonHandledKeysAreBeingPressed = false;
384 break;
385 case Keys.End:
386 this.CURRENT_TOP_ADDR = (int)((MemoryRangeSize - 1) - max_ram_view); //NonHandledKeysAreBeingPressed = false;
387 break;
388 default:
389 //NonHandledKeysAreBeingPressed = true;
390 break;
391 }
392 break;
393 }
394
395 if (!haveModifier)
396 {
397 switch (e.KeyCode)
398 {
399 case Keys.Up:
400 if (this.CURRENT_TOP_ADDR == 0 && (this.CURRENT_TOP_ADDR - small_scroll_change > this.CURRENT_TOP_ADDR))
401 {
402 this.CURRENT_TOP_ADDR = ORIGINAL_ADDR;
403 }
404 else
405 {
406 this.CURRENT_TOP_ADDR -= (int)small_scroll_change; //NonHandledKeysAreBeingPressed = false;
407 }
408 break;
409 case Keys.Down:
410 this.CURRENT_TOP_ADDR += (int)small_scroll_change; //NonHandledKeysAreBeingPressed = false;
411 break;
412 case Keys.PageUp:
413 if (this.CURRENT_TOP_ADDR == 0 && (this.CURRENT_TOP_ADDR - large_scroll_change > this.CURRENT_TOP_ADDR))
414 {
415 this.CURRENT_TOP_ADDR = ORIGINAL_ADDR;
416 }
417 else
418 {
419 this.CURRENT_TOP_ADDR -= (int)(large_scroll_change); //NonHandledKeysAreBeingPressed = false;
420 }
421 break;
422 case Keys.PageDown:
423 this.CURRENT_TOP_ADDR += (int)(large_scroll_change); //NonHandledKeysAreBeingPressed = false;
424 break;
425 default:
426 //NonHandledKeysAreBeingPressed = true;
427 break;
428 }
429 }
430 if (this.CURRENT_TOP_ADDR < MemoryRangeStart) this.CURRENT_TOP_ADDR = MemoryRangeStart;
431 //if (this.CURRENT_TOP_ADDR >= VTLB_VADDR_SIZE) this.CURRENT_TOP_ADDR = (size - 1) - max_ram_view;
432 if (this.CURRENT_TOP_ADDR + max_ram_view >= MemoryRangeSize) this.CURRENT_TOP_ADDR = (int)(MemoryRangeSize - max_ram_view);
433
434 //this.UpdateEnabled = reenable;
435 }
436
437 private void UIMemoryViewer_KeyDown(object sender, KeyEventArgs e) { this.Handle_KeyDown(sender, e); }
438 private void txtAddresses_KeyDown(object sender, KeyEventArgs e) { this.Handle_KeyDown(sender, e); }
439 private void txtData_KeyDown(object sender, KeyEventArgs e) { this.Handle_KeyDown(sender, e); }
440
441 private void ramScroll_Scroll(object sender, ScrollEventArgs e) { this.Handle_Scroll(sender, e); }
442
443 private ScrollEventArgs GetMouseWheelScrollChange(int WheelDelta)
444 {
445 ScrollEventArgs args = new ScrollEventArgs(ScrollEventType.SmallIncrement,1);
446 if (WheelDelta < 0)
447 {
448 //// negative: scroll down
449 //// SmallDecrement -or- LargeDecrement
450 //if (WheelDelta <= small_scroll_change)
451 //{
452 // args = new ScrollEventArgs(ScrollEventType.SmallDecrement,(int)small_scroll_change);
453 //}
454 //if (WheelDelta > small_scroll_change && WheelDelta <= large_scroll_change)
455 //{
456 // args = new ScrollEventArgs(ScrollEventType.LargeDecrement, (int)large_scroll_change);
457 //}
458 args = new ScrollEventArgs(ScrollEventType.SmallIncrement, 1);
459 }
460 else
461 {
462 //// positive: scroll up
463 //// SmallIncrement -or- LargeIncrement
464 //if (WheelDelta <= small_scroll_change)
465 //{
466 // args = new ScrollEventArgs(ScrollEventType.SmallIncrement, (int)small_scroll_change);
467 //}
468 //if (WheelDelta > small_scroll_change && WheelDelta <= large_scroll_change)
469 //{
470 // args = new ScrollEventArgs(ScrollEventType.LargeIncrement, (int)large_scroll_change);
471 //}
472 args = new ScrollEventArgs(ScrollEventType.SmallDecrement, 1);
473 }
474 return args;
475 }
476
477 void txtAddresses_MouseWheel(object sender, MouseEventArgs e) { this.Handle_Scroll(sender, GetMouseWheelScrollChange(e.Delta)); }
478 void txtData_MouseWheel(object sender, MouseEventArgs e) { this.Handle_Scroll(sender, GetMouseWheelScrollChange(e.Delta)); }
479
480
481 private void Handle_Scroll(object sender, ScrollEventArgs e)
482 {
483 //isScrolling = true;
484 //bool reenable = false;
485 //if (this.UpdateEnabled) reenable = true;
486 //this.UpdateEnabled = false;
487
488 this.UpdateMaxRamView();
489 int ORIGINAL_ADDR = this.CURRENT_TOP_ADDR;
490 //uint size = MemorySize;
491 if (e.Type == ScrollEventType.EndScroll) return;
492
493 switch (e.Type)
494 {
495 case ScrollEventType.SmallDecrement:
496 if (this.CURRENT_TOP_ADDR == 0 && ((this.CURRENT_TOP_ADDR - small_scroll_change) > this.CURRENT_TOP_ADDR))
497 {
498 this.CURRENT_TOP_ADDR = ORIGINAL_ADDR;
499 }
500 else
501 {
502 this.CURRENT_TOP_ADDR -= (small_scroll_change);
503 }
504 break;
505 case ScrollEventType.SmallIncrement:
506 this.CURRENT_TOP_ADDR += (small_scroll_change);
507 break;
508
509 case ScrollEventType.LargeDecrement:
510 if (this.CURRENT_TOP_ADDR == 0 && ((this.CURRENT_TOP_ADDR - large_scroll_change) > this.CURRENT_TOP_ADDR))
511 {
512 this.CURRENT_TOP_ADDR = ORIGINAL_ADDR;
513 }
514 else
515 {
516 this.CURRENT_TOP_ADDR -= (large_scroll_change);
517 }
518 break;
519 case ScrollEventType.LargeIncrement:
520 this.CURRENT_TOP_ADDR += (large_scroll_change);
521 break;
522 case ScrollEventType.ThumbPosition:
523 //this.CURRENT_TOP_ADDR = (uint)e.NewValue;
524 //break;
525 default:
526 this.CURRENT_TOP_ADDR = (int)(e.NewValue & 0xFFFFFFF0);
527 break;
528 }
529 if (this.CURRENT_TOP_ADDR < 0) this.CURRENT_TOP_ADDR = 0;
530 //if (this.CURRENT_TOP_ADDR >= VTLB_VADDR_SIZE) this.CURRENT_TOP_ADDR = VTLB_VADDR_SIZE - max_ram_view;
531 //if (this.CURRENT_TOP_ADDR < 0 || this.CURRENT_TOP_ADDR >= VTLB_VADDR_SIZE) this.CURRENT_TOP_ADDR = ORIGINAL_ADDR;
532 if (this.CURRENT_TOP_ADDR + max_ram_view >= MemoryRangeSize) this.CURRENT_TOP_ADDR = (int)(MemoryRangeSize - max_ram_view);
533 //this.UpdateEnabled = reenable;
534 //isScrolling = false;
535 }
536
537 }
538 }

  ViewVC Help
Powered by ViewVC 1.1.22