-
Notifications
You must be signed in to change notification settings - Fork 42
Open
Description
In my abstracting write-function, I prevent having to unnecessarily clone the byte array this way:
pub fn write_reg_bin_value(
reg_value_path: &RegValuePath,
bytes: &Vec<u8>,
) -> Result<(), io::Error> {
let key = RegKey::predef(reg_value_path.hkey)
.open_subkey_with_flags(reg_value_path.subkey_path, KEY_SET_VALUE)?;
let unsafe_reg_value = ManuallyDrop::new(RegValue {
vtype: RegType::REG_BINARY,
// Unsafely double-owned `Vec`.
bytes: unsafe { Vec::from_raw_parts(bytes.as_ptr() as _, bytes.len(), bytes.capacity()) },
});
// A panic would leak the reg value, but at least not cause a double-drop.
let result = key.set_raw_value(reg_value_path.value_name, &unsafe_reg_value);
// Drop only parts in fact owned. Use `ManuallyDrop` like `Vec::into_raw_parts()`, which is available in nightly Rust (as of Nov. 2023).
let RegValue { bytes, .. } = ManuallyDrop::into_inner(unsafe_reg_value);
let _ = ManuallyDrop::new(bytes);
result?;
Ok(())
}This is quite hacky, of course.
When winreg generates a RegValue by reading it from the registry, it would use Cow::Owned. But when writing one with RegKey::set_raw_value(), which borrows it immutably anyways, Cow::Borrowed would suffice, so you don't have to unnecessarily clone the value, just for an immutalbe borrow!
Metadata
Metadata
Assignees
Labels
No labels