ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater/Docking/UI/UIMemoryViewer.cs
Revision: 200
Committed: Thu May 31 07:29:44 2012 UTC (11 years, 6 months ago) by william
File size: 18551 byte(s)
Log Message:

File Contents

# Content
1 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 public partial class UIMemoryViewer : UserControl, IProcessConfig, IAcceptsPlugin<IConfigPlugin>//, IAcceptsMemoryRange
17 {
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 for (uint i = MemoryStart; i < (MemoryStart + MemorySize); i += max_address_width) { ramScroll.Maximum += (int)max_address_width; }
33 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 }
44 #region IProcessConfig Members
45 private Process _AcceptedProcess;
46 public Process AcceptedProcess
47 {
48 get { return _AcceptedProcess; }
49 set
50 {
51 _AcceptedProcess = value;
52 update_timer.Enabled = (value != null);
53 UpdateEnabled = update_timer.Enabled;
54 }
55 }
56 #endregion
57 #region IAcceptsPlugin<IConfigPlugin> Members
58 public IConfigPlugin AcceptedPlugin { get; set; }
59 #endregion
60 #region IAcceptsMemoryRange members
61 public uint MemoryStart { get; set; }
62 public uint MemorySize { get; set; }
63 #endregion
64 public void GotoTop() { this.CURRENT_TOP_ADDR = 0; }
65 public void GotoBottom() { uint size = MemorySize; this.CURRENT_TOP_ADDR = (uint)((size - 1) - max_ram_view); }
66 public void GotoAddress(uint addr) { this.CURRENT_TOP_ADDR = (uint)addr & 0xFFFFFFF0; }
67 private bool _UpdateEnabled;
68 public bool UpdateEnabled
69 {
70 get { return _UpdateEnabled; }
71 set
72 {
73 _UpdateEnabled = value;
74 if (value) { this.update_timer.Enabled = true; }
75 else { this.update_timer.Enabled = false; }
76 }
77 }
78 private bool _CanChangeUpdateInterval;
79 public bool CanChangeUpdateInterval
80 {
81 get { return _CanChangeUpdateInterval; }
82 set { _CanChangeUpdateInterval = value; }
83 }
84
85 public int UpdateInterval
86 {
87 get { return this.update_timer.Interval; }
88 set { if (CanChangeUpdateInterval) this.update_timer.Interval = value; }
89 }
90 private string AddressList = "";
91 private string AsciiData = "";
92 private byte[] RamData = new byte[] { };
93
94 const uint max_address_width = 16;
95 static uint max_ram_view = max_address_width * 27;
96
97 static uint small_scroll_change = max_address_width * 1; // scrolls one line (when you clikc the up or down arrows)
98 static uint medium_scroll_change = max_ram_view / 2; // scrolls half a page
99 static uint large_scroll_change = max_ram_view; // scrolls a full page
100 private uint _CURRENT_TOP_ADDR;
101 uint CURRENT_TOP_ADDR
102 {
103 get { return _CURRENT_TOP_ADDR; }
104 set { _CURRENT_TOP_ADDR = value; }
105 }
106 //uint CURRENT_BOITTOM_ADDR() { return CURRENT_TOP_ADDR + max_ram_view; }
107 private void UpdateMaxRamView()
108 {
109 Graphics g = this.CreateGraphics();
110 Size size = g.MeasureString("00", txtData.Font).ToSize();
111 int ByteHeight = size.Height;
112 int TotalHeight = txtData.Height;
113 uint NumberOfBytes = (uint)((TotalHeight / ByteHeight) * max_address_width);
114 uint byte_width = (max_address_width * 2);
115 max_ram_view = NumberOfBytes + (byte_width - 1);
116 }
117 private void btnGotoAddress_Click(object sender, EventArgs e)
118 {
119 this.GotoAddress(txthexGoto.ToUInt32());
120 }
121
122 private void btnEditBytes_Click(object sender, EventArgs e)
123 {
124 bool reenable = false;
125 if (this.UpdateEnabled) reenable = true;
126 this.UpdateEnabled = false;
127 ByteEditor editor = new ByteEditor((txtData.ByteProvider as DynamicByteProvider).Bytes.ToArray(), this.CURRENT_TOP_ADDR);
128 editor.ShowDialog();
129 if (editor.BytesEdited)
130 {
131 DynamicByteProvider _DynamicByteProvider = new DynamicByteProvider(editor.AsBytes);
132 txtData.ByteProvider = _DynamicByteProvider;
133 _DynamicByteProvider.Changed += new EventHandler(HexResourceViewerBytes_Changed);
134 this.WriteCurrentBytes();
135 }
136 this.UpdateEnabled = reenable;
137 }
138 private bool ForceUpdate = false;
139 private bool ShouldUpdateResults()
140 {
141 //if (ResultsUpdateWorkerThread.IsBusy) { return false; }
142 if (ForceUpdate) return true;
143 //else if (TextIsBeingSelected) return false;
144 //else if (NonHandledKeysAreBeingPressed) return false;
145 else if (this.UpdateEnabled) return true;
146 else { return false; }
147 }
148 private void UpdateGui(bool force)
149 {
150 if (AcceptedProcess == null) { return; }
151 if (AcceptedPlugin == null) { return; }
152
153 if (!this.ShouldUpdateResults()) { return; }// this.Logger.LogDebugMessage(string.Format("ShouldUpdateResults() -> returning false")); return; }
154 this.UpdateMaxRamView();
155 //if (!force)
156 //{
157 if (!ResultsUpdateWorkerThread.IsBusy)
158 ResultsUpdateWorkerThread.RunWorkerAsync();
159 //}
160 //else
161 //{
162 // while (!ResultsUpdateWorkerThread.IsBusy) { ResultsUpdateWorkerThread.CancelAsync(); Application.DoEvents(); }
163 // ResultsUpdateWorkerThread.RunWorkerAsync();
164 //}
165 }
166 private void UpdateGui()
167 {
168 this.UpdateGui(false);
169 }
170 private byte[] GetMemory()
171 {
172 try
173 {
174 Sojaner.MemoryScanner.ProcessMemoryReader reader = new Sojaner.MemoryScanner.ProcessMemoryReader();
175 reader.ReadProcess = this.AcceptedProcess;
176 reader.OpenProcess();
177 int bytesReadSize;
178 byte[] data = reader.ReadProcessMemory(CURRENT_TOP_ADDR, max_ram_view, out bytesReadSize);
179 //this.Logger.LogDebugMessage(string.Format("GetMemory() -> Memory Size: {0}0x{2:X8}{1}", "{", "}", data.Length));
180 return data;
181 }
182 catch (Exception ex)
183 {
184 logger.Error.WriteLine("{0}.GetMemory():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString());
185 byte[] data = new byte[max_ram_view];
186 for (int i = 0; i < data.Length; i++) { data[i] = 0x0; }
187 return data;
188 }
189 }
190 private void UpdateMemroyView() { this.UpdateMemroyView(this.CURRENT_TOP_ADDR); }
191 private void UpdateMemroyView(uint address)
192 {
193 try
194 {
195 if (AcceptedProcess == null) { return; }
196 if (AcceptedPlugin == null) { return; }
197
198 byte[] data = GetMemory();
199
200 List<byte> ByteData = new List<byte>((int)(address + (max_ram_view - 0)));
201
202 try
203 {
204 AddressList = "";
205 AsciiData = "";
206
207 // create a byte array holding only the bytes that we need
208 for (uint i = address; i < (address + (max_ram_view + 1)); i += 1) { ByteData.Add(data[i]); }
209
210 // write the addreses out
211 for (uint i = address; i < (address + max_ram_view); i += max_address_width)
212 {
213 AddressList = AddressList + string.Format("{0:X8}:\n", i);
214 }
215 // write out the ascii data
216 StringBuilder builder = new StringBuilder();
217 for (uint i = address; i < (address + max_ram_view); i += max_address_width)
218 {
219 for (uint j = 0; j < max_address_width; j++)
220 {
221 uint current_addr = i + j;
222 if (current_addr >= MemorySize) break;
223 byte ascii_value_raw = data[current_addr];
224 char ascii_value = (char)data[current_addr];
225 if (ascii_value_raw >= 0x20 && ascii_value_raw <= 0x7e)
226 {
227 builder.Append(ascii_value.ToString());
228 }
229 else
230 {
231 builder.Append(".");
232 }
233 }
234 builder.AppendLine();
235 }
236 AsciiData = builder.ToString();
237 // write out the bytes
238 RamData = ByteData.ToArray();
239
240
241 }
242 catch (Exception ex)
243 {
244 logger.Error.WriteLine("{0}.UpdateMemroyView():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString());
245 return;
246 }
247 }
248 catch (Exception ex) { logger.Error.WriteLine("{0}.UpdateMemroyView():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); }
249 }
250 private void HexResourceViewerBytes_Changed(object sender, System.EventArgs e)
251 {
252 this.WriteCurrentBytes();
253 }
254 private void WriteCurrentBytes()
255 {
256 try
257 {
258 if (AcceptedProcess == null) { return; }
259 if (AcceptedPlugin == null) { return; }
260 // Byte changed
261 byte[] data = (txtData.ByteProvider as DynamicByteProvider).Bytes.ToArray();
262
263
264 Sojaner.MemoryScanner.ProcessMemoryReader reader = new Sojaner.MemoryScanner.ProcessMemoryReader();
265 reader.ReadProcess = this.AcceptedProcess;
266 reader.OpenProcess();
267 int bytesReadSize;
268
269 for (int i = 0; i < data.Length; i += sizeof(uint))
270 {
271 uint addr = (uint)(this.CURRENT_TOP_ADDR + i);
272 uint data_to_write = BitConverter.ToUInt32(data, i);
273 reader.WriteProcessMemory((UIntPtr)addr, data, out bytesReadSize);
274 }
275 }
276 catch (Exception ex) { logger.Error.WriteLine("{0}.WriteCurrentBytes():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); }
277 }
278
279 private void update_timer_Tick(object sender, EventArgs e) { this.UpdateGui(); }
280 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()); } }
281 private void ResultsUpdateWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
282 {
283 try
284 {
285 txtAddresses.Clear(); txtAddresses.Text = AddressList;
286 //txtAscii.Clear(); txtAscii.Text = AsciiData;
287 //this.Logger.LogDebugMessage(string.Format("RunWorkerCompeleted() -> Memory Size: {0}0x{2:X8}{1}", "{", "}", RamData.Length));
288 DynamicByteProvider _DynamicByteProvider = new DynamicByteProvider(RamData);
289 txtData.ByteProvider = _DynamicByteProvider;
290 _DynamicByteProvider.Changed += new EventHandler(HexResourceViewerBytes_Changed);
291 }
292 catch (ObjectDisposedException) { } // ignore errors aobut disposed objects (usually only happens when the parent closes)
293 catch (Exception ex) { logger.Error.WriteLine("{0}.ResultsUpdateWorkerThread_RunWorkerCompleted():{1}{2}", this.GetType().Name, System.Environment.NewLine, ex.ToString()); }
294 }
295 private void Handle_KeyDown(object sender, KeyEventArgs e)
296 {
297 //isScrolling = false;
298 //bool reenable = false;
299 //if (this.UpdateEnabled) reenable = true;
300 //this.UpdateEnabled = false;
301
302 this.UpdateMaxRamView();
303 uint ORIGINAL_ADDR = this.CURRENT_TOP_ADDR;
304
305 ////if (e.Type == ScrollEventType.EndScroll) return;
306 uint size = MemorySize;
307
308 bool haveModifier = false;
309 switch (e.Modifiers)
310 {
311 case Keys.Control:
312 switch (e.KeyCode)
313 {
314 case Keys.Home:
315 this.CURRENT_TOP_ADDR = 0; //NonHandledKeysAreBeingPressed = false;
316 break;
317 case Keys.End:
318 this.CURRENT_TOP_ADDR = (uint)((size - 1) - max_ram_view); //NonHandledKeysAreBeingPressed = false;
319 break;
320 default:
321 //NonHandledKeysAreBeingPressed = true;
322 break;
323 }
324 break;
325 }
326
327 if (!haveModifier)
328 {
329 switch (e.KeyCode)
330 {
331 case Keys.Up:
332 this.CURRENT_TOP_ADDR -= (uint)small_scroll_change; //NonHandledKeysAreBeingPressed = false;
333 break;
334 case Keys.Down:
335 this.CURRENT_TOP_ADDR += (uint)small_scroll_change; //NonHandledKeysAreBeingPressed = false;
336 break;
337 case Keys.PageUp:
338 this.CURRENT_TOP_ADDR -= (uint)(large_scroll_change); //NonHandledKeysAreBeingPressed = false;
339 break;
340 case Keys.PageDown:
341 this.CURRENT_TOP_ADDR += (uint)(large_scroll_change); //NonHandledKeysAreBeingPressed = false;
342 break;
343 default:
344 //NonHandledKeysAreBeingPressed = true;
345 break;
346 }
347 }
348 if (this.CURRENT_TOP_ADDR < MemoryStart) this.CURRENT_TOP_ADDR = MemoryStart;
349 //if (this.CURRENT_TOP_ADDR >= VTLB_VADDR_SIZE) this.CURRENT_TOP_ADDR = (size - 1) - max_ram_view;
350 if (this.CURRENT_TOP_ADDR + max_ram_view >= MemoryStart) this.CURRENT_TOP_ADDR = (size - 1) - max_ram_view;
351
352 //this.UpdateEnabled = reenable;
353 }
354
355 private void UIMemoryViewer_KeyDown(object sender, KeyEventArgs e) { this.Handle_KeyDown(sender, e); }
356 private void txtAddresses_KeyDown(object sender, KeyEventArgs e) { this.Handle_KeyDown(sender, e); }
357 private void txtData_KeyDown(object sender, KeyEventArgs e) { this.Handle_KeyDown(sender, e); }
358
359 private void ramScroll_Scroll(object sender, ScrollEventArgs e) { this.Handle_Scroll(sender, e); }
360 private void Handle_Scroll(object sender, ScrollEventArgs e)
361 {
362 //isScrolling = true;
363 //bool reenable = false;
364 //if (this.UpdateEnabled) reenable = true;
365 //this.UpdateEnabled = false;
366
367 this.UpdateMaxRamView();
368 uint ORIGINAL_ADDR = this.CURRENT_TOP_ADDR;
369 uint size = MemorySize;
370 if (e.Type == ScrollEventType.EndScroll) return;
371
372 switch (e.Type)
373 {
374 case ScrollEventType.SmallDecrement:
375 this.CURRENT_TOP_ADDR -= (small_scroll_change);
376 break;
377 case ScrollEventType.SmallIncrement:
378 this.CURRENT_TOP_ADDR += (small_scroll_change);
379 break;
380
381 case ScrollEventType.LargeDecrement:
382 this.CURRENT_TOP_ADDR -= (large_scroll_change);
383 break;
384 case ScrollEventType.LargeIncrement:
385 this.CURRENT_TOP_ADDR += (large_scroll_change);
386 break;
387 case ScrollEventType.ThumbPosition:
388 //this.CURRENT_TOP_ADDR = (uint)e.NewValue;
389 //break;
390 default:
391 this.CURRENT_TOP_ADDR = (uint)((uint)e.NewValue & 0xFFFFFFF0);
392 break;
393 }
394 if (this.CURRENT_TOP_ADDR < 0) this.CURRENT_TOP_ADDR = 0;
395 //if (this.CURRENT_TOP_ADDR >= VTLB_VADDR_SIZE) this.CURRENT_TOP_ADDR = VTLB_VADDR_SIZE - max_ram_view;
396 //if (this.CURRENT_TOP_ADDR < 0 || this.CURRENT_TOP_ADDR >= VTLB_VADDR_SIZE) this.CURRENT_TOP_ADDR = ORIGINAL_ADDR;
397 if (this.CURRENT_TOP_ADDR + max_ram_view >= MemorySize) this.CURRENT_TOP_ADDR = (size - 1) - max_ram_view;
398 //this.UpdateEnabled = reenable;
399 //isScrolling = false;
400 }
401 }
402 }