Windows: Fallback for overlapped I/O

Try waiting on the file handle once. If that fails then give up.
This commit is contained in:
Chris Denton
2022-07-06 16:38:35 +01:00
parent acc5441656
commit 43496d7808
2 changed files with 26 additions and 1 deletions
+13 -1
View File
@@ -326,7 +326,9 @@ union IO_STATUS_BLOCK_union {
}
impl Default for IO_STATUS_BLOCK_union {
fn default() -> Self {
Self { Pointer: ptr::null_mut() }
let mut this = Self { Pointer: ptr::null_mut() };
this.Status = STATUS_PENDING;
this
}
}
#[repr(C)]
@@ -335,6 +337,16 @@ pub struct IO_STATUS_BLOCK {
u: IO_STATUS_BLOCK_union,
pub Information: usize,
}
impl IO_STATUS_BLOCK {
pub fn status(&self) -> NTSTATUS {
// SAFETY: If `self.u.Status` was set then this is obviously safe.
// If `self.u.Pointer` was set then this is the equivalent to converting
// the pointer to an integer, which is also safe.
// Currently the only safe way to construct `IO_STATUS_BLOCK` outside of
// this module is to call the `default` method, which sets the `Status`.
unsafe { self.u.Status }
}
}
pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
dwErrorCode: DWORD,
+13
View File
@@ -248,6 +248,13 @@ impl Handle {
offset.map(|n| n as _).as_ref(),
None,
);
let status = if status == c::STATUS_PENDING {
c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE);
io_status.status()
} else {
status
};
match status {
// If the operation has not completed then abort the process.
// Doing otherwise means that the buffer and stack may be written to
@@ -291,6 +298,12 @@ impl Handle {
None,
)
};
let status = if status == c::STATUS_PENDING {
unsafe { c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE) };
io_status.status()
} else {
status
};
match status {
// If the operation has not completed then abort the process.
// Doing otherwise means that the buffer may be read and the stack