Skip to content

Commit b23efcb

Browse files
GamePad640xpr03
authored andcommitted
Use official windows-sys crate for WinAPI instead of deprecated winapi crate
1 parent 0e354a3 commit b23efcb

File tree

2 files changed

+54
-50
lines changed

2 files changed

+54
-50
lines changed

notify/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ kqueue = { version = "1.0", optional = true }
3535
mio = { version = "0.8", features = ["os-ext"], optional = true }
3636

3737
[target.'cfg(windows)'.dependencies]
38-
winapi = { version = "0.3.8", features = ["fileapi", "handleapi", "ioapiset", "minwinbase", "synchapi", "winbase", "winnt"] }
38+
windows-sys = { version = "0.42.0", features = ["Win32_System_Threading", "Win32_Foundation", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_WindowsProgramming", "Win32_System_IO"] }
3939

4040
[target.'cfg(any(target_os="freebsd", target_os="openbsd", target_os = "netbsd", target_os = "dragonflybsd"))'.dependencies]
4141
kqueue = "^1.0.4" # fix for #344

notify/src/windows.rs

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,7 @@
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};
199
use crate::{event::*, WatcherKind};
2010
use crate::{Error, EventHandler, RecursiveMode, Result, Watcher};
2111
use std::collections::HashMap;
@@ -29,6 +19,23 @@ use std::ptr;
2919
use std::slice;
3020
use std::sync::{Arc, Mutex};
3121
use 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

3340
const 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

237243
fn 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
310315
unsafe 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

Comments
 (0)