ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater/Docking/UI/UIMemoryViewer.cs
Revision: 285
Committed: Tue Jun 5 01:54:33 2012 UTC (11 years, 8 months ago) by william
File size: 23735 byte(s)
Log Message:
+ search wip

File Contents

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