xref: /aosp_15_r20/external/crosvm/hypervisor/src/haxm/win.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2020 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::ptr::null_mut;
6 
7 use base::errno_result;
8 use base::FromRawDescriptor;
9 use base::Result;
10 use base::SafeDescriptor;
11 use win_util::win32_wide_string;
12 use winapi::um::fileapi::CreateFileW;
13 use winapi::um::fileapi::CREATE_ALWAYS;
14 use winapi::um::handleapi::INVALID_HANDLE_VALUE;
15 use winapi::um::winnt::FILE_ATTRIBUTE_NORMAL;
16 use winapi::um::winnt::GENERIC_READ;
17 use winapi::um::winnt::GENERIC_WRITE;
18 
open_haxm_device(use_ghaxm: bool) -> Result<SafeDescriptor>19 pub(super) fn open_haxm_device(use_ghaxm: bool) -> Result<SafeDescriptor> {
20     // SAFETY:
21     // Open calls are safe because we give a constant nul-terminated string and verify the
22     // result.
23     let ret = unsafe {
24         CreateFileW(
25             win32_wide_string(if use_ghaxm {
26                 "\\\\.\\GHAX"
27             } else {
28                 "\\\\.\\HAX"
29             })
30             .as_ptr(),
31             GENERIC_READ | GENERIC_WRITE,
32             0,
33             null_mut(),
34             CREATE_ALWAYS,
35             FILE_ATTRIBUTE_NORMAL,
36             null_mut(),
37         )
38     };
39 
40     if ret == INVALID_HANDLE_VALUE {
41         return errno_result();
42     }
43     // SAFETY:
44     // Safe because we verify that ret is valid and we own the fd.
45     Ok(unsafe { SafeDescriptor::from_raw_descriptor(ret) })
46 }
47 
open_haxm_vm_device(use_ghaxm: bool, vm_id: u32) -> Result<SafeDescriptor>48 pub(super) fn open_haxm_vm_device(use_ghaxm: bool, vm_id: u32) -> Result<SafeDescriptor> {
49     let name = if use_ghaxm {
50         format!("\\\\.\\ghax_vm{:02}", vm_id)
51     } else {
52         format!("\\\\.\\hax_vm{:02}", vm_id)
53     };
54     // SAFETY:
55     // Open calls are safe because we give a constant nul-terminated string and verify the
56     // result.
57     let ret = unsafe {
58         CreateFileW(
59             win32_wide_string(&name).as_ptr(),
60             GENERIC_READ | GENERIC_WRITE,
61             0,
62             null_mut(),
63             CREATE_ALWAYS,
64             FILE_ATTRIBUTE_NORMAL,
65             null_mut(),
66         )
67     };
68 
69     if ret == INVALID_HANDLE_VALUE {
70         return errno_result();
71     }
72     // SAFETY:
73     // Safe because we verify that ret is valid and we own the fd.
74     Ok(unsafe { SafeDescriptor::from_raw_descriptor(ret) })
75 }
76 
open_haxm_vcpu_device( use_ghaxm: bool, vm_id: u32, vcpu_id: u32, ) -> Result<SafeDescriptor>77 pub(super) fn open_haxm_vcpu_device(
78     use_ghaxm: bool,
79     vm_id: u32,
80     vcpu_id: u32,
81 ) -> Result<SafeDescriptor> {
82     let name = if use_ghaxm {
83         format!("\\\\.\\ghax_vm{:02}_vcpu{:02}", vm_id, vcpu_id)
84     } else {
85         format!("\\\\.\\hax_vm{:02}_vcpu{:02}", vm_id, vcpu_id)
86     };
87     // SAFETY:
88     // Open calls are safe because we give a constant nul-terminated string and verify the
89     // result.
90     let ret = unsafe {
91         CreateFileW(
92             win32_wide_string(&name).as_ptr(),
93             GENERIC_READ | GENERIC_WRITE,
94             0,
95             null_mut(),
96             CREATE_ALWAYS,
97             FILE_ATTRIBUTE_NORMAL,
98             null_mut(),
99         )
100     };
101 
102     if ret == INVALID_HANDLE_VALUE {
103         return errno_result();
104     }
105     // SAFETY:
106     // Safe because we verify that ret is valid and we own the fd.
107     Ok(unsafe { SafeDescriptor::from_raw_descriptor(ret) })
108 }
109