Windows: Fallback for overlapped I/O
Try waiting on the file handle once. If that fails then give up.
This commit is contained in:
parent
ae60dbdcac
commit
3ae47e76a8
@ -326,7 +326,9 @@ union IO_STATUS_BLOCK_union {
|
|||||||
}
|
}
|
||||||
impl Default for IO_STATUS_BLOCK_union {
|
impl Default for IO_STATUS_BLOCK_union {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { Pointer: ptr::null_mut() }
|
let mut this = Self { Pointer: ptr::null_mut() };
|
||||||
|
this.Status = STATUS_PENDING;
|
||||||
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -335,6 +337,16 @@ pub struct IO_STATUS_BLOCK {
|
|||||||
u: IO_STATUS_BLOCK_union,
|
u: IO_STATUS_BLOCK_union,
|
||||||
pub Information: usize,
|
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(
|
pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
|
||||||
dwErrorCode: DWORD,
|
dwErrorCode: DWORD,
|
||||||
|
@ -248,6 +248,13 @@ unsafe fn synchronous_read(
|
|||||||
offset.map(|n| n as _).as_ref(),
|
offset.map(|n| n as _).as_ref(),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let status = if status == c::STATUS_PENDING {
|
||||||
|
c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE);
|
||||||
|
io_status.status()
|
||||||
|
} else {
|
||||||
|
status
|
||||||
|
};
|
||||||
match status {
|
match status {
|
||||||
// If the operation has not completed then abort the process.
|
// If the operation has not completed then abort the process.
|
||||||
// Doing otherwise means that the buffer and stack may be written to
|
// Doing otherwise means that the buffer and stack may be written to
|
||||||
@ -291,6 +298,12 @@ fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
let status = if status == c::STATUS_PENDING {
|
||||||
|
unsafe { c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE) };
|
||||||
|
io_status.status()
|
||||||
|
} else {
|
||||||
|
status
|
||||||
|
};
|
||||||
match status {
|
match status {
|
||||||
// If the operation has not completed then abort the process.
|
// If the operation has not completed then abort the process.
|
||||||
// Doing otherwise means that the buffer may be read and the stack
|
// Doing otherwise means that the buffer may be read and the stack
|
||||||
|
Loading…
Reference in New Issue
Block a user