Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit e59e580

Browse files
ChrisDentonMark-Simulacrum
authored andcommitted
Windows: Fallback for overlapped I/O
Try waiting on the file handle once. If that fails then give up.
1 parent 196b8c4 commit e59e580

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

library/std/src/sys/windows/c.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,9 @@ union IO_STATUS_BLOCK_union {
325325
}
326326
impl Default for IO_STATUS_BLOCK_union {
327327
fn default() -> Self {
328-
Self { Pointer: ptr::null_mut() }
328+
let mut this = Self { Pointer: ptr::null_mut() };
329+
this.Status = STATUS_PENDING;
330+
this
329331
}
330332
}
331333
#[repr(C)]
@@ -334,6 +336,16 @@ pub struct IO_STATUS_BLOCK {
334336
u: IO_STATUS_BLOCK_union,
335337
pub Information: usize,
336338
}
339+
impl IO_STATUS_BLOCK {
340+
pub fn status(&self) -> NTSTATUS {
341+
// SAFETY: If `self.u.Status` was set then this is obviously safe.
342+
// If `self.u.Pointer` was set then this is the equivalent to converting
343+
// the pointer to an integer, which is also safe.
344+
// Currently the only safe way to construct `IO_STATUS_BLOCK` outside of
345+
// this module is to call the `default` method, which sets the `Status`.
346+
unsafe { self.u.Status }
347+
}
348+
}
337349

338350
pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
339351
dwErrorCode: DWORD,

library/std/src/sys/windows/handle.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ impl Handle {
248248
offset.map(|n| n as _).as_ref(),
249249
None,
250250
);
251+
252+
let status = if status == c::STATUS_PENDING {
253+
c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE);
254+
io_status.status()
255+
} else {
256+
status
257+
};
251258
match status {
252259
// If the operation has not completed then abort the process.
253260
// Doing otherwise means that the buffer and stack may be written to
@@ -291,6 +298,12 @@ impl Handle {
291298
None,
292299
)
293300
};
301+
let status = if status == c::STATUS_PENDING {
302+
unsafe { c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE) };
303+
io_status.status()
304+
} else {
305+
status
306+
};
294307
match status {
295308
// If the operation has not completed then abort the process.
296309
// Doing otherwise means that the buffer may be read and the stack

0 commit comments

Comments
 (0)