/usr/share/doc/libparse-win32registry-perl/examples/regdiff.pl is in libparse-win32registry-perl 1.0-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if 0; # not running under some shell
use strict;
use warnings;
use File::Basename;
use Getopt::Long;
use Parse::Win32Registry;
binmode(STDOUT, ':utf8');
Getopt::Long::Configure('bundling');
GetOptions('previous|p' => \my $show_previous,
'values|v' => \my $show_values);
my $left_filename = shift or die usage();
my $right_filename = shift or die usage();
my $initial_key_path = shift;
my $left_registry = Parse::Win32Registry->new($left_filename)
or die "'$left_filename' is not a registry file\n";
my $right_registry = Parse::Win32Registry->new($right_filename)
or die "'$right_filename' is not a registry file\n";
my $left_root_key = $left_registry->get_root_key
or die "Could not get root key of '$left_filename'\n";
my $right_root_key = $right_registry->get_root_key
or die "Could not get root key of '$right_filename'\n";
if (defined($initial_key_path)) {
$left_root_key = $left_root_key->get_subkey($initial_key_path);
if (!defined($left_root_key)) {
die "Could not find the key '$initial_key_path' in '$left_filename'\n";
}
$right_root_key = $right_root_key->get_subkey($initial_key_path);
if (!defined($right_root_key)) {
die "Could not find the key '$initial_key_path' in '$right_filename'\n";
}
}
# Descend both registry trees together
traverse_together($left_root_key, $right_root_key);
sub traverse_together {
my $left_key = shift;
my $right_key =shift;
# Build a combined list of 'left' and 'right' values
my %values = ();
if (defined($left_key)) {
foreach my $left_value ($left_key->get_list_of_values) {
$values{$left_value->get_name}{left} = $left_value;
}
}
if (defined($right_key)) {
foreach my $right_value ($right_key->get_list_of_values) {
$values{$right_value->get_name}{right} = $right_value;
}
}
# Count the number of changed values
my $changed = 0;
foreach my $value_name (keys %values) {
if (defined $values{$value_name}{left}
&& defined $values{$value_name}{right}) {
if ($values{$value_name}{left}->get_data
ne $values{$value_name}{right}->get_data) {
# value has been changed
$changed++;
}
}
else {
# Value has been deleted or inserted
$changed++;
}
}
if (defined($left_key) && !defined($right_key)) {
# Right key has been deleted
print "DELETED\t", $left_key->as_string, "\n";
}
elsif (!defined($left_key) && defined($right_key)) {
# Right key has been inserted
print "ADDED\t", $right_key->as_string, "\n";
}
else {
# If both keys are present, compare timestamps
# to see if there have been any changes.
# If the keys do not have timestamps, use the count of changed values
# to determine if the key should be displayed or not.
my $left_timestamp = $left_key->get_timestamp;
my $right_timestamp = $right_key->get_timestamp;
my $is_winnt = defined($left_timestamp) && defined($right_timestamp);
if ($is_winnt && $left_timestamp < $right_timestamp) {
# Right key is newer
print "NEWER\t", $right_key->as_string, "\n";
if ($show_previous) {
print "WAS\t", $left_key->as_string, "\n";
}
}
elsif ($is_winnt && $left_timestamp > $right_timestamp) {
# Right key is older
print "OLDER\t", $right_key->as_string, "\n";
if ($show_previous) {
print "WAS\t", $left_key->as_string, "\n";
}
}
else {
# There are no differences between the timestamps
# or neither key has a valid timestamp.
if ($show_values) {
if ($changed > 0) {
#print "\t$changed VALUES CHANGED IN\n";
if (defined($left_key)) {
print "\t", $left_key->as_string, "\n";
}
else {
print "\t", $right_key->as_string, "\n";
}
}
}
}
}
if ($show_values) {
# Print out changed values
foreach my $value_name (keys %values) {
my $left_value = $values{$value_name}{left};
my $right_value = $values{$value_name}{right};
if (defined($left_value) && !defined($right_value)) {
print "DELETED\t", $left_value->as_string, "\n";
}
elsif (!defined($left_value) && defined($right_value)) {
print "ADDED\t", $right_value->as_string, "\n";
}
else {
if ($left_value->get_data ne $right_value->get_data) {
print "CHANGED\t", $right_value->as_string, "\n";
if ($show_previous) {
print "WAS\t", $left_value->as_string, "\n";
}
}
}
}
}
# Build a combined list of 'left' and 'right' subkeys
my %subkeys = ();
if (defined($left_key)) {
foreach my $left_subkey ($left_key->get_list_of_subkeys) {
$subkeys{$left_subkey->get_name}{left} = $left_subkey;
}
}
if (defined($right_key)) {
foreach my $right_subkey ($right_key->get_list_of_subkeys) {
$subkeys{$right_subkey->get_name}{right} = $right_subkey;
}
}
foreach my $key_name (keys %subkeys) {
traverse_together($subkeys{$key_name}{left},
$subkeys{$key_name}{right});
}
}
sub usage {
my $script_name = basename $0;
return <<USAGE;
$script_name for Parse::Win32Registry $Parse::Win32Registry::VERSION
Compares two registry files.
$script_name <filename1> <filename2> [subkey] [-p] [-v]
-p or --previous show the previous key or value
(this is not normally shown)
-v or --values display values
USAGE
}
|