I am trying to create a safe wrapper around some Win32 APIs using Microsoft's windows crate like so:
use windows::{Win32::Foundation::*, Win32::System::Threading::*};
fn create_process(app_name: &std::ffi::OsStr) -> bool {
let mut startup_info: STARTUPINFOW = unsafe { std::mem::zeroed() };
startup_info.cb = std::mem::size_of::<STARTUPINFOW>() as u32;
let mut process_info: PROCESS_INFORMATION = unsafe {std::mem::zeroed() };
unsafe {
let success = CreateProcessW(
app_name, // lpapplicationname
None, // lpcommandname
std::ptr::null(), // lpprocessattributes
std::ptr::null(), // lpthreadattributes
true, // binherithandles
CREATE_SUSPENDED, // dwcreationflags
std::ptr::null(), // lpenvironment
&startup_info, // lpstartupinfo
&mut process_info // lpprocessinformation
).as_bool();
success
}
}
fn main() {
let app = std::ffi::OsStr::new("C:\\Windows\\system32\\notepad.exe");
let success = create_process(app);
print!("{}", success);
}
This works as expected.
However, the documentation for CreateProcessW states that
The lpApplicationName parameter can be NULL.
Thus, I would like to wrap the &OsStr
in an Option<&OsStr>
so I can use None
when no lpApplicationName is needed.
But I cannot find a way to convert from Option<&OsStr>
to anything that satisfies IntoParam<'a, PWSTR>
for lpApplicationName.
As of #1801 &OsStr
should implement IntoParam<PWSTR>
. Since null()
also implements it, you should be able to write:
use windows::core::{IntoParam, Param};
let app_name_param: Param<'_, PWSTR> = if let Some(app_name) = app_name {
app_name.into_param()
} else {
Param::None
};
...and pass app_name_param
to CreateProcessW
.
(I can't test this because I run on Linux, where Foundation/mod.rs
fails to compile due to requiring std::os::windows::ffi::OsStrExt
.)