xref: /aosp_15_r20/external/crosvm/vm_control/src/sys/windows.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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 #[cfg(feature = "gpu")]
6 pub(crate) mod gpu;
7 
8 use std::io::Result;
9 use std::mem::size_of;
10 use std::path::Path;
11 use std::time::Duration;
12 
13 use base::error;
14 use base::named_pipes::BlockingMode;
15 use base::named_pipes::FramingMode;
16 use base::named_pipes::MultiPartMessagePipe;
17 use base::named_pipes::OverlappedWrapper;
18 use base::Error;
19 use base::Event;
20 use base::PipeTube;
21 use hypervisor::MemCacheType;
22 use hypervisor::Vm;
23 use resources::Alloc;
24 use resources::SystemAllocator;
25 
26 use crate::client::HandleRequestResult;
27 use crate::VmMappedMemoryRegion;
28 use crate::VmRequest;
29 
30 pub const SERVICE_MESSAGE_HEADER_SIZE: usize = size_of::<u32>();
31 
handle_request<T: AsRef<Path> + std::fmt::Debug>( request: &VmRequest, socket_path: T, ) -> HandleRequestResult32 pub fn handle_request<T: AsRef<Path> + std::fmt::Debug>(
33     request: &VmRequest,
34     socket_path: T,
35 ) -> HandleRequestResult {
36     match base::named_pipes::create_client_pipe(
37         socket_path
38             .as_ref()
39             .to_str()
40             .expect("socket path must be a string"),
41         &FramingMode::Message,
42         &BlockingMode::Wait,
43         /* overlapped= */ false,
44     ) {
45         Ok(pipe) => {
46             let tube = PipeTube::from(pipe, None);
47             if let Err(e) = tube.send(request) {
48                 error!(
49                     "failed to send request to pipe at '{:?}': {}",
50                     socket_path, e
51                 );
52                 return Err(());
53             }
54             match tube.recv() {
55                 Ok(response) => Ok(response),
56                 Err(e) => {
57                     error!(
58                         "failed to recv response from pipe at '{:?}': {}",
59                         socket_path, e
60                     );
61                     Err(())
62                 }
63             }
64         }
65         Err(e) => {
66             error!("failed to connect to socket at '{:?}': {}", socket_path, e);
67             Err(())
68         }
69     }
70 }
71 
handle_request_with_timeout<T: AsRef<Path> + std::fmt::Debug>( request: &VmRequest, socket_path: T, timeout: Option<Duration>, ) -> HandleRequestResult72 pub fn handle_request_with_timeout<T: AsRef<Path> + std::fmt::Debug>(
73     request: &VmRequest,
74     socket_path: T,
75     timeout: Option<Duration>,
76 ) -> HandleRequestResult {
77     if timeout.is_none() {
78         handle_request(request, socket_path)
79     } else {
80         error!("handle_request_with_timeout() not implemented for Windows");
81         Err(())
82     }
83 }
84 
85 /// Send the size header first and then the protbuf message.
86 ///
87 /// A helper function to keep communication with service consistent across crosvm code.
send_service_message( connection: &MultiPartMessagePipe, message: &[u8], overlapped_wrapper: &mut OverlappedWrapper, ) -> Result<()>88 pub fn send_service_message(
89     connection: &MultiPartMessagePipe,
90     message: &[u8],
91     overlapped_wrapper: &mut OverlappedWrapper,
92 ) -> Result<()> {
93     let size_in_bytes = message.len() as u32;
94     connection.write_overlapped_blocking_message(
95         &size_in_bytes.to_be_bytes(),
96         message,
97         overlapped_wrapper,
98     )
99 }
100 
101 /// Read and wait for the header to arrive in the named pipe. Once header is available, use the
102 /// size to fetch the message.
103 ///
104 /// A helper function to keep communication with service consistent across crosvm code.
recv_service_message( connection: &MultiPartMessagePipe, overlapped_wrapper: &mut OverlappedWrapper, exit_event: &Event, ) -> Result<Vec<u8>>105 pub fn recv_service_message(
106     connection: &MultiPartMessagePipe,
107     overlapped_wrapper: &mut OverlappedWrapper,
108     exit_event: &Event,
109 ) -> Result<Vec<u8>> {
110     connection.read_overlapped_blocking_message(
111         SERVICE_MESSAGE_HEADER_SIZE,
112         |bytes: &[u8]| {
113             assert_eq!(bytes.len(), SERVICE_MESSAGE_HEADER_SIZE);
114             u32::from_be_bytes(bytes.try_into().expect("failed to get array from slice")) as usize
115         },
116         overlapped_wrapper,
117         exit_event,
118     )
119 }
120 
should_prepare_memory_region() -> bool121 pub fn should_prepare_memory_region() -> bool {
122     false
123 }
124 
prepare_shared_memory_region( _vm: &mut dyn Vm, _allocator: &mut SystemAllocator, _alloc: Alloc, _cache: MemCacheType, ) -> std::result::Result<VmMappedMemoryRegion, Error>125 pub fn prepare_shared_memory_region(
126     _vm: &mut dyn Vm,
127     _allocator: &mut SystemAllocator,
128     _alloc: Alloc,
129     _cache: MemCacheType,
130 ) -> std::result::Result<VmMappedMemoryRegion, Error> {
131     unimplemented!()
132 }
133 
134 /// State of a specific audio device on boot.
135 pub struct InitialAudioSessionState {
136     // Uniquely identify an audio device. In ALSA terminology, this is the card_index as opposed to
137     // a device index.
138     pub card_index: usize,
139     // GUID assigned to the device's IAudioClient
140     pub audio_client_guid: String,
141 }
142