//#define USE_AUTOMATIC_MEMORY_SEARCH_RANGE // when defined will automatically choose the best starting address and size for memory search otherwise it will use the constants defined in MemorySizeConstants #if !USE_AUTOMATIC_MEMORY_SEARCH_RANGE #define FORCE_USE_OF_MEMORYSIZECONSTANTS // when defined wil force the use of the constants defined in MemorySizeConstants for memory search range #endif //#define DONOT_HAVE_RANGED_SEARCH_SUPPORT // when defined, indicates that ranged searches have not been implemented #define INCREASE_NUMBER_OF_RESULTS_BEFORE_DISPLAY // when defined will set MIN RESULTS to 0x2701 otherwise 0x03e8 //#define DO_NOT_SUSPEND_RESUME_THREAD_ON_FREEZE // when defined will not freeze/resume thread on freeze using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; using RomCheater.PluginFramework.Interfaces; using System.Diagnostics; using RomCheater.Docking.MemorySearch; using libWin32.Win32.Threading; using System.Threading; using RomCheater.Logging; using System.IO; using Sojaner.MemoryScanner.MemoryProviers; using RomCheater.PluginFramework.Events; using System.Reflection; using Sojaner.MemoryScanner; using System.Collections; using RomCheater.Serialization; namespace RomCheater.Docking { public partial class FloatingMemorySearcher : DockContent, IAcceptsPlugin, IAcceptsProcess, IAcceptsProcessAndConfig, ISearchInProgress, IAcceptsBrowseMemoryRegion, IAcceptsMemoryRange { #if INCREASE_NUMBER_OF_RESULTS_BEFORE_DISPLAY const int MIN_NUMBER_OF_RESULTS_BEFORE_DISPLAY = 0x2701; // 10,000 results #else const int MIN_NUMBER_OF_RESULTS_BEFORE_DISPLAY = 0x03e8; // 1,000 results #endif private bool DefaultUnsignedState = true; // set unsigned to true public FloatingMemorySearcher() { InitializeComponent(); this.AcceptedPlugin = null; OnBrowseMemoryRegion = null; this.AcceptedProcess = null; SearchInProgess = false; Reload(); } public FloatingMemorySearcher(IConfigPlugin config) : this() { this.AcceptedPlugin = config; } public FloatingMemorySearcher(IConfigPlugin config, Process process) : this() { this.AcceptedPlugin = config; this.AcceptedProcess = process; } #region IAcceptsProcess Members private Process _AcceptedProcess; public Process AcceptedProcess { get { return _AcceptedProcess; } set { _AcceptedProcess = value; UpdateAcceptedProcess(value); } } #endregion #region IAcceptsPlugin Members private IConfigPlugin _AcceptedPlugin; public IConfigPlugin AcceptedPlugin { get { return _AcceptedPlugin; } set { _AcceptedPlugin = value; UpdateAcceptedPlugin(value); } } #endregion #region IAcceptsBrowseMemoryRegion members public event BaseEventHandler OnBrowseMemoryRegion; #endregion private void UpdateAcceptedPlugin(IConfigPlugin config) { this.lstResults.AcceptedPlugin = config; this.lstPatchList.AcceptedPlugin = config; if (config != null) { MemoryRangeStart = AcceptedPlugin.MemoryRangeStart; MemoryRangeSize = AcceptedPlugin.MemoryRangeStart + AcceptedPlugin.MemoryRangeSize; } } private void UpdateAcceptedProcess(Process process) { this.lstResults.AcceptedProcess = process; this.lstPatchList.AcceptedProcess = process; #if USE_AUTOMATIC_MEMORY_SEARCH_RANGE && FORCE_USE_OF_MEMORYSIZECONSTANTS logger.Warn.WriteLine("FloatingMemorySearcher.UpdateAcceptedProcessAndConfig(IConfigPlugin config, Process process):"); logger.Warn.WriteLine("Both USE_AUTOMATIC_MEMORY_SEARCH_RANGE and FORCE_USE_OF_MEMORYSIZECONSTANTS are defined"); logger.Warn.WriteLine("FORCE_USE_OF_MEMORYSIZECONSTANTS will take precedence and will ignore the values supplied in the memeory search range"); #endif #if FORCE_USE_OF_MEMORYSIZECONSTANTS // force use of MemorySizeConstants txtMemoryRangeStart.Value = MemorySizeConstants.MinimumSearchAddress; txtMemoryRangeSize.Value = MemorySizeConstants.MinimumSearchAddress + MemorySizeConstants.MaximumSearchSize; #endif #if USE_AUTOMATIC_MEMORY_SEARCH_RANGE && !FORCE_USE_OF_MEMORYSIZECONSTANTS ////// code to automatically choose the best starting memory address and size //if (process != null) //{ // string filename = process.MainModule.FileName; // //string filename = @"c:\Windows\notepad.exe"; // PEReader peReader = new PEReader(filename); //} //else //{ //txtMemoryRangeStart.Value = MemorySizeConstants.MinimumSearchAddress; //txtMemoryRangeSize.Value = MemorySizeConstants.MinimumSearchAddress + MemorySizeConstants.MaximumSearchSize; //} if (AcceptedPlugin != null) { MemoryRangeStart = AcceptedPlugin.MemoryRangeStart; MemoryRangeSize = AcceptedPlugin.MemoryRangeStart + AcceptedPlugin.MemoryRangeSize; } #endif } #region ISearchInProgress members private bool _SearchInProgess; public bool SearchInProgess { get { return _SearchInProgess; } private set { _SearchInProgess = value; if (this.AcceptedPlugin != null) this.AcceptedPlugin.SetMemorySearchReference(this); } } #endregion #region IAcceptsMemoryRange #if !FORCE_USE_OF_MEMORYSIZECONSTANTS private uint _MemoryRangeStart; private uint _MemoryRangeSize; #endif public uint MemoryRangeStart { get { #if FORCE_USE_OF_MEMORYSIZECONSTANTS return MemorySizeConstants.MinimumSearchAddress; #else return _MemoryRangeStart; #endif } set { #if !FORCE_USE_OF_MEMORYSIZECONSTANTS _MemoryRangeStart = value; txtMemoryRangeStart.Value = value; #endif } } public uint MemoryRangeSize { get { #if FORCE_USE_OF_MEMORYSIZECONSTANTS return MemorySizeConstants.MinimumSearchAddress + MemorySizeConstants.MaximumSearchSize; #else return _MemoryRangeSize; #endif } set { #if !FORCE_USE_OF_MEMORYSIZECONSTANTS _MemoryRangeSize = value; txtMemoryRangeSize.Value = value; #endif } } #endregion public void Reload() { chkUnsigned.Checked = DefaultUnsignedState; radio_8bits.Checked = true; radiocompare_equal.Checked = true; radio_oldvalue.Checked = true; chkRefreshResults.Checked = true; } public enum eListViewResults { SEARCH_RESULTS_LIST = 0x3000, PATCH_RESULTS_LIST = 0x3001, UKNOWN_RESULTS_LIST = 0x3001 } bool IsFirstSearch = true; SearchType SearchArgs; static int col_Found_Address = 1; static int col_Found_Value = 2; static int col_Found_Frozen = 3; static int col_Added_Address = 1; static int col_Added_Value = 2; static int col_Added_Frozen = 3; List ResultItems = new List(); List AddedItems = new List(); private bool _PatchedValue_NeedsUpdate; bool PatchedValue_NeedsUpdate { get { if (_PatchedValue_NeedsUpdate) this.ThawResultsUpdate(); return _PatchedValue_NeedsUpdate; } set { _PatchedValue_NeedsUpdate = value; if (value) this.ThawResultsUpdate(); } } private delegate ListViewItem ThreadSafe_GetResultItem(int index, int lv_type); private ListViewItem GetResultItem(int index, int lv_type) { try { AddressValuePairList lv = null; switch (lv_type) { case (int)eListViewResults.SEARCH_RESULTS_LIST: lv = lstResults; break; case (int)eListViewResults.PATCH_RESULTS_LIST: lv = lstPatchList; break; default: throw new IndexOutOfRangeException("Detected: " + Enum.GetName(typeof(eListViewResults), eListViewResults.UKNOWN_RESULTS_LIST) + " with value: " + lv_type.ToString("x4")); } ListViewItem item = new ListViewItem(); item = (ListViewItem)lv.Items[index].Clone(); return item; } catch (Exception) { return null; } } private void radiocompare_equal_CheckedChanged(object sender, EventArgs e) { //if (!radiocompare_between.Checked && !radiocompare_notbetween.Checked) //{ if (radio_oldvalue.Checked) { txtStartAddr.ReadOnly = true; txtEndAddr.ReadOnly = true; } if (radio_specificvalue.Checked) { txtStartAddr.ReadOnly = false; txtEndAddr.ReadOnly = true; } //} } private void radiocompare_between_CheckedChanged(object sender, EventArgs e) { if (!radiocompare_equal.Checked && !radiocompare_greaterthan.Checked && !radiocompare_greaterthan.Checked && !radiocompare_lessthan.Checked && !radiocompare_greaterthan_orequal.Checked && !radiocompare_lessthan_orequal.Checked && !radiocompare_notequal.Checked) if (radiocompare_between.Checked) { txtStartAddr.ReadOnly = false; txtEndAddr.ReadOnly = false; return; } if (!radiocompare_between.Checked && !radiocompare_notbetween.Checked) { if (radio_oldvalue.Checked) { txtStartAddr.ReadOnly = true; txtEndAddr.ReadOnly = true; } if (radio_specificvalue.Checked) { txtStartAddr.ReadOnly = false; txtEndAddr.ReadOnly = true; } } } private void radiocompare_notbetween_CheckedChanged(object sender, EventArgs e) { if (!radiocompare_equal.Checked && !radiocompare_greaterthan.Checked && !radiocompare_greaterthan.Checked && !radiocompare_lessthan.Checked && !radiocompare_greaterthan_orequal.Checked && !radiocompare_lessthan_orequal.Checked && !radiocompare_notequal.Checked) if (radiocompare_notbetween.Checked) { txtStartAddr.ReadOnly = false; txtEndAddr.ReadOnly = false; return; } if (!radiocompare_between.Checked && !radiocompare_notbetween.Checked) { if (radio_oldvalue.Checked) { txtStartAddr.ReadOnly = true; txtEndAddr.ReadOnly = true; } if (radio_specificvalue.Checked) { txtStartAddr.ReadOnly = false; txtEndAddr.ReadOnly = true; } } } private void radio_8bits_CheckedChanged(object sender, EventArgs e) { if (chkUnsigned.Checked) { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } else { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } } private void radio_16bits_CheckedChanged(object sender, EventArgs e) { if (chkUnsigned.Checked) { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } else { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } } private void radio_32bits_CheckedChanged(object sender, EventArgs e) { if (chkUnsigned.Checked) { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } else { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } } private void radio_64bits_CheckedChanged(object sender, EventArgs e) { if (chkUnsigned.Checked) { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } else { txtStartAddr.CreateTypeSize(); txtEndAddr.CreateTypeSize(); } } private void radio_oldvalue_CheckedChanged(object sender, EventArgs e) { if (!radiocompare_between.Checked && !radiocompare_notbetween.Checked) { txtStartAddr.ReadOnly = true; txtEndAddr.ReadOnly = true; } } private void radio_specificvalue_CheckedChanged(object sender, EventArgs e) { if (!radiocompare_between.Checked && !radiocompare_notbetween.Checked) { txtStartAddr.ReadOnly = false; txtEndAddr.ReadOnly = true; } } private void chkRefreshResults_CheckedChanged(object sender, EventArgs e) { if (chkRefreshResults.Checked) { timer_update_results.Enabled = true; } else { timer_update_results.Enabled = false; ResultsUpdateWorkerThread.CancelAsync(); } } private void timer_update_results_Tick(object sender, EventArgs e) { if (chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) { ResultsUpdateWorkerThread.RunWorkerAsync(); } } private bool ShouldUpdateResults() { if (this.AcceptedProcess == null) return false; if (SearchWorkerThread.IsBusy) return false; //if (JokerSearchWorker.IsBusy) return false; if (this.IsResultsUpdateFrozen) return false; if (mnuAddedResults.Visible) return false; if (mnuResults.Visible) return false; if (Process.GetProcessById(this.AcceptedProcess.Id) == null) return false; if (lstResults.Items.Count > 0) return true; if (lstPatchList.Items.Count > 0) return true; return false; } private void ResultsUpdateWorkerThread_DoWork(object sender, DoWorkEventArgs e) { Thread.Sleep(250); // keep thread from blocking if (!this.ShouldUpdateResults()) return; ////if (SearchArgs == null) return; ////if (this.IsResultsUpdateFrozen) return; ////// put thread to sleep for 500ms ////System.Threading.Thread.Sleep(500); //PCSX2MemoryProvider provider = new PCSX2MemoryProvider(this.SearchPCSX2ProcessPID, resultslog); //byte[] buffered_mem = provider.GetMemory(); //MemoryStream ms = new MemoryStream(buffered_mem); //BinaryReader r_ms = new BinaryReader(ms); #region Update Results List ResultItems = new List(); //r_ms.BaseStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < lstResults.Items.Count; i++) { if (this.lstResults.InvokeRequired) { ThreadSafe_GetResultItem _get_item = new ThreadSafe_GetResultItem(GetResultItem); object item = this.lstResults.Invoke(_get_item, new object[] { i, (int)eListViewResults.SEARCH_RESULTS_LIST }); if (item != null) ResultItems.Add((ListViewItem)item); } else { ResultItems.Add(lstResults.Items[i]); } } for (int i = 0; i < ResultItems.Count; i++) { if (ResultsUpdateWorkerThread.CancellationPending == true) { e.Cancel = true; return; } int Address = 0; ResultDataType _result = (ResultDataType)ResultItems[i].Tag; Address = Convert.ToInt32(ResultItems[i].SubItems[col_Found_Address].Text, 16); //r_ms.BaseStream.Seek(Address, SeekOrigin.Begin); using (GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this)) { provider.OpenProvider(); int bytesReadSize; byte[] data; uint bytesToRead = 0; switch (_result.ValueType) { case SearchDataTypes._8bits: bytesToRead = 1; break; case SearchDataTypes._16bits: bytesToRead = 2; break; case SearchDataTypes._32bits: bytesToRead = 4; break; case SearchDataTypes._64bits: bytesToRead = 8; break; } provider.ReadProcessMemory(Address, bytesToRead, out bytesReadSize, out data); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader r_ms = new BinaryReader(ms)) { switch (_result.ValueType) { case SearchDataTypes._8bits: if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x2}", r_ms.ReadByte()); } else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x2}", r_ms.ReadSByte()); } break; case SearchDataTypes._16bits: if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x4}", r_ms.ReadUInt16()); } else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x4}", r_ms.ReadInt16()); } break; case SearchDataTypes._32bits: if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x8}", r_ms.ReadUInt32()); } else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x8}", r_ms.ReadInt32()); } break; case SearchDataTypes._64bits: if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x16}", r_ms.ReadUInt64()); } else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x16}", r_ms.ReadInt64()); } break; } r_ms.Close(); } } provider.CloseProvider(); } //Application.DoEvents(); } #endregion #region Update Added Results List AddedItems = new List(); //r_ms.BaseStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < lstPatchList.Items.Count; i++) { if (this.lstResults.InvokeRequired) { ThreadSafe_GetResultItem _get_item = new ThreadSafe_GetResultItem(GetResultItem); object item = this.lstResults.Invoke(_get_item, new object[] { i, (int)eListViewResults.PATCH_RESULTS_LIST }); if (item != null) AddedItems.Add((ListViewItem)item); } else { AddedItems.Add(lstPatchList.Items[i]); } } for (int i = 0; i < AddedItems.Count; i++) { if (ResultsUpdateWorkerThread.CancellationPending == true) { e.Cancel = true; return; } int Address = 0; ResultDataType _result = (ResultDataType)AddedItems[i].Tag; Address = Convert.ToInt32(AddedItems[i].SubItems[col_Added_Address].Text, 16); using (GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this)) { provider.OpenProvider(); int bytesReadSize; byte[] data; uint bytesToRead = 0; switch (_result.ValueType) { case SearchDataTypes._8bits: bytesToRead = 1; break; case SearchDataTypes._16bits: bytesToRead = 2; break; case SearchDataTypes._32bits: bytesToRead = 4; break; case SearchDataTypes._64bits: bytesToRead = 8; break; } provider.ReadProcessMemory(Address, bytesToRead, out bytesReadSize, out data); provider.CloseProvider(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader r_ms = new BinaryReader(ms)) { switch (_result.ValueType) { case SearchDataTypes._8bits: if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x2}", r_ms.ReadByte()); } else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x2}", r_ms.ReadSByte()); } break; case SearchDataTypes._16bits: if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x4}", r_ms.ReadUInt16()); } else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x4}", r_ms.ReadInt16()); } break; case SearchDataTypes._32bits: if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x8}", r_ms.ReadUInt32()); } else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x8}", r_ms.ReadInt32()); } break; case SearchDataTypes._64bits: if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x16}", r_ms.ReadUInt64()); } else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x16}", r_ms.ReadInt64()); } break; } r_ms.Close(); } } } //Application.DoEvents(); } #endregion } private void ResultsUpdateWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { try { //if ((lstResults.SelectedItems.Count > 0) && !PatchedValue_NeedsUpdate ) return; //if ((lstPatchList.SelectedItems.Count > 0) && !PatchedValue_NeedsUpdate) return; if (!this.ShouldUpdateResults()) return; if (ResultItems.Count > 0) { //lstResults.Items.Clear(); //lstResults.Items.AddRange(ResultItems.ToArray()); for (int i = 0; i < ResultItems.Count; i++) { lstResults.Items[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text = ResultItems[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text; } } if (AddedItems.Count > 0) { //lstPatchList.Items.Clear(); //lstPatchList.Items.AddRange(AddedItems.ToArray()); for (int i = 0; i < AddedItems.Count; i++) { lstPatchList.Items[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text = AddedItems[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text; } } PatchedValue_NeedsUpdate = false; } catch { } } private void btnImportFile_Click(object sender, EventArgs e) { this.FreezeResultsUpdate(); if (!lstPatchList.ImportFromFile()) { MessageBox.Show("Failed to Import Patch List from File.", "Import Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); this.ThawResultsUpdate(); return; } else { MessageBox.Show("Succesfully Imported Patch List from File.", "Import Success", MessageBoxButtons.OK, MessageBoxIcon.Information); this.ThawResultsUpdate(); return; } } bool g_isFrozen = false; private bool IsResultsUpdateFrozen { get { return g_isFrozen; } set { g_isFrozen = value; } } private void ThawResultsUpdate() { this.IsResultsUpdateFrozen = false; if (this.AcceptedProcess != null) { #if !DO_NOT_SUSPEND_RESUME_THREAD_ON_FREEZE ThreadControl.ResumeProcess(this.AcceptedProcess.Id); #endif } } private void FreezeResultsUpdate() { this.IsResultsUpdateFrozen = true; //this.IsResultsUpdateFrozen = false; if (this.AcceptedProcess != null) { #if !DO_NOT_SUSPEND_RESUME_THREAD_ON_FREEZE ThreadControl.SuspendProcess(this.AcceptedProcess.Id); #endif } } private void btnExportFile_Click(object sender, EventArgs e) { this.FreezeResultsUpdate(); if (!lstPatchList.ExportToFile()) { MessageBox.Show("Failed to Export Patch List to File.", "Export Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); this.ThawResultsUpdate(); return; } else { MessageBox.Show("Succesfully Exported Patch List to File.", "Export Success", MessageBoxButtons.OK, MessageBoxIcon.Information); this.ThawResultsUpdate(); return; } } private void btnImportClipboard_Click(object sender, EventArgs e) { this.FreezeResultsUpdate(); if (!lstPatchList.ImportFromClipboard()) { MessageBox.Show("Failed to Import Patch List from Clipboard.", "Import Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); this.ThawResultsUpdate(); return; } else { MessageBox.Show("Succesfully Import Patch List from Clipboard.", "Import Success", MessageBoxButtons.OK, MessageBoxIcon.Information); this.ThawResultsUpdate(); } } private void btnExportClipboard_Click(object sender, EventArgs e) { this.FreezeResultsUpdate(); if (!lstPatchList.ExportToClipboard()) { MessageBox.Show("Failed to Export Patch List to Clipboard.", "Export Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); this.ThawResultsUpdate(); return; } else { MessageBox.Show("Succesfully Exported Patch List to Clipboard.", "Export Success", MessageBoxButtons.OK, MessageBoxIcon.Information); this.ThawResultsUpdate(); return; } } private void btnAddPatchAddress_Click(object sender, EventArgs e) { PatchAdder adder = new PatchAdder((IAcceptsProcessAndConfig)this); adder.ShowDialog(); if (adder.WasAPatchAdded) AddToPatchList(adder.AddedPatchValue); } private void btnAddAddressRange_Click(object sender, EventArgs e) { PatchRangeAdder adder = new PatchRangeAdder((IAcceptsProcessAndConfig)this); adder.ShowDialog(); if (adder.WasAPatchAdded) AddToPatchList(adder.AddedPatchValue); } private void AddToPatchList(List item) { foreach (ResultDataType data in item) { AddToPatchList(data); } } private void AddToPatchList(ResultDataType item) { ResultItem item2 = null; switch (item.ValueType) { case SearchDataTypes._8bits: if (item.IsUnsigned) { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToByte(item.Value)); } else { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToSByte(item.Value)); } break; case SearchDataTypes._16bits: if (item.IsUnsigned) { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToUInt16(item.Value)); } else { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToInt16(item.Value)); } break; case SearchDataTypes._32bits: if (item.IsUnsigned) { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToUInt32(item.Value)); } else { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToInt32(item.Value)); } break; case SearchDataTypes._64bits: if (item.IsUnsigned) { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToUInt64(item.Value)); } else { item2 = new ResultItem(item.Address, item.IsFrozen, Convert.ToInt64(item.Value)); } break; } this.AddToPatchList(item2); } private void AddToPatchList(ListViewItem item) { try { ResultDataType _result = (ResultDataType)item.Tag; this.AddToPatchList(_result); } catch (InvalidCastException ex) { // unable to cast MessageBox.Show(ex.Message, "Invalid Cast Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { // other exception MessageBox.Show(ex.Message, "Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void AddToPatchList(ResultItem item) { if (!lstPatchList.Items.Contains(item)) lstPatchList.Items.Add(item); } private void AddToPatchList(string address, SearchDataTypes bitsize, bool IsUnsigned) { ResultItemState state = new ResultItemState(address, bitsize, IsUnsigned, (IAcceptsProcessAndConfig)this); ResultItem item = new ResultItem(state.Address, state.Value, state.Frozen, state.ValueType, state.IsUnsigned); this.AddToPatchList(item); } private void mnuItemAddToPatchList_Click(object sender, EventArgs e) { if (!(lstResults.SelectedItems.Count > 0)) return; //if (SearchArgs == null) return; try { for (int i = 0; i < lstResults.SelectedIndices.Count; i++) { //ResultDataType result = (ResultDataType)lstResults.Items[selected_index].Tag; ListViewItem item = lstResults.Items[lstResults.SelectedIndices[i]]; this.AddToPatchList(item); } } catch (Exception ex) { logger.Error.WriteLine(ex.ToString()); } } private void mnuItemRemoveResult_Click(object sender, EventArgs e) { if (!(lstPatchList.SelectedItems.Count > 0)) return; //if (SearchArgs == null) return; try { this.FreezeResultsUpdate(); for (int i = 0; i < lstPatchList.SelectedIndices.Count; i++) { //lstPatchList.ThawItem(lstPatchList.SelectedIndices[i]); lstPatchList.Items[lstPatchList.SelectedIndices[i]].Remove(); } this.ThawResultsUpdate(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } private void PatchRange(bool SingleEntry) { //if (SearchArgs == null) return; #region Patch Selected Address // stop ResultsUpdate Thread ResultsUpdateWorkerThread.CancelAsync(); List patch_list = new List(); List SelectedIndexes = new List(); if (SingleEntry) { SelectedIndexes.Add(lstPatchList.SelectedIndices[0]); } else { foreach (int index in lstPatchList.SelectedIndices) { SelectedIndexes.Add(index); } } //PCSX2MemoryProvider provider = new PCSX2MemoryProvider(this.SearchPCSX2ProcessPID, resultslog); foreach (int index in SelectedIndexes) { if (SingleEntry) { SearchPatcher patcher = null; uint Address = 0; ListViewItem item = lstPatchList.Items[index]; ResultDataType _result = (ResultDataType)item.Tag; Address = Convert.ToUInt32(item.SubItems[col_Found_Address].Text, 16); switch (_result.ValueType) { case SearchDataTypes._8bits: if (_result.IsUnsigned) { byte value = Convert.ToByte(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } else { sbyte value = Convert.ToSByte(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } break; case SearchDataTypes._16bits: if (_result.IsUnsigned) { ushort value = Convert.ToUInt16(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } else { short value = Convert.ToInt16(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } break; case SearchDataTypes._32bits: if (_result.IsUnsigned) { uint value = Convert.ToUInt32(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } else { int value = Convert.ToInt32(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } break; case SearchDataTypes._64bits: if (_result.IsUnsigned) { ulong value = Convert.ToUInt32(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } else { long value = Convert.ToInt32(item.SubItems[col_Found_Value].Text, 16); patcher = new SearchPatcher((IAcceptsProcessAndConfig)this, Address, value); timer_update_results.Enabled = false; patcher.ShowDialog(); timer_update_results.Enabled = true; PatchedValue_NeedsUpdate = true; if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy) ResultsUpdateWorkerThread.RunWorkerAsync(); } break; } } else { ListViewItem item = lstPatchList.Items[index]; ResultDataType _result = (ResultDataType)item.Tag; patch_list.Add(_result); } } if (patch_list.Count > 0) { SearchRangePatcher rangePatcher = new SearchRangePatcher((IAcceptsProcessAndConfig)this, patch_list); rangePatcher.ShowDialog(); } #endregion } private void mnuItemPatchSelectedEntry_Click(object sender, EventArgs e) { if (!(lstPatchList.SelectedItems.Count == 1)) return; PatchRange(true); } private void mnuItemPatchSelectedRange_Click(object sender, EventArgs e) { if (!(lstPatchList.SelectedItems.Count >= 1)) return; PatchRange(false); } private void mnuItemFreezeSelectedPatches_Click(object sender, EventArgs e) { if (!(lstPatchList.SelectedItems.Count > 0)) return; //if (SearchArgs == null) return; try { lstPatchList.ProcessID = this.AcceptedProcess.Id; this.FreezeResultsUpdate(); for (int i = 0; i < lstPatchList.SelectedIndices.Count; i++) { lstPatchList.FreezeItem(lstPatchList.SelectedIndices[i]); } // force thaw and update this.ThawResultsUpdate(); this.Update(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } private void mnuItemThawSelectedPatches_Click(object sender, EventArgs e) { if (!(lstPatchList.SelectedItems.Count > 0)) return; //if (SearchArgs == null) return; try { lstPatchList.ProcessID = this.AcceptedProcess.Id; this.FreezeResultsUpdate(); for (int i = 0; i < lstPatchList.SelectedIndices.Count; i++) { lstPatchList.ThawItem(lstPatchList.SelectedIndices[i]); } // force thaw and update this.ThawResultsUpdate(); this.Update(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } private void SearchWorkerThread_DoWork(object sender, DoWorkEventArgs e) { Stopwatch st = new Stopwatch(); st.Start(); Stopwatch st_first_search = new Stopwatch(); Stopwatch st_nonrange_search = new Stopwatch(); Stopwatch st_ranged_search = new Stopwatch(); e.Result = st; //List> tmp_Results = new List>(); List> second_tmp_Results = new List>(); //const int ElementsBeforeDisplay = 100; SearchArgs.LogSearchOptions(); uint STEP_SIZE = (uint)SearchArgs.DataType / 8; bool unsigned = SearchArgs.IsUnsignedDataType; SearchDataTypes sdt = SearchArgs.DataType; byte[] buffered_mem = new byte[(MemoryRangeSize - MemoryRangeStart)]; // throws OutOfMemoryException if size is over 2G using (GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this)) { provider.OpenProvider(); int bytes_read = 0; provider.ReadProcessMemoryAtOnce(MemoryRangeStart, (MemoryRangeSize - MemoryRangeStart), out bytes_read, out buffered_mem); provider.CloseProvider(); } if (buffered_mem.Length == 0) { logger.Warn.WriteLine("Buffered Memory is Zero Length."); return; } using (MemoryStream ms = new MemoryStream(buffered_mem)) { using (BinaryReader r_ms = new BinaryReader(ms)) { logger.Debug.WriteLine(string.Format("Buffered Memory Size -> 0x{0:x8}", buffered_mem.Length)); int Last_Whole_Percent_Done = 0; #region First Search if (SearchArgs.IsFirstSearch) { st_first_search.Start(); //SearchArgs.Results.Clear(); r_ms.BaseStream.Seek(0, SeekOrigin.Begin); int count = (int)buffered_mem.Length / (int)STEP_SIZE; #region using (SearchResultWriter writer = new SearchResultWriter(count)) using (SearchResultWriter writer = new SearchResultWriter(count)) { //List> results_list = new List>(); //for (uint i = 0; i < buffered_mem.Length; i += STEP_SIZE) //{ #region while (r_ms.BaseStream.Position < r_ms.BaseStream.Length) while (r_ms.BaseStream.Position < r_ms.BaseStream.Length) { //using (ResultType _tmp_result = new ResultType()) //{ switch (sdt) { case SearchDataTypes._8bits: if (unsigned) { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadByte()); } else { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadSByte()); } break; case SearchDataTypes._16bits: if (unsigned) { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadUInt16()); } else { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadInt16()); } break; case SearchDataTypes._32bits: if (unsigned) { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadUInt32()); } else { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadInt32()); } break; case SearchDataTypes._64bits: if (unsigned) { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadUInt64()); } else { writer.WriteResult((uint)r_ms.BaseStream.Position, r_ms.ReadInt64()); } break; } //results_list.Add(_tmp_result); //SearchArgs.Results.Add(_tmp_result); double double_percent_done = 100.0 * (double)((double)r_ms.BaseStream.Position / (double)r_ms.BaseStream.Length); int int_percent_done = (int)double_percent_done; if (int_percent_done != Last_Whole_Percent_Done) { if (int_percent_done <= 100) { resultsprogress.Value = int_percent_done; resultsprogress.Message = string.Format(" -> Reading Address: 0x{0:x8}", (r_ms.BaseStream.Position + MemoryRangeStart)); Last_Whole_Percent_Done = int_percent_done; } } } if (SearchWorkerThread.CancellationPending == true) { e.Cancel = true; return; } #endregion } #endregion //} //SearchArgs.Results.AddRange(results_list); //results_list = null; resultsprogress.Value = 100; resultsprogress.Message = ""; //Application.DoEvents(); st_first_search.Stop(); logger.Profiler.WriteLine("First search took a total of {0} seconds to complete.", st_first_search.Elapsed.TotalSeconds); Last_Whole_Percent_Done = 0; } #endregion #region Subsequent Searches r_ms.BaseStream.Seek(0, SeekOrigin.Begin); // hack to help with OutOfMemory Exceptions (OldValue and Equal compare will always add all found search results) bool NeedToCompare = true; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue && SearchArgs.CompareType == SearchCompareTypes.Equal && SearchArgs.IsFirstSearch) { NeedToCompare = false; //second_tmp_Results = null; // Free Memory } if (NeedToCompare) { if (SearchArgs.CompareType != SearchCompareTypes.Between && SearchArgs.CompareType != SearchCompareTypes.NotBetween) { #region Non-Range Searches st_nonrange_search.Start(); //second_tmp_Results = new List>(SearchArgs.Results.Count * 1024); ////second_tmp_Results.c using (SearchResultReader reader = new SearchResultReader()) { for (int i = 0; i < reader.ResultCount; i += 1) { if (reader.ReadCurrentAddess) { if (!reader.ReadCurrentValue) { switch (SearchArgs.DataType) { case SearchDataTypes._8bits: if (unsigned) { reader.CurrentResult(); } else { reader.CurrentResult(); } break; case SearchDataTypes._16bits: if (unsigned) { reader.CurrentResult(); } else { reader.CurrentResult(); } break; case SearchDataTypes._32bits: if (unsigned) { reader.CurrentResult(); } else { reader.CurrentResult(); } break; case SearchDataTypes._64bits: if (unsigned) { reader.CurrentResult(); } else { reader.CurrentResult(); } break; } } } uint address = reader.CurrentAddress(); if (MemoryRangeStart > 0 && !SearchArgs.IsFirstSearch) { address = address - MemoryRangeStart; } try { r_ms.BaseStream.Seek(address, SeekOrigin.Begin); } catch(Exception) { throw; } switch (SearchArgs.DataType) { #region Comparer Support #region case SearchDataTypes._8bits: case SearchDataTypes._8bits: if (SearchArgs.IsUnsignedDataType) { byte lookup_value = r_ms.ReadByte(); _8bit_unsigned_comparer_ comparer = new _8bit_unsigned_comparer_(SearchArgs, address); byte value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); comparer.Value = value; } else { value = Convert.ToByte(SearchArgs.CompareStartValue); comparer.Value = value; } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } else { sbyte lookup_value = r_ms.ReadSByte(); _8bit_signed_comparer_ comparer = new _8bit_signed_comparer_(SearchArgs, address); sbyte value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); } else { value = Convert.ToSByte(SearchArgs.CompareStartValue); } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } break; #endregion #region case SearchDataTypes._16bits: case SearchDataTypes._16bits: if (SearchArgs.IsUnsignedDataType) { ushort lookup_value = r_ms.ReadUInt16(); _16bit_unsigned_comparer_ comparer = new _16bit_unsigned_comparer_(SearchArgs, address); ushort value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); comparer.Value = value; } else { value = Convert.ToUInt16(SearchArgs.CompareStartValue); comparer.Value = value; } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } else { short lookup_value = r_ms.ReadInt16(); _16bit_signed_comparer_ comparer = new _16bit_signed_comparer_(SearchArgs, address); short value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); } else { value = Convert.ToInt16(SearchArgs.CompareStartValue); } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } break; #endregion #region case SearchDataTypes._32bits: case SearchDataTypes._32bits: if (SearchArgs.IsUnsignedDataType) { uint lookup_value = r_ms.ReadUInt32(); _32bit_unsigned_comparer_ comparer = new _32bit_unsigned_comparer_(SearchArgs, address); uint value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); comparer.Value = value; } else { value = Convert.ToUInt32(SearchArgs.CompareStartValue); comparer.Value = value; } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } else { int lookup_value = r_ms.ReadInt32(); _32bit_signed_comparer_ comparer = new _32bit_signed_comparer_(SearchArgs, address); int value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); } else { value = Convert.ToInt32(SearchArgs.CompareStartValue); } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } break; #endregion #region case SearchDataTypes._64bits: case SearchDataTypes._64bits: if (SearchArgs.IsUnsignedDataType) { ulong lookup_value = r_ms.ReadUInt64(); _64bit_unsigned_comparer_ comparer = new _64bit_unsigned_comparer_(SearchArgs, address); ulong value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); comparer.Value = value; } else { value = Convert.ToUInt64(SearchArgs.CompareStartValue); comparer.Value = value; } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } else { long lookup_value = r_ms.ReadInt64(); _64bit_signed_comparer_ comparer = new _64bit_signed_comparer_(SearchArgs, address); long value = 0; if (SearchArgs.CompareValueType == CompareValueTypes.OldValue) { value = reader.CurrentResult(); } else { value = Convert.ToInt64(SearchArgs.CompareStartValue); } if (comparer.Compare(lookup_value, value)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; // free memory } break; #endregion #endregion } double double_percent_done = 100.0 * (double)((double)i / (double)reader.ResultCount); int int_percent_done = (int)double_percent_done; if (int_percent_done != Last_Whole_Percent_Done) { if (int_percent_done <= 100) { resultsprogress.Value = int_percent_done; resultsprogress.Message = string.Format(" -> Reading Address: 0x{0:x8}", i + MemoryRangeStart); Last_Whole_Percent_Done = int_percent_done; } } } } st_nonrange_search.Stop(); logger.Profiler.WriteLine("Non-Ranged search took a total of {0} seconds to complete.", st_nonrange_search.Elapsed.TotalSeconds); Last_Whole_Percent_Done = 0; #endregion } #region Ranged Searches #if !DONOT_HAVE_RANGED_SEARCH_SUPPORT if (SearchArgs.CompareType == SearchCompareTypes.Between || SearchArgs.CompareType == SearchCompareTypes.NotBetween) { st_ranged_search.Start(); object start, end; start = SearchArgs.CompareStartValue; end = SearchArgs.CompareEndValue; using (SearchResultReader reader = new SearchResultReader()) { for (int i = 0; i < reader.ResultCount; i += 1) { uint address = reader.CurrentAddress(); if (MemoryRangeStart > 0 && !SearchArgs.IsFirstSearch) { address = address - MemoryRangeStart; } r_ms.BaseStream.Seek(address, SeekOrigin.Begin); if (SearchArgs.CompareType == SearchCompareTypes.Between) { InRangeComparer comparer = new InRangeComparer(address, 0); if (comparer.Compare(start, end, SearchArgs.DataType, SearchArgs.IsUnsignedDataType, r_ms)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; } else if (SearchArgs.CompareType == SearchCompareTypes.NotBetween) { NotInRangeComparer comparer = new NotInRangeComparer(address, 0); if (comparer.Compare(start, end, SearchArgs.DataType, SearchArgs.IsUnsignedDataType, r_ms)) { ResultType _tmp_result = new ResultType(comparer.Address, comparer.Value); second_tmp_Results.Add(_tmp_result); } comparer = null; } else { throw new InvalidOperationException("Encounted unkown range search type: " + SearchArgs.CompareType); } double double_percent_done = 100.0 * (double)((double)i / (double)reader.ResultCount); int int_percent_done = (int)double_percent_done; if (int_percent_done != Last_Whole_Percent_Done) { if (int_percent_done <= 100) { resultsprogress.Value = int_percent_done; resultsprogress.Message = string.Format(" -> Reading Address: 0x{0:x8}", i + MemoryRangeStart); Last_Whole_Percent_Done = int_percent_done; } } } } st_ranged_search.Stop(); logger.Profiler.WriteLine("Ranged search took a total of {0} seconds to complete.", st_ranged_search.Elapsed.TotalSeconds); } #endif #endregion } #endregion // leave SearchArgs.Results alone, if false if (NeedToCompare) { // fix addresses when memory start is not zero if (MemoryRangeStart > 0 && SearchArgs.IsFirstSearch) { for (int i = 0; i < second_tmp_Results.Count; i++) { second_tmp_Results[i].Address = second_tmp_Results[i].Address + MemoryRangeStart; } } using (SearchResultWriter writer = new SearchResultWriter(second_tmp_Results.Count)) { for (int i = 0; i < second_tmp_Results.Count; i++) { switch (sdt) { case SearchDataTypes._8bits: if (unsigned) { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToByte(second_tmp_Results[i].Value)); } else { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToSByte(second_tmp_Results[i].Value)); } break; case SearchDataTypes._16bits: if (unsigned) { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToUInt16(second_tmp_Results[i].Value)); } else { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToInt16(second_tmp_Results[i].Value)); } break; case SearchDataTypes._32bits: if (unsigned) { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToUInt32(second_tmp_Results[i].Value)); } else { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToInt32(second_tmp_Results[i].Value)); } break; case SearchDataTypes._64bits: if (unsigned) { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToUInt64(second_tmp_Results[i].Value)); } else { writer.WriteResult(second_tmp_Results[i].Address, Convert.ToInt64(second_tmp_Results[i].Value)); } break; } } } second_tmp_Results = null; // free memory } r_ms.Close(); } } } private void SearchWorkerThread_ProgressChanged(object sender, ProgressChangedEventArgs e) { //if (SearchArgs.ProgressLogger != null) //{ // resultsprogress.Value = e.ProgressPercentage; // //Application.DoEvents(); //} } private void SearchWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (!e.Cancelled) { Stopwatch st = (e.Result as Stopwatch); st.Stop(); logger.Profiler.WriteLine("Search took {0} seconds, overall, to complete.", st.Elapsed.TotalSeconds); } resultsprogress.Value = 100; using (SearchResultReader reader = new SearchResultReader()) { logger.Debug.WriteLine(string.Format("Results Count -> 0x{0:x8}", reader.ResultCount)); if (reader.ResultCount == 1) // debug message for 1 result using 32bit unsigned logger.Debug.WriteLine(string.Format("Debug: Found 1 result -> Address: 0x{0:x8} Value: 0x{1:x16}", reader.CurrentAddress(), reader.CurrentResult())); logger.Info.WriteLine(string.Format("Found 0x{0:x8} results", reader.ResultCount)); if (reader.ResultCount <= MIN_NUMBER_OF_RESULTS_BEFORE_DISPLAY) { lstResults.Items.Clear(); List items = new List(); for (int i = 0; i < reader.ResultCount; i++) { ResultItem item = new ResultItem(0, false); //item.Text = string.Format("0x{0:x8}", SearchArgs.Results[i].Address); //item.SubItems.Add(string.Format("0x{0:x8}", SearchArgs.Results[i].Address)); switch (SearchArgs.DataType) { case SearchDataTypes._8bits: if (SearchArgs.IsUnsignedDataType) { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } else { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } break; case SearchDataTypes._16bits: if (SearchArgs.IsUnsignedDataType) { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } else { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } break; case SearchDataTypes._32bits: if (SearchArgs.IsUnsignedDataType) { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } else { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } break; case SearchDataTypes._64bits: if (SearchArgs.IsUnsignedDataType) { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } else { item = new ResultItem(reader.CurrentAddress(), false, reader.CurrentResult()); } break; } if (!items.Contains(item)) items.Add(item); } lstResults.Items.AddRange(items.ToArray()); } } this.DoSearchDoneSpecific(); //System.Threading.Thread.Sleep(100); //if (_SEARCH_MODE != SearchMode.SEARCH_MODE_NORMAL_WITH_JOKER) this.ThawResultsUpdate(); Application.DoEvents(); } private void DoSearchDoneSpecific() { SearchWorkerThread.CancelAsync(); if (lstResults.Items.Count > 0) { timer_update_results.Enabled = true; } else { timer_update_results.Enabled = false; } search_progress_updater.Enabled = false; btnCancel.Enabled = false; btnReset.Enabled = true; btnSearch.Enabled = true; grpCompareType.Enabled = true; grpCompareValue.Enabled = true; resultsprogress.Value = 0; resultsprogress.Message = ""; grpDataType.Enabled = false; // resume process on reset, incase it was suspended ThreadControl.ResumeProcess(this.AcceptedProcess.Id); //Application.DoEvents(); this.Refresh(); } private void DoCancelSpecific() { this.DoSearchDoneSpecific(); } private void DoResetSpecific() { this.DoCancelSpecific(); IsFirstSearch = true; grpDataType.Enabled = true; } private void search_progress_updater_Tick(object sender, EventArgs e) { if ((this.AcceptedProcess ==null) || Process.GetProcessById(this.AcceptedProcess.Id) == null) { SearchWorkerThread.CancelAsync(); //JokerSearchWorker.CancelAsync(); ResultsUpdateWorkerThread.CancelAsync(); } } #region Search Button private void btnSearch_Click(object sender, EventArgs e) { this.SearchInProgess = true; //btnCancel.Enabled = true; //btnReset.Enabled = false; //btnSearch.Enabled = false; this.FreezeResultsUpdate(); this.handle_btnSearch_Click(); } private void handle_btnSearch_Click() { //this.FreezeResultsUpdate(); lstResults.Items.Clear(); if (lstResults.Items.Count > 0) { timer_update_results.Enabled = true; } else { timer_update_results.Enabled = false; } resultsprogress.Value = 0; bool _is_unsigned = chkUnsigned.Checked; SearchType search_type = new SearchType(); SearchDataTypes _data_type = new SearchDataTypes(); SearchCompareTypes _compare_type = new SearchCompareTypes(); CompareValueTypes _compare_value_type = new CompareValueTypes(); object start_value = 0; object end_value = 0; // get datatype if (radio_8bits.Checked) { _data_type = SearchDataTypes._8bits; } else if (radio_16bits.Checked) { _data_type = SearchDataTypes._16bits; } else if (radio_32bits.Checked) { _data_type = SearchDataTypes._32bits; } else if (radio_64bits.Checked) { _data_type = SearchDataTypes._64bits; } else { logger.Error.WriteLine("Could not determine search data type bit size. (was not 8/16/32/or 64bits)"); } // get compare type if (radiocompare_equal.Checked) { _compare_type = SearchCompareTypes.Equal; } else if (radiocompare_greaterthan.Checked) { _compare_type = SearchCompareTypes.GreaterThan; } else if (radiocompare_lessthan.Checked) { _compare_type = SearchCompareTypes.LessThan; } else if (radiocompare_greaterthan_orequal.Checked) { _compare_type = SearchCompareTypes.GreaterThanOrEqual; } else if (radiocompare_lessthan_orequal.Checked) { _compare_type = SearchCompareTypes.LessThanOrEqual; } else if (radiocompare_notequal.Checked) { _compare_type = SearchCompareTypes.NotEqual; } else if (radiocompare_between.Checked) { _compare_type = SearchCompareTypes.Between; } else if (radiocompare_notbetween.Checked) { _compare_type = SearchCompareTypes.NotBetween; } else { logger.Error.WriteLine("Could not determine search comparison type. (was not == > < >= <= != <> or !<>)"); } // get compare valure type if (radio_oldvalue.Checked) { _compare_value_type = CompareValueTypes.OldValue; } else if (radio_specificvalue.Checked) { _compare_value_type = CompareValueTypes.SpecificValue; } else { logger.Error.WriteLine("Could not determine search comparison type. (was not old or specific value"); } if (_compare_value_type == CompareValueTypes.SpecificValue || (_compare_type == SearchCompareTypes.Between || _compare_type == SearchCompareTypes.NotBetween)) { switch (_data_type) { case SearchDataTypes._8bits: if (_is_unsigned) { start_value = txtStartAddr.ToByte(); } else { start_value = txtStartAddr.ToSByte(); } break; case SearchDataTypes._16bits: if (_is_unsigned) { start_value = txtStartAddr.ToUInt16(); } else { start_value = txtStartAddr.ToInt16(); } break; case SearchDataTypes._32bits: if (_is_unsigned) { start_value = txtStartAddr.ToUInt32(); } else { start_value = txtStartAddr.ToInt32(); } break; case SearchDataTypes._64bits: if (_is_unsigned) { start_value = txtStartAddr.ToUInt64(); } else { start_value = txtStartAddr.ToInt64(); } break; default: throw new InvalidOperationException("In SearchType(): Encounterd an Unkown Search Data Type."); } } if (_compare_type == SearchCompareTypes.Between || _compare_type == SearchCompareTypes.NotBetween) { switch (_data_type) { case SearchDataTypes._8bits: if (_is_unsigned) { end_value = txtEndAddr.ToByte(); } else { end_value = txtEndAddr.ToSByte(); } break; case SearchDataTypes._16bits: if (_is_unsigned) { end_value = txtEndAddr.ToUInt16(); } else { end_value = txtEndAddr.ToInt16(); } break; case SearchDataTypes._32bits: if (_is_unsigned) { end_value = txtEndAddr.ToUInt32(); } else { end_value = txtEndAddr.ToInt32(); } break; case SearchDataTypes._64bits: if (_is_unsigned) { end_value = txtEndAddr.ToUInt64(); } else { end_value = txtEndAddr.ToInt64(); } break; default: throw new InvalidOperationException("In SearchType(): Encounterd an Unkown Search Data Type."); } } search_type = new SearchType(_data_type, _is_unsigned, _compare_type, _compare_value_type, start_value, end_value, resultsprogress); //search_type.LogSearchOptions(); search_type.IsFirstSearch = IsFirstSearch; DoSearch(search_type); IsFirstSearch = false; } private void DoSearch(SearchType args) { if (!args.IsFirstSearch && SearchArgs != null) { //args.Results.AddRange(SearchArgs.Results.ToArray()); //args.Results = SearchArgs.Results; } SearchArgs = args; #if DONOT_HAVE_RANGED_SEARCH_SUPPORT if (SearchArgs.CompareType == SearchCompareTypes.Between || SearchArgs.CompareType == SearchCompareTypes.NotBetween) { throw new NotImplementedException("Between and Not Between Range searches have not been implemented."); } #endif search_progress_updater.Enabled = true; //padPluginSelector.Enabled = false; //gsPluginSelector.Enabled = false; btnReset.Enabled = false; btnSearch.Enabled = false; btnCancel.Enabled = true; grpDataType.Enabled = false; grpCompareType.Enabled = false; grpCompareValue.Enabled = false; this.Refresh(); Application.DoEvents(); SearchWorkerThread.RunWorkerAsync(); } #endregion private void btnReset_Click(object sender, EventArgs e) { this.SearchInProgess = false; //btnSearch.Enabled = true; //btnCancel.Enabled = false; this.DoResetSpecific(); lstResults.Items.Clear(); //try { SearchArgs.Results = new List>(); } //catch { } } private void btnCancel_Click(object sender, EventArgs e) { this.SearchInProgess = false; //btnCancel.Enabled = false; //btnSearch.Enabled = true; //btnReset.Enabled = true; this.DoCancelSpecific(); } private void mnuItemPatchListViewMemoryRegion_Click(object sender, EventArgs e) { List patch_list = new List(); List SelectedIndexes = new List(); foreach (int index in lstPatchList.SelectedIndices) { SelectedIndexes.Add(index); } foreach (int index in SelectedIndexes) { ListViewItem item = lstPatchList.Items[index]; ResultDataType rdt = (ResultDataType)item.Tag; ViewMemoryRegion(rdt); break; // only get the fist item } } private void mnuItemResultsListViewMemoryRegion_Click(object sender, EventArgs e) { List patch_list = new List(); List SelectedIndexes = new List(); foreach (int index in lstResults.SelectedIndices) { SelectedIndexes.Add(index); } foreach (int index in SelectedIndexes) { ListViewItem item = lstResults.Items[index]; ResultDataType rdt = (ResultDataType)item.Tag; ViewMemoryRegion(rdt); break; // only get the fist item } } private void ViewMemoryRegion(ResultDataType rdt) { if (OnBrowseMemoryRegion != null) OnBrowseMemoryRegion(new BrowseMemoryRegionEvent(this, rdt.Address)); } private void mnuAddedResults_Opening(object sender, CancelEventArgs e) { if (!(lstPatchList.Items.Count > 0)) { mnuItemRemoveResult.Visible = false; e.Cancel = true; } if (!(lstPatchList.Items.Count > 0)) { mnuItemPatchSelectedEntry.Visible = false; e.Cancel = true; } if (e.Cancel) return; if (lstPatchList.Items.Count > 0) mnuItemRemoveResult.Visible = true; if (lstPatchList.Items.Count > 0) mnuItemPatchSelectedEntry.Visible = true; if (!(lstPatchList.Items.Count > 0)) { mnuItemFreezeSelectedPatches.Visible = false; e.Cancel = true; } if (!(lstPatchList.Items.Count > 0)) { mnuItemThawSelectedPatches.Visible = false; e.Cancel = true; } if (e.Cancel) return; if (lstPatchList.Items.Count > 0) mnuItemFreezeSelectedPatches.Visible = true; if (lstPatchList.Items.Count > 0) mnuItemThawSelectedPatches.Visible = true; if (lstPatchList.SelectedItems.Count == 0) e.Cancel = true; if (e.Cancel) return; } private void mnuResults_Opening(object sender, CancelEventArgs e) { if (!(lstResults.Items.Count > 0)) e.Cancel = true; if (lstResults.SelectedItems.Count == 0) e.Cancel = true; if (SearchArgs == null) e.Cancel = true; if (e.Cancel) return; } private void chkMemoryRangeExpertMode_CheckedChanged(object sender, EventArgs e) { txtMemoryRangeStart.ReadOnly = !chkMemoryRangeExpertMode.Checked; txtMemoryRangeSize.ReadOnly = !chkMemoryRangeExpertMode.Checked; } private void txtMemoryRangeStart_ValueChanged(object sender, ValueChangedEventArgs e) { this.MemoryRangeStart = Convert.ToUInt32(e.NewValue); } private void txtMemoryRangeSize_ValueChanged(object sender, ValueChangedEventArgs e) { this.MemoryRangeSize = Convert.ToUInt32(e.NewValue); } } }