@@ -24,13 +24,14 @@ use windows_sys::Win32::Foundation::{
2424    INVALID_HANDLE_VALUE ,  WAIT_OBJECT_0 , 
2525} ; 
2626use  windows_sys:: Win32 :: Storage :: FileSystem :: { 
27-     CreateFileW ,  ReadDirectoryChangesW ,  FILE_ACTION_ADDED ,  FILE_ACTION_MODIFIED , 
28-     FILE_ACTION_REMOVED ,  FILE_ACTION_RENAMED_NEW_NAME ,  FILE_ACTION_RENAMED_OLD_NAME , 
29-     FILE_FLAG_BACKUP_SEMANTICS ,  FILE_FLAG_OVERLAPPED ,  FILE_LIST_DIRECTORY , 
30-     FILE_NOTIFY_CHANGE_ATTRIBUTES ,  FILE_NOTIFY_CHANGE_CREATION ,  FILE_NOTIFY_CHANGE_DIR_NAME , 
31-     FILE_NOTIFY_CHANGE_FILE_NAME ,  FILE_NOTIFY_CHANGE_LAST_WRITE ,  FILE_NOTIFY_CHANGE_SECURITY , 
32-     FILE_NOTIFY_CHANGE_SIZE ,  FILE_NOTIFY_INFORMATION ,  FILE_SHARE_DELETE ,  FILE_SHARE_READ , 
33-     FILE_SHARE_WRITE ,  OPEN_EXISTING , 
27+     CreateFileW ,  ReadDirectoryChangesExW ,  ReadDirectoryNotifyExtendedInformation , 
28+     FILE_ACTION_ADDED ,  FILE_ACTION_MODIFIED ,  FILE_ACTION_REMOVED ,  FILE_ACTION_RENAMED_NEW_NAME , 
29+     FILE_ACTION_RENAMED_OLD_NAME ,  FILE_ATTRIBUTE_DIRECTORY ,  FILE_FLAG_BACKUP_SEMANTICS , 
30+     FILE_FLAG_OVERLAPPED ,  FILE_LIST_DIRECTORY ,  FILE_NOTIFY_CHANGE_ATTRIBUTES , 
31+     FILE_NOTIFY_CHANGE_CREATION ,  FILE_NOTIFY_CHANGE_DIR_NAME ,  FILE_NOTIFY_CHANGE_FILE_NAME , 
32+     FILE_NOTIFY_CHANGE_LAST_WRITE ,  FILE_NOTIFY_CHANGE_SECURITY ,  FILE_NOTIFY_CHANGE_SIZE , 
33+     FILE_NOTIFY_EXTENDED_INFORMATION ,  FILE_SHARE_DELETE ,  FILE_SHARE_READ ,  FILE_SHARE_WRITE , 
34+     OPEN_EXISTING , 
3435} ; 
3536use  windows_sys:: Win32 :: System :: Threading :: { 
3637    CreateSemaphoreW ,  ReleaseSemaphore ,  WaitForSingleObjectEx ,  INFINITE , 
@@ -305,7 +306,7 @@ fn start_read(
305306
306307        // This is using an asynchronous call with a completion routine for receiving notifications 
307308        // An I/O completion port would probably be more performant 
308-         let  ret = ReadDirectoryChangesW ( 
309+         let  ret = ReadDirectoryChangesExW ( 
309310            handle, 
310311            request. buffer . as_mut_ptr ( )  as  * mut  c_void , 
311312            BUF_SIZE , 
@@ -314,6 +315,7 @@ fn start_read(
314315            & mut  0u32  as  * mut  u32 ,  // not used for async reqs 
315316            overlapped, 
316317            Some ( handle_event) , 
318+             ReadDirectoryNotifyExtendedInformation , 
317319        ) ; 
318320
319321        if  ret == 0  { 
@@ -382,12 +384,13 @@ unsafe extern "system" fn handle_event(
382384    // In Wine, FILE_NOTIFY_INFORMATION structs are packed placed in the buffer; 
383385    // they are aligned to 16bit (WCHAR) boundary instead of 32bit required by FILE_NOTIFY_INFORMATION. 
384386    // Hence, we need to use `read_unaligned` here to avoid UB. 
385-     let  mut  cur_entry = ptr:: read_unaligned ( cur_offset as  * const  FILE_NOTIFY_INFORMATION ) ; 
387+     let  mut  cur_entry = ptr:: read_unaligned ( cur_offset as  * const  FILE_NOTIFY_EXTENDED_INFORMATION ) ; 
386388    loop  { 
387389        // filename length is size in bytes, so / 2 
388390        let  len = cur_entry. FileNameLength  as  usize  / 2 ; 
389391        let  encoded_path:  & [ u16 ]  = slice:: from_raw_parts ( 
390-             cur_offset. offset ( std:: mem:: offset_of!( FILE_NOTIFY_INFORMATION ,  FileName )  as  isize ) 
392+             cur_offset
393+                 . offset ( std:: mem:: offset_of!( FILE_NOTIFY_EXTENDED_INFORMATION ,  FileName )  as  isize ) 
391394                as  _ , 
392395            len, 
393396        ) ; 
@@ -422,44 +425,49 @@ unsafe extern "system" fn handle_event(
422425
423426            let  event_handler = |res| emit_event ( & request. event_handler ,  res) ; 
424427
425-             if  cur_entry. Action  == FILE_ACTION_RENAMED_OLD_NAME  { 
426-                 let  mode = RenameMode :: From ; 
427-                 let  kind = ModifyKind :: Name ( mode) ; 
428-                 let  kind = EventKind :: Modify ( kind) ; 
429-                 let  ev = newe. set_kind ( kind) ; 
430-                 event_handler ( Ok ( ev) ) 
431-             }  else  { 
432-                 match  cur_entry. Action  { 
433-                     FILE_ACTION_RENAMED_NEW_NAME  => { 
434-                         let  kind = EventKind :: Modify ( ModifyKind :: Name ( RenameMode :: To ) ) ; 
435-                         let  ev = newe. set_kind ( kind) ; 
436-                         event_handler ( Ok ( ev) ) ; 
437-                     } 
438-                     FILE_ACTION_ADDED  => { 
439-                         let  kind = EventKind :: Create ( CreateKind :: Any ) ; 
440-                         let  ev = newe. set_kind ( kind) ; 
441-                         event_handler ( Ok ( ev) ) ; 
442-                     } 
443-                     FILE_ACTION_REMOVED  => { 
444-                         let  kind = EventKind :: Remove ( RemoveKind :: Any ) ; 
445-                         let  ev = newe. set_kind ( kind) ; 
446-                         event_handler ( Ok ( ev) ) ; 
447-                     } 
448-                     FILE_ACTION_MODIFIED  => { 
449-                         let  kind = EventKind :: Modify ( ModifyKind :: Any ) ; 
450-                         let  ev = newe. set_kind ( kind) ; 
451-                         event_handler ( Ok ( ev) ) ; 
452-                     } 
453-                     _ => ( ) , 
454-                 } ; 
455-             } 
428+             match  cur_entry. Action  { 
429+                 FILE_ACTION_RENAMED_OLD_NAME  => { 
430+                     let  kind = EventKind :: Modify ( ModifyKind :: Name ( RenameMode :: From ) ) ; 
431+                     let  ev = newe. set_kind ( kind) ; 
432+                     event_handler ( Ok ( ev) ) 
433+                 } 
434+                 FILE_ACTION_RENAMED_NEW_NAME  => { 
435+                     let  kind = EventKind :: Modify ( ModifyKind :: Name ( RenameMode :: To ) ) ; 
436+                     let  ev = newe. set_kind ( kind) ; 
437+                     event_handler ( Ok ( ev) ) ; 
438+                 } 
439+                 FILE_ACTION_ADDED  => { 
440+                     let  kind = if  ( cur_entry. FileAttributes  &  FILE_ATTRIBUTE_DIRECTORY )  != 0  { 
441+                         EventKind :: Create ( CreateKind :: Folder ) 
442+                     }  else  { 
443+                         EventKind :: Create ( CreateKind :: File ) 
444+                     } ; 
445+                     let  ev = newe. set_kind ( kind) ; 
446+                     event_handler ( Ok ( ev) ) ; 
447+                 } 
448+                 FILE_ACTION_REMOVED  => { 
449+                     let  kind = if  ( cur_entry. FileAttributes  &  FILE_ATTRIBUTE_DIRECTORY )  != 0  { 
450+                         EventKind :: Remove ( RemoveKind :: Folder ) 
451+                     }  else  { 
452+                         EventKind :: Remove ( RemoveKind :: File ) 
453+                     } ; 
454+                     let  ev = newe. set_kind ( kind) ; 
455+                     event_handler ( Ok ( ev) ) ; 
456+                 } 
457+                 FILE_ACTION_MODIFIED  => { 
458+                     let  kind = EventKind :: Modify ( ModifyKind :: Any ) ; 
459+                     let  ev = newe. set_kind ( kind) ; 
460+                     event_handler ( Ok ( ev) ) ; 
461+                 } 
462+                 _ => ( ) , 
463+             } ; 
456464        } 
457465
458466        if  cur_entry. NextEntryOffset  == 0  { 
459467            break ; 
460468        } 
461469        cur_offset = cur_offset. offset ( cur_entry. NextEntryOffset  as  isize ) ; 
462-         cur_entry = ptr:: read_unaligned ( cur_offset as  * const  FILE_NOTIFY_INFORMATION ) ; 
470+         cur_entry = ptr:: read_unaligned ( cur_offset as  * const  FILE_NOTIFY_EXTENDED_INFORMATION ) ; 
463471    } 
464472} 
465473
0 commit comments