From 0f30b622214f3a28a0bf4b611941c8318a77dd19 Mon Sep 17 00:00:00 2001 From: Sashank Date: Mon, 27 Jul 2026 02:03:28 +0530 Subject: [PATCH] fix: support QWord, ExpandString and MultiString in the .reg fallback writer (#715) --- Scripts/Helpers/Apply-RegistryRegFile.ps1 | 19 ++++++++++++++++++- Tests/Apply-RegistryRegFile.Tests.ps1 | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Scripts/Helpers/Apply-RegistryRegFile.ps1 b/Scripts/Helpers/Apply-RegistryRegFile.ps1 index 1a79685..f2d48d8 100644 --- a/Scripts/Helpers/Apply-RegistryRegFile.ps1 +++ b/Scripts/Helpers/Apply-RegistryRegFile.ps1 @@ -11,28 +11,45 @@ function Get-NormalizedRegistryValueName { return [string]$ValueName } +<# + .SYNOPSIS + Converts a parsed .reg operation into a Name/Kind/Value set for RegistryKey.SetValue. +#> function Convert-RegOperationToValueKind { param( [Parameter(Mandatory)] $Operation ) - $valueName = if ([string]::IsNullOrEmpty([string]$Operation.ValueName)) { '' } else { [string]$Operation.ValueName } + $valueName = Get-NormalizedRegistryValueName -ValueName $Operation.ValueName $valueType = [string]$Operation.ValueType $operationKeyPath = [string]$Operation.KeyPath + # ValueType here is whatever Get-RegFileOperations parsed it as. + # Hex2/Hex7 are its names for REG_EXPAND_SZ/REG_MULTI_SZ, already decoded to string/string[]. switch ($valueType) { 'DWord' { $unsigned = [uint32]$Operation.ValueData $value = [BitConverter]::ToInt32([BitConverter]::GetBytes($unsigned), 0) return @{ Name = $valueName; Kind = [Microsoft.Win32.RegistryValueKind]::DWord; Value = $value } } + 'QWord' { + $unsigned = [uint64]$Operation.ValueData + $value = [BitConverter]::ToInt64([BitConverter]::GetBytes($unsigned), 0) + return @{ Name = $valueName; Kind = [Microsoft.Win32.RegistryValueKind]::QWord; Value = $value } + } 'String' { return @{ Name = $valueName; Kind = [Microsoft.Win32.RegistryValueKind]::String; Value = [string]$Operation.ValueData } } + 'Hex2' { + return @{ Name = $valueName; Kind = [Microsoft.Win32.RegistryValueKind]::ExpandString; Value = [string]$Operation.ValueData } + } 'Binary' { return @{ Name = $valueName; Kind = [Microsoft.Win32.RegistryValueKind]::Binary; Value = [byte[]]$Operation.ValueData } } + 'Hex7' { + return @{ Name = $valueName; Kind = [Microsoft.Win32.RegistryValueKind]::MultiString; Value = [string[]]@($Operation.ValueData) } + } default { throw "Unsupported value type '$valueType' while applying reg operation for '$operationKeyPath'" } diff --git a/Tests/Apply-RegistryRegFile.Tests.ps1 b/Tests/Apply-RegistryRegFile.Tests.ps1 index 1719913..85b22d9 100644 --- a/Tests/Apply-RegistryRegFile.Tests.ps1 +++ b/Tests/Apply-RegistryRegFile.Tests.ps1 @@ -9,8 +9,11 @@ BeforeAll { Describe 'Convert-RegOperationToValueKind' { It 'converts to a registry-compatible value' -ForEach @( @{ Case = 'an unsigned DWord'; ValueName = $null; ValueType = 'DWord'; ValueData = [uint32]::MaxValue; ExpectedName = ''; ExpectedKind = [Microsoft.Win32.RegistryValueKind]::DWord; ExpectedValue = -1 } + @{ Case = 'an unsigned QWord'; ValueName = 'Big'; ValueType = 'QWord'; ValueData = [uint64]::MaxValue; ExpectedName = 'Big'; ExpectedKind = [Microsoft.Win32.RegistryValueKind]::QWord; ExpectedValue = -1L } @{ Case = 'a string value'; ValueName = 'Name'; ValueType = 'String'; ValueData = 42; ExpectedName = 'Name'; ExpectedKind = [Microsoft.Win32.RegistryValueKind]::String; ExpectedValue = '42' } + @{ Case = 'an expandable string value'; ValueName = 'Path'; ValueType = 'Hex2'; ValueData = 'test%PATH%'; ExpectedName = 'Path'; ExpectedKind = [Microsoft.Win32.RegistryValueKind]::ExpandString; ExpectedValue = 'test%PATH%' } @{ Case = 'a binary value'; ValueName = 'Bytes'; ValueType = 'Binary'; ValueData = @(1, 255); ExpectedName = 'Bytes'; ExpectedKind = [Microsoft.Win32.RegistryValueKind]::Binary; ExpectedValue = [byte[]](1, 255) } + @{ Case = 'a multi-string value'; ValueName = 'List'; ValueType = 'Hex7'; ValueData = @('a', 'b', 'c'); ExpectedName = 'List'; ExpectedKind = [Microsoft.Win32.RegistryValueKind]::MultiString; ExpectedValue = [string[]]@('a', 'b', 'c') } ) { $result = Convert-RegOperationToValueKind -Operation ([PSCustomObject]@{ KeyPath = 'HK'; ValueName = $ValueName; ValueType = $ValueType; ValueData = $ValueData