@@ -91,55 +91,56 @@ public static unsafe SearchResult MemSearch(this Vmm vmm,
9191 {
9292 return result ; // No search items, return empty result.
9393 }
94- var hSearches = GCHandle . Alloc ( searches , GCHandleType . Pinned ) ;
9594 var context = ( Vmmi . VMMDLL_MEM_SEARCH_CONTEXT * ) NativeMemory . Alloc ( ( nuint ) sizeof ( Vmmi . VMMDLL_MEM_SEARCH_CONTEXT ) ) ;
9695 try
9796 {
98- Vmmi . SearchResultCallback del = SearchResultCallback ; // Prevent delegate from being GC'ed during the call.
99- * context = new Vmmi . VMMDLL_MEM_SEARCH_CONTEXT
97+ fixed ( void * pSearches = searches )
10098 {
101- dwVersion = VMMDLL_MEM_SEARCH_VERSION ,
102- vaMin = addr_min ,
103- vaMax = addr_max ,
104- cMaxResult = cMaxResult ,
105- ReadFlags = ( uint ) readFlags ,
106- pfnResultOptCB = Marshal . GetFunctionPointerForDelegate ( del )
107- } ;
108- context ->cSearch = ( uint ) searches . Length ;
109- context ->search = hSearches . AddrOfPinnedObject ( ) ;
110- var ctReg = ct . Register ( ( ) =>
111- {
112- context ->fAbortRequested = 1 ;
113- } ) ;
114- try
115- {
116- result . IsSuccess = Vmmi . VMMDLL_MemSearch ( vmm , pid , context , IntPtr . Zero , IntPtr . Zero ) ;
117- }
118- finally
119- {
120- // IMPORTANT: Ensure we unregister the cancellation token callback before the context is freed.
121- // This will block (WaitForCallbackIfNecessary) until the callback is completed (if it is already in progress).
122- ctReg . Dispose ( ) ;
123- }
99+ Vmmi . SearchResultCallback del = SearchResultCallback ; // Prevent delegate from being GC'ed during the call.
100+ * context = new Vmmi . VMMDLL_MEM_SEARCH_CONTEXT
101+ {
102+ dwVersion = VMMDLL_MEM_SEARCH_VERSION ,
103+ vaMin = addr_min ,
104+ vaMax = addr_max ,
105+ cMaxResult = cMaxResult ,
106+ ReadFlags = ( uint ) readFlags ,
107+ pfnResultOptCB = Marshal . GetFunctionPointerForDelegate ( del ) ,
108+ cSearch = ( uint ) searches . Length ,
109+ search = pSearches
110+ } ;
111+ var ctReg = ct . Register ( ( ) =>
112+ {
113+ context ->fAbortRequested = 1 ;
114+ } ) ;
115+ try
116+ {
117+ result . IsSuccess = Vmmi . VMMDLL_MemSearch ( vmm , pid , context , IntPtr . Zero , IntPtr . Zero ) ;
118+ }
119+ finally
120+ {
121+ // IMPORTANT: Ensure we unregister the cancellation token callback before the context is freed.
122+ // This will block (WaitForCallbackIfNecessary) until the callback is completed (if it is already in progress).
123+ ctReg . Dispose ( ) ;
124+ }
124125
125- ct . ThrowIfCancellationRequested ( ) ;
126- return result ;
126+ ct . ThrowIfCancellationRequested ( ) ;
127+ return result ;
127128
128- bool SearchResultCallback ( Vmmi . VMMDLL_MEM_SEARCH_CONTEXT ctx , ulong va , uint iSearch )
129- {
130- var e = new SearchResult . Entry
129+ bool SearchResultCallback ( Vmmi . VMMDLL_MEM_SEARCH_CONTEXT ctx , ulong va , uint iSearch )
131130 {
132- Address = va ,
133- SearchTermId = iSearch
134- } ;
135- result . _results . Add ( e ) ;
136- return result . _results . Count < ctx . cMaxResult ;
131+ var e = new SearchResult . Entry
132+ {
133+ Address = va ,
134+ SearchTermId = iSearch
135+ } ;
136+ result . _results . Add ( e ) ;
137+ return result . _results . Count < ctx . cMaxResult ;
138+ }
137139 }
138140 }
139141 finally
140142 {
141143 NativeMemory . Free ( context ) ;
142- hSearches . Free ( ) ;
143144 }
144145 }
145146
0 commit comments