Files
libguestfs/contrib/windows-icons.pl

121 lines
3.5 KiB
Perl
Executable File

#!/usr/bin/perl -w
# libguestfs
# Copyright (C) 2012 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# This script lets you extract all the icons from a Windows guest. We
# use this to locate the Windows logo in new releases of Windows (see
# src/inspect-icon.c).
#
# Use it like this:
# ./run ./contrib/windows-icons.pl /path/to/windows-disk.img
use strict;
use Sys::Guestfs;
use File::Temp qw{tempdir};
# Check that the tools we need are installed.
system ("wrestool --help >/dev/null 2>&1") == 0 or
die "'wrestool' program is not installed\n";
#system ("icotool --help >/dev/null 2>&1") == 0 or
# die "'icotool' program is not installed\n";
# Check user provided disk image argument(s).
if (@ARGV == 0) {
print STDERR "usage: $0 /path/to/windows-disk.img\n";
exit 1
}
# Assume libguestfs >= 1.19.32, because that means we don't
# have to worry about protocol limits in various calls.
my $g = Sys::Guestfs->new;
my %version = $g->version ();
unless ($version{minor} >= 20 ||
$version{minor} >= 19 && $version{release} >= 32) {
die "$0: version of libguestfs is too old, use >= 1.19.32\n"
}
# Open the disk image(s).
$g->add_drive ($_, readonly => 1) foreach @ARGV;
$g->launch ();
# Check it's Windows.
my @roots = $g->inspect_os ();
if (@roots == 0) {
die "$0: no operating system found in disk image\n"
}
my $root = $roots[0];
if ($g->inspect_get_type ($root) ne "windows") {
die "$0: disk image is not Windows (type = ", $g->inspect_get_type ($root),
")\n"
}
# Mount it up.
my %mps = $g->inspect_get_mountpoints ($root);
my @mps = sort { length $a <=> length $b } (keys %mps);
for my $mp (@mps) {
eval { $g->mount_ro ($mps{$mp}, $mp) };
if ($@) {
print "$@ (ignored)\n"
}
}
# Create an output directory.
my $output = tempdir (CLEANUP => 0);
print "writing icons to $output\n";
chdir $output or die "chdir: $output: $!";
# Get a list of all files.
my @files = $g->find ("/");
@files = map { "/$_" } @files;
print "writing list of files to $output/files\n";
open FILES, ">files" or die "open: files: $!";
print FILES join("\n", @files) or die "write: files: $!";
close FILES or die "close: files: $!";
# Find all *.exe files. (XXX Can other file types contain resources?)
my @exe_files = grep { $_ =~ /\.exe$/i && $g->is_file ($_) } @files;
foreach (@exe_files) {
# Download each *.exe file.
my $basename = $_;
$basename =~ s{.*/}{};
$g->download ($_, $basename);
# Extract any icon (2) or group-icon (14) resources it may contain.
system ("wrestool", "-x", "--type=2", "-o", "./", $basename);
system ("wrestool", "-x", "--type=14", "-o", "./", $basename);
unlink $basename;
}
# Find and download all other image files.
foreach (@files) {
my $basename = $_;
$basename =~ s{.*/}{};
if ($g->is_file ($_) &&
$basename =~ /\.(png|git|jpeg|jpg|bmp|ico)$/i) {
$g->download ($_, $basename);
}
}
$g->close;