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 char
s.
Implementations§
Source§impl<'h> NtHiveNameString<'h>
impl<'h> NtHiveNameString<'h>
Sourcepub const fn len(&self) -> usize
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.
Sourcepub fn to_string_checked(&self) -> Option<String>
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.
Sourcepub fn to_string_lossy(&self) -> String
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?
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>
impl<'h> Clone for NtHiveNameString<'h>
Source§fn clone(&self) -> NtHiveNameString<'h>
fn clone(&self) -> NtHiveNameString<'h>
1.0.0 · Source§const fn clone_from(&mut self, source: &Self)
const fn clone_from(&mut self, source: &Self)
source
. Read more