xref: /aosp_15_r20/external/crosvm/win_util/src/lib.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 //! Library for common Windows-specfic utilities
6*bb4ee6a4SAndroid Build Coastguard Worker //!
7*bb4ee6a4SAndroid Build Coastguard Worker //! TODO(b/223723424) win_util should be merged into win_sys_util or part of the
8*bb4ee6a4SAndroid Build Coastguard Worker //! base.
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker // Do nothing on unix as win_util is windows only.
11*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(windows)]
12*bb4ee6a4SAndroid Build Coastguard Worker // TODO: Many pub functions take `RawHandle` (which is a pointer on Windows) but are not marked
13*bb4ee6a4SAndroid Build Coastguard Worker // `unsafe`.
14*bb4ee6a4SAndroid Build Coastguard Worker #![allow(clippy::not_unsafe_ptr_arg_deref)]
15*bb4ee6a4SAndroid Build Coastguard Worker 
16*bb4ee6a4SAndroid Build Coastguard Worker mod large_integer;
17*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::large_integer::*;
18*bb4ee6a4SAndroid Build Coastguard Worker 
19*bb4ee6a4SAndroid Build Coastguard Worker mod security_attributes;
20*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::security_attributes::*;
21*bb4ee6a4SAndroid Build Coastguard Worker 
22*bb4ee6a4SAndroid Build Coastguard Worker mod dll_notification;
23*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CString;
24*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::OsStr;
25*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::OsString;
26*bb4ee6a4SAndroid Build Coastguard Worker use std::io;
27*bb4ee6a4SAndroid Build Coastguard Worker use std::iter::once;
28*bb4ee6a4SAndroid Build Coastguard Worker use std::os::windows::ffi::OsStrExt;
29*bb4ee6a4SAndroid Build Coastguard Worker use std::os::windows::ffi::OsStringExt;
30*bb4ee6a4SAndroid Build Coastguard Worker use std::os::windows::io::RawHandle;
31*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr;
32*bb4ee6a4SAndroid Build Coastguard Worker use std::slice;
33*bb4ee6a4SAndroid Build Coastguard Worker 
34*bb4ee6a4SAndroid Build Coastguard Worker mod keyboard;
35*bb4ee6a4SAndroid Build Coastguard Worker pub use keyboard::*;
36*bb4ee6a4SAndroid Build Coastguard Worker use libc::c_ulong;
37*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
38*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
39*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::DWORD;
40*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::FALSE;
41*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::TRUE;
42*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::ntdef::UNICODE_STRING;
43*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::handleapi::CloseHandle;
44*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::handleapi::DuplicateHandle;
45*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::handleapi::SetHandleInformation;
46*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::handleapi::INVALID_HANDLE_VALUE;
47*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::minwinbase::STILL_ACTIVE;
48*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::GetCurrentProcess;
49*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::GetExitCodeProcess;
50*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::OpenProcess;
51*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::ResumeThread;
52*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winbase::CreateFileMappingA;
53*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winbase::HANDLE_FLAG_INHERIT;
54*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::DUPLICATE_SAME_ACCESS;
55*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::HRESULT;
56*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::PROCESS_DUP_HANDLE;
57*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::WCHAR;
58*bb4ee6a4SAndroid Build Coastguard Worker 
59*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::dll_notification::*;
60*bb4ee6a4SAndroid Build Coastguard Worker 
61*bb4ee6a4SAndroid Build Coastguard Worker pub mod dpapi;
62*bb4ee6a4SAndroid Build Coastguard Worker 
63*bb4ee6a4SAndroid Build Coastguard Worker #[macro_export]
64*bb4ee6a4SAndroid Build Coastguard Worker macro_rules! syscall_bail {
65*bb4ee6a4SAndroid Build Coastguard Worker     ($details:expr) => {
66*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: Safe because GetLastError is thread safe and won't access the memory.
67*bb4ee6a4SAndroid Build Coastguard Worker         ::anyhow::bail!("{} (Error code {})", $details, unsafe {
68*bb4ee6a4SAndroid Build Coastguard Worker             ::winapi::um::errhandlingapi::GetLastError()
69*bb4ee6a4SAndroid Build Coastguard Worker         })
70*bb4ee6a4SAndroid Build Coastguard Worker     };
71*bb4ee6a4SAndroid Build Coastguard Worker }
72*bb4ee6a4SAndroid Build Coastguard Worker 
73*bb4ee6a4SAndroid Build Coastguard Worker #[macro_export]
74*bb4ee6a4SAndroid Build Coastguard Worker macro_rules! fail_if_zero {
75*bb4ee6a4SAndroid Build Coastguard Worker     ($syscall:expr) => {
76*bb4ee6a4SAndroid Build Coastguard Worker         if $syscall == 0 {
77*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
78*bb4ee6a4SAndroid Build Coastguard Worker         }
79*bb4ee6a4SAndroid Build Coastguard Worker     };
80*bb4ee6a4SAndroid Build Coastguard Worker }
81*bb4ee6a4SAndroid Build Coastguard Worker 
82*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the lower 32 bits of a u64 as a u32 (c_ulong/DWORD)
get_low_order(number: u64) -> c_ulong83*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_low_order(number: u64) -> c_ulong {
84*bb4ee6a4SAndroid Build Coastguard Worker     (number & (u32::MAX as u64)) as c_ulong
85*bb4ee6a4SAndroid Build Coastguard Worker }
86*bb4ee6a4SAndroid Build Coastguard Worker 
87*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the upper 32 bits of a u64 as a u32 (c_ulong/DWORD)
get_high_order(number: u64) -> c_ulong88*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_high_order(number: u64) -> c_ulong {
89*bb4ee6a4SAndroid Build Coastguard Worker     (number >> 32) as c_ulong
90*bb4ee6a4SAndroid Build Coastguard Worker }
91*bb4ee6a4SAndroid Build Coastguard Worker 
win32_string(value: &str) -> CString92*bb4ee6a4SAndroid Build Coastguard Worker pub fn win32_string(value: &str) -> CString {
93*bb4ee6a4SAndroid Build Coastguard Worker     CString::new(value).unwrap()
94*bb4ee6a4SAndroid Build Coastguard Worker }
95*bb4ee6a4SAndroid Build Coastguard Worker 
win32_wide_string(value: &str) -> Vec<u16>96*bb4ee6a4SAndroid Build Coastguard Worker pub fn win32_wide_string(value: &str) -> Vec<u16> {
97*bb4ee6a4SAndroid Build Coastguard Worker     OsStr::new(value).encode_wide().chain(once(0)).collect()
98*bb4ee6a4SAndroid Build Coastguard Worker }
99*bb4ee6a4SAndroid Build Coastguard Worker 
100*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the length, in u16 words (*not* UTF-16 chars), of a null-terminated u16 string.
101*bb4ee6a4SAndroid Build Coastguard Worker /// Safe when `wide` is non-null and points to a u16 string terminated by a null character.
strlen_ptr_u16(wide: *const u16) -> usize102*bb4ee6a4SAndroid Build Coastguard Worker unsafe fn strlen_ptr_u16(wide: *const u16) -> usize {
103*bb4ee6a4SAndroid Build Coastguard Worker     assert!(!wide.is_null());
104*bb4ee6a4SAndroid Build Coastguard Worker     for i in 0.. {
105*bb4ee6a4SAndroid Build Coastguard Worker         if *wide.offset(i) == 0 {
106*bb4ee6a4SAndroid Build Coastguard Worker             return i as usize;
107*bb4ee6a4SAndroid Build Coastguard Worker         }
108*bb4ee6a4SAndroid Build Coastguard Worker     }
109*bb4ee6a4SAndroid Build Coastguard Worker     unreachable!()
110*bb4ee6a4SAndroid Build Coastguard Worker }
111*bb4ee6a4SAndroid Build Coastguard Worker 
112*bb4ee6a4SAndroid Build Coastguard Worker /// Converts a UTF-16 null-terminated string to an owned `String`.  Any invalid code points are
113*bb4ee6a4SAndroid Build Coastguard Worker /// converted to `std::char::REPLACEMENT_CHARACTER`.
114*bb4ee6a4SAndroid Build Coastguard Worker ///
115*bb4ee6a4SAndroid Build Coastguard Worker /// # Safety
116*bb4ee6a4SAndroid Build Coastguard Worker ///
117*bb4ee6a4SAndroid Build Coastguard Worker /// Safe when `wide` is non-null and points to a u16 string terminated by a null character.
from_ptr_win32_wide_string(wide: *const u16) -> String118*bb4ee6a4SAndroid Build Coastguard Worker pub unsafe fn from_ptr_win32_wide_string(wide: *const u16) -> String {
119*bb4ee6a4SAndroid Build Coastguard Worker     assert!(!wide.is_null());
120*bb4ee6a4SAndroid Build Coastguard Worker     let len = strlen_ptr_u16(wide);
121*bb4ee6a4SAndroid Build Coastguard Worker     let slice = slice::from_raw_parts(wide, len);
122*bb4ee6a4SAndroid Build Coastguard Worker     String::from_utf16_lossy(slice)
123*bb4ee6a4SAndroid Build Coastguard Worker }
124*bb4ee6a4SAndroid Build Coastguard Worker 
125*bb4ee6a4SAndroid Build Coastguard Worker /// Converts a `UNICODE_STRING` into an `OsString`.
126*bb4ee6a4SAndroid Build Coastguard Worker /// ## Safety
127*bb4ee6a4SAndroid Build Coastguard Worker /// Safe when `unicode_string` is non-null and points to a valid
128*bb4ee6a4SAndroid Build Coastguard Worker /// `UNICODE_STRING` struct.
unicode_string_to_os_string(unicode_string: &UNICODE_STRING) -> OsString129*bb4ee6a4SAndroid Build Coastguard Worker pub fn unicode_string_to_os_string(unicode_string: &UNICODE_STRING) -> OsString {
130*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
131*bb4ee6a4SAndroid Build Coastguard Worker     // * Buffer is guaranteed to be properly aligned and valid for the entire length of the string.
132*bb4ee6a4SAndroid Build Coastguard Worker     // * The slice is only temporary, until we perform the `from_wide` conversion with `OsString`,
133*bb4ee6a4SAndroid Build Coastguard Worker     //   so the memory referenced by the slice is not modified during that duration.
134*bb4ee6a4SAndroid Build Coastguard Worker     OsString::from_wide(unsafe {
135*bb4ee6a4SAndroid Build Coastguard Worker         slice::from_raw_parts(
136*bb4ee6a4SAndroid Build Coastguard Worker             unicode_string.Buffer,
137*bb4ee6a4SAndroid Build Coastguard Worker             unicode_string.Length as usize / std::mem::size_of::<WCHAR>(),
138*bb4ee6a4SAndroid Build Coastguard Worker         )
139*bb4ee6a4SAndroid Build Coastguard Worker     })
140*bb4ee6a4SAndroid Build Coastguard Worker }
141*bb4ee6a4SAndroid Build Coastguard Worker 
duplicate_handle_with_target_pid(hndl: RawHandle, target_pid: u32) -> io::Result<RawHandle>142*bb4ee6a4SAndroid Build Coastguard Worker pub fn duplicate_handle_with_target_pid(hndl: RawHandle, target_pid: u32) -> io::Result<RawHandle> {
143*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: Caller will guarantee `hndl` and `target_pid` are valid and won't be dropped.
144*bb4ee6a4SAndroid Build Coastguard Worker     unsafe {
145*bb4ee6a4SAndroid Build Coastguard Worker         let target_process_handle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, target_pid);
146*bb4ee6a4SAndroid Build Coastguard Worker         if target_process_handle.is_null() {
147*bb4ee6a4SAndroid Build Coastguard Worker             return Err(io::Error::last_os_error());
148*bb4ee6a4SAndroid Build Coastguard Worker         }
149*bb4ee6a4SAndroid Build Coastguard Worker         let result = duplicate_handle_with_target_handle(hndl, target_process_handle);
150*bb4ee6a4SAndroid Build Coastguard Worker         CloseHandle(target_process_handle);
151*bb4ee6a4SAndroid Build Coastguard Worker         result
152*bb4ee6a4SAndroid Build Coastguard Worker     }
153*bb4ee6a4SAndroid Build Coastguard Worker }
154*bb4ee6a4SAndroid Build Coastguard Worker 
duplicate_handle_from_source_process( source_process_handle: RawHandle, hndl: RawHandle, target_process_handle: RawHandle, ) -> io::Result<RawHandle>155*bb4ee6a4SAndroid Build Coastguard Worker pub fn duplicate_handle_from_source_process(
156*bb4ee6a4SAndroid Build Coastguard Worker     source_process_handle: RawHandle,
157*bb4ee6a4SAndroid Build Coastguard Worker     hndl: RawHandle,
158*bb4ee6a4SAndroid Build Coastguard Worker     target_process_handle: RawHandle,
159*bb4ee6a4SAndroid Build Coastguard Worker ) -> io::Result<RawHandle> {
160*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY:
161*bb4ee6a4SAndroid Build Coastguard Worker     // 1. We are checking the return code
162*bb4ee6a4SAndroid Build Coastguard Worker     // 2. new_handle_ptr points to a valid location on the stack
163*bb4ee6a4SAndroid Build Coastguard Worker     // 3. Caller guarantees hndl is a real valid handle.
164*bb4ee6a4SAndroid Build Coastguard Worker     unsafe {
165*bb4ee6a4SAndroid Build Coastguard Worker         let mut new_handle: RawHandle = ptr::null_mut();
166*bb4ee6a4SAndroid Build Coastguard Worker         let success_flag = DuplicateHandle(
167*bb4ee6a4SAndroid Build Coastguard Worker             /* hSourceProcessHandle= */ source_process_handle,
168*bb4ee6a4SAndroid Build Coastguard Worker             /* hSourceHandle= */ hndl,
169*bb4ee6a4SAndroid Build Coastguard Worker             /* hTargetProcessHandle= */ target_process_handle,
170*bb4ee6a4SAndroid Build Coastguard Worker             /* lpTargetHandle= */ &mut new_handle,
171*bb4ee6a4SAndroid Build Coastguard Worker             /* dwDesiredAccess= */ 0,
172*bb4ee6a4SAndroid Build Coastguard Worker             /* bInheritHandle= */ TRUE,
173*bb4ee6a4SAndroid Build Coastguard Worker             /* dwOptions= */ DUPLICATE_SAME_ACCESS,
174*bb4ee6a4SAndroid Build Coastguard Worker         );
175*bb4ee6a4SAndroid Build Coastguard Worker 
176*bb4ee6a4SAndroid Build Coastguard Worker         if success_flag == FALSE {
177*bb4ee6a4SAndroid Build Coastguard Worker             Err(io::Error::last_os_error())
178*bb4ee6a4SAndroid Build Coastguard Worker         } else {
179*bb4ee6a4SAndroid Build Coastguard Worker             Ok(new_handle)
180*bb4ee6a4SAndroid Build Coastguard Worker         }
181*bb4ee6a4SAndroid Build Coastguard Worker     }
182*bb4ee6a4SAndroid Build Coastguard Worker }
183*bb4ee6a4SAndroid Build Coastguard Worker 
duplicate_handle_with_target_handle( hndl: RawHandle, target_process_handle: RawHandle, ) -> io::Result<RawHandle>184*bb4ee6a4SAndroid Build Coastguard Worker fn duplicate_handle_with_target_handle(
185*bb4ee6a4SAndroid Build Coastguard Worker     hndl: RawHandle,
186*bb4ee6a4SAndroid Build Coastguard Worker     target_process_handle: RawHandle,
187*bb4ee6a4SAndroid Build Coastguard Worker ) -> io::Result<RawHandle> {
188*bb4ee6a4SAndroid Build Coastguard Worker     duplicate_handle_from_source_process(
189*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: `GetCurrentProcess` just gets the current process handle.
190*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { GetCurrentProcess() },
191*bb4ee6a4SAndroid Build Coastguard Worker         hndl,
192*bb4ee6a4SAndroid Build Coastguard Worker         target_process_handle,
193*bb4ee6a4SAndroid Build Coastguard Worker     )
194*bb4ee6a4SAndroid Build Coastguard Worker }
195*bb4ee6a4SAndroid Build Coastguard Worker 
duplicate_handle(hndl: RawHandle) -> io::Result<RawHandle>196*bb4ee6a4SAndroid Build Coastguard Worker pub fn duplicate_handle(hndl: RawHandle) -> io::Result<RawHandle> {
197*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: `GetCurrentProcess` just gets the current process handle.
198*bb4ee6a4SAndroid Build Coastguard Worker     duplicate_handle_with_target_handle(hndl, unsafe { GetCurrentProcess() })
199*bb4ee6a4SAndroid Build Coastguard Worker }
200*bb4ee6a4SAndroid Build Coastguard Worker 
201*bb4ee6a4SAndroid Build Coastguard Worker /// Sets whether a handle is inheritable. Note that this only works on some types of handles,
202*bb4ee6a4SAndroid Build Coastguard Worker /// such as files, pipes, etc. See
203*bb4ee6a4SAndroid Build Coastguard Worker /// <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-sethandleinformation#parameters>
204*bb4ee6a4SAndroid Build Coastguard Worker /// for further details.
set_handle_inheritance(hndl: RawHandle, inheritable: bool) -> io::Result<()>205*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_handle_inheritance(hndl: RawHandle, inheritable: bool) -> io::Result<()> {
206*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: Even if hndl is invalid, no unsafe memory access will result.
207*bb4ee6a4SAndroid Build Coastguard Worker     let res = unsafe {
208*bb4ee6a4SAndroid Build Coastguard Worker         SetHandleInformation(
209*bb4ee6a4SAndroid Build Coastguard Worker             hndl,
210*bb4ee6a4SAndroid Build Coastguard Worker             HANDLE_FLAG_INHERIT,
211*bb4ee6a4SAndroid Build Coastguard Worker             if inheritable { HANDLE_FLAG_INHERIT } else { 0 },
212*bb4ee6a4SAndroid Build Coastguard Worker         )
213*bb4ee6a4SAndroid Build Coastguard Worker     };
214*bb4ee6a4SAndroid Build Coastguard Worker     if res == 0 {
215*bb4ee6a4SAndroid Build Coastguard Worker         Err(io::Error::last_os_error())
216*bb4ee6a4SAndroid Build Coastguard Worker     } else {
217*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
218*bb4ee6a4SAndroid Build Coastguard Worker     }
219*bb4ee6a4SAndroid Build Coastguard Worker }
220*bb4ee6a4SAndroid Build Coastguard Worker 
221*bb4ee6a4SAndroid Build Coastguard Worker /// Rusty version of CreateFileMappingA.
222*bb4ee6a4SAndroid Build Coastguard Worker ///
223*bb4ee6a4SAndroid Build Coastguard Worker /// # Safety
224*bb4ee6a4SAndroid Build Coastguard Worker /// If provided, the caller must ensure hndl is valid.
create_file_mapping( handle: Option<RawHandle>, size: u64, protection: DWORD, name: Option<&str>, ) -> io::Result<RawHandle>225*bb4ee6a4SAndroid Build Coastguard Worker pub unsafe fn create_file_mapping(
226*bb4ee6a4SAndroid Build Coastguard Worker     handle: Option<RawHandle>,
227*bb4ee6a4SAndroid Build Coastguard Worker     size: u64,
228*bb4ee6a4SAndroid Build Coastguard Worker     protection: DWORD,
229*bb4ee6a4SAndroid Build Coastguard Worker     name: Option<&str>,
230*bb4ee6a4SAndroid Build Coastguard Worker ) -> io::Result<RawHandle> {
231*bb4ee6a4SAndroid Build Coastguard Worker     let name_cstr = name.map(|s| CString::new(s).unwrap());
232*bb4ee6a4SAndroid Build Coastguard Worker     let name = name_cstr.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut());
233*bb4ee6a4SAndroid Build Coastguard Worker 
234*bb4ee6a4SAndroid Build Coastguard Worker     // Safe because:
235*bb4ee6a4SAndroid Build Coastguard Worker     // 1. The caller guarantees handle is valid (if provided).
236*bb4ee6a4SAndroid Build Coastguard Worker     // 2. The C string is guaranteed valid.
237*bb4ee6a4SAndroid Build Coastguard Worker     // 3. We check the results of the call.
238*bb4ee6a4SAndroid Build Coastguard Worker     let mapping_handle = CreateFileMappingA(
239*bb4ee6a4SAndroid Build Coastguard Worker         match handle {
240*bb4ee6a4SAndroid Build Coastguard Worker             Some(h) => h,
241*bb4ee6a4SAndroid Build Coastguard Worker             None => INVALID_HANDLE_VALUE,
242*bb4ee6a4SAndroid Build Coastguard Worker         },
243*bb4ee6a4SAndroid Build Coastguard Worker         SecurityAttributes::new_with_security_descriptor(
244*bb4ee6a4SAndroid Build Coastguard Worker             SelfRelativeSecurityDescriptor::get_singleton(),
245*bb4ee6a4SAndroid Build Coastguard Worker             /* inherit= */ true,
246*bb4ee6a4SAndroid Build Coastguard Worker         )
247*bb4ee6a4SAndroid Build Coastguard Worker         .as_mut(),
248*bb4ee6a4SAndroid Build Coastguard Worker         protection,
249*bb4ee6a4SAndroid Build Coastguard Worker         get_high_order(size),
250*bb4ee6a4SAndroid Build Coastguard Worker         get_low_order(size),
251*bb4ee6a4SAndroid Build Coastguard Worker         name,
252*bb4ee6a4SAndroid Build Coastguard Worker     );
253*bb4ee6a4SAndroid Build Coastguard Worker 
254*bb4ee6a4SAndroid Build Coastguard Worker     if mapping_handle.is_null() {
255*bb4ee6a4SAndroid Build Coastguard Worker         Err(io::Error::last_os_error())
256*bb4ee6a4SAndroid Build Coastguard Worker     } else {
257*bb4ee6a4SAndroid Build Coastguard Worker         Ok(mapping_handle)
258*bb4ee6a4SAndroid Build Coastguard Worker     }
259*bb4ee6a4SAndroid Build Coastguard Worker }
260*bb4ee6a4SAndroid Build Coastguard Worker 
261*bb4ee6a4SAndroid Build Coastguard Worker #[derive(PartialEq, Eq)]
262*bb4ee6a4SAndroid Build Coastguard Worker pub enum ThreadState {
263*bb4ee6a4SAndroid Build Coastguard Worker     // The specified thread was not suspended.
264*bb4ee6a4SAndroid Build Coastguard Worker     NotSuspended,
265*bb4ee6a4SAndroid Build Coastguard Worker     // The specified thread was suspended, but was restarted.
266*bb4ee6a4SAndroid Build Coastguard Worker     Restarted,
267*bb4ee6a4SAndroid Build Coastguard Worker     // The specified thread is still suspended.
268*bb4ee6a4SAndroid Build Coastguard Worker     StillSuspended,
269*bb4ee6a4SAndroid Build Coastguard Worker }
270*bb4ee6a4SAndroid Build Coastguard Worker 
271*bb4ee6a4SAndroid Build Coastguard Worker /// Decrements a thread's suspend count. When the suspend count reaches 0, the
272*bb4ee6a4SAndroid Build Coastguard Worker /// thread is resumed. Returned `ThreadState` indicates whether the thread was
273*bb4ee6a4SAndroid Build Coastguard Worker /// resumed.
resume_thread(handle: RawHandle) -> io::Result<ThreadState>274*bb4ee6a4SAndroid Build Coastguard Worker pub fn resume_thread(handle: RawHandle) -> io::Result<ThreadState> {
275*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: Even an invalid handle should cause no adverse effects.
276*bb4ee6a4SAndroid Build Coastguard Worker     match unsafe { ResumeThread(handle) } {
277*bb4ee6a4SAndroid Build Coastguard Worker         u32::MAX => Err(io::Error::last_os_error()),
278*bb4ee6a4SAndroid Build Coastguard Worker         0 => Ok(ThreadState::NotSuspended),
279*bb4ee6a4SAndroid Build Coastguard Worker         1 => Ok(ThreadState::Restarted),
280*bb4ee6a4SAndroid Build Coastguard Worker         _ => Ok(ThreadState::StillSuspended),
281*bb4ee6a4SAndroid Build Coastguard Worker     }
282*bb4ee6a4SAndroid Build Coastguard Worker }
283*bb4ee6a4SAndroid Build Coastguard Worker 
284*bb4ee6a4SAndroid Build Coastguard Worker /// Retrieves the termination status of the specified process.
get_exit_code_process(handle: RawHandle) -> io::Result<Option<DWORD>>285*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_exit_code_process(handle: RawHandle) -> io::Result<Option<DWORD>> {
286*bb4ee6a4SAndroid Build Coastguard Worker     let mut exit_code: DWORD = 0;
287*bb4ee6a4SAndroid Build Coastguard Worker     // SAFETY: Even an invalid handle should cause no adverse effects.
288*bb4ee6a4SAndroid Build Coastguard Worker     match unsafe { GetExitCodeProcess(handle, &mut exit_code) } {
289*bb4ee6a4SAndroid Build Coastguard Worker         0 => Err(io::Error::last_os_error()),
290*bb4ee6a4SAndroid Build Coastguard Worker         _ => {
291*bb4ee6a4SAndroid Build Coastguard Worker             if exit_code == STILL_ACTIVE {
292*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(None)
293*bb4ee6a4SAndroid Build Coastguard Worker             } else {
294*bb4ee6a4SAndroid Build Coastguard Worker                 Ok(Some(exit_code))
295*bb4ee6a4SAndroid Build Coastguard Worker             }
296*bb4ee6a4SAndroid Build Coastguard Worker         }
297*bb4ee6a4SAndroid Build Coastguard Worker     }
298*bb4ee6a4SAndroid Build Coastguard Worker }
299*bb4ee6a4SAndroid Build Coastguard Worker 
300*bb4ee6a4SAndroid Build Coastguard Worker pub type HResult<T> = Result<T, HRESULT>;
301*bb4ee6a4SAndroid Build Coastguard Worker 
302*bb4ee6a4SAndroid Build Coastguard Worker /// Each type of process should have its own type here. This affects both exit
303*bb4ee6a4SAndroid Build Coastguard Worker /// handling and sandboxing policy.
304*bb4ee6a4SAndroid Build Coastguard Worker ///
305*bb4ee6a4SAndroid Build Coastguard Worker /// WARNING: do NOT change the values items in this enum. The enum value is used in our exit codes,
306*bb4ee6a4SAndroid Build Coastguard Worker /// and relied upon by metrics analysis. The max value for this enum is 0x1F = 31 as it is
307*bb4ee6a4SAndroid Build Coastguard Worker /// restricted to five bits per `crate::crosvm::sys::windows::exit::to_process_type_error`.
308*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, enumn::N)]
309*bb4ee6a4SAndroid Build Coastguard Worker #[repr(u8)]
310*bb4ee6a4SAndroid Build Coastguard Worker pub enum ProcessType {
311*bb4ee6a4SAndroid Build Coastguard Worker     UnknownType = 0,
312*bb4ee6a4SAndroid Build Coastguard Worker     Block = 1,
313*bb4ee6a4SAndroid Build Coastguard Worker     Main = 2,
314*bb4ee6a4SAndroid Build Coastguard Worker     Metrics = 3,
315*bb4ee6a4SAndroid Build Coastguard Worker     Net = 4,
316*bb4ee6a4SAndroid Build Coastguard Worker     Slirp = 5,
317*bb4ee6a4SAndroid Build Coastguard Worker     Gpu = 6,
318*bb4ee6a4SAndroid Build Coastguard Worker     Snd = 7,
319*bb4ee6a4SAndroid Build Coastguard Worker     Broker = 8,
320*bb4ee6a4SAndroid Build Coastguard Worker     Spu = 9,
321*bb4ee6a4SAndroid Build Coastguard Worker }
322*bb4ee6a4SAndroid Build Coastguard Worker 
323*bb4ee6a4SAndroid Build Coastguard Worker /// State of a crosvm child process.
324*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)]
325*bb4ee6a4SAndroid Build Coastguard Worker pub enum ProcessState {
326*bb4ee6a4SAndroid Build Coastguard Worker     UnknownState,
327*bb4ee6a4SAndroid Build Coastguard Worker     /// Process is running normally.
328*bb4ee6a4SAndroid Build Coastguard Worker     Healthy,
329*bb4ee6a4SAndroid Build Coastguard Worker     /// Process died unexpectedly - it is either killed, crashed or something else.
330*bb4ee6a4SAndroid Build Coastguard Worker     Died,
331*bb4ee6a4SAndroid Build Coastguard Worker     /// Process exited on request or gracefully.
332*bb4ee6a4SAndroid Build Coastguard Worker     Exited,
333*bb4ee6a4SAndroid Build Coastguard Worker }
334*bb4ee6a4SAndroid Build Coastguard Worker 
335*bb4ee6a4SAndroid Build Coastguard Worker /// Priority of a crosvm child process.
336*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)]
337*bb4ee6a4SAndroid Build Coastguard Worker pub enum ProcessPriority {
338*bb4ee6a4SAndroid Build Coastguard Worker     UnknwonPriority,
339*bb4ee6a4SAndroid Build Coastguard Worker     /// Crosvm critical process. In absence of this process crosvm cannot function normally.
340*bb4ee6a4SAndroid Build Coastguard Worker     Critical,
341*bb4ee6a4SAndroid Build Coastguard Worker     /// Non-critical process - the process is safe to restart. Crosvm/guest may continue to
342*bb4ee6a4SAndroid Build Coastguard Worker     /// function normally when such process dies.
343*bb4ee6a4SAndroid Build Coastguard Worker     NonCritical,
344*bb4ee6a4SAndroid Build Coastguard Worker }
345*bb4ee6a4SAndroid Build Coastguard Worker 
346*bb4ee6a4SAndroid Build Coastguard Worker /// Information about crosvm child process.
347*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)]
348*bb4ee6a4SAndroid Build Coastguard Worker pub struct ProcessInfo {
349*bb4ee6a4SAndroid Build Coastguard Worker     pub id: u64,
350*bb4ee6a4SAndroid Build Coastguard Worker     pub ptype: ProcessType,
351*bb4ee6a4SAndroid Build Coastguard Worker     pub priority: ProcessPriority,
352*bb4ee6a4SAndroid Build Coastguard Worker     pub state: ProcessState,
353*bb4ee6a4SAndroid Build Coastguard Worker }
354*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
355*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
356*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
357*bb4ee6a4SAndroid Build Coastguard Worker 
358*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
high_low_order_utilities()359*bb4ee6a4SAndroid Build Coastguard Worker     fn high_low_order_utilities() {
360*bb4ee6a4SAndroid Build Coastguard Worker         let some_number: u64 = 0xA3200500FFB40123;
361*bb4ee6a4SAndroid Build Coastguard Worker         let high_order: u64 = get_high_order(some_number).into();
362*bb4ee6a4SAndroid Build Coastguard Worker         let low_order: u64 = get_low_order(some_number).into();
363*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(some_number, (high_order << 32) + low_order);
364*bb4ee6a4SAndroid Build Coastguard Worker     }
365*bb4ee6a4SAndroid Build Coastguard Worker 
366*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
strlen()367*bb4ee6a4SAndroid Build Coastguard Worker     fn strlen() {
368*bb4ee6a4SAndroid Build Coastguard Worker         let u16s = [0];
369*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: u16s is a valid wide string
370*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(unsafe { strlen_ptr_u16(u16s.as_ptr()) }, 0);
371*bb4ee6a4SAndroid Build Coastguard Worker         let u16s = [
372*bb4ee6a4SAndroid Build Coastguard Worker             0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834, 0,
373*bb4ee6a4SAndroid Build Coastguard Worker         ];
374*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: u16s is a valid wide string
375*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(unsafe { strlen_ptr_u16(u16s.as_ptr()) }, 9);
376*bb4ee6a4SAndroid Build Coastguard Worker     }
377*bb4ee6a4SAndroid Build Coastguard Worker 
378*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
from_win32_wide_string()379*bb4ee6a4SAndroid Build Coastguard Worker     fn from_win32_wide_string() {
380*bb4ee6a4SAndroid Build Coastguard Worker         let u16s = [0];
381*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: u16s is a valid wide string
382*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(unsafe { from_ptr_win32_wide_string(u16s.as_ptr()) }, "");
383*bb4ee6a4SAndroid Build Coastguard Worker         let u16s = [
384*bb4ee6a4SAndroid Build Coastguard Worker             0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834, 0,
385*bb4ee6a4SAndroid Build Coastguard Worker         ];
386*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
387*bb4ee6a4SAndroid Build Coastguard Worker             // SAFETY: u16s is a valid wide string
388*bb4ee6a4SAndroid Build Coastguard Worker             unsafe { from_ptr_win32_wide_string(u16s.as_ptr()) },
389*bb4ee6a4SAndroid Build Coastguard Worker             "��mus�ic�"
390*bb4ee6a4SAndroid Build Coastguard Worker         );
391*bb4ee6a4SAndroid Build Coastguard Worker     }
392*bb4ee6a4SAndroid Build Coastguard Worker }
393