Home > front end >  How to allocate memory for RegGetValueW (via the Windows crate for Rust)
How to allocate memory for RegGetValueW (via the Windows crate for Rust)

Time:11-02

I'm attempting to read a value from the windows registry using the official windows rust bindings.

I've tried a lot of different things without success, so I created a C version as a sanity test:

WCHAR value[64];
PVOID pvData = value;
DWORD size = sizeof(value);

LSTATUS result = RegGetValue(
    HKEY_CURRENT_USER,
    L"SOFTWARE\\MyTest\\foo",
    NULL,
    RRF_RT_REG_SZ,
    NULL,
    pvData,
    &size);

if (result == ERROR_SUCCESS) {
    wprintf(L"Value data: %s (%d)\n", (PWSTR)pvData, size);
}

This works as expected and prints Value data: hello (12) (It's not perfect but the end result shows at least a working happy path with no cleanup.)

My latest Rust attempt is:

unsafe {
  
    let mut value: Vec<u16> = vec![0; 64];

    let mut my_size: u32 = 0;
    let size = &mut my_size as *mut u32;

    let result = RegGetValueW(
        HKEY_CURRENT_USER,
        "SOFTWARE\\MyTest\\foo",
        None,
        RRF_RT_REG_SZ,
        std::ptr::null_mut(), // Doesn't allow None
        value.as_mut_ptr() as *mut c_void,
        size
    );

    println!("Result: {:?}", result);
    println!("Value data: {:?} ({:?})", value, *size);
    // Result: LSTATUS(234)         // 234 = ERROR_MORE_DATA, so pvData is not large enough
    // Value data: [0, 0, ...] (14) // 14 is peculiar given the C   size reports 12
}

Would greatly appreciate some guidance or nudge in the right direction!

CodePudding user response:

I had two major issues that needed to be resolved:

WCHAR would be a u16 in rust

I was using u8

let mut value: Vec<u16> = vec![0; 64];

When using u16 I also needed to change the size passed to RegGetValueW

let mut my_size = (std::mem::size_of::<u16>() * value.len()) as u32;
  • Related