11using System ;
2- using System . Collections . Generic ;
32using System . Data ;
43using System . Diagnostics . Contracts ;
54using System . Drawing ;
98using ReClassNET . Debugger ;
109using ReClassNET . Memory ;
1110using ReClassNET . Native ;
11+ using ReClassNET . Nodes ;
1212using ReClassNET . UI ;
1313using ReClassNET . Util ;
1414
@@ -27,6 +27,7 @@ private class FoundCodeInfo
2727 private readonly RemoteProcess process ;
2828
2929 private DataTable data ;
30+ private volatile bool acceptNewRecords = true ;
3031
3132 public event StopEventHandler Stop ;
3233
@@ -74,76 +75,9 @@ protected override void OnFormClosed(FormClosedEventArgs e)
7475
7576 #region Event Handler
7677
77- #endregion
78-
79- public void AddRecord ( ExceptionDebugInfo ? context )
80- {
81- if ( context == null )
82- {
83- return ;
84- }
85- if ( IsDisposed )
86- {
87- return ;
88- }
89-
90- if ( InvokeRequired )
91- {
92- Invoke ( ( MethodInvoker ) ( ( ) => AddRecord ( context ) ) ) ;
93-
94- return ;
95- }
96-
97- var row = data . AsEnumerable ( ) . FirstOrDefault ( r => r . Field < FoundCodeInfo > ( "info" ) . DebugInfo . ExceptionAddress == context . Value . ExceptionAddress ) ;
98- if ( row != null )
99- {
100- row [ "counter" ] = row . Field < int > ( "counter" ) + 1 ;
101- }
102- else
103- {
104- var disassembler = new Disassembler ( process . NativeHelper ) ;
105- var causedByInstruction = disassembler . RemoteGetPreviousInstruction ( process , context . Value . ExceptionAddress ) ;
106-
107- var instructions = new DisassembledInstruction [ 5 ] ;
108- instructions [ 2 ] = causedByInstruction ;
109- instructions [ 1 ] = disassembler . RemoteGetPreviousInstruction ( process , instructions [ 2 ] . Address ) ;
110- instructions [ 0 ] = disassembler . RemoteGetPreviousInstruction ( process , instructions [ 1 ] . Address ) ;
111-
112- var nextInstructions = disassembler . RemoteDisassembleCode ( process , context . Value . ExceptionAddress , 30 ) ;
113- for ( var i = 0 ; i < 2 ; ++ i )
114- {
115- instructions [ 3 + i ] = nextInstructions [ i ] ;
116- }
117-
118- row = data . NewRow ( ) ;
119- row [ "counter" ] = 1 ;
120- row [ "instruction" ] = causedByInstruction . Instruction ;
121- row [ "info" ] = new FoundCodeInfo
122- {
123- DebugInfo = context . Value ,
124- Instructions = instructions
125- } ;
126- data . Rows . Add ( row ) ;
127- }
128- }
129-
13078 private void foundCodeDataGridView_SelectionChanged ( object sender , EventArgs e )
13179 {
132- var row = foundCodeDataGridView . SelectedRows . Cast < DataGridViewRow > ( ) . FirstOrDefault ( ) ;
133- if ( row == null )
134- {
135- infoTextBox . Text = string . Empty ;
136-
137- return ;
138- }
139-
140- var view = row . DataBoundItem as DataRowView ;
141- if ( view == null )
142- {
143- return ;
144- }
145-
146- var info = view [ "info" ] as FoundCodeInfo ;
80+ var info = GetSelectedInfo ( ) ;
14781 if ( info == null )
14882 {
14983 return ;
@@ -202,12 +136,40 @@ private void foundCodeDataGridView_SelectionChanged(object sender, EventArgs e)
202136
203137 private void FoundCodeForm_FormClosed ( object sender , FormClosedEventArgs e )
204138 {
205- Stop ? . Invoke ( this , EventArgs . Empty ) ;
139+ StopRecording ( ) ;
140+ }
141+
142+ private void createFunctionButton_Click ( object sender , EventArgs e )
143+ {
144+ var info = GetSelectedInfo ( ) ;
145+ if ( info == null )
146+ {
147+ return ;
148+ }
149+
150+ var disassembler = new Disassembler ( process . NativeHelper ) ;
151+ var functionStartAddress = disassembler . RemoteGetFunctionStartAddress ( process , info . DebugInfo . ExceptionAddress ) ;
152+ if ( functionStartAddress . IsNull ( ) )
153+ {
154+ MessageBox . Show ( "Could not find the start of the function. Aborting." , "Warning" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
155+
156+ return ;
157+ }
158+
159+ var node = ClassNode . Create ( ) ;
160+ node . Address = functionStartAddress ;
161+ node . AddNode ( new FunctionNode
162+ {
163+ Comment = info . Instructions [ 2 ] . Instruction
164+ } ) ;
165+
166+ var mainForm = Application . OpenForms [ 0 ] as MainForm ;
167+ mainForm . ClassView . SelectedClass = node ;
206168 }
207169
208170 private void stopButton_Click ( object sender , EventArgs e )
209171 {
210- Stop ? . Invoke ( this , EventArgs . Empty ) ;
172+ StopRecording ( ) ;
211173
212174 stopButton . Visible = false ;
213175 closeButton . Visible = true ;
@@ -217,5 +179,80 @@ private void closeButton_Click(object sender, EventArgs e)
217179 {
218180 Close ( ) ;
219181 }
182+
183+ #endregion
184+
185+ private FoundCodeInfo GetSelectedInfo ( )
186+ {
187+ var row = foundCodeDataGridView . SelectedRows . Cast < DataGridViewRow > ( ) . FirstOrDefault ( ) ;
188+ if ( row != null )
189+ {
190+ var view = row . DataBoundItem as DataRowView ;
191+ if ( view != null )
192+ {
193+ return view [ "info" ] as FoundCodeInfo ;
194+ }
195+ }
196+
197+ return null ;
198+ }
199+
200+ private void StopRecording ( )
201+ {
202+ acceptNewRecords = false ;
203+
204+ Stop ? . Invoke ( this , EventArgs . Empty ) ;
205+ }
206+
207+ public void AddRecord ( ExceptionDebugInfo ? context )
208+ {
209+ if ( context == null )
210+ {
211+ return ;
212+ }
213+ if ( ! acceptNewRecords )
214+ {
215+ return ;
216+ }
217+
218+ if ( InvokeRequired )
219+ {
220+ Invoke ( ( MethodInvoker ) ( ( ) => AddRecord ( context ) ) ) ;
221+
222+ return ;
223+ }
224+
225+ var row = data . AsEnumerable ( ) . FirstOrDefault ( r => r . Field < FoundCodeInfo > ( "info" ) . DebugInfo . ExceptionAddress == context . Value . ExceptionAddress ) ;
226+ if ( row != null )
227+ {
228+ row [ "counter" ] = row . Field < int > ( "counter" ) + 1 ;
229+ }
230+ else
231+ {
232+ var disassembler = new Disassembler ( process . NativeHelper ) ;
233+ var causedByInstruction = disassembler . RemoteGetPreviousInstruction ( process , context . Value . ExceptionAddress ) ;
234+
235+ var instructions = new DisassembledInstruction [ 5 ] ;
236+ instructions [ 2 ] = causedByInstruction ;
237+ instructions [ 1 ] = disassembler . RemoteGetPreviousInstruction ( process , instructions [ 2 ] . Address ) ;
238+ instructions [ 0 ] = disassembler . RemoteGetPreviousInstruction ( process , instructions [ 1 ] . Address ) ;
239+
240+ int i = 3 ;
241+ foreach ( var instruction in disassembler . RemoteDisassembleCode ( process , context . Value . ExceptionAddress , 30 ) . Take ( 2 ) )
242+ {
243+ instructions [ i ++ ] = instruction ;
244+ }
245+
246+ row = data . NewRow ( ) ;
247+ row [ "counter" ] = 1 ;
248+ row [ "instruction" ] = causedByInstruction . Instruction ;
249+ row [ "info" ] = new FoundCodeInfo
250+ {
251+ DebugInfo = context . Value ,
252+ Instructions = instructions
253+ } ;
254+ data . Rows . Add ( row ) ;
255+ }
256+ }
220257 }
221258}
0 commit comments