RegOpenKeyExA保持返回无效的参数

时间:2016-08-01 18:12:26

标签: rust

我尝试使用winapi (0.2.8)advapi32 (0.2.0)包来编辑与鼠标加速相关的注册表。每次调用advapi32::RegOpenKeyExA时程序崩溃,结果值都设置为INVALID_PARAMETER (87)。违规代码是:

fn switch_acceleration(values: HashMap<&str, &str>) {
    let mouse: LPCSTR = CString::new("Control Panel\\Mouse").unwrap().as_ptr();

    unsafe {
        let hkey: *mut HKEY = ptr::null_mut();
        let reg_open_result = advapi32::RegOpenKeyExA(HKEY_CURRENT_USER, mouse, 0 as u32, winnt::KEY_WRITE | winnt::KEY_WOW64_64KEY, hkey);
        println!("{}", reg_open_result);

        for (key, value) in &values {
            let setting = CString::new(*key).unwrap().as_ptr();
            let new_val = CString::new(*value).unwrap().as_ptr() as *const u8;
            advapi32::RegSetValueExA(*hkey, setting, 0, winnt::REG_SZ, new_val, (size_of_val(&new_val) as u32));
        }

        advapi32::RegCloseKey(*hkey);            
    }
}

我尝试删除KEY_WOW_64和/或用KEY_WRITE替换KEY_ACCESS_ALL来更改samDesired选项,我尝试更换注册表项以打开其他内容但是我总是得到无论我尝试什么,都会出现相同的错误代码。哪一个论点无效?

1 个答案:

答案 0 :(得分:2)

您的代码存在两个问题:

  1. 基础CString正在取消分配,因为没有引用它。 as_ptr返回一个原始指针,原始指针中没有生命周期的信息,所以Rust认为可以解除分配字符串。解决方案是在使用as_ptr之前命名字符串(也在循环内部):

    let m = CString::new("Control Panel\\Mouse").unwrap();
    let mouse: LPCSTR = m.as_ptr();
    
  2. 请阅读试图解决此问题的CString::as_ptrthis RFC的更新文档。

    1. 您正在传递一个空指针(href)作为out参数。您必须将hkey的声明更改为

      let mut hkey: HKEY = 0;
      
    2. &mut hkey as *mut HKEY调用中使用advapi32::RegOpenKeyExA