use std::fs::File;
use std::io;
use std::io::Error;
use win_util::LargeInteger;
pub use winapi::um::winioctl::FSCTL_SET_ZERO_DATA;
use winapi::um::winnt::LARGE_INTEGER;
#[repr(C)]
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
struct FILE_ZERO_DATA_INFORMATION {
FileOffset: LARGE_INTEGER,
BeyondFinalZero: LARGE_INTEGER,
}
pub(crate) fn file_punch_hole(handle: &File, offset: u64, length: u64) -> io::Result<()> {
let large_offset = if offset > i64::MAX as u64 {
return Err(std::io::Error::from_raw_os_error(libc::EINVAL));
} else {
LargeInteger::new(offset as i64)
};
if (offset + length) > i64::MAX as u64 {
return Err(std::io::Error::from_raw_os_error(libc::EINVAL));
}
let end_offset = LargeInteger::new((offset + length) as i64);
let zero_data = FILE_ZERO_DATA_INFORMATION {
FileOffset: *large_offset,
BeyondFinalZero: *end_offset,
};
let result = unsafe { super::ioctl::ioctl_with_ref(handle, FSCTL_SET_ZERO_DATA, &zero_data) };
if result != 0 {
return Err(Error::from_raw_os_error(result));
}
Ok(())
}