如何安全地将 win32 的 PSTR 或 PWSTR 包装在选项类型中(例如 Option<&OsStr>)?

How to safely wrap win32's PSTR or PWSTR in an Option type (e.g. Option<&OsStr>)?

我正在尝试使用 Microsoft 的 windows crate 围绕某些 Win32 API 创建一个安全包装器,如下所示:

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);

}

这按预期工作。

但是,documentation for CreateProcessW 指出

The lpApplicationName parameter can be NULL.

因此,我想将 &OsStr 包装在 Option<&OsStr> 中,以便在不需要 lpApplicationName 时可以使用 None

但是我找不到一种方法可以将 Option<&OsStr> 转换为满足 IntoParam<'a, PWSTR> 的任何 lpApplicationName。

#1801 开始,&OsStr 应该实施 IntoParam<PWSTR>。由于 null() 也实现了它,你应该可以这样写:

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
};

...并将 app_name_param 传递给 CreateProcessW

(我无法测试这个,因为我在 Linux 上 运行,其中 Foundation/mod.rs 由于要求 std::os::windows::ffi::OsStrExt 而无法编译。)