Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/base/src/sys/windows/punch_hole.rs
5394 views
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::fs::File;
6
use std::io;
7
use std::io::Error;
8
9
use win_util::LargeInteger;
10
pub use winapi::um::winioctl::FSCTL_SET_ZERO_DATA;
11
use winapi::um::winnt::LARGE_INTEGER;
12
13
// This struct is not implemented in the winapi so we need to implement it ourselves
14
#[repr(C)]
15
#[allow(non_snake_case)] // to match win32 naming api.
16
#[allow(non_camel_case_types)]
17
struct FILE_ZERO_DATA_INFORMATION {
18
FileOffset: LARGE_INTEGER,
19
BeyondFinalZero: LARGE_INTEGER,
20
}
21
22
pub(crate) fn file_punch_hole(handle: &File, offset: u64, length: u64) -> io::Result<()> {
23
let large_offset = if offset > i64::MAX as u64 {
24
return Err(std::io::Error::from_raw_os_error(libc::EINVAL));
25
} else {
26
LargeInteger::new(offset as i64)
27
};
28
29
if (offset + length) > i64::MAX as u64 {
30
return Err(std::io::Error::from_raw_os_error(libc::EINVAL));
31
}
32
33
let end_offset = LargeInteger::new((offset + length) as i64);
34
35
let zero_data = FILE_ZERO_DATA_INFORMATION {
36
FileOffset: *large_offset,
37
BeyondFinalZero: *end_offset,
38
};
39
40
// SAFETY:
41
// Safe because we check the return value and all values should be set
42
let result = unsafe { super::ioctl::ioctl_with_ref(handle, FSCTL_SET_ZERO_DATA, &zero_data) };
43
44
if result != 0 {
45
return Err(Error::from_raw_os_error(result));
46
}
47
48
Ok(())
49
}
50
51