@@ -20,8 +20,7 @@ use windows::Win32::Security::{
2020 TOKEN_ADJUST_PRIVILEGES , TOKEN_PRIVILEGES ,
2121} ;
2222
23- use core:: mem:: { align_of, size_of, MaybeUninit } ;
24- use core:: ptr;
23+ use core:: mem:: { align_of, size_of} ;
2524use std:: ffi:: OsString ;
2625use std:: os:: windows:: ffi:: OsStringExt ;
2726
@@ -170,8 +169,6 @@ unsafe fn enable_debug_privilege() -> Result<()> {
170169
171170pub struct WindowsOs {
172171 info : OsInfo ,
173- cached_processes : Vec < ProcessInfo > ,
174- cached_modules : Vec < KernelModule > ,
175172}
176173
177174impl WindowsOs {
@@ -270,8 +267,6 @@ impl Clone for WindowsOs {
270267 fn clone ( & self ) -> Self {
271268 Self {
272269 info : self . info . clone ( ) ,
273- cached_processes : vec ! [ ] ,
274- cached_modules : vec ! [ ] ,
275270 }
276271 }
277272}
@@ -284,11 +279,7 @@ impl Default for WindowsOs {
284279 arch : ArchitectureIdent :: X86 ( 64 , false ) ,
285280 } ;
286281
287- Self {
288- info,
289- cached_modules : vec ! [ ] ,
290- cached_processes : vec ! [ ] ,
291- }
282+ Self { info }
292283 }
293284}
294285
@@ -299,39 +290,55 @@ impl Os for WindowsOs {
299290 /// Walks a process list and calls a callback for each process structure address
300291 ///
301292 /// The callback is fully opaque. We need this style so that C FFI can work seamlessly.
302- fn process_address_list_callback ( & mut self , callback : AddressCallback ) -> Result < ( ) > {
293+ fn process_address_list_callback ( & mut self , mut callback : AddressCallback ) -> Result < ( ) > {
303294 let handle =
304295 Handle ( unsafe { CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS , 0 ) } . map_err ( conv_err) ?) ;
305296
306- let mut maybe_entry = MaybeUninit :: < PROCESSENTRY32W > :: uninit ( ) ;
297+ let mut entry = PROCESSENTRY32W :: default ( ) ;
298+ entry. dwSize = size_of :: < PROCESSENTRY32W > ( ) as u32 ;
299+
300+ if unsafe { Process32FirstW ( * handle, & mut entry) } . is_err ( ) {
301+ return Ok ( ( ) ) ;
302+ }
307303
308- unsafe {
309- ptr:: write (
310- & mut ( * maybe_entry. as_mut_ptr ( ) ) . dwSize ,
311- size_of :: < PROCESSENTRY32W > ( ) as u32 ,
312- ) ;
304+ loop {
305+ if !callback. call ( Address :: from ( entry. th32ProcessID as umem ) ) {
306+ break ;
307+ }
308+
309+ if unsafe { Process32NextW ( * handle, & mut entry) } . is_err ( ) {
310+ break ;
311+ }
313312 }
314313
315- let ptr = maybe_entry. as_mut_ptr ( ) ;
314+ Ok ( ( ) )
315+ }
316+
317+ /// Find process information by its internal address
318+ fn process_info_by_address ( & mut self , address : Address ) -> Result < ProcessInfo > {
319+ let pid = address. to_umem ( ) as Pid ;
320+ let handle =
321+ Handle ( unsafe { CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS , 0 ) } . map_err ( conv_err) ?) ;
322+
323+ let mut entry = PROCESSENTRY32W :: default ( ) ;
324+ entry. dwSize = size_of :: < PROCESSENTRY32W > ( ) as u32 ;
325+
326+ if unsafe { Process32FirstW ( * handle, & mut entry) } . is_err ( ) {
327+ return Err ( Error ( ErrorOrigin :: OsLayer , ErrorKind :: NotFound ) ) ;
328+ }
316329
317- std:: iter:: once ( unsafe { Process32FirstW ( * handle, ptr) } )
318- . chain ( std:: iter:: repeat_with ( || unsafe {
319- Process32NextW ( * handle, ptr)
320- } ) )
321- . take_while ( |b| b. is_ok ( ) )
322- . map ( |_| unsafe { maybe_entry. assume_init ( ) } )
323- . map ( |p| {
324- let address = Address :: from ( p. th32ProcessID as umem ) ;
325- let len = p. szExeFile . iter ( ) . take_while ( |& & c| c != 0 ) . count ( ) ;
330+ loop {
331+ if entry. th32ProcessID as Pid == pid {
332+ let len = entry. szExeFile . iter ( ) . take_while ( |& & c| c != 0 ) . count ( ) ;
326333
327- let path = OsString :: from_wide ( & p . szExeFile [ ..len] ) ;
334+ let path = OsString :: from_wide ( & entry . szExeFile [ ..len] ) ;
328335 let path = path. to_string_lossy ( ) ;
329336 let path = & * path;
330337 let name = path. rsplit_once ( '\\' ) . map ( |( _, end) | end) . unwrap_or ( path) ;
331338
332- self . cached_processes . push ( ProcessInfo {
339+ return Ok ( ProcessInfo {
333340 address,
334- pid : address . to_umem ( ) as _ ,
341+ pid,
335342 state : ProcessState :: Alive ,
336343 name : name. into ( ) ,
337344 path : path. into ( ) ,
@@ -342,21 +349,14 @@ impl Os for WindowsOs {
342349 dtb1 : Address :: invalid ( ) ,
343350 dtb2 : Address :: invalid ( ) ,
344351 } ) ;
352+ }
345353
346- address
347- } )
348- . feed_into ( callback) ;
349-
350- Ok ( ( ) )
351- }
354+ if unsafe { Process32NextW ( * handle, & mut entry) } . is_err ( ) {
355+ break ;
356+ }
357+ }
352358
353- /// Find process information by its internal address
354- fn process_info_by_address ( & mut self , address : Address ) -> Result < ProcessInfo > {
355- self . cached_processes
356- . iter ( )
357- . find ( |p| p. address == address)
358- . cloned ( )
359- . ok_or ( Error ( ErrorOrigin :: OsLayer , ErrorKind :: NotFound ) )
359+ Err ( Error ( ErrorOrigin :: OsLayer , ErrorKind :: NotFound ) )
360360 }
361361
362362 /// Construct a process by its info, borrowing the OS
@@ -379,10 +379,9 @@ impl Os for WindowsOs {
379379 /// # Arguments
380380 /// * `callback` - where to pass each matching module to. This is an opaque callback.
381381 fn module_address_list_callback ( & mut self , mut callback : AddressCallback ) -> Result < ( ) > {
382- self . cached_modules = Self :: query_kernel_modules ( ) ?;
383-
384- ( 0 ..self . cached_modules . len ( ) )
385- . map ( Address :: from)
382+ Self :: query_kernel_modules ( ) ?
383+ . into_iter ( )
384+ . map ( |m| m. base )
386385 . take_while ( |a| callback. call ( * a) )
387386 . for_each ( |_| { } ) ;
388387
@@ -394,8 +393,9 @@ impl Os for WindowsOs {
394393 /// # Arguments
395394 /// * `address` - address where module's information resides in
396395 fn module_by_address ( & mut self , address : Address ) -> Result < ModuleInfo > {
397- self . cached_modules
398- . get ( address. to_umem ( ) as usize )
396+ Self :: query_kernel_modules ( ) ?
397+ . into_iter ( )
398+ . find ( |km| km. base == address)
399399 . map ( |km| ModuleInfo {
400400 address,
401401 size : km. size ,
0 commit comments