Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/disk/src/sys/windows.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::Read;
7
use std::io::Seek;
8
use std::io::SeekFrom;
9
use std::os::windows::fs::OpenOptionsExt;
10
11
use base::info;
12
use base::read_overlapped_blocking;
13
use cros_async::Executor;
14
use winapi::um::winbase::FILE_FLAG_NO_BUFFERING;
15
use winapi::um::winbase::FILE_FLAG_OVERLAPPED;
16
use winapi::um::winnt::FILE_SHARE_READ;
17
18
use crate::DiskFileParams;
19
use crate::Error;
20
use crate::Result;
21
use crate::SingleFileDisk;
22
23
impl SingleFileDisk {
24
pub fn new(disk: File, ex: &Executor) -> Result<Self> {
25
ex.async_overlapped_from(disk)
26
.map_err(Error::CreateSingleFileDisk)
27
.map(|inner| SingleFileDisk { inner })
28
}
29
}
30
31
pub fn open_raw_disk_image(params: &DiskFileParams) -> Result<File> {
32
let mut options = File::options();
33
options.read(true).write(!params.is_read_only);
34
if params.lock {
35
if params.is_read_only {
36
// Shared read-only file access.
37
options.share_mode(FILE_SHARE_READ);
38
} else {
39
// Exclusive file access.
40
options.share_mode(0);
41
}
42
}
43
44
let mut flags = 0;
45
if params.is_direct {
46
info!("Opening disk file with no buffering");
47
flags |= FILE_FLAG_NO_BUFFERING;
48
}
49
if params.is_overlapped {
50
info!("Opening disk file for overlapped IO");
51
flags |= FILE_FLAG_OVERLAPPED;
52
}
53
if flags != 0 {
54
options.custom_flags(flags);
55
}
56
57
let raw_image = base::open_file_or_duplicate(&params.path, &options)
58
.map_err(|e| Error::OpenFile(params.path.display().to_string(), e))?;
59
60
Ok(raw_image)
61
}
62
63
/// On Windows, if the file is sparse, we set the option. On Linux this is not needed.
64
pub fn apply_raw_disk_file_options(raw_image: &File, is_sparse_file: bool) -> Result<()> {
65
if is_sparse_file {
66
base::set_sparse_file(raw_image).map_err(Error::SetSparseFailure)?;
67
}
68
Ok(())
69
}
70
71
pub fn read_from_disk(
72
mut file: &File,
73
offset: u64,
74
buf: &mut [u8],
75
overlapped_mode: bool,
76
) -> Result<()> {
77
file.seek(SeekFrom::Start(offset))
78
.map_err(Error::SeekingFile)?;
79
if overlapped_mode {
80
read_overlapped_blocking(file, offset, buf)
81
.map(|_| ())
82
.map_err(Error::ReadingHeader)
83
} else {
84
file.read_exact(buf).map_err(Error::ReadingHeader)
85
}
86
}
87
88