ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater/Docking/UI/UIMemoryViewer.cs
Revision: 256
Committed: Sun Jun 3 16:50:16 2012 UTC (11 years ago) by william
File size: 23076 byte(s)
Log Message:
UIMemoryViewer:
* re-enable GetFirstNonZeroByte()
+ make code changes that were not implemented (due to GetFirstNonZeroByte() being disabled)

File Contents

# Content
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
17 namespace RomCheater.Docking.UI
18 {
19 public partial class UIMemoryViewer : UserControl,
20 IAcceptsPlugin<IConfigPlugin>,
21 IAcceptsProcess<Process>,
22 IAcceptsProcessAndConfig
23 {
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 for (int i = MemoryStart; i < (MemoryStart + max_ram_view); i += max_address_width) { ramScroll.Maximum += (int)max_address_width; }
39 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
50 txtAddresses.MouseWheel += new MouseEventHandler(txtAddresses_MouseWheel);
51 txtData.MouseWheel += new MouseEventHandler(txtData_MouseWheel);
52 }
53
54 private void GetFirstNonZeroByte()
55 {
56 #if !DISABLE_GETFIRSTNONZERO_BYTE
57 if (!DesignMode)
58 {
59 GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this);
60 provider.OpenProvider();
61 int addr = 0;
62 provider.ReadFirstNonZeroByte(MemoryStart, MemorySize, out addr);
63 provider.CloseProvider();
64 GotoAddress(addr);
65 }
66 #endif
67 }
68
69 #region IAcceptsProcess<Process> Members
70 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 #if !DISABLE_GETFIRSTNONZEROBYTE_ONUPDATE_ACCEPTEDPROCESS
80 if (value != null)
81 GetFirstNonZeroByte();
82 #endif
83 }
84 }
85 #endregion
86 #region IAcceptsPlugin<IConfigPlugin> Members
87 public IConfigPlugin AcceptedPlugin { get; set; }
88 #endregion
89 #region IAcceptsMemoryRange members
90 public int MemoryStart { get { return 0; } }
91 public uint MemorySize { get { return int.MaxValue; } }
92 #endregion
93 public void GotoTop() { this.CURRENT_TOP_ADDR = 0; }
94 public void GotoBottom() { uint size = (uint)MemorySize; this.CURRENT_TOP_ADDR = (int)((size - 1) - max_ram_view); }
95 public void GotoAddress(int addr) { this.CURRENT_TOP_ADDR = (int)(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 int max_address_width = 16;
124 static int max_ram_view = max_address_width * 27;
125
126 static int small_scroll_change = max_address_width * 1; // scrolls one line (when you clikc the up or down arrows)
127 static int medium_scroll_change = max_ram_view / 2; // scrolls half a page
128 static int large_scroll_change = max_ram_view; // scrolls a full page
129 private int _CURRENT_TOP_ADDR;
130 int CURRENT_TOP_ADDR
131 {
132 get { return _CURRENT_TOP_ADDR; }
133 set { txthexGoto.Value = _CURRENT_TOP_ADDR = value; }
134 }
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 int NumberOfBytes = (int)((TotalHeight / ByteHeight) * max_address_width);
143 int 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.ToInt32());
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 //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 }
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 byte[] data = new byte[] { };
202 try
203 {
204 GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this);
205 provider.OpenProvider();
206 int bytesReadSize;
207 provider.ReadProcessMemory(CURRENT_TOP_ADDR, (uint)max_ram_view, out bytesReadSize, out data);
208 provider.CloseProvider();
209
210 }
211 catch (Exception ex)
212 {
213 logger.Error.WriteLine("{0}.GetMemory():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString());
214 }
215 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 }
225 private void UpdateMemroyView() { this.UpdateMemroyView(this.CURRENT_TOP_ADDR); }
226 private void UpdateMemroyView(int address)
227 {
228 try
229 {
230 if (AcceptedProcess == null) { return; }
231 if (AcceptedPlugin == null) { return; }
232
233 byte[] data = GetMemory();
234 try
235 {
236 RamData = data;
237
238
239 AddressList = "";
240 AsciiData = "";
241 // write the addreses out
242 for (int i = address; i < (address + max_ram_view); i += max_address_width)
243 {
244 AddressList = AddressList + string.Format("{0:X8}:\n", i);
245 }
246 //// write out the ascii data
247 StringBuilder builder = new StringBuilder();
248 for (int i = address; i < (address + max_ram_view); i += max_address_width)
249 {
250 try
251 {
252 for (int j = 0; j < max_address_width; j++)
253 {
254 int 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 }
267 builder.AppendLine();
268 }
269 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 }
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 //private void HexResourceViewerBytes_Changed(object sender, System.EventArgs e)
288 //{
289 // this.WriteCurrentBytes();
290 //}
291 private void WriteCurrentBytes(int start_address, byte[] data)
292 {
293 try
294 {
295 if (AcceptedProcess == null) { return; }
296 if (AcceptedPlugin == null) { return; }
297 // Byte changed
298 //byte[] data = (txtData.ByteProvider as DynamicByteProvider).Bytes.ToArray();
299 GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this);
300 provider.OpenProvider();
301 int bytesReadSize;
302
303 for (int i = 0; i < data.Length; i ++)
304 {
305 int addr = (int)(start_address + i);
306 byte data_to_write = data[i];
307 provider.WriteProcessMemory(addr, data_to_write, out bytesReadSize);
308 }
309 provider.CloseProvider();
310 }
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 //_DynamicByteProvider.Changed += new EventHandler(HexResourceViewerBytes_Changed);
326 }
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 int ORIGINAL_ADDR = this.CURRENT_TOP_ADDR;
339
340 ////if (e.Type == ScrollEventType.EndScroll) return;
341 //uint size = max_ram_view;
342
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 this.CURRENT_TOP_ADDR = (int)((MemorySize - 1) - max_ram_view); //NonHandledKeysAreBeingPressed = false;
354 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 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 -= (int)small_scroll_change; //NonHandledKeysAreBeingPressed = false;
374 }
375 break;
376 case Keys.Down:
377 this.CURRENT_TOP_ADDR += (int)small_scroll_change; //NonHandledKeysAreBeingPressed = false;
378 break;
379 case Keys.PageUp:
380 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 -= (int)(large_scroll_change); //NonHandledKeysAreBeingPressed = false;
387 }
388 break;
389 case Keys.PageDown:
390 this.CURRENT_TOP_ADDR += (int)(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 if (this.CURRENT_TOP_ADDR + max_ram_view >= MemorySize) this.CURRENT_TOP_ADDR = (int)(MemorySize - max_ram_view);
400
401 //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
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 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 int ORIGINAL_ADDR = this.CURRENT_TOP_ADDR;
457 //uint size = MemorySize;
458 if (e.Type == ScrollEventType.EndScroll) return;
459
460 switch (e.Type)
461 {
462 case ScrollEventType.SmallDecrement:
463 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 break;
472 case ScrollEventType.SmallIncrement:
473 this.CURRENT_TOP_ADDR += (small_scroll_change);
474 break;
475
476 case ScrollEventType.LargeDecrement:
477 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 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 = (int)(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 if (this.CURRENT_TOP_ADDR + max_ram_view >= MemorySize) this.CURRENT_TOP_ADDR = (int)(MemorySize - max_ram_view);
500 //this.UpdateEnabled = reenable;
501 //isScrolling = false;
502 }
503
504 }
505 }