//#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; namespace RomCheater.Docking { public partial class FloatingMemorySearcher : DockContent, IAcceptsPlugin, IAcceptsProcess, IAcceptsProcessAndConfig, ISearchInProgress { private bool DefaultUnsignedState = true; // set unsigned to true public FloatingMemorySearcher() { InitializeComponent(); this.AcceptedPlugin = 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; UpdateAcceptedProcessAndConfig(AcceptedPlugin, value); } } #endregion #region IAcceptsPlugin Members private IConfigPlugin _AcceptedPlugin; public IConfigPlugin AcceptedPlugin { get { return _AcceptedPlugin; } set { _AcceptedPlugin = value; UpdateAcceptedProcessAndConfig(value, AcceptedProcess); } } #endregion private void UpdateAcceptedProcessAndConfig(IConfigPlugin config, Process process) { this.lstResults.AcceptedPlugin = config; this.lstResults.AcceptedProcess = process; this.lstPatchList.AcceptedPlugin = config; this.lstPatchList.AcceptedProcess = process; } #region ISearchInProgress members public bool SearchInProgess { get; private set; } #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 } static int col_Found_Address = 0; static int col_Found_Value = 1; static int col_Found_Frozen = 2; static int col_Added_Address = 0; static int col_Added_Value = 1; static int col_Added_Frozen = 2; 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; } uint Address = 0; ResultDataType _result = (ResultDataType)ResultItems[i].Tag; Address = Convert.ToUInt32(ResultItems[i].SubItems[col_Found_Address].Text, 16); //r_ms.BaseStream.Seek(Address, SeekOrigin.Begin); GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this); 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); MemoryStream ms = new MemoryStream(data); 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(); 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; } uint Address = 0; ResultDataType _result = (ResultDataType)AddedItems[i].Tag; Address = Convert.ToUInt32(AddedItems[i].SubItems[col_Added_Address].Text, 16); GenericMemoryProvider provider = new GenericMemoryProvider((IAcceptsProcessAndConfig)this); 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); MemoryStream ms = new MemoryStream(data); 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(this.AcceptedProcess.Id); adder.ShowDialog(); if (adder.WasAPatchAdded) AddToPatchList(adder.AddedPatchValue); } private void btnAddAddressRange_Click(object sender, EventArgs e) { PatchRangeAdder adder = new PatchRangeAdder(this.AcceptedProcess.Id); 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, this.AcceptedProcess.Id); 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) { } private void SearchWorkerThread_ProgressChanged(object sender, ProgressChangedEventArgs e) { } private void SearchWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { } 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(); } } private void btnSearch_Click(object sender, EventArgs e) { this.FreezeResultsUpdate(); } } }