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