es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo envolver de forma segura los PSTR o PWSTR de win32 en un tipo de opción (por ejemplo, Option<&OsStr>)?

Estoy tratando de crear un envoltorio seguro alrededor de algunas API de Win32 utilizando la librería de Microsoft “windows” de la siguiente manera:

use windows::{Win32::Foundation::<em>, Win32::System::Threading::</em>};

<p>fn create<em>process(app</em>name: &std::ffi::OsStr) -> bool {
    let mut startup<em>info: STARTUPINFOW = unsafe { std::mem::zeroed() };
    startup</em>info.cb = std::mem::size<em>of::<STARTUPINFOW>() as u32;
    let mut process</em>info: PROCESS_INFORMATION = unsafe {std::mem::zeroed() };</p>

<pre><code>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
}
</code></pre>

<p>}</p>

<p>fn main() {
    let app = std::ffi::OsStr::new("C:\Windows\system32\notepad.exe");
    let success = create_process(app);
    print!("{}", success);</p>

<p>}

Esto funciona como se esperaba.

Sin embargo, la documentación para CreateProcessW indica que

El parámetro lpApplicationName puede ser NULL.

Por lo tanto, me gustaría envolver el código “&OsStr” en un “Option<&OsStr>” para poder usar “None” cuando no se necesite lpApplicationName.

Pero no puedo encontrar una forma de convertir de “Option<&OsStr>” a cualquier cosa que satisfaga “IntoParam<‘a, PWSTR>” para lpApplicationName.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para convertir de Option<&OsStr> a algo que satisfaga IntoParam<'a, PWSTR> para lpApplicationName en la API CreateProcessW, puedes utilizar el método into_param del trait windows::IntoParam.

    Aquí hay una versión actualizada del código que debería funcionar con Option<&OsStr>:

    use windows::{IntoParam, Win32::Foundation::*, Win32::System::Threading::*};
    
    fn create_process(app_name: Option<&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() };
    
        let app_name_param = app_name.map(|s| s.into_param()).unwrap_or_else(|| "".into_param());
    
        unsafe {
            let success = CreateProcessW(
                app_name_param,      // 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(Some(app));
        print!("{}", success);
    }
    

    En este código actualizado, app_name es una Option<&std::ffi::OsStr>. Utilizamos el método map para convertirlo en una Option<pwstr>, donde PWSTR es la representación de Rust de una cadena Unicode de Windows. Si app_name es Some, llamamos al método into_param para convertir el &OsStr en un PWSTR. Si app_name es None, creamos un PWSTR vacío llamando a "".into_param().

    Ten en cuenta que necesitamos pasar una referencia mutable a los parámetros startup_info y process_info, sin utilizar la sintaxis &, ya que eso produce un error de tipo.

Comments are closed.