Este script é uma atualização do script dpfp-firmware-cutter, funcionando corretamente agora.
#!/usr/bin/perl
# Tool to cut the Digital Persona Fingerprint Sensor firmware from a driver
# distribution.
# Version 0.1
#
# Copyright (C) 2005 Daniel Drake <dsd@gentoo.org>
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
use Digest::MD5;
use Getopt::Long;
use vars qw/ %opt /;
my $driver_path = $ARGV[0];
my $dll_path;
my $buffer;
my $md5;
my $cmd;
my $deletedir;
my $from_web = 0;
my $device_type;
my $driver_path;
GetOptions('from-web' => \$from_web, 'device=s' => \$device_type, 'path=s' => \$driver_path);
if (($driver_path eq '' && $from_web == 0) || $device_type eq '') {
print <<END;
dpfp-firmware-cutter: Extract the Digital Persona Fingerprint Reader firmware
from a driver distribution.
USAGE: dpfp-firmware-cutter -d <devicetype> -p <driverpath>
OR: dpfp-firmware-cutter -d <devicetype> --from-web
AVAILABLE DEVICE TYPES: uru4000, uru4000b
---> Microsoft devices require the uru4000b firmware. <---
For 'uru4000b' devices, driverpath can be either:
1. Path to the driver installer (DP_PM_10Eng.exe) available from microsoft
or 2. Path to where DP_PM_10Eng.exe has been extracted (e.g. by cabextract(1))
or 3. Path where driver CD has been mounted
For 'uru4000' devices, driverpath can be either:
1. Path to the driver installer (dpdrv224-85.exe) available from
digitalpersona.com
or 2. Path to where dpdrv224-85.exe has been extracted (e.g. by cabextract(1))
Instead of specifying a driver path, you can alternatively use the "--from-web"
option to download the firmware from the internet. The driver is downloaded
directly from the vendor, and since the URL may change, this mechanism is not
guaranteed to work.
This program extracts the firmware into a file which you
should place in your hotplug firmware directory (usually /lib/firmware). The
resultant filename is printed upon completion.
END
exit;
}
if ($device_type ne 'uru4000b' && $device_type ne 'uru4000') {
print "Unrecognised device type: $device_type\n";
print "Available types: uru4000b, uru4000\n";
exit;
}
if ($device_type eq 'uru4000b') {
$outfile = 'dpfp-uru4000b-001';
$seek = 0xE58C;
$readlen = 1268;
$reallen = 1904;
$dllmd5 = "2d590f24820b54487612e72163d349d3";
if ($from_web) {
#$cmd = 'wget "
http://download.microsoft.com/download/3/9/e/39e93743-71c9-452f-b69c-90b227a57f1b/DP_PM_10Eng.exe"';
print "Downloading file...\n";
#$ret = `$cmd`;
print "Download complete.\n";
$driver_path = './DP_PM_10Eng.exe';
}
if (substr($driver_path, -15) eq "DP_PM_10Eng.exe") {
print "Extracting DP_PM_10Eng.exe...\n";
$cmd = 'cabextract -d __output__ "'. $driver_path . '"';
$ret = `$cmd`;
print "Extract done\n";
unlink($driver_path) if $from_web;
$driver_path = "./__output__";
$deletedir = 1;
}
if (-e $driver_path . "/dpD0Bx01.dll") {
$dll_path = $driver_path . "/dpD0Bx01.dll";
} elsif (-e $driver_path . "/Driver/dpD0Bx01.dll") {
$dll_path = $driver_path . "/Driver/dpD0Bx01.dll";
} else {
print "ERROR: Unable to find dpD0Bx01.dll\n";
print "Maybe this is an unsupported driver distribution?\n";
exit;
}
}
if ($device_type eq 'uru4000') {
$outfile = 'dpfp-uru4000-002';
$dllmd5 = "79fd7b411fe3e09f85e9eaaa2fcb4de2";
$seek = 0xFAAC;
$readlen = 1210;
$reallen = 1536;
$encryption_byte_offset = 0x3f7;
if ($from_web) {
$cmd = 'wget "
http://www.digitalpersona.com/downloads/support-downloads/dpdrv224-85.exe"';
# $cmd = 'wget "
http://www.digitalpersona.com/support/downloads/supportdownloads/dpdrv224-85.exe"';
print "Downloading file...\n";
$ret = `$cmd`;
print "Download complete.\n";
$driver_path = './dpdrv224-85.exe';
}
if (substr($driver_path, -15) eq "dpdrv224-85.exe") {
print "Extracting drdrv224-85.exe...\n";
$cmd = 'cabextract -d __output__ "'. $driver_path . '"';
$ret = `$cmd`;
print "Extract done\n";
unlink($driver_path) if $from_web;
$driver_path = "./__output__";
$deletedir = 1;
}
if (-e $driver_path . "/dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0") {
$dll_path = $driver_path . "/dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0";
} else {
print "ERROR: Unable to find dpD00701.dll_XP.C9795C90_5A7C_44A3_8DBA_7E867BAFE6D0\n";
print "Maybe this is an unsupported driver distribution?\n";
exit;
}
}
print "Found firmware container at $dll_path \n";
open(DLL, $dll_path) or die "Can't open !!";
open(OUT, '>'.$outfile) or die "Can't open outfile: $outfile";
binmode(DLL);
# Check md5sum
$md5 = Digest::MD5->new->addfile(*DLL)->hexdigest;
if ($md5 != $dllmd5) {
print "ERROR: Unrecognised md5sum.";
print "This probably means that you are using an unsupported driver version.\n";
exit;
}
# Grab the firmware
seek(DLL, $seek, 0);
$ret = read(DLL, $buffer, $readlen);
if ($ret != $readlen) {
print "File I/O error, could not read all $readlen bytes\n";
exit;
}
if ($encryption_byte_offset != 0) {
print "Disabling encryption bit\n";
$cur = substr($buffer, $encryption_byte_offset, 1);
$val = ord($cur);
$val = $val & 0xEF;
substr($buffer, $encryption_byte_offset, 1) = chr($val);
}
print OUT $buffer;
# Pad to required bytes
for ($i = 0; $i < ($reallen - $readlen); $i++) {
print OUT "{COMENTARIO}";
}
close OUT;
close DLL;
if ($deletedir) {
$cmd = 'rm -rf __output__';
$ret = `$cmd`;
}
print "\nFirmware written to ./$outfile\n";
print "You should place this file in your hotplug firmware directory\n";
print "(usually /lib/firmware)\n";