@@ -271,69 +271,103 @@ pub fn is_powershell_parent() -> bool {
271271 use std:: os:: windows:: ffi:: OsStringExt as _;
272272 use win_bindings:: * ;
273273
274- let mut pid = Some ( -1 /* NtCurrentProcess */ ) ;
274+ struct NtHandle {
275+ handle : isize ,
276+ }
277+
278+ impl Drop for NtHandle {
279+ fn drop ( & mut self ) {
280+ if self . handle != -1 {
281+ unsafe {
282+ nt_close ( self . handle ) ;
283+ }
284+ }
285+ }
286+ }
287+
288+ let mut handle = Some ( NtHandle { handle : -1 } ) ;
275289
276290 unsafe {
277291 let reset = |fname : & mut [ u16 ] | {
278292 let ustr = & mut * fname. as_mut_ptr ( ) . cast :: < UnicodeString > ( ) ;
279293 ustr. length = 0 ;
280294 ustr. maximum_length = MaxPath as _ ;
281- ustr. buffer = fname
282- . as_mut_ptr ( )
283- . byte_offset ( std:: mem:: size_of :: < UnicodeString > ( ) as _ ) ;
284295 } ;
285296
286297 // The API for this is extremely irritating, the struct and string buffer
287298 // need to be the same :/
288299 let mut file_name = [ 0u16 ; MaxPath as usize + std:: mem:: size_of :: < UnicodeString > ( ) / 2 ] ;
289300
290- while let Some ( ppid ) = pid {
301+ while let Some ( ph ) = handle {
291302 let mut basic_info = std:: mem:: MaybeUninit :: < ProcessBasicInformation > :: uninit ( ) ;
292303 let mut length = 0 ;
293304 if dbg ! ( nt_query_information_process(
294- ppid ,
305+ ph . handle ,
295306 Processinfoclass :: ProcessBasicInformation ,
296307 basic_info. as_mut_ptr( ) . cast( ) ,
297308 std:: mem:: size_of:: <ProcessBasicInformation >( ) as _,
298309 & mut length,
299310 ) ) != StatusSuccess
300311 {
301- return false ;
312+ break ;
302313 }
303314
304315 if length != std:: mem:: size_of :: < ProcessBasicInformation > ( ) as u32 {
305- return false ;
316+ break ;
306317 }
307318
308319 let basic_info = basic_info. assume_init ( ) ;
309320 reset ( & mut file_name) ;
310321
322+ let ppid = basic_info. inherited_from_unique_process_id as isize ;
323+
324+ if ppid == 0 || ppid == -1 {
325+ break ;
326+ }
327+
328+ let mut parent_handle = -1 ;
329+ let obj_attr = std:: mem:: zeroed ( ) ;
330+ let client_id = ClientId {
331+ unique_process : ppid,
332+ unique_thread : 0 ,
333+ } ;
334+ if dbg ! ( nt_open_process(
335+ & mut parent_handle,
336+ ProcessAccessRights :: ProcessQueryInformation ,
337+ & obj_attr,
338+ & client_id
339+ ) ) != StatusSuccess
340+ {
341+ break ;
342+ }
343+
344+ handle = Some ( NtHandle {
345+ handle : parent_handle,
346+ } ) ;
347+
311348 if dbg ! ( nt_query_information_process(
312- basic_info . inherited_from_unique_process_id as _ ,
349+ parent_handle ,
313350 Processinfoclass :: ProcessImageFileName ,
314351 file_name. as_mut_ptr( ) . cast( ) ,
315352 ( file_name. len( ) * 2 ) as _,
316353 & mut length,
317354 ) ) != StatusSuccess
318355 {
319- return false ;
356+ break ;
320357 }
321358
322359 let ustr = & * file_name. as_ptr ( ) . cast :: < UnicodeString > ( ) ;
323- let os = std:: ffi:: OsString :: from_wide (
324- & file_name [ std :: mem :: size_of :: < UnicodeString > ( ) * 2
325- ..std :: mem :: size_of :: < UnicodeString > ( ) * 2 + ustr. length as usize ] ,
326- ) ;
360+ let os = std:: ffi:: OsString :: from_wide ( std :: slice :: from_raw_parts (
361+ ustr . buffer ,
362+ ( ustr. length >> 1 ) as usize ,
363+ ) ) ;
327364
328365 let path = os. to_string_lossy ( ) ;
329- dbg ! ( & path) ;
366+ eprintln ! ( "{ path}" ) ;
330367 let p = std:: path:: Path :: new ( path. as_ref ( ) ) ;
331368 if p. file_stem ( ) == Some ( std:: ffi:: OsStr :: new ( "pwsh" ) ) {
332369 return true ;
333370 }
334-
335- pid = ( basic_info. inherited_from_unique_process_id != 0 )
336- . then_some ( basic_info. inherited_from_unique_process_id as isize ) ;
337371 }
338372
339373 false
0 commit comments