gentoo90 / winreg-rs

Rust bindings to MS Windows Registry API
MIT License
168 stars 36 forks source link

RegKey::encode doesn't work with existing transaction #54

Closed dnlmlr closed 1 year ago

dnlmlr commented 1 year ago

Problem Description

The encode function fails when the subkey was created using a transaction. Example (self implements Serialize):

let t = Transaction::new().unwrap();
let key = RegKey::predef(HKEY_LOCAL_MACHINE)
    .open_subkey_transacted(Self::REGKEY_BASE, &t)
    .unwrap();
let (entry, _disp) = key
    .create_subkey_transacted(Self::REGKEY, &t)
    .unwrap();
entry.encode(self).unwrap();
t.commit().unwrap();

Error on the entry.encode line:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Os { code: 6700, kind: Uncategorized, message: "[(translated) The transaction handle associated with this action is invalid.]" })'

Possible Solution

When looking at the code, it seems like the encode function simply creates a new Encoder using the Encoder::from_key function and commits the transaction at the end. A possible solution (as far as I can tell) might be to simply add a RegKey::encode_transacted(value: &T, t: &Transaction) function that uses Encoder::new and doesn't call commit at the end.

If I'm not missing anything and you think this is a sensible solution, let me know and I can implement it and create a PR

Edit: I just saw that the Encoder::new function is private. This solution would therefore require either creating a new Encoder::from_key_transacted function or setting Encoder::new to pub(crate)

dnlmlr commented 1 year ago

I just created a PR that shows an implementation of this issue #55 . That was pretty much faster than describing what I would implement without actually doing it. Let me know what you think about it.

gentoo90 commented 1 year ago

Fixed in 42aa6f5a02e63eb8ec99952bf6d8993c0ab70eed