Enum NtHiveNameString

Source
pub enum NtHiveNameString<'h> {
    Latin1(&'h [u8]),
    Utf16LE(&'h [u8]),
}
Expand description

Zero-copy representation of a key name or value name string stored in hive data. Can be either in Latin1 (ISO-8859-1) or UTF-16 (Little-Endian).

This allows to work with the string without performing any allocations or conversions. If the alloc feature is enabled, to_string_checked and to_string_lossy can be used to to retrieve a String.

Variants§

§

Latin1(&'h [u8])

A byte stream where each byte is a single character of the Latin1 (ISO-8859-1) character set. Each byte can simply be casted to a char (as Unicode is ordered the same as Latin1).

§

Utf16LE(&'h [u8])

A byte stream where every two bytes make up a UTF-16 code point in little-endian order. Use u16::from_le_bytes and char::decode_utf16 if you want to get a stream of chars.

Implementations§

Source§

impl<'h> NtHiveNameString<'h>

Source

pub const fn is_empty(&self) -> bool

Returns true if self has a length of zero bytes.

Source

pub const fn len(&self) -> usize

Returns the length of self.

This length is in bytes, not characters! In other words, it may not be what a human considers the length of the string.

Source

pub fn to_string_checked(&self) -> Option<String>

Attempts to convert self to an owned String. Returns Some(String) if all characters could be converted successfully or None if a decoding error occurred.

Source

pub fn to_string_lossy(&self) -> String

Converts self to an owned String, replacing invalid data with the replacement character (U+FFFD).

Examples found in repository?
examples/readhive.rs (line 33)
11fn main() -> Result<(), String> {
12    // Parse arguments.
13    let args: Vec<String> = env::args().collect();
14    if args.len() < 2 {
15        println!("Usage: readhive <FILENAME>");
16        return Ok(());
17    }
18
19    // Read the hive file.
20    let filename = &args[1];
21    let mut f = File::open(filename).map_err(|e| format!("Error opening hive file: {e}"))?;
22    let mut buffer = Vec::<u8>::new();
23    f.read_to_end(&mut buffer)
24        .map_err(|e| format!("Error reading hive file: {e}"))?;
25
26    // Parse the hive.
27    let hive = Hive::new(buffer.as_ref()).map_err(|e| format!("Error parsing hive file: {e}"))?;
28
29    // Print the name of the root key node.
30    let root_key = hive
31        .root_key_node()
32        .map_err(|e| format!("Error getting root key: {e}"))?;
33    println!("{}", root_key.name().unwrap().to_string_lossy());
34
35    process_subkey(root_key, 0)?;
36
37    Ok(())
38}
39
40fn process_subkey<B>(key_node: KeyNode<B>, level: usize) -> Result<(), String>
41where
42    B: SplitByteSlice,
43{
44    // Print the names of subkeys of this node.
45    if let Some(subkeys) = key_node.subkeys() {
46        let subkeys = subkeys.map_err(|e| format!("Error getting subkeys: {e}"))?;
47
48        for key_node in subkeys {
49            let key_node = key_node.map_err(|e| format!("Error enumerating key: {e}"))?;
50            let key_name = key_node
51                .name()
52                .map_err(|e| format!("Error getting key name: {e}"))?;
53
54            print_indentation(level);
55            println!("● {key_name}");
56
57            if let Some(class_name) = key_node.class_name() {
58                let class_name =
59                    class_name.map_err(|e| format!("Error getting class name: {e}"))?;
60                print_indentation(level);
61                println!("  Class Name: {class_name}");
62            }
63
64            // Print the names of the values of this node.
65            if let Some(value_iter) = key_node.values() {
66                let value_iter =
67                    value_iter.map_err(|e| format!("Error creating value iterator: {e}"))?;
68
69                for value in value_iter {
70                    let value = value.map_err(|e| format!("Error enumerating value: {e}"))?;
71
72                    let mut value_name = value
73                        .name()
74                        .map_err(|e| format!("Error getting value name: {e}"))?
75                        .to_string_lossy();
76                    if value_name.is_empty() {
77                        value_name.push_str("(Default)");
78                    }
79
80                    let value_type = value
81                        .data_type()
82                        .map_err(|e| format!("Error getting value type: {e}"))?;
83
84                    let data_size = value.data_size();
85
86                    // First line: Value Name, Data Type, and Data Size
87                    print_indentation(level);
88                    println!("  ○ {value_name} - {value_type:?} - {data_size}");
89
90                    // Second line: The actual Value Data
91                    print_indentation(level);
92                    print!("    ");
93
94                    match value_type {
95                        KeyValueDataType::RegSZ | KeyValueDataType::RegExpandSZ => {
96                            let string_data = value
97                                .string_data()
98                                .map_err(|e| format!("Error getting string data: {e}"))?;
99                            println!("{string_data}")
100                        }
101                        KeyValueDataType::RegBinary => {
102                            let binary_data = value
103                                .data()
104                                .map_err(|e| format!("Error getting binary data: {e}"))?;
105                            match binary_data {
106                                KeyValueData::Small(data) => println!("{data:?}"),
107                                KeyValueData::Big(_iter) => println!("BIG DATA"),
108                            }
109                        }
110                        KeyValueDataType::RegDWord | KeyValueDataType::RegDWordBigEndian => {
111                            let dword_data = value
112                                .dword_data()
113                                .map_err(|e| format!("Error getting DWORD data: {e}"))?;
114                            println!("{dword_data}")
115                        }
116                        KeyValueDataType::RegMultiSZ => {
117                            let multi_string_data = value
118                                .multi_string_data()
119                                .map_err(|e| format!("Error getting multi string data: {e}"))?
120                                .collect::<Result<Vec<_>>>()
121                                .map_err(|e| {
122                                    format!("Error getting multi string element data: {e}")
123                                })?;
124                            println!("{multi_string_data:?}")
125                        }
126                        KeyValueDataType::RegQWord => {
127                            let qword_data = value
128                                .qword_data()
129                                .map_err(|e| format!("Error getting QWORD data: {e}"))?;
130                            println!("{qword_data}")
131                        }
132                        _ => println!(),
133                    }
134                }
135            }
136
137            // Process subkeys.
138            process_subkey(key_node, level + 1)?;
139        }
140    }
141
142    Ok(())
143}

Trait Implementations§

Source§

impl<'h> Clone for NtHiveNameString<'h>

Source§

fn clone(&self) -> NtHiveNameString<'h>

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'h> Debug for NtHiveNameString<'h>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for NtHiveNameString<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Ord for NtHiveNameString<'_>

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq<&str> for NtHiveNameString<'_>

Source§

fn eq(&self, other: &&str) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'h> PartialEq<NtHiveNameString<'h>> for &str

Source§

fn eq(&self, other: &NtHiveNameString<'h>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'h> PartialEq<NtHiveNameString<'h>> for str

Source§

fn eq(&self, other: &NtHiveNameString<'h>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq<str> for NtHiveNameString<'_>

Source§

fn eq(&self, other: &str) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq for NtHiveNameString<'_>

Source§

fn eq(&self, other: &Self) -> bool

Checks that two strings are a case-insensitive match (according to Windows’ definition of case-insensitivity, which only considers the Unicode Basic Multilingual Plane).

1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd<&str> for NtHiveNameString<'_>

Source§

fn partial_cmp(&self, other: &&str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<'h> PartialOrd<NtHiveNameString<'h>> for &str

Source§

fn partial_cmp(&self, other: &NtHiveNameString<'h>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<'h> PartialOrd<NtHiveNameString<'h>> for str

Source§

fn partial_cmp(&self, other: &NtHiveNameString<'h>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl PartialOrd<str> for NtHiveNameString<'_>

Source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl PartialOrd for NtHiveNameString<'_>

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<'h> Eq for NtHiveNameString<'h>

Auto Trait Implementations§

§

impl<'h> Freeze for NtHiveNameString<'h>

§

impl<'h> RefUnwindSafe for NtHiveNameString<'h>

§

impl<'h> Send for NtHiveNameString<'h>

§

impl<'h> Sync for NtHiveNameString<'h>

§

impl<'h> Unpin for NtHiveNameString<'h>

§

impl<'h> UnwindSafe for NtHiveNameString<'h>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.