From 2c046a67b2019b34a6007cfb53f4a2b0e96fede1 Mon Sep 17 00:00:00 2001 From: David Durieux Date: Sat, 30 Apr 2022 11:55:38 +0200 Subject: [PATCH] Rewrite registry to get in low level to have the right encoding string --- .../Agent/Task/Inventory/Generic/Screen.pm | 8 +- .../Agent/Task/Inventory/Win32/AntiVirus.pm | 26 ++- .../Agent/Task/Inventory/Win32/CPU.pm | 21 ++- .../Agent/Task/Inventory/Win32/License.pm | 26 ++- .../Agent/Task/Inventory/Win32/Networks.pm | 27 ++- .../Agent/Task/Inventory/Win32/Softwares.pm | 108 ++++++------ lib/FusionInventory/Agent/Tools/Win32.pm | 163 +++++++++++++++++- 7 files changed, 269 insertions(+), 110 deletions(-) diff --git a/lib/FusionInventory/Agent/Task/Inventory/Generic/Screen.pm b/lib/FusionInventory/Agent/Task/Inventory/Generic/Screen.pm index 6aa698d30f..ac2e961af4 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Generic/Screen.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Generic/Screen.pm @@ -8,7 +8,6 @@ use parent 'FusionInventory::Agent::Task::Inventory::Module'; use English qw(-no_match_vars); use MIME::Base64; use UNIVERSAL::require; - use File::Find; use FusionInventory::Agent::Tools; use FusionInventory::Agent::Tools::Screen; @@ -148,8 +147,11 @@ sub _getScreensFromWindows { foreach my $screen (@screens) { next unless $screen->{id}; - $screen->{edid} = getRegistryValue( - path => "HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/$screen->{id}/Device Parameters/EDID", + # $screen->{id} =~ s/\\/\//g; + $screen->{edid} = getNewRegistryValues( + root => "HKEY_LOCAL_MACHINE", + path => "SYSTEM/CurrentControlSet/Enum/$screen->{id}/Device Parameters", + keyName => "EDID", logger => $params{logger} ); $screen->{edid} =~ s/^\s+$// if $screen->{edid}; diff --git a/lib/FusionInventory/Agent/Task/Inventory/Win32/AntiVirus.pm b/lib/FusionInventory/Agent/Task/Inventory/Win32/AntiVirus.pm index 9be8785032..a3cf56d83e 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Win32/AntiVirus.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Win32/AntiVirus.pm @@ -461,31 +461,25 @@ sub _setNortonInfos { sub _getSoftwareRegistryKeys { my ($base, $values, $callback) = @_; - my $reg; if (is64bit()) { - $reg = getRegistryKey( - path => 'HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/'.$base, - wmiopts => { # Only used for remote WMI optimization - values => $values - } + my %reg = getNewRegistryValues( + root => "HKEY_LOCAL_MACHINE", + path => 'SOFTWARE/Wow6432Node/'.$base ); - if ($reg) { + if (%reg) { if ($callback) { - my $filter = &{$callback}($reg); + my $filter = &{$callback}(%reg); return $filter if $filter; } else { - return $reg; + return %reg; } } } - - $reg = getRegistryKey( - path => 'HKEY_LOCAL_MACHINE/SOFTWARE/'.$base, - wmiopts => { # Only used for remote WMI optimization - values => $values - } + my %reg = getNewRegistryValues( + root => "HKEY_LOCAL_MACHINE", + path => 'SOFTWARE/'.$base ); - return ($callback && $reg) ? &{$callback}($reg) : $reg; + return ($callback && %reg) ? &{$callback}(%reg) : %reg; } 1; diff --git a/lib/FusionInventory/Agent/Task/Inventory/Win32/CPU.pm b/lib/FusionInventory/Agent/Task/Inventory/Win32/CPU.pm index 9bcabeec50..375553b7dd 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Win32/CPU.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Win32/CPU.pm @@ -53,12 +53,11 @@ sub _getCPUs { my @dmidecodeInfos = $remotewmi || Win32::GetOSName() eq 'Win2003' ? () : getCpusFromDmidecode(); - # the CPU description in WMI is false, we use the registry instead - my $registryInfos = getRegistryKey( - path => "HKEY_LOCAL_MACHINE/Hardware/Description/System/CentralProcessor", - wmiopts => { # Only used for remote WMI optimization - values => [ qw/Identifier ProcessorNameString VendorIdentifier/ ] - } + my %registryInfos = getNewRegistryAll( + logger => $params{logger}, + root => "HKEY_LOCAL_MACHINE", + path => "Hardware/Description/System/CentralProcessor", + %params ); my $cpuId = 0; @@ -77,26 +76,26 @@ sub _getCPUs { )) { my $dmidecodeInfo = $dmidecodeInfos[$cpuId]; - my $registryInfo = $registryInfos->{"$logicalId/"}; + my $registryInfo = $registryInfos{"$logicalId"}; # Compute WMI threads for this CPU if not available in dmidecode, this is the case on win2003r2 with 932370 hotfix applied (see #2894) my $wmi_threads = !$dmidecodeInfo->{THREAD} && $object->{NumberOfCores} ? $object->{NumberOfLogicalProcessors}/$object->{NumberOfCores} : undef; # Split CPUID from its value inside registry - my @splitted_identifier = split(/ |\n/, $registryInfo->{'/Identifier'} || $object->{Description}); + my @splitted_identifier = split(/ |\n/, $registryInfo->{Identifier} || $object->{Description}); my $name = $dmidecodeInfo->{NAME}; unless ($name) { - $name = trimWhitespace($registryInfo->{'/ProcessorNameString'} || $object->{Name}); + $name = trimWhitespace($registryInfo->{ProcessorNameString} || $object->{Name}); $name =~ s/\((R|TM)\)//gi if $name; } my $cpu = { CORE => $dmidecodeInfo->{CORE} || $object->{NumberOfCores}, THREAD => $dmidecodeInfo->{THREAD} || $wmi_threads, - DESCRIPTION => $dmidecodeInfo->{DESCRIPTION} || $registryInfo->{'/Identifier'} || $object->{Description}, + DESCRIPTION => $dmidecodeInfo->{DESCRIPTION} || $registryInfo->{Identifier} || $object->{Description}, NAME => $name, - MANUFACTURER => $dmidecodeInfo->{MANUFACTURER} || getCanonicalManufacturer($registryInfo->{'/VendorIdentifier'} || $object->{Manufacturer}), + MANUFACTURER => $dmidecodeInfo->{MANUFACTURER} || getCanonicalManufacturer($registryInfo->{VendorIdentifier} || $object->{Manufacturer}), SERIAL => $dmidecodeInfo->{SERIAL} || $object->{SerialNumber}, SPEED => $dmidecodeInfo->{SPEED} || $object->{MaxClockSpeed}, FAMILYNUMBER => $dmidecodeInfo->{FAMILYNUMBER} || $splitted_identifier[2], diff --git a/lib/FusionInventory/Agent/Task/Inventory/Win32/License.pm b/lib/FusionInventory/Agent/Task/Inventory/Win32/License.pm index 88d1a61003..52a47d49ce 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Win32/License.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Win32/License.pm @@ -36,18 +36,26 @@ sub doInventory { my @licenses; - my $officeKey = getRegistryKey( - path => "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Office" + my %officeKey = getNewRegistryAll( + logger => $params{logger}, + root => "HKEY_LOCAL_MACHINE", + path => "SOFTWARE/Microsoft/Office", + %params ); - _scanOfficeLicences($officeKey) if $officeKey; + + _scanOfficeLicences(%officeKey) if %officeKey; my $fileAdobe = 'C:\Program Files\Common Files\Adobe\Adobe PCD\cache\cache.db'; if (is64bit()) { $fileAdobe = 'C:\Program Files (x86)\Common Files\Adobe\Adobe PCD\cache\cache.db'; - my $officeKey32 = getRegistryKey( - path => "HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/Office" + my %officeKey32 = getNewRegistryAll( + logger => $params{logger}, + root => "HKEY_LOCAL_MACHINE", + path => "SOFTWARE/Wow6432Node/Microsoft/Office", + %params ); - _scanOfficeLicences($officeKey32) if $officeKey32; + + _scanOfficeLicences(%officeKey32) if %officeKey32; } push @licenses, getAdobeLicensesWithoutSqlite($fileAdobe) if (-e $fileAdobe); @@ -116,7 +124,7 @@ sub _scanWmiSoftwareLicensingProducts { } sub _scanOfficeLicences { - my ($key) = @_; + my (%key) = @_; # registry data structure: # SOFTWARE/Microsoft/Office @@ -127,8 +135,8 @@ sub _scanOfficeLicences { # └── ProductID:value # └── ... - foreach my $versionKey (keys %{$key}) { - my $registrationKey = $key->{$versionKey}->{'Registration/'}; + foreach my $versionKey (keys %key) { + my $registrationKey = $key{$versionKey}->{Registration}; next unless $registrationKey; foreach my $uuidKey (keys %{$registrationKey}) { diff --git a/lib/FusionInventory/Agent/Task/Inventory/Win32/Networks.pm b/lib/FusionInventory/Agent/Task/Inventory/Win32/Networks.pm index 1aa2dc49b7..708e8f38d3 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Win32/Networks.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Win32/Networks.pm @@ -27,7 +27,7 @@ sub doInventory { my $inventory = $params{inventory}; my (@gateways, @dns, @ips); - my $keys; + my %keys; foreach my $interface (getInterfaces()) { push @gateways, $interface->{IPGATEWAY} @@ -44,14 +44,13 @@ sub doInventory { delete $interface->{GUID}; # Don't reload registry keys between interfaces checks - $keys = getRegistryKey( - path => "HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E972-E325-11CE-BFC1-08002BE10318}", - wmiopts => { # Only used for remote WMI optimization - values => [ qw/PnpInstanceID MediaSubType/ ] - } - ) unless $keys; + %keys = getNewRegistryAll( + logger => $params{logger}, + root => "HKEY_LOCAL_MACHINE", + path => "SYSTEM/CurrentControlSet/Control/Network/{4D36E972-E325-11CE-BFC1-08002BE10318}", + ) unless %keys; - $interface->{TYPE} = _getMediaType($interface->{PNPDEVICEID}, $keys); + $interface->{TYPE} = _getMediaType($interface->{PNPDEVICEID}, %keys); $inventory->addEntry( section => 'NETWORKS', @@ -68,23 +67,23 @@ sub doInventory { } sub _getMediaType { - my ($deviceid, $keys) = @_; + my ($deviceid, %keys) = @_; - return unless defined $deviceid && $keys; + return unless defined $deviceid && %keys; my $subtype; - foreach my $subkey_name (keys %{$keys}) { + foreach my $subkey_name (keys %keys) { # skip variables next if $subkey_name =~ m{^/}; - my $subkey_connection = $keys->{$subkey_name}->{'Connection/'} + my $subkey_connection = $keys{$subkey_name}->{Connection} or next; - my $subkey_deviceid = $subkey_connection->{'/PnpInstanceID'} + my $subkey_deviceid = $subkey_connection->{PnpInstanceID} or next; # Normalize PnpInstanceID $subkey_deviceid =~ s/\\\\/\\/g; if (lc($subkey_deviceid) eq lc($deviceid)) { - $subtype = $subkey_connection->{'/MediaSubType'}; + $subtype = $subkey_connection->{MediaSubType}; last; } } diff --git a/lib/FusionInventory/Agent/Task/Inventory/Win32/Softwares.pm b/lib/FusionInventory/Agent/Task/Inventory/Win32/Softwares.pm index b46edb29bc..15dcf023ce 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Win32/Softwares.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Win32/Softwares.pm @@ -66,7 +66,7 @@ sub doInventory { if ($is64bit) { my $softwares32 = _getSoftwaresList( - path => "HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall", + path => "SOFTWARE/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall", is64bit => 0 ) || []; foreach my $software (@$softwares32) { @@ -120,12 +120,13 @@ sub _loadUserSoftware { my $userName = $userList->{$profileName} or next; - my $profileSoft = "HKEY_USERS/$profileName/SOFTWARE/"; + my $profileSoft = "$profileName/SOFTWARE/"; $profileSoft .= is64bit() && !$is64bit ? "Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall" : "Microsoft/Windows/CurrentVersion/Uninstall"; my $softwares = _getSoftwaresList( + root => "HKEY_USERS", path => $profileSoft, is64bit => $is64bit, userid => $profileName, @@ -143,22 +144,22 @@ sub _loadUserSoftware { sub _getUsersFromRegistry { my (%params) = @_; - my $profileList = getRegistryKey( - path => 'HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/ProfileList', - wmiopts => { # Only used for remote WMI optimization - values => [ qw/ProfileImagePath Sid/ ], - } + my %profileList = getNewRegistryAll( + logger => $params{logger}, + root => "HKEY_LOCAL_MACHINE", + path => "SOFTWARE/Microsoft/Windows NT/CurrentVersion/ProfileList", + %params ); - next unless $profileList; + return unless %profileList; my $userList; - foreach my $profileName (keys %$profileList) { + foreach my $profileName (keys %profileList) { next unless $profileName =~ m{/$}; next unless length($profileName) > 10; - my $profilePath = $profileList->{$profileName}{'/ProfileImagePath'}; - my $sid = $profileList->{$profileName}{'/Sid'}; + my $profilePath = $profileList{$profileName}->{ProfileImagePath}; + my $sid = $profileList{$profileName}->{Sid}; next unless $sid; next unless $profilePath; my $user = basename($profilePath); @@ -196,9 +197,7 @@ sub _keyLastWriteDateString { return unless ($OSNAME eq 'MSWin32'); - return unless (ref($key) eq "Win32::TieRegistry"); - - my @lastWrite = FileTimeToSystemTime($key->Information("LastWrite")); + my @lastWrite = FileTimeToSystemTime($key->{_lastWrite}); return unless (@lastWrite > 3); @@ -208,53 +207,52 @@ sub _keyLastWriteDateString { sub _getSoftwaresList { my (%params) = @_; - my $softwares = getRegistryKey( - path => "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall", - wmiopts => { # Only used for remote WMI optimization - values => [ qw/ - DisplayName Comments HelpLink ReleaseType DisplayVersion - Publisher URLInfoAbout UninstallString InstallDate MinorVersion - MajorVersion NoRemove SystemComponent - / ] - }, + my $path = "SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"; + my $root = "HKEY_LOCAL_MACHINE"; + if (defined $params{path}) { + $path = $params{path}; + } + if (defined $params{root}) { + $root = $params{root}; + } + + my %softwares = getNewRegistryAll( + logger => $params{logger}, + root => $root, + path => $path, %params ); + return unless %softwares; my @list; - return unless $softwares; - - foreach my $rawGuid (keys %$softwares) { + foreach my $rawGuid (keys %softwares) { # skip variables next if $rawGuid =~ m{^/}; # only keep subkeys with more than 1 value - my $data = $softwares->{$rawGuid}; + my $data = $softwares{$rawGuid}; next unless keys %$data > 1; - my $guid = $rawGuid; - $guid =~ s/\/$//; # drop the tailing / - my $software = { FROM => "registry", - NAME => encodeFromRegistry($data->{'/DisplayName'}) || - encodeFromRegistry($guid), # folder name - COMMENTS => encodeFromRegistry($data->{'/Comments'}), - HELPLINK => encodeFromRegistry($data->{'/HelpLink'}), - RELEASE_TYPE => encodeFromRegistry($data->{'/ReleaseType'}), - VERSION => encodeFromRegistry($data->{'/DisplayVersion'}), - PUBLISHER => encodeFromRegistry($data->{'/Publisher'}), - URL_INFO_ABOUT => encodeFromRegistry($data->{'/URLInfoAbout'}), - UNINSTALL_STRING => encodeFromRegistry($data->{'/UninstallString'}), - INSTALLDATE => _dateFormat($data->{'/InstallDate'}), - VERSION_MINOR => hex2dec($data->{'/MinorVersion'}), - VERSION_MAJOR => hex2dec($data->{'/MajorVersion'}), - NO_REMOVE => hex2dec($data->{'/NoRemove'}), + NAME => $data->{DisplayName} || $rawGuid, # folder name + COMMENTS => $data->{Comments}, + HELPLINK => $data->{HelpLink}, + RELEASE_TYPE => $data->{ReleaseType}, + VERSION => $data->{DisplayVersion}, + PUBLISHER => $data->{Publisher}, + URL_INFO_ABOUT => $data->{URLInfoAbout}, + UNINSTALL_STRING => $data->{UninstallString}, + INSTALLDATE => _dateFormat($data->{InstallDate}), + VERSION_MINOR => $data->{MinorVersion}, + VERSION_MAJOR => $data->{MajorVersion}, + NO_REMOVE => $data->{NoRemove}, ARCH => $params{is64bit} ? 'x86_64' : 'i586', - GUID => $guid, + GUID => $rawGuid, USERNAME => $params{username}, USERID => $params{userid}, - SYSTEM_CATEGORY => $data->{'/SystemComponent'} && hex2dec($data->{'/SystemComponent'}) ? + SYSTEM_CATEGORY => $data->{SystemComponent} ? CATEGORY_SYSTEM_COMPONENT : CATEGORY_APPLICATION }; @@ -347,17 +345,17 @@ sub _processMSIE { "Internet Explorer (64bit)" : "Internet Explorer"; # Will use key last write date as INSTALLDATE - my $installedkey = getRegistryKey( + my %installedkey = getNewRegistryValues( + logger => $params{logger}, + root => "HKEY_LOCAL_MACHINE", path => is64bit() && !$params{is64bit} ? - "HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/Internet Explorer" : - "HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer", - wmiopts => { # Only used for remote WMI optimization - values => [ qw/svcVersion Version/ ], - subkeys => 0 - } + "SOFTWARE/Wow6432Node/Microsoft/Internet Explorer" : + "SOFTWARE/Microsoft/Internet Explorer", + %params ); - my $version = $installedkey->{"/svcVersion"} || $installedkey->{"/Version"}; + + my $version = $installedkey{svcVersion} || $installedkey{Version}; return unless $version; # Not installed @@ -368,8 +366,8 @@ sub _processMSIE { ARCH => $params{is64bit} ? 'x86_64' : 'i586', NAME => $name, VERSION => $version, - PUBLISHER => "Microsoft Corporation", - INSTALLDATE => _dateFormat(_keyLastWriteDateString($installedkey)) + PUBLISHER => "Microsoft Corporation" + # INSTALLDATE => _dateFormat(_keyLastWriteDateString(%installedkey)) } ); diff --git a/lib/FusionInventory/Agent/Tools/Win32.pm b/lib/FusionInventory/Agent/Tools/Win32.pm index b599803242..fd61ae07f8 100644 --- a/lib/FusionInventory/Agent/Tools/Win32.pm +++ b/lib/FusionInventory/Agent/Tools/Win32.pm @@ -15,7 +15,7 @@ use constant KEY_WOW64_64 => 0x100; use constant KEY_WOW64_32 => 0x200; use Cwd; -use Encode; +use Encode qw( encode decode is_utf8 ); use English qw(-no_match_vars); use File::Temp qw(:seekable tempfile); use File::Basename qw(basename); @@ -25,6 +25,7 @@ use Win32::TieRegistry ( ArrayValues => 0, qw/KEY_READ/ ); +use Win32API::Registry qw( :ALL ); use FusionInventory::Agent::Tools; use FusionInventory::Agent::Tools::Expiration; @@ -50,6 +51,8 @@ our @EXPORT = qw( FreeAgentMem getWMIService getFormatedWMIDateTime + getNewRegistryAll + getNewRegistryValues ); my $_is64bits = undef; @@ -83,7 +86,7 @@ sub encodeFromRegistry { ## no critic (ExplicitReturnUndef) return undef unless $string; - return $string if Encode::is_utf8($string); + return $string if is_utf8($string); return decode(getLocalCodepage(), $string); } @@ -215,6 +218,155 @@ sub _getWMIObjects { return @objects; } + +############## NEW REGISTRY ############## + +sub getNewRegistryAll { + my (%params) = @_; + + # my %ret; + if (!$params{path}) { + $params{logger}->error( + "No registry value path provided" + ) if $params{logger}; + return; + } + if (!$params{root}) { + $params{logger}->error( + "No registry value root provided" + ) if $params{logger}; + return; + } + + my %ret; + + my %keys = getNewRegistrySubKeys( + logger => $params{logger}, + root => $params{root}, + path => $params{path} + ); + foreach my $keyName (keys %keys) { + my %values = getNewRegistryValues( + logger => $params{logger}, + root => $params{root}, + path => $params{path}.'/'.$keyName, + lastwrite => $keys{$keyName} + ); + $ret{$keyName} = { %values }; + } + return %ret; +} + +sub getNewRegistrySubKeys { + my (%params) = @_; + + my %ret; + + my $swKey; + my $keyIndex = 0; + my $keyName; + my $keyLastWrite; + + my $path = $params{path}; + $path =~ s/\//\\\\/g; + + my $root = _getNewRegistryRoot( + root => $params{root} + ); + + RegOpenKeyExW($root, encode("UTF-16LE", $path), 0, KEY_ENUMERATE_SUB_KEYS, $swKey); + for ($keyIndex = 0; RegEnumKeyExW($swKey, $keyIndex, $keyName, 0, [], [], [], $keyLastWrite); $keyIndex++) { + $keyName =~ s/^((?:..)*)\0\0//s; + $ret{decode("UTF-16LE", $keyName)} = $keyLastWrite; + # push @ret, decode("UTF-16LE", $keyName); + } + return %ret; +} + +sub getNewRegistryValues { + my (%params) = @_; + + my %ret; + my $keyIndex = 0; + my $keyName; + my $keyType; + my $keyValue; + my $swKey; + my $path = $params{path}; + my $root = _getNewRegistryRoot( + root => $params{root} + ); + + $path =~ s/\//\\\\/g; + + if (defined $params{lastwrite}) { + $ret{_lastWrite} = $params{lastwrite}; + } + + RegOpenKeyExW($root, encode("UTF-16LE", $path), 0, KEY_READ, $swKey); + + for ($keyIndex = 0; RegEnumValueW($swKey, $keyIndex, $keyName, 100, [], $keyType, $keyValue, 100); $keyIndex++) { + my $newKeyValue; + if ($keyType == REG_DWORD) { + $newKeyValue = unpack("L", $keyValue); + } else { + $keyValue =~ s/\x00$//; + $newKeyValue = decode("UTF-16LE", $keyValue); + # $newKeyValue =~ s/^((?:..)*)\0\0//s; + } + $keyName =~ s/^((?:..)*)\0\0//s; + $ret{decode("UTF-16LE", $keyName)} = $newKeyValue; + } + return %ret; +} + +sub getNewRegistryValue { + my (%params) = @_; + + my $swKey; + my $keyType; + my $keyValue; + my $path = $params{path}; + my $root = _getNewRegistryRoot( + root => $params{root} + ); + + RegOpenKeyExW($root, encode("UTF-16LE", $path), 0, KEY_READ, $swKey); + RegQueryValueExW($swKey, encode("UTF-16LE", $params{keyName}), [], $keyType, $keyValue, 100); + return $keyValue; + + $keyValue =~ s/^((?:..)*)\0\0//s; + if ($keyType == REG_DWORD) { + $keyValue = unpack("L", $keyValue); + } else { + $keyValue = decode("UTF-16LE", $keyValue); + } + return $keyValue; +} + +sub _getNewRegistryRoot { + my (%params) = @_; + + my $root = $params{root}; + if ($root eq "HKEY_CLASSES_ROOT") { + $root = HKEY_CLASSES_ROOT; + } elsif ($root eq "HKEY_CURRENT_USER") { + $root = HKEY_CURRENT_USER; + } elsif ($root eq "HKEY_LOCAL_MACHINE") { + $root = HKEY_LOCAL_MACHINE; + } elsif ($root eq "HKEY_USER") { + $root = HKEY_USERS; + } + return $root; +} + + + + + +########## END NEW REGISTRY ############## + + sub getRegistryValue { my (%params) = @_; @@ -260,6 +412,13 @@ sub getRegistryValue { ); } + return _getRegistryDynamic( + logger => $params{logger}, + path => $params{path}, + valueName => '', + withtype => '' + ); + my $key = _getRegistryKey( logger => $params{logger}, root => $root,