Skip to main content

windows_registry/
value_iterator.rs

1use super::*;
2
3/// An iterator of registry values.
4pub struct ValueIterator<'a> {
5    key: &'a Key,
6    range: core::ops::Range<usize>,
7    name: Vec<u16>,
8    data: Data,
9}
10
11impl<'a> ValueIterator<'a> {
12    pub(crate) fn new(key: &'a Key) -> Result<Self> {
13        let mut count = 0;
14        let mut name_max_len = 0;
15        let mut value_max_len = 0;
16
17        let result = unsafe {
18            RegQueryInfoKeyW(
19                key.0,
20                null_mut(),
21                null_mut(),
22                null_mut(),
23                null_mut(),
24                null_mut(),
25                null_mut(),
26                &mut count,
27                &mut name_max_len,
28                &mut value_max_len,
29                null_mut(),
30                null_mut(),
31            )
32        };
33
34        win32_error(result)?;
35
36        Ok(Self {
37            key,
38            range: 0..count as usize,
39            name: vec![0; name_max_len as usize + 1],
40            data: Data::new(value_max_len as usize),
41        })
42    }
43}
44
45impl Iterator for ValueIterator<'_> {
46    type Item = (String, Value);
47
48    fn next(&mut self) -> Option<Self::Item> {
49        self.range.next().and_then(|index| {
50            let mut ty = 0;
51            let mut name_len = self.name.len() as u32;
52            let mut data_len = self.data.len() as u32;
53
54            let result = unsafe {
55                RegEnumValueW(
56                    self.key.0,
57                    index as u32,
58                    self.name.as_mut_ptr(),
59                    &mut name_len,
60                    core::ptr::null(),
61                    &mut ty,
62                    self.data.as_mut_ptr(),
63                    &mut data_len,
64                )
65            };
66
67            if result != 0 {
68                debug_assert_eq!(result, ERROR_NO_MORE_ITEMS);
69                None
70            } else {
71                let name = String::from_utf16_lossy(&self.name[0..name_len as usize]);
72                Some((
73                    name,
74                    Value {
75                        data: Data::from_slice(&self.data[0..data_len as usize]),
76                        ty: ty.into(),
77                    },
78                ))
79            }
80        })
81    }
82}