Make synchronous_write safe to call

This commit is contained in:
Chris Denton 2022-04-04 06:08:16 +01:00
parent 084b71a54f
commit 88c05edc9d
No known key found for this signature in database
GPG key ID: 713472F2F45627DE
2 changed files with 18 additions and 23 deletions

View file

@ -986,13 +986,6 @@ pub fn ReadFileEx(
lpOverlapped: LPOVERLAPPED,
lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
) -> BOOL;
pub fn WriteFile(
hFile: BorrowedHandle<'_>,
lpBuffer: LPVOID,
nNumberOfBytesToWrite: DWORD,
lpNumberOfBytesWritten: LPDWORD,
lpOverlapped: LPOVERLAPPED,
) -> BOOL;
pub fn WriteFileEx(
hFile: BorrowedHandle<'_>,
lpBuffer: LPVOID,

View file

@ -192,7 +192,7 @@ pub fn cancel_io(&self) -> io::Result<()> {
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
unsafe { self.synchronous_write(&buf, None) }
self.synchronous_write(&buf, None)
}
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
@ -205,7 +205,7 @@ pub fn is_write_vectored(&self) -> bool {
}
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
unsafe { self.synchronous_write(&buf, Some(offset)) }
self.synchronous_write(&buf, Some(offset))
}
pub fn try_clone(&self) -> io::Result<Self> {
@ -276,25 +276,27 @@ unsafe fn synchronous_read(
/// See #81357.
///
/// If `offset` is `None` then the current file position is used.
unsafe fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> {
fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> {
let mut io_status = c::IO_STATUS_BLOCK::default();
// The length is clamped at u32::MAX.
let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
let status = c::NtWriteFile(
self.as_handle(),
ptr::null_mut(),
None,
ptr::null_mut(),
&mut io_status,
buf.as_ptr(),
len,
offset.map(|n| n as _).as_ref(),
None,
);
let status = unsafe {
c::NtWriteFile(
self.as_handle(),
ptr::null_mut(),
None,
ptr::null_mut(),
&mut io_status,
buf.as_ptr(),
len,
offset.map(|n| n as _).as_ref(),
None,
)
};
match status {
// If the operation has not completed then abort the process.
// Doing otherwise means that the buffer maybe read and the stack
// Doing otherwise means that the buffer may be read and the stack
// written to after this function returns.
c::STATUS_PENDING => {
eprintln!("I/O error: operation failed to complete synchronously");
@ -305,7 +307,7 @@ unsafe fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Resul
status if c::nt_success(status) => Ok(io_status.Information),
status => {
let error = c::RtlNtStatusToDosError(status);
let error = unsafe { c::RtlNtStatusToDosError(status) };
Err(io::Error::from_raw_os_error(error as _))
}
}