55//!
66//! [ref]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363950(v=vs.85).aspx
77
8- use winapi:: shared:: minwindef:: TRUE ;
9- use winapi:: shared:: winerror:: ERROR_OPERATION_ABORTED ;
10- use winapi:: um:: fileapi;
11- use winapi:: um:: handleapi:: { self , INVALID_HANDLE_VALUE } ;
12- use winapi:: um:: ioapiset;
13- use winapi:: um:: minwinbase:: { LPOVERLAPPED , OVERLAPPED } ;
14- use winapi:: um:: synchapi;
15- use winapi:: um:: winbase:: { self , INFINITE , WAIT_OBJECT_0 } ;
16- use winapi:: um:: winnt:: { self , FILE_NOTIFY_INFORMATION , HANDLE } ;
17-
18- use crate :: { bounded, unbounded, BoundSender , Receiver , Sender , Config } ;
8+ use crate :: { bounded, unbounded, BoundSender , Config , Receiver , Sender } ;
199use crate :: { event:: * , WatcherKind } ;
2010use crate :: { Error , EventHandler , RecursiveMode , Result , Watcher } ;
2111use std:: collections:: HashMap ;
@@ -29,6 +19,23 @@ use std::ptr;
2919use std:: slice;
3020use std:: sync:: { Arc , Mutex } ;
3121use std:: thread;
22+ use windows_sys:: Win32 :: Foundation :: {
23+ CloseHandle , ERROR_OPERATION_ABORTED , HANDLE , INVALID_HANDLE_VALUE , WAIT_OBJECT_0 ,
24+ } ;
25+ use windows_sys:: Win32 :: Storage :: FileSystem :: {
26+ CreateFileW , ReadDirectoryChangesW , FILE_ACTION_ADDED , FILE_ACTION_MODIFIED ,
27+ FILE_ACTION_REMOVED , FILE_ACTION_RENAMED_NEW_NAME , FILE_ACTION_RENAMED_OLD_NAME ,
28+ FILE_FLAG_BACKUP_SEMANTICS , FILE_FLAG_OVERLAPPED , FILE_LIST_DIRECTORY ,
29+ FILE_NOTIFY_CHANGE_ATTRIBUTES , FILE_NOTIFY_CHANGE_CREATION , FILE_NOTIFY_CHANGE_DIR_NAME ,
30+ FILE_NOTIFY_CHANGE_FILE_NAME , FILE_NOTIFY_CHANGE_LAST_WRITE , FILE_NOTIFY_CHANGE_SECURITY ,
31+ FILE_NOTIFY_CHANGE_SIZE , FILE_NOTIFY_INFORMATION , FILE_SHARE_DELETE , FILE_SHARE_READ ,
32+ FILE_SHARE_WRITE , OPEN_EXISTING ,
33+ } ;
34+ use windows_sys:: Win32 :: System :: Threading :: {
35+ CreateSemaphoreW , ReleaseSemaphore , WaitForSingleObjectEx ,
36+ } ;
37+ use windows_sys:: Win32 :: System :: WindowsProgramming :: INFINITE ;
38+ use windows_sys:: Win32 :: System :: IO :: { CancelIo , OVERLAPPED } ;
3239
3340const BUF_SIZE : u32 = 16384 ;
3441
@@ -132,7 +139,7 @@ impl ReadDirectoryChangesServer {
132139
133140 unsafe {
134141 // wait with alertable flag so that the completion routine fires
135- let waitres = synchapi :: WaitForSingleObjectEx ( self . wakeup_sem , 100 , TRUE ) ;
142+ let waitres = WaitForSingleObjectEx ( self . wakeup_sem , 100 , 1 ) ;
136143 if waitres == WAIT_OBJECT_0 {
137144 let _ = self . meta_tx . send ( MetaEvent :: WatcherAwakened ) ;
138145 }
@@ -141,7 +148,7 @@ impl ReadDirectoryChangesServer {
141148
142149 // we have to clean this up, since the watcher may be long gone
143150 unsafe {
144- handleapi :: CloseHandle ( self . wakeup_sem ) ;
151+ CloseHandle ( self . wakeup_sem ) ;
145152 }
146153 }
147154
@@ -170,14 +177,14 @@ impl ReadDirectoryChangesServer {
170177 . collect ( ) ;
171178 let handle;
172179 unsafe {
173- handle = fileapi :: CreateFileW (
180+ handle = CreateFileW (
174181 encoded_path. as_ptr ( ) ,
175- winnt:: FILE_LIST_DIRECTORY ,
176- winnt:: FILE_SHARE_READ | winnt:: FILE_SHARE_DELETE | winnt:: FILE_SHARE_WRITE ,
177- ptr:: null_mut ( ) ,
178- fileapi:: OPEN_EXISTING ,
179- winbase:: FILE_FLAG_BACKUP_SEMANTICS | winbase:: FILE_FLAG_OVERLAPPED ,
182+ FILE_LIST_DIRECTORY ,
183+ FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE ,
180184 ptr:: null_mut ( ) ,
185+ OPEN_EXISTING ,
186+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED ,
187+ 0 ,
181188 ) ;
182189
183190 if handle == INVALID_HANDLE_VALUE {
@@ -199,11 +206,10 @@ impl ReadDirectoryChangesServer {
199206 None
200207 } ;
201208 // every watcher gets its own semaphore to signal completion
202- let semaphore =
203- unsafe { synchapi:: CreateSemaphoreW ( ptr:: null_mut ( ) , 0 , 1 , ptr:: null_mut ( ) ) } ;
204- if semaphore. is_null ( ) || semaphore == INVALID_HANDLE_VALUE {
209+ let semaphore = unsafe { CreateSemaphoreW ( ptr:: null_mut ( ) , 0 , 1 , ptr:: null_mut ( ) ) } ;
210+ if semaphore == 0 || semaphore == INVALID_HANDLE_VALUE {
205211 unsafe {
206- handleapi :: CloseHandle ( handle) ;
212+ CloseHandle ( handle) ;
207213 }
208214 return Err ( Error :: generic ( "Failed to create semaphore for watch." ) . add_path ( path) ) ;
209215 }
@@ -236,16 +242,15 @@ impl ReadDirectoryChangesServer {
236242
237243fn stop_watch ( ws : & WatchState , meta_tx : & Sender < MetaEvent > ) {
238244 unsafe {
239- let cio = ioapiset :: CancelIo ( ws. dir_handle ) ;
240- let ch = handleapi :: CloseHandle ( ws. dir_handle ) ;
245+ let cio = CancelIo ( ws. dir_handle ) ;
246+ let ch = CloseHandle ( ws. dir_handle ) ;
241247 // have to wait for it, otherwise we leak the memory allocated for there read request
242248 if cio != 0 && ch != 0 {
243- while synchapi:: WaitForSingleObjectEx ( ws. complete_sem , INFINITE , TRUE ) != WAIT_OBJECT_0
244- {
249+ while WaitForSingleObjectEx ( ws. complete_sem , INFINITE , 1 ) != WAIT_OBJECT_0 {
245250 // drain the apc queue, fix for https://github.com/notify-rs/notify/issues/287#issuecomment-801465550
246251 }
247252 }
248- handleapi :: CloseHandle ( ws. complete_sem ) ;
253+ CloseHandle ( ws. complete_sem ) ;
249254 }
250255 let _ = meta_tx. send ( MetaEvent :: SingleWatchComplete ) ;
251256}
@@ -258,13 +263,13 @@ fn start_read(rd: &ReadData, event_handler: Arc<Mutex<dyn EventHandler>>, handle
258263 data : rd. clone ( ) ,
259264 } ) ;
260265
261- let flags = winnt :: FILE_NOTIFY_CHANGE_FILE_NAME
262- | winnt :: FILE_NOTIFY_CHANGE_DIR_NAME
263- | winnt :: FILE_NOTIFY_CHANGE_ATTRIBUTES
264- | winnt :: FILE_NOTIFY_CHANGE_SIZE
265- | winnt :: FILE_NOTIFY_CHANGE_LAST_WRITE
266- | winnt :: FILE_NOTIFY_CHANGE_CREATION
267- | winnt :: FILE_NOTIFY_CHANGE_SECURITY ;
266+ let flags = FILE_NOTIFY_CHANGE_FILE_NAME
267+ | FILE_NOTIFY_CHANGE_DIR_NAME
268+ | FILE_NOTIFY_CHANGE_ATTRIBUTES
269+ | FILE_NOTIFY_CHANGE_SIZE
270+ | FILE_NOTIFY_CHANGE_LAST_WRITE
271+ | FILE_NOTIFY_CHANGE_CREATION
272+ | FILE_NOTIFY_CHANGE_SECURITY ;
268273
269274 let monitor_subdir = if ( & request. data . file ) . is_none ( ) && request. data . is_recursive {
270275 1
@@ -278,12 +283,12 @@ fn start_read(rd: &ReadData, event_handler: Arc<Mutex<dyn EventHandler>>, handle
278283 // for our own purposes
279284
280285 let req_buf = request. buffer . as_mut_ptr ( ) as * mut c_void ;
281- let request_p = Box :: into_raw ( request) as * mut c_void ;
286+ let request_p = Box :: into_raw ( request) as isize ;
282287 overlapped. hEvent = request_p;
283288
284289 // This is using an asynchronous call with a completion routine for receiving notifications
285290 // An I/O completion port would probably be more performant
286- let ret = winbase :: ReadDirectoryChangesW (
291+ let ret = ReadDirectoryChangesW (
287292 handle,
288293 req_buf,
289294 BUF_SIZE ,
@@ -299,7 +304,7 @@ fn start_read(rd: &ReadData, event_handler: Arc<Mutex<dyn EventHandler>>, handle
299304 // allow overlapped to drop by omitting forget()
300305 let request: Box < ReadDirectoryRequest > = mem:: transmute ( request_p) ;
301306
302- synchapi :: ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
307+ ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
303308 } else {
304309 // read ok. forget overlapped to let the completion routine handle memory
305310 mem:: forget ( overlapped) ;
@@ -310,15 +315,15 @@ fn start_read(rd: &ReadData, event_handler: Arc<Mutex<dyn EventHandler>>, handle
310315unsafe extern "system" fn handle_event (
311316 error_code : u32 ,
312317 _bytes_written : u32 ,
313- overlapped : LPOVERLAPPED ,
318+ overlapped : * mut OVERLAPPED ,
314319) {
315320 let overlapped: Box < OVERLAPPED > = Box :: from_raw ( overlapped) ;
316321 let request: Box < ReadDirectoryRequest > = Box :: from_raw ( overlapped. hEvent as * mut _ ) ;
317322
318323 if error_code == ERROR_OPERATION_ABORTED {
319324 // received when dir is unwatched or watcher is shutdown; return and let overlapped/request
320325 // get drop-cleaned
321- synchapi :: ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
326+ ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
322327 return ;
323328 }
324329
@@ -359,30 +364,30 @@ unsafe extern "system" fn handle_event(
359364
360365 let event_handler = |res| emit_event ( & request. event_handler , res) ;
361366
362- if ( * cur_entry) . Action == winnt :: FILE_ACTION_RENAMED_OLD_NAME {
367+ if ( * cur_entry) . Action == FILE_ACTION_RENAMED_OLD_NAME {
363368 let mode = RenameMode :: From ;
364369 let kind = ModifyKind :: Name ( mode) ;
365370 let kind = EventKind :: Modify ( kind) ;
366371 let ev = newe. set_kind ( kind) ;
367372 event_handler ( Ok ( ev) )
368373 } else {
369374 match ( * cur_entry) . Action {
370- winnt :: FILE_ACTION_RENAMED_NEW_NAME => {
375+ FILE_ACTION_RENAMED_NEW_NAME => {
371376 let kind = EventKind :: Modify ( ModifyKind :: Name ( RenameMode :: To ) ) ;
372377 let ev = newe. set_kind ( kind) ;
373378 event_handler ( Ok ( ev) ) ;
374379 }
375- winnt :: FILE_ACTION_ADDED => {
380+ FILE_ACTION_ADDED => {
376381 let kind = EventKind :: Create ( CreateKind :: Any ) ;
377382 let ev = newe. set_kind ( kind) ;
378383 event_handler ( Ok ( ev) ) ;
379384 }
380- winnt :: FILE_ACTION_REMOVED => {
385+ FILE_ACTION_REMOVED => {
381386 let kind = EventKind :: Remove ( RemoveKind :: Any ) ;
382387 let ev = newe. set_kind ( kind) ;
383388 event_handler ( Ok ( ev) ) ;
384389 }
385- winnt :: FILE_ACTION_MODIFIED => {
390+ FILE_ACTION_MODIFIED => {
386391 let kind = EventKind :: Modify ( ModifyKind :: Any ) ;
387392 let ev = newe. set_kind ( kind) ;
388393 event_handler ( Ok ( ev) ) ;
@@ -415,9 +420,8 @@ impl ReadDirectoryChangesWatcher {
415420 ) -> Result < ReadDirectoryChangesWatcher > {
416421 let ( cmd_tx, cmd_rx) = unbounded ( ) ;
417422
418- let wakeup_sem =
419- unsafe { synchapi:: CreateSemaphoreW ( ptr:: null_mut ( ) , 0 , 1 , ptr:: null_mut ( ) ) } ;
420- if wakeup_sem. is_null ( ) || wakeup_sem == INVALID_HANDLE_VALUE {
423+ let wakeup_sem = unsafe { CreateSemaphoreW ( ptr:: null_mut ( ) , 0 , 1 , ptr:: null_mut ( ) ) } ;
424+ if wakeup_sem == 0 || wakeup_sem == INVALID_HANDLE_VALUE {
421425 return Err ( Error :: generic ( "Failed to create wakeup semaphore." ) ) ;
422426 }
423427
@@ -436,7 +440,7 @@ impl ReadDirectoryChangesWatcher {
436440 // so that if you add a watch you don't block for 100ms in watch() while the
437441 // server sleeps.
438442 unsafe {
439- synchapi :: ReleaseSemaphore ( self . wakeup_sem , 1 , ptr:: null_mut ( ) ) ;
443+ ReleaseSemaphore ( self . wakeup_sem , 1 , ptr:: null_mut ( ) ) ;
440444 }
441445 }
442446
0 commit comments