ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater/Docking/UI/UIMemoryViewer.cs
Revision: 246
Committed: Sun Jun 3 15:15:51 2012 UTC (11 years, 6 months ago) by william
File size: 23085 byte(s)
Log Message:

File Contents

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