windows_registry/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#![doc = include_str!("../readme.md")]
#![cfg(windows)]
#![no_std]

#[macro_use]
extern crate alloc;

use alloc::{string::String, vec::Vec};
use core::ops::Deref;
use core::ptr::{null, null_mut};

mod bindings;
use bindings::*;

mod key;
pub use key::Key;

mod value;
pub use value::Value;

mod data;
use data::Data;

mod pcwstr;
use pcwstr::*;

mod key_iterator;
pub use key_iterator::KeyIterator;

mod value_iterator;
pub use value_iterator::ValueIterator;

mod r#type;
pub use r#type::Type;

pub use windows_result::Result;
use windows_result::*;

pub use windows_strings::HSTRING;
use windows_strings::{PCWSTR, *};

/// The predefined `HKEY_CLASSES_ROOT` registry key.
pub const CLASSES_ROOT: &Key = &Key(HKEY_CLASSES_ROOT);

/// The predefined `HKEY_CURRENT_CONFIG` registry key.
pub const CURRENT_CONFIG: &Key = &Key(HKEY_CURRENT_CONFIG);

/// The predefined `HKEY_CURRENT_USER` registry key.
pub const CURRENT_USER: &Key = &Key(HKEY_CURRENT_USER);

/// The predefined `HKEY_LOCAL_MACHINE` registry key.
pub const LOCAL_MACHINE: &Key = &Key(HKEY_LOCAL_MACHINE);

/// The predefined `HKEY_USERS` registry key.
pub const USERS: &Key = &Key(HKEY_USERS);

fn win32_error(result: u32) -> Result<()> {
    if result == 0 {
        Ok(())
    } else {
        Err(Error::from_hresult(HRESULT::from_win32(result)))
    }
}

fn invalid_data() -> Error {
    Error::from_hresult(HRESULT::from_win32(ERROR_INVALID_DATA))
}

fn from_le_bytes(ty: Type, from: &[u8]) -> Result<u64> {
    match ty {
        Type::U32 if from.len() == 4 => Ok(u32::from_le_bytes(from.try_into().unwrap()).into()),
        Type::U64 if from.len() == 8 => Ok(u64::from_le_bytes(from.try_into().unwrap())),
        _ => Err(invalid_data()),
    }
}

// Get the string as 8-bit bytes including the two terminating null bytes.
fn as_bytes(value: &HSTRING) -> &[u8] {
    unsafe { core::slice::from_raw_parts(value.as_ptr() as *const _, (value.len() + 1) * 2) }
}