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