Parnus has asked for the wisdom of the Perl Monks concerning the following question:
#!/usr/bin/perl #parse diff.txt produced by Winalysis 2.5, retrieve the registry entri +es from the server as specified by the input file my $debug = $ARGV[0] || 0; use Win32::TieRegistry;# (Delimiter => "/");#, TiedHash => \%Registry) +; my $sMachineName = 'hacomtw05'; my $sFileName = 'hacomtw05.diff.txt'; my %Done; my $i = 0; my @NewKeys; my %ChangedKeys; my @DeletedKeys; open(IN,$sFileName) || die("Could not open $filename for reading: $!\n +"); my @Txt = <IN>; close IN; for ($i = 0; $i < $#Txt; $i++) { if($Txt[$i+1] =~ /New Key/) { chomp $Txt[$i]; push @NewKeys,$Txt[$i]; $i++; } elsif($Txt[$i+1] =~ /Value Changed/) { chomp $Txt[$i]; chomp $Txt[$i+1]; my @Vals = split(/\t/,$Txt[$i+1]); dprint ('Chg: ',$Txt[$i]," ",join("^^",@Vals),"\n"); $ChangedKeys{$Txt[$i]} = [ $Vals[2], $Vals[3] ]; $i++; } elsif($Txt[$i+1] =~ /Key Last Modified Date/ && $Txt[$i+2] =~ /Val +ue Changed/) { chomp $Txt[$i]; chomp $Txt[$i+2]; my @Vals = split(/\t/,$Txt[$i+2]); dprint ('Mod: ',$Txt[$i]," ",join("^^",@Vals),"\n"); $ChangedKeys{$Txt[$i]} = [ $Vals[2], $Vals[3] ]; $i += 2; } elsif($Txt[$i+1] =~ /Deleted Value/) { chomp $Txt[$i]; push @DeletedKeys, $Txt[$i]; $i++; } } $key= new Win32::TieRegistry "LMachine\\",{ Access=>KEY_READ, Delimite +r=>"\\" }; print getNewKeys(); print getChangedKeys(); print getDeletedKeys(); sub getNewKeys { my $str = ''; $str .= "NEW KEYS:\n"; $str .= "Index\tName\tDatatype\tValue\n"; $i = 1; foreach ( @NewKeys ) { s/^HKLM/LMachine/; my $sKeyPath = $_; dprint ($sKeyPath . "\n"); my @ValueMatrix = parseValue( $sKeyPath, 'recurse' ); my $j; for ($j = 0; $j < $#ValueMatrix; $j++) { my $valueString = $ValueMatrix[$j][0]; my $dataType = $ValueMatrix[$j][1]; my $attribute = $ValueMatrix[$j][2]; if($valueString) { $sKeyPath =~ s/^LMachine/HKEY_LOCAL_MACHINE/; $str .= $i++ . "\t" . $sKeyPath . "\\" . $attribute . +"\t" . $dataType . "\t" . $valueString . "\n"; } } } chomp $str; return $str; } sub getChangedKeys { my $str = ''; $str .= "\nCHANGED KEYS:\n"; $str .= "Index\tName\tDatatype\tOld Value\tNew Value\n"; $i = 1; foreach ( keys %ChangedKeys ) { s/^HKLM/LMachine/; my $sKeyPath = $_; dprint ($sKeyPath . "\n"); my ($valueString, $dataType, $attribute) = parseValue( $sKeyPa +th, 'flat' ); if($valueString) { $sKeyPath =~ s/^LMachine/HKEY_LOCAL_MACHINE/; if(length($valueString) > 255) { $valueString = substr($valueString, 0, 252) . '...' +; } $str .= $i++ . "\t" . $sKeyPath . "\\" . $attribute . "\t" + . $dataType . "\t" . $ChangedKeys{$_}[0] . "\t" . $valueString . "\n +"; } else { dprint ("Skipping a key...\n"); } #exit; } chomp $str; return $str; } sub parseValue { my $sKeyPath = shift; my $mode = shift; my $attribute; $Done{$sKeyPath} ? return 0 : {$Done{$sKeyPath} = 1}; if ($mode eq 'flat' or $mode eq 'default') { my @fullPath = split(/\\/,$sKeyPath); $attribute = pop @fullPath; $sKeyPath = join('\\',@fullPath); @fullPath = undef; } my $remKey= $key->Connect( $sMachineName, $sKeyPath, { Access=>KEY +_READ, Delimiter=>"\\" } ) or return (0,0,0); $remKey->SplitMultis(1); $remKey->FixSzNulls(1); if ($mode eq 'recurse') { my @Names = $remKey->ValueNames; $remKey->Flush(); my @ReturnMatrix; my @SubKeys = $remKey->SubKeyNames; $remKey->Flush(); #deeeep recursion... go team! foreach( @SubKeys ) { push @ReturnMatrix, parseValue( $sKeyPath . '\\' . $_, 're +curse' ); } foreach( @Names ) { my ($tempString, $tempType, $tempAttr) = parseValue( $sKey +Path . '\\' . $_, 'flat' ); push @ReturnMatrix, [ $tempString, $tempType, $tempAttr ]; } return @ReturnMatrix; } elsif ($mode eq 'flat') { my ($valueString, $valueType) = $remKey->GetValue($attribute); my $dataType = "UNKNOWN"; if ($valueType == Win32::TieRegistry::REG_SZ) { $dataType = "R +EG_SZ"; } elsif ($valueType == Win32::TieRegistry::REG_EXPAND_SZ) { $dat +aType = "REG_EXPAND_SZ"; } elsif ($valueType == Win32::TieRegistry::REG_MULTI_SZ) { $dataType = "REG_MULTI_SZ"; my @temp = $remKey->GetValue($attribute); $valueString = join('|',@{$temp[0]}); } elsif ($valueType == Win32::TieRegistry::REG_DWORD) { $dataTyp +e = "REG_DWORD"; } elsif ($valueType == Win32::TieRegistry::REG_BINARY) { $dataType = "REG_BINARY"; $valueString = "[BINARY DATA]"; } else { ($valueString, $dataType, $attribute) = parseValue($sKe +yPath . '\\' . $attribute . '\\\\', 'default');} $remKey->Flush(); return ($valueString, $dataType, $attribute); } else { my ($valueString) = $remKey->GetValue($sKeyPath); my $valueType = 1; my $dataType = "UNKNOWN"; if ($valueType == Win32::TieRegistry::REG_SZ) { $dataType = + "REG_SZ";} elsif ($valueType == Win32::TieRegistry::REG_EXPAND_SZ) {$data +Type = "REG_EXPAND_SZ";} elsif ($valueType == Win32::TieRegistry::REG_MULTI_SZ) { $dataType = "REG_MULTI_SZ"; my @temp = $remKey->GetValue($attribute); $valueString = join('|',@{$temp[0]}); } elsif ($valueType == Win32::TieRegistry::REG_DWORD) {$dataType + = "REG_DWORD";} elsif ($valueType == Win32::TieRegistry::REG_BINARY) { $dataType = "REG_BINARY"; $valueString = "[BINARY DATA]"; } $remKey->Flush(); return ($valueString, $dataType, '(default)'); } } sub doneIt { $Done{shift} ? return 0 : return 1; } sub getDeletedKeys { my $str = ''; $str = "\nDELETED KEYS:\n"; $str .= "Index\tName\n"; $i = 1; foreach ( @DeletedKeys ) { $str .= $i++ . "\t" . $_ . "\n"; } chomp $str; return $str; } sub dprint { print join('',@_) if $debug; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
(tye)Re: Hacking away at Win32::TieRegistry
by tye (Sage) on Jan 19, 2001 at 01:03 UTC |