1use bitflags::bitflags;
4
5bitflags! {
6 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
8 pub struct KeyFlags: u16 {
9 const VOLATILE = 0x0001;
10 const HIVE_EXIT = 0x0002;
11 const HIVE_ENTRY = 0x0004;
12 const NO_DELETE = 0x0008;
13 const SYM_LINK = 0x0010;
14 const COMP_NAME = 0x0020;
15 const PREDEF_HANDLE = 0x0040;
16 const VIRT_MIRRORED = 0x0080;
17 const VIRT_TARGET = 0x0100;
18 const VIRTUAL_STORE = 0x0200;
19 }
20}
21
22bitflags! {
23 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
25 pub struct ValueFlags: u16 {
26 const COMP_NAME = 0x0001;
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32#[repr(u32)]
33pub enum ValueType {
34 None = 0,
35 Sz = 1,
36 ExpandSz = 2,
37 Binary = 3,
38 Dword = 4,
39 DwordBigEndian = 5,
40 Link = 6,
41 MultiSz = 7,
42 ResourceList = 8,
43 FullResourceDescriptor = 9,
44 ResourceRequirementsList = 10,
45 Qword = 11,
46 Unknown(u32),
47}
48
49impl ValueType {
50 pub fn from_raw(raw: u32) -> Self {
51 match raw {
52 0 => Self::None,
53 1 => Self::Sz,
54 2 => Self::ExpandSz,
55 3 => Self::Binary,
56 4 => Self::Dword,
57 5 => Self::DwordBigEndian,
58 6 => Self::Link,
59 7 => Self::MultiSz,
60 8 => Self::ResourceList,
61 9 => Self::FullResourceDescriptor,
62 10 => Self::ResourceRequirementsList,
63 11 => Self::Qword,
64 other => Self::Unknown(other),
65 }
66 }
67
68 pub fn name(&self) -> &str {
69 match self {
70 Self::None => "REG_NONE",
71 Self::Sz => "REG_SZ",
72 Self::ExpandSz => "REG_EXPAND_SZ",
73 Self::Binary => "REG_BINARY",
74 Self::Dword => "REG_DWORD",
75 Self::DwordBigEndian => "REG_DWORD_BIG_ENDIAN",
76 Self::Link => "REG_LINK",
77 Self::MultiSz => "REG_MULTI_SZ",
78 Self::ResourceList => "REG_RESOURCE_LIST",
79 Self::FullResourceDescriptor => "REG_FULL_RESOURCE_DESCRIPTOR",
80 Self::ResourceRequirementsList => "REG_RESOURCE_REQUIREMENTS_LIST",
81 Self::Qword => "REG_QWORD",
82 Self::Unknown(_) => "REG_UNKNOWN",
83 }
84 }
85}
86
87impl std::fmt::Display for ValueType {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 write!(f, "{}", self.name())
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn key_flags_comp_name() {
99 let flags = KeyFlags::COMP_NAME | KeyFlags::HIVE_ENTRY;
100 assert!(flags.contains(KeyFlags::COMP_NAME));
101 assert!(flags.contains(KeyFlags::HIVE_ENTRY));
102 assert!(!flags.contains(KeyFlags::VOLATILE));
103 }
104
105 #[test]
106 fn value_type_roundtrip() {
107 for raw in 0..=11 {
108 let vt = ValueType::from_raw(raw);
109 assert_ne!(vt.name(), "REG_UNKNOWN");
110 }
111 assert!(matches!(ValueType::from_raw(99), ValueType::Unknown(99)));
112 }
113
114 #[test]
115 fn value_type_display() {
116 assert_eq!(ValueType::Sz.to_string(), "REG_SZ");
117 assert_eq!(ValueType::Dword.to_string(), "REG_DWORD");
118 assert_eq!(ValueType::MultiSz.to_string(), "REG_MULTI_SZ");
119 }
120}