windows_erg/registry/
builder.rs1use super::key::RegistryKey;
4use super::types::{Access, Hive, Wow64View};
5use crate::{Error, Result};
6use windows::Win32::Foundation::ERROR_FILE_NOT_FOUND;
7use windows::Win32::System::Registry::*;
8use windows::core::HSTRING;
9
10pub struct RegistryKeyBuilder {
12 hive: Option<Hive>,
13 path: Option<String>,
14 access: Access,
15 wow64: Option<Wow64View>,
16}
17
18impl RegistryKeyBuilder {
19 pub fn new() -> Self {
21 RegistryKeyBuilder {
22 hive: None,
23 path: None,
24 access: Access::Read,
25 wow64: None,
26 }
27 }
28
29 pub fn hive(mut self, hive: Hive) -> Self {
31 self.hive = Some(hive);
32 self
33 }
34
35 pub fn path(mut self, path: impl Into<String>) -> Self {
37 self.path = Some(path.into());
38 self
39 }
40
41 pub fn read(mut self) -> Self {
43 self.access = Access::Read;
44 self
45 }
46
47 pub fn write(mut self) -> Self {
49 self.access = Access::ReadWrite;
50 self
51 }
52
53 pub fn read_write(mut self) -> Self {
55 self.access = Access::ReadWrite;
56 self
57 }
58
59 pub fn wow64_32(mut self) -> Self {
61 self.wow64 = Some(Wow64View::Key32);
62 self
63 }
64
65 pub fn wow64_64(mut self) -> Self {
67 self.wow64 = Some(Wow64View::Key64);
68 self
69 }
70
71 pub fn open(self) -> Result<RegistryKey> {
73 let hive = self.hive.ok_or_else(|| {
74 Error::InvalidParameter(crate::error::InvalidParameterError::new(
75 "hive",
76 "Registry hive must be specified",
77 ))
78 })?;
79 let path = self.path.ok_or_else(|| {
80 Error::InvalidParameter(crate::error::InvalidParameterError::new(
81 "path",
82 "Registry path must be specified",
83 ))
84 })?;
85
86 let mut sam_flags = self.access.to_sam_flags();
87 if let Some(wow64) = self.wow64 {
88 sam_flags |= wow64.to_sam_flags();
89 }
90
91 let subkey_wide = HSTRING::from(&path);
92 let mut handle = HKEY::default();
93
94 unsafe {
95 let result = RegOpenKeyExW(
96 hive.as_hkey(),
97 &subkey_wide,
98 0,
99 REG_SAM_FLAGS(sam_flags),
100 &mut handle,
101 );
102
103 if result.is_err() {
104 if result == ERROR_FILE_NOT_FOUND {
105 return Err(Error::Registry(crate::error::RegistryError::KeyNotFound(
106 crate::error::RegistryKeyNotFoundError::new(path),
107 )));
108 }
109 return Err(Error::WindowsApi(
110 crate::error::WindowsApiError::with_context(result.into(), "RegOpenKeyExW"),
111 ));
112 }
113 }
114
115 Ok(RegistryKey::from_handle_with_metadata(
116 handle,
117 true,
118 Some(hive),
119 Some(path),
120 ))
121 }
122}
123
124impl Default for RegistryKeyBuilder {
125 fn default() -> Self {
126 Self::new()
127 }
128}