Skip to content

Commit f469897

Browse files
author
Steve Lee (POWERSHELL HE/HIM) (from Dev Box)
committed
Fix registry resource to allow setting value with no data
1 parent 5e860e2 commit f469897

File tree

5 files changed

+93
-53
lines changed

5 files changed

+93
-53
lines changed

build.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ if (!$SkipBuild) {
354354

355355
if ($IsWindows) {
356356
Copy-Item "$path/$binary.exe" $target -ErrorAction Ignore -Verbose
357+
Copy-Item "$path/$binary.pdb" $target -ErrorAction Ignore -Verbose
357358
}
358359
else {
359360
Copy-Item "$path/$binary" $target -ErrorAction Ignore -Verbose

registry/locales/en-us.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ unsupportedValueDataType = "Unsupported registry value data type"
4444
tracingInitError = "Unable to set global default tracing subscriber. Tracing is disabled."
4545
debugAttach = "attach debugger to pid %{pid} and press any key to continue"
4646
debugEventReadError = "Error: Failed to read event: %{err}"
47-
debugEventUnexpectedError = "Unexpected event: %{e:?}"
47+
debugEventUnexpectedError = "Unexpected event: %{e}"
4848

4949
[registry_helper]
50-
whatIfCreateKey = "key: %{subkey} not found, would create it"
50+
whatIfCreateKey = "Key '%{subkey}' not found, would create it"
5151
removeErrorKeyNotExist = "Key already does not exist"
5252
removeDeletingSubKey = "Deleting subkey '%{name}' using %{parent}"

registry/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub enum RegistryValueData {
1212
DWord(u32),
1313
MultiString(Vec<String>),
1414
QWord(u64),
15+
None,
1516
}
1617

1718
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]

registry/src/registry_helper.rs

Lines changed: 68 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ impl RegistryHelper {
7272
Ok(Registry {
7373
key_path: self.config.key_path.clone(),
7474
value_name: Some(value_name.clone()),
75-
value_data: Some(convert_reg_value(&value)?),
75+
value_data: match value {
76+
Data::None => None,
77+
_ => Some(convert_reg_value(&value)?)
78+
},
7679
..Default::default()
7780
})
7881
} else {
@@ -100,7 +103,7 @@ impl RegistryHelper {
100103
};
101104

102105
if self.what_if {
103-
what_if_metadata.push(t!("registry_helper.whatIfCreateKey", "subkey" => subkey).to_string());
106+
what_if_metadata.push(t!("registry_helper.whatIfCreateKey", subkey = subkey).to_string());
104107
}
105108
else {
106109
reg_key = reg_key.create(path, Security::CreateSubKey)?;
@@ -116,60 +119,69 @@ impl RegistryHelper {
116119
Err(e) => return self.handle_error_or_what_if(e)
117120
};
118121

119-
if let Some(value_data) = &self.config.value_data {
120-
let Ok(value_name) = U16CString::from_str(self.config.value_name.as_ref().unwrap()) else {
121-
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueName".to_string()));
122-
};
122+
let value_data = match &self.config.value_data {
123+
Some(value_data) => value_data,
124+
None => &RegistryValueData::None,
125+
};
123126

124-
let data = match value_data {
125-
RegistryValueData::String(s) => {
126-
let Ok(utf16) = U16CString::from_str(s) else {
127-
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueData".to_string()));
128-
};
129-
Data::String(utf16)
130-
},
131-
RegistryValueData::ExpandString(s) => {
127+
let Ok(value_name) = U16CString::from_str(self.config.value_name.as_ref().unwrap()) else {
128+
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueName".to_string()));
129+
};
130+
131+
let data = match value_data {
132+
RegistryValueData::String(s) => {
133+
let Ok(utf16) = U16CString::from_str(s) else {
134+
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueData".to_string()));
135+
};
136+
Data::String(utf16)
137+
},
138+
RegistryValueData::ExpandString(s) => {
139+
let Ok(utf16) = U16CString::from_str(s) else {
140+
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueData".to_string()));
141+
};
142+
Data::ExpandString(utf16)
143+
},
144+
RegistryValueData::Binary(b) => {
145+
Data::Binary(b.clone())
146+
},
147+
RegistryValueData::DWord(d) => {
148+
Data::U32(*d)
149+
},
150+
RegistryValueData::MultiString(m) => {
151+
let mut m16: Vec<UCString<u16>> = Vec::<UCString<u16>>::new();
152+
for s in m {
132153
let Ok(utf16) = U16CString::from_str(s) else {
133154
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueData".to_string()));
134155
};
135-
Data::ExpandString(utf16)
136-
},
137-
RegistryValueData::Binary(b) => {
138-
Data::Binary(b.clone())
139-
},
140-
RegistryValueData::DWord(d) => {
141-
Data::U32(*d)
142-
},
143-
RegistryValueData::MultiString(m) => {
144-
let mut m16: Vec<UCString<u16>> = Vec::<UCString<u16>>::new();
145-
for s in m {
146-
let Ok(utf16) = U16CString::from_str(s) else {
147-
return self.handle_error_or_what_if(RegistryError::Utf16Conversion("valueData".to_string()));
148-
};
149-
m16.push(utf16);
150-
}
151-
Data::MultiString(m16)
152-
},
153-
RegistryValueData::QWord(q) => {
154-
Data::U64(*q)
155-
},
156-
};
157-
158-
if self.what_if {
159-
return Ok(Some(Registry {
160-
key_path: self.config.key_path.clone(),
161-
value_data: Some(convert_reg_value(&data)?),
162-
value_name: self.config.value_name.clone(),
163-
metadata: if what_if_metadata.is_empty() { None } else { Some(Metadata { what_if: Some(what_if_metadata) })},
164-
..Default::default()
165-
}));
166-
}
156+
m16.push(utf16);
157+
}
158+
Data::MultiString(m16)
159+
},
160+
RegistryValueData::QWord(q) => {
161+
Data::U64(*q)
162+
},
163+
RegistryValueData::None => {
164+
Data::None
165+
},
166+
};
167167

168-
if let Some(reg_key) = reg_key {
169-
reg_key.set_value(&value_name, &data)?;
170-
};
168+
if self.what_if {
169+
return Ok(Some(Registry {
170+
key_path: self.config.key_path.clone(),
171+
value_data: match data {
172+
Data::None => None,
173+
_ => Some(convert_reg_value(&data)?),
174+
},
175+
value_name: self.config.value_name.clone(),
176+
metadata: if what_if_metadata.is_empty() { None } else { Some(Metadata { what_if: Some(what_if_metadata) })},
177+
..Default::default()
178+
}));
171179
}
172180

181+
if let Some(reg_key) = reg_key {
182+
reg_key.set_value(&value_name, &data)?;
183+
};
184+
173185
if self.what_if {
174186
return Ok(Some(Registry {
175187
key_path: self.config.key_path.clone(),
@@ -222,8 +234,12 @@ impl RegistryHelper {
222234
let parent_key: RegKey;
223235
let mut subkeys: Vec<&str> = Vec::new();
224236
let parent_key_path = get_parent_key_path(&self.subkey);
225-
let subkey_name = &self.subkey[parent_key_path.len() + 1..];
226-
subkeys.push(subkey_name);
237+
let subkey_name = if parent_key_path.is_empty() { &self.subkey } else {
238+
&self.subkey[parent_key_path.len() + 1..]
239+
};
240+
if !subkey_name.is_empty() {
241+
subkeys.push(subkey_name);
242+
}
227243
let mut current_key_path = parent_key_path;
228244

229245
loop {
@@ -316,6 +332,7 @@ fn convert_reg_value(value: &Data) -> Result<RegistryValueData, RegistryError> {
316332
Ok(RegistryValueData::MultiString(m))
317333
},
318334
Data::U64(q) => Ok(RegistryValueData::QWord(*q)),
335+
Data::None => Ok(RegistryValueData::None),
319336
_ => Err(RegistryError::UnsupportedValueDataType)
320337
}
321338
}

registry/tests/registry.config.set.tests.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,25 @@ Describe 'registry config set tests' {
7272

7373
Get-Item -Path 'HKCU:\1\2' -ErrorAction Ignore | Should -BeNullOrEmpty
7474
}
75+
76+
It 'Can set value without data' -Skip:(!$IsWindows) {
77+
$configYaml = @'
78+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
79+
resources:
80+
- name: Key
81+
type: Microsoft.Windows/Registry
82+
properties:
83+
keyPath: 'HKCU\1'
84+
valueName: Test
85+
_exist: true
86+
'@
87+
88+
$out = dsc config set -i $configYaml | ConvertFrom-Json
89+
$LASTEXITCODE | Should -Be 0
90+
$out.results[0].result.afterState.keyPath | Should -BeExactly 'HKCU\1'
91+
$out.results[0].result.afterState.valueName | Should -BeExactly 'Test'
92+
$out.results[0].result.afterState.valueData | Should -BeNullOrEmpty
93+
94+
Remove-Item -Path 'HKCU:\1' -Recurse -ErrorAction Ignore
95+
}
7596
}

0 commit comments

Comments
 (0)