windowsrustwindows-rs

"The parameter is incorrect" error when trying to get a registry key using Windows API via windows crate


I am trying to get a registry key using Windows API via the windows crate. But I am getting this error:

Error: Error { code: HRESULT(0x80070057), message: "The parameter is incorrect." }

Here is my code:

pub fn get_registry_key<'a>(hkey: HKEY, subkey: &'a str, key: &'a str, flags: REG_ROUTINE_FLAGS) -> Result<*mut c_void, windows::core::Error> {
    unsafe {
        let mut data: *mut c_void;
        let mut data_length: u32 = 0;
        // Stores the subkey and key
        let subkey_hstring = HSTRING::from(subkey);
        let key_hstring = HSTRING::from(key);

        // Get the data length to allocate memory
        RegGetValueW(hkey, PCWSTR(subkey_hstring.as_ptr()), PCWSTR(key_hstring.as_ptr()), flags, None, None, Some(&mut data_length))?;
        println!("Length: {}", data_length);
        let layout = Layout::from_size_align(data_length as usize, 1).unwrap();
        data = std::alloc::alloc(layout) as *mut c_void;

        RegGetValueW(hkey, PCWSTR(subkey_hstring.as_ptr()), PCWSTR(key_hstring.as_ptr()), flags, None, Some(data), None)?;
        Ok(data)
    }
}

According to the documentation, I should be doing it correctly. I am able to get the data length and allocate memory to it but cannot get the data itself. What am I doing wrong?


Solution

  • According to the documentation

    The pcbData parameter can be NULL only if pvData is NULL.

    But you set pcbData to None in your second call while pvData is Some(data).
    You have to pass Some(&mut data_length) again:

    pub fn get_registry_key<'a>(hkey: HKEY, subkey: &'a str, key: &'a str, flags: REG_ROUTINE_FLAGS) -> Result<*mut c_void, windows::core::Error> {
        unsafe {
            let mut data: *mut c_void;
            let mut data_length: u32 = 0;
            // Stores the subkey and key
            let subkey_hstring = HSTRING::from(subkey);
            let key_hstring = HSTRING::from(key);
    
            // Get the data length to allocate memory
            RegGetValueW(hkey, PCWSTR(subkey_hstring.as_ptr()), PCWSTR(key_hstring.as_ptr()), flags, None, None, Some(&mut data_length))?;
            println!("Length: {}", data_length);
            let layout = Layout::from_size_align(data_length as usize, 1).unwrap();
            data = std::alloc::alloc(layout) as *mut c_void;
    
            RegGetValueW(hkey, PCWSTR(subkey_hstring.as_ptr()), PCWSTR(key_hstring.as_ptr()), flags, None, Some(data), Some(&mut data_length))?;
            Ok(data)
        }
    }