1use core::iter::FusedIterator;
5use core::mem;
6use core::ops::Range;
7
8use zerocopy::byteorder::LittleEndian;
9use zerocopy::{
10 FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut,
11 Unaligned, U16,
12};
13
14use crate::error::{NtHiveError, Result};
15use crate::helpers::byte_subrange;
16use crate::hive::Hive;
17use crate::index_root::{IndexRootKeyNodes, IndexRootKeyNodesMut};
18use crate::key_node::{KeyNode, KeyNodeMut};
19use crate::leaf::{LeafKeyNodes, LeafKeyNodesMut, LeafType};
20
21#[derive(FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned)]
24#[repr(packed)]
25pub(crate) struct SubkeysListHeader {
26 pub(crate) signature: [u8; 2],
27 pub(crate) count: U16<LittleEndian>,
28}
29
30pub(crate) struct SubkeysList<'h, B: SplitByteSlice> {
35 hive: &'h Hive<B>,
36 header_range: Range<usize>,
37 pub(crate) data_range: Range<usize>,
38}
39
40impl<'h, B> SubkeysList<'h, B>
41where
42 B: SplitByteSlice,
43{
44 pub(crate) fn new(hive: &'h Hive<B>, cell_range: Range<usize>) -> Result<Self> {
45 Self::new_internal(hive, cell_range, true)
46 }
47
48 pub(crate) fn new_without_index_root(
49 hive: &'h Hive<B>,
50 cell_range: Range<usize>,
51 ) -> Result<Self> {
52 Self::new_internal(hive, cell_range, false)
54 }
55
56 fn new_internal(
57 hive: &'h Hive<B>,
58 cell_range: Range<usize>,
59 index_root_supported: bool,
60 ) -> Result<Self> {
61 let header_range = byte_subrange(&cell_range, mem::size_of::<SubkeysListHeader>())
62 .ok_or_else(|| NtHiveError::InvalidHeaderSize {
63 offset: hive.offset_of_data_offset(cell_range.start),
64 expected: mem::size_of::<SubkeysListHeader>(),
65 actual: cell_range.len(),
66 })?;
67 let data_range = header_range.end..cell_range.end;
68
69 let subkeys_list = Self {
70 hive,
71 header_range,
72 data_range,
73 };
74 subkeys_list.validate_signature(index_root_supported)?;
75
76 Ok(subkeys_list)
77 }
78
79 pub(crate) fn header(&self) -> Ref<&[u8], SubkeysListHeader> {
80 Ref::from_bytes(&self.hive.data[self.header_range.clone()]).unwrap()
81 }
82
83 fn validate_signature(&self, index_root_supported: bool) -> Result<()> {
84 let header = self.header();
85
86 match &header.signature {
87 b"lf" | b"lh" | b"li" => return Ok(()),
89
90 b"ri" => {
92 if index_root_supported {
93 return Ok(());
94 }
95 }
96
97 _ => (),
99 }
100
101 let expected_signature: &[u8] = if index_root_supported {
102 b"lf|lh|li|ri"
103 } else {
104 b"lf|lh|li"
105 };
106
107 Err(NtHiveError::InvalidTwoByteSignature {
108 offset: self.hive.offset_of_field(&header.signature),
109 expected: expected_signature,
110 actual: header.signature,
111 })
112 }
113}
114
115#[derive(Clone)]
124pub enum SubKeyNodes<'h, B: SplitByteSlice> {
125 IndexRoot(IndexRootKeyNodes<'h, B>),
126 Leaf(LeafKeyNodes<'h, B>),
127}
128
129impl<'h, B> SubKeyNodes<'h, B>
130where
131 B: SplitByteSlice,
132{
133 pub(crate) fn new(hive: &'h Hive<B>, cell_range: Range<usize>) -> Result<Self> {
134 let subkeys_list = SubkeysList::new(hive, cell_range)?;
135 let header = subkeys_list.header();
136 let signature = header.signature;
137 let count = header.count.get();
138 let count_field_offset = subkeys_list.hive.offset_of_field(&header.count);
139 let data_range = subkeys_list.data_range;
140
141 match &signature {
142 b"lf" | b"lh" | b"li" => {
143 let leaf_type = LeafType::from_signature(&signature).unwrap();
145 let iter =
146 LeafKeyNodes::new(hive, count, count_field_offset, data_range, leaf_type)?;
147 Ok(Self::Leaf(iter))
148 }
149 b"ri" => {
150 let iter = IndexRootKeyNodes::new(hive, count, count_field_offset, data_range)?;
152 Ok(Self::IndexRoot(iter))
153 }
154 _ => unreachable!(),
155 }
156 }
157}
158
159impl<'h, B> Iterator for SubKeyNodes<'h, B>
160where
161 B: SplitByteSlice,
162{
163 type Item = Result<KeyNode<'h, B>>;
164
165 fn next(&mut self) -> Option<Self::Item> {
166 match self {
167 Self::IndexRoot(iter) => iter.next(),
168 Self::Leaf(iter) => iter.next(),
169 }
170 }
171
172 fn count(self) -> usize {
173 match self {
174 Self::IndexRoot(iter) => iter.count(),
175 Self::Leaf(iter) => iter.count(),
176 }
177 }
178
179 fn last(self) -> Option<Self::Item> {
180 match self {
181 Self::IndexRoot(iter) => iter.last(),
182 Self::Leaf(iter) => iter.last(),
183 }
184 }
185
186 fn nth(&mut self, n: usize) -> Option<Self::Item> {
187 match self {
188 Self::IndexRoot(iter) => iter.nth(n),
189 Self::Leaf(iter) => iter.nth(n),
190 }
191 }
192
193 fn size_hint(&self) -> (usize, Option<usize>) {
194 match self {
195 Self::IndexRoot(iter) => iter.size_hint(),
196 Self::Leaf(iter) => iter.size_hint(),
197 }
198 }
199}
200
201impl<B> FusedIterator for SubKeyNodes<'_, B> where B: SplitByteSlice {}
202
203pub(crate) enum SubKeyNodesMut<'h, B: SplitByteSliceMut> {
212 IndexRoot(IndexRootKeyNodesMut<'h, B>),
213 Leaf(LeafKeyNodesMut<'h, B>),
214}
215
216impl<'h, B> SubKeyNodesMut<'h, B>
217where
218 B: SplitByteSliceMut,
219{
220 pub(crate) fn new(hive: &'h mut Hive<B>, cell_range: Range<usize>) -> Result<Self> {
221 let subkeys_list = SubkeysList::new(&*hive, cell_range)?;
222 let header = subkeys_list.header();
223 let signature = header.signature;
224 let count = header.count.get();
225 let count_field_offset = subkeys_list.hive.offset_of_field(&header.count);
226 let data_range = subkeys_list.data_range;
227
228 match &signature {
229 b"lf" | b"lh" | b"li" => {
230 let leaf_type = LeafType::from_signature(&signature).unwrap();
232 let iter =
233 LeafKeyNodesMut::new(hive, count, count_field_offset, data_range, leaf_type)?;
234 Ok(Self::Leaf(iter))
235 }
236 b"ri" => {
237 let iter = IndexRootKeyNodesMut::new(hive, count, count_field_offset, data_range)?;
239 Ok(Self::IndexRoot(iter))
240 }
241 _ => unreachable!(),
242 }
243 }
244
245 pub fn next(&mut self) -> Option<Result<KeyNodeMut<B>>> {
246 match self {
247 Self::IndexRoot(iter) => iter.next(),
248 Self::Leaf(iter) => iter.next(),
249 }
250 }
251}