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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 207 - (hide annotations) (download)
Thu May 31 09:47:29 2012 UTC (8 years, 4 months ago) by william
File size: 22673 byte(s)
+ fix support for editing bytes in memory view

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

  ViewVC Help
Powered by ViewVC 1.1.22