home *** CD-ROM | disk | FTP | other *** search
Text File | 2005-07-05 | 20.1 KB | 1,188 lines |
- #!/usr/bin/perl
-
- #/*
- #* 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.
- #*
- #*/
-
-
- use strict;
- use Fcntl ':mode';
-
- my @sections;
- my %strings;
- my %version;
- my $driver_name;
- my $confdir = "/etc/ndiswrapper";
- my $hotplug_conf = "modules.ndiswrapper";
- my $instdir;
- my %fuzzlist;
- my $bustype;
-
- #Blacklist of files not to install.
- my @copy_blacklist;
-
- #Fixup list for parameters.
- my %param_fixlist = ("EnableRadio|0" => "EnableRadio|1",
- "IBSSGMode|0" => "IBSSGMode|2",
- "PrivacyMode|0" => "PrivacyMode|2",
- "AdhocGMode|1" => "AdhocGMode|0");
-
- if(@ARGV < 1)
- {
- usage();
- exit();
- }
-
- my $res;
- if($ARGV[0] eq "-i" and @ARGV == 2)
- {
- $res = install($ARGV[1]);
- }
- elsif($ARGV[0] eq "-d" and @ARGV == 3)
- {
- $res = devid_driver($ARGV[1], $ARGV[2]);
- }
- elsif($ARGV[0] eq "-e" and @ARGV == 2)
- {
- $res = remove($ARGV[1]);
- }
- elsif($ARGV[0] eq "-l" and @ARGV == 1)
- {
- $res = list();
- }
- elsif($ARGV[0] eq "-m" and @ARGV == 1)
- {
- $res = modconf();
- }
- elsif($ARGV[0] eq "-hotplug" and @ARGV == 1)
- {
- $res = hotplug_conf();
- }
- else
- {
- usage();
- exit();
- }
-
- exit $res;
-
- sub usage
- {
- print "Usage: ndiswrapper OPTION\n".
- "\n".
- "Manage ndis drivers for ndiswrapper.\n".
- "-i inffile Install driver described by 'inffile'\n".
- "-d devid driver Use installed 'driver' for 'devid'\n".
- "-e driver Remove 'driver'\n".
- "-l List installed drivers\n".
- "-m Write configuration for modprobe\n".
- "-hotplug (Re)Generate hotplug information\n".
- "\n\nwhere 'devid' is either PCIID or USBID of the form ".
- "XXXX:XXXX\n";
-
- }
-
-
- sub install
- {
- my $inf = shift;
- $driver_name = lc($inf);
- $driver_name =~ s/\.inf//;
- $driver_name = `basename $driver_name`;
- $instdir = `dirname $inf`;
- chomp($instdir);
- chomp($driver_name);
-
- if(isInstalled($driver_name))
- {
- print "$driver_name is already installed. Use -e to remove it\n";
- return -1;
- }
-
- if(!opendir(DH, $confdir))
- {
- mkdir($confdir);
- }
- else
- {
- close(DH);
- }
-
- print "Installing $driver_name\n";
- if(!mkdir("$confdir/$driver_name"))
- {
- print "Unable to create directory $confdir/$driver_name. Make sure you are running as root\n";
- return -1;
- }
-
- loadinf($inf);
- initStrings();
- parseVersion();
- `cp -u $inf $confdir/$driver_name/$driver_name.inf`;
- processPCIFuzz();
- }
-
-
-
- sub isInstalled
- {
- my $installed;
- my $name = shift;
- my $mode = (stat("$confdir"))[2];
- if (!S_ISDIR($mode)) {
- return 0;
- }
- open(LS, "ls -1 $confdir|");
- while(my $f = <LS>)
- {
- chomp($f);
- $mode = (stat("$confdir/$f"))[2];
- if(S_ISDIR($mode) and $name eq $f)
- {
- $installed = 1;
- }
-
- }
- close(LS);
- return $installed;
- }
-
-
- sub remove
- {
- my $name = shift;
- if(!isInstalled($name))
- {
- print "Driver $name is not installed. Use -l to list installed drivers\n";
- return;
- }
- `rm -rf $confdir/$name`;
- }
-
- sub devid_driver
- {
- my $devid = shift;
- my $driver = shift;
- my $done = 0;
-
- $devid = uc($devid);
- if (!($devid =~ /[0-9A-Z]{4}:[0-9A-Z]{4}/))
- {
- print "'$devid' is not a valid device ID\n";
- return;
- }
- open(LS, "ls -1 $confdir/$driver/ |");
- while(my $f = <LS>)
- {
- chomp($f);
- if ($f =~ /\.([05]).conf$/)
- {
- `ln -s $f $confdir/$driver/$devid.$1.conf`;
- print "Driver '$driver' is used for '$devid'\n";
- $done = 1;
- last;
- }
- }
- close(LS);
- if ($done == 0)
- {
- print "Driver '$driver' is not installed properly!\n";
- }
- return;
- }
-
- sub hotplug_conf
- {
- my $vendor;
- my $device;
- my $subvendor;
- my $subdevice;
- if(!open(CONF, ">$confdir/$hotplug_conf")) {
- print "Unable to create file hotplug modules configuration file";
- return -1;
- }
- printf CONF "# pci module vendor device subvendor subdevice class class_mask driver_data";
-
- open(LS, "ls -1 $confdir|");
- while(my $driver = <LS>) {
- chomp($driver);
- my $mode = (stat("$confdir/$driver"))[2];
- if(S_ISDIR($mode)) {
- open(LS2, "ls -1 $confdir/$driver/ |");
- while (my $file = <LS2>) {
- chomp ($file);
- if ($file =~ s/.conf//) {
- $file = lc($file);
- if($file =~ /(.{4}):(.{4}):(.{4}):(.{4})/) {
- $vendor = "0x0000$1";
- $device = "0x0000$2";
- $subvendor = "0x0000$3";
- $subdevice = "0x0000$4";
- }
- elsif($file =~ /(.{4}):(.{4})/) {
- $vendor = "0x0000$1";
- $device = "0x0000$2";
- $subvendor = "0xffffffff";
- $subdevice = "0xffffffff";
- }
- printf CONF "ndiswrapper $vendor $device $subvendor $subdevice 0x00000000 0x00000000 0x0\n";
- }
- }
- close(LS2);
- }
- }
-
- close(CONF);
- close(LS);
- return 0;
- }
-
- sub list
- {
- my $s;
-
- my $cards = getPresentCards();
-
- if(!$cards)
- {
- print "WARNING: Cannot locate lspci and lsusb. Unable to see if hardware is present.\n";
- }
-
- my $mode = (stat("$confdir"))[2];
- if (!S_ISDIR($mode)) {
- print "No drivers installed\n$s";
- return;
- }
- open(LS, "ls -1 $confdir|");
- while(my $f = <LS>)
- {
- chomp($f);
- my $mode = (stat("$confdir/$f"))[2];
- if(S_ISDIR($mode))
- {
- $s .= "$f\t".installStatus($cards, $f)."\n";
- }
- }
- if($s)
- {
- print "Installed ndis drivers:\n$s";
- }
- else
- {
- print "No drivers installed\n$s";
- }
- close(LS);
- }
-
- sub modconf
- {
- my $alias = 0;
- my $err = 0;
-
- my @modprobe = ("/sbin/modprobe", "/usr/sbin/modprobe", "modprobe");
- my $ok = 0;
- for(my $i = 0; $i < @modprobe; $i++)
- {
- if(open(MODPROBE, "$modprobe[$i] -c|"))
- {
- $ok = 1;
- $i = @modprobe;
- }
- }
- if(!$ok)
- {
- return -1;
- }
-
- while(my $line = <MODPROBE>)
- {
- if($line =~ /^alias\s.+\sndiswrapper/)
- {
- print "modprobe config already contains alias directive\n\n";
- $alias = 1;
- }
- elsif($line =~ /^install\s.*ndiswrapper/)
- {
- print "You should not need an install directive in you modprobe config file.\n";
- modconf_err($line);
- $err = 1;
- }
- elsif($line =~ /^post-install\s+ndiswrapper/)
- {
- print "You should not need a post-install directive in you modprobe config file.\n";
- modconf_err($line);
- $err = 1;
- }
- }
- close(MODPROBE);
-
- if($alias)
- {
- return;
- }
-
-
- my $v = `uname -r`;
-
-
- $v =~ /(\d+)\.(\d+)\.(\d+)/;
- my $major = $1;
- my $minor = $2;
- my $rev = $3;
- my $modconf;
- if($minor > 4)
- {
- if(-d "/etc/modprobe.d")
- {
- $modconf = "/etc/modprobe.d/ndiswrapper"
- }
- else
- {
- $modconf = "/etc/modprobe.conf"
- }
- }
- else
- {
- if(-d "/etc/modutils")
- {
- $modconf = "/etc/modutils/ndiswrapper";
- }
- else
- {
- $modconf = "/etc/modules.conf";
- }
- }
-
-
- print "Adding \"alias wlan0 ndiswrapper\" to $modconf\n";
- system("echo \"alias wlan0 ndiswrapper\" >>$modconf");
-
- if(-x "/sbin/update-modules")
- {
- system("/sbin/update-modules");
- }
- }
-
- sub modconf_err
- {
- my $line = shift;
- print "Please remove the line saying:\n\n";
- print "$line\n";
- print "unless you are 100% sure of what you are doing.\n";
- }
-
-
- sub getPresentCards
- {
- #01:00.0 Class 0300: 1002:4c66 (rev 01)
- # Subsystem: 1043:1732
- my @cards;
-
- my @lspci = ("/sbin/lspci", "/usr/sbin/lspci", "lspci");
- for(my $i = 0; $i < @lspci; $i++)
- {
- if(open(LSPCI, "$lspci[$i] -vn|"))
- {
- my $card;
- while(my $line = <LSPCI>)
- {
- if($line =~ /^[0-9]+.*:\s(.{4}):(.{4}).*/)
- {
- my %c;
- $card = \%c;
- $card->{vendor} = $1;
- $card->{device} = $2;
- }
- if($line =~ /.+Subsystem:\s*(.{4}):(.{4}).*/)
- {
- $card->{subvendor} = $1;
- $card->{subdevice} = $2;
-
- push(@cards, $card);
- }
-
- }
- last;
- }
- }
-
- my @lsusb = ("/sbin/lsusb", "/usr/sbin/lsusb", "lsusb");
- for(my $i = 0; $i < @lsusb; $i++)
- {
- if(open(LSUSB, "$lsusb[$i] |"))
- {
- my $card;
- while(my $line = <LSUSB>)
- {
- if($line =~ /.*: ID\s(.{4}):(.{4}).*/)
- {
- my %c;
- $card = \%c;
- $card->{vendor} = $1;
- $card->{device} = $2;
-
- push(@cards, $card);
- }
- }
- last;
- }
- }
-
- return \@cards;
- }
-
-
- sub installStatus
- {
- my $cards = shift;
- my $driver = shift;
-
- my $sys = 0;
- my $conf = 0;
- my $inf = 0;
-
- if(!$cards)
- {
- return;
- }
-
- open(LS2, "ls -1 $confdir/$driver|");
-
- while(my $device = <LS2>)
- {
- chomp($device);
- my $d = $device;
-
- $sys = 1 if $d =~ /\.sys$/;
- $inf = 1 if $d =~ /\.inf$/;
- $conf = 1 if $conf eq 0 and $d =~ /\.conf$/;
- $d =~ s/.conf//;
- if($d =~ /(.{4}):(.{4}):(.{4}):(.{4})/)
- {
- for(my $i = 0; $$cards[$i]; $i++)
- {
- if($$cards[$i]->{vendor} == $1 and
- $$cards[$i]->{device} == $2 and
- $$cards[$i]->{subvendor} == $3 and
- $$cards[$i]->{subdevice} == $4)
- {
- $conf = 3;
- last;
- }
- }
-
- }
- elsif($d =~ /(.{4}):(.{4})/)
- {
- for(my $i = 0; $$cards[$i]; $i++)
- {
- if($$cards[$i]->{vendor} == $1 and
- $$cards[$i]->{device} == $2)
- {
- my $mode = (lstat("$confdir/$driver/$device"))[2];
- if(S_ISLNK($mode))
- {
- $conf = 2;
- }
- else
- {
- $conf = 3;
- }
- last;
- }
- }
- }
- }
- close(LS2);
-
- my $ret;
- if ($sys eq 0 || $inf eq 0 || $conf eq 0)
- {
- $ret = "invalid driver!";
- }
- else
- {
- $ret = $ret . "driver present " if $conf eq 1;
- $ret = $ret . "driver present, hardware present " if
- $conf eq 2;
- $ret = $ret . "driver present, hardware present " if
- $conf eq 3;
- }
- return $ret;
- }
-
-
-
- #
- # Create symlink for PCI general device if not existing
- #
- sub processPCIFuzz
- {
- my @devs = keys(%fuzzlist);
- for(my $i = 0; $i < @devs; $i++)
- {
- my $dev = $devs[$i];
- if($dev ne $fuzzlist{$dev})
- {
- `ln -s $confdir/$driver_name/$fuzzlist{$dev}.$bustype.conf $confdir/$driver_name/$dev.$bustype.conf`;
- }
- }
- }
-
- #
- # Collect a list of supported PCI-Id's so we can add fuzzy entries if needed.
- #
- sub addPCIFuzzEntry
- {
- my $vendor = shift;
- my $device = shift;
- my $subvendor = shift;
- my $subdevice = shift;
-
- my $s = "$vendor:$device";
-
- if(!$subvendor or !$fuzzlist{$s})
- {
- my $s2 = $s;
- if($subvendor)
- {
- $s2 .= ":$subvendor:$subdevice";
- }
- $fuzzlist{$s} = $s2;
- }
- }
-
-
- sub parseVersion
- {
- my $s = getSection("version");
- if(!$s)
- {
- return;
- }
- my @lines = split("\n", $s->{data});
-
- for(my $i = 0; $i < @lines; $i++)
- {
- (my $key, my $val) = getKeyVal($lines[$i]);
- if($key eq "Provider")
- {
- $val =~ s/"(.+)"/$1/;
- $version{$key} = $val;
- }
- if($key eq "DriverVer")
- {
- $val =~ s/"(.+)"/$1/;
- $version{$key} = $val;
- }
- }
- parseManu();
- }
-
- #
- # Parse the [Manufacturer] section.
- #
- sub parseManu
- {
- #Examples:
- #Vendor
- #Vendor,ME,NT,NT.5.1
- #Vendor.NTx86
-
- my $manu = getSection("manufacturer");
- if(!$manu)
- {
- return -1;
- }
-
- my @lines = split("\n", $manu->{data});
- for(my $i = 0; $i < @lines; $i++)
- {
- my $line = remComment($lines[$i]);
- (my $key, my $val) = getKeyVal($line, "=");
-
- if ($key eq $version{"Provider"})
- {
- $strings{$key} = trim($val);
- }
-
- if($val)
- {
- my $section;
- my @flavours = split(",", $val);
- my $flavour = "";
- if(@flavours == 1)
- {
- #Vendor
- $section = $val;
- }
- else
- {
- #Vendor,flavour1, flavour2 etc;
- for(my $i = 1; $i < @flavours; $i++)
- {
- my $flav = trim($flavours[$i]);
- $flav =~ s/\s*(\S+)\s*/$1/;
- if(uc($flav) eq "NT.5.1")
- {
- #This is the best (XP)
- $section = $flavours[0] . "." . $flav;
- $flavour = $flav;
- }
- elsif(substr(uc($flav),0,2) eq "NT" and $section eq "")
- {
- #This is the second best (win2k)
- $section = $flavours[0] . "." . $flav;
- $flavour = $flav;
- }
- }
-
- }
- my $res = parseVendor($flavour, $section);
- if(!$res)
- {
- return $res;
- }
- }
- }
- }
-
- #
- # Parse a vendor section. This section contains the device-ids. Each poiting to a section with config info.
- #
- sub parseVendor
- {
- my $flavour = shift;
- my $vendor_name = shift;
- my $vend = getSection($vendor_name);
-
- if(!$vend)
- {
- print "no vendor\n";
- return -1;
- }
-
- my @lines = split("\n", $vend->{data});
- for(my $i = 0; $i < @lines; $i++)
- {
- my $line = remComment($lines[$i]);
- (my $name, my $val) = getKeyVal($line, "=");
-
- if($val)
- {
- (my $section, my $id) = split(",", $val);
- $section = trim($section);
- $id = trim($id);
- ($bustype, my $vendor, my $device, my $subvendor, my $subdevice) = parseID($id);
- if($vendor)
- {
- parseDevice($flavour, $section, $vendor, $device, $subvendor, $subdevice);
- }
- }
- }
- }
-
-
- #
- # This section contains pointers to registry sections and copyfiles sections.
- #
- sub parseDevice
- {
- my $flavour = shift;
- my $device_sect = shift;
- my $device = shift;
- my $vendor = shift;
- my $subvendor = shift;
- my $subdevice = shift;
-
- my $dev = getSection("$device_sect.$flavour");
- if(!$dev)
- {
- $dev = getSection("$device_sect.NT");
- }
- if(!$dev)
- {
- $dev = getSection("$device_sect.NTx86");
- }
- if(!$dev)
- {
- $dev = getSection("$device_sect");
- }
-
- if(!$dev)
- {
- print "no dev $device_sect $flavour\n";
- return -1;
- }
-
- # print "$device:$vendor:$subvendor:$subdevice $flavour\n";
-
- my $copyfiles;
- my $addreg;
- my @lines = split("\n", $dev->{data});
-
- for(my $i = 0; $i < @lines; $i++)
- {
- my $line = remComment($lines[$i]);
- (my $key, my $val) = getKeyVal($line, "=");
- if($key)
- {
- if(lc($key) eq "addreg")
- {
- $addreg = $val;
- }
- if(lc($key) eq "copyfiles")
- {
- $copyfiles = $val;
- }
- }
- }
-
- my $filename = "$device:$vendor";
- if($subvendor)
- {
- $filename .= ":$subvendor:$subdevice"
- }
-
- $filename .= ".$bustype.conf";
-
- if($bustype == 5)
- {
- addPCIFuzzEntry($device, $vendor, $subvendor, $subdevice);
- }
-
- if(!open(CONF, ">$confdir/$driver_name/$filename"))
- {
- print "Unable to create file $filename";
- return -1;
- }
-
- my $ver=$version{"DriverVer"};
- my $provider=$version{"Provider"};
- my $providerstring = stripquotes(substStr(trim($provider)));
-
- printf CONF "NdisVersion|0x50001\n";
- printf CONF "Environment|1\n";
- printf CONF "BusType|$bustype\n";
- printf CONF "mac_address|XX:XX:XX:XX:XX:XX\n";
- printf CONF "ndis_version|$providerstring,$ver\n\n";
- close(CONF);
-
- if(!open(CONF, "|sort|uniq >>$confdir/$driver_name/$filename"))
- {
- print "Unable to create file $filename";
- return -1;
- }
-
- my @addregs = split(",", $addreg);
- for(my $i = 0; $i < @addregs; $i++)
- {
- my $reg = trim($addregs[$i]);
- addReg($reg);
- }
-
- my @copyfiles = split(",", $copyfiles);
- for(my $i = 0; $i < @copyfiles; $i++)
- {
- my $file = trim($copyfiles[$i]);
- copyfiles($file);
- }
-
- close(CONF);
- }
-
-
- #
- # Process a copyfiles section.
- #
- sub copyfiles
- {
- my $copy_name = shift;
- my $copy = getSection($copy_name);
- if(!$copy)
- {
- printf "Parse error in inf. Unable to find section $copy_name\n";
- return -1;
- }
-
- my @lines = split("\n", $copy->{data});
-
- for(my $i = 0; $i < @lines; $i++)
- {
- my $line = $lines[$i];
- $line = trim($line);
-
- last if (!$line);
- last if ($line =~ /^\[/);
- my @files = split(",", $line);
- for (my $j = 0; $j < @files; $j++)
- {
- my $file = $files[$j];
- $file =~ s/^;//;
- $file = trim(remComment($file));
- $file =~ s/,+.*//;
- $file = trim($file);
- my $nocopy = 0;
- for(my $k = 0; $k < @copy_blacklist; $k++)
- {
- if($copy_blacklist[$k] eq lc($file))
- {
- $nocopy = 1;
- }
- }
-
- my $dir = finddir($file);
- if($dir)
- {
- $dir = findfile("", $dir);
- }
-
- my $realname = findfile($dir, $file);
-
- if($realname)
- {
- my $newname = lc($realname);
- if($dir)
- {
- $realname = "$dir/$realname";
- }
- if(!$nocopy)
- {
- `cp -u $instdir/$realname $confdir/$driver_name/$newname`;
- `chmod 644 $confdir/$driver_name/$newname`;
- }
-
- }
- }
- }
- }
-
- sub finddir
- {
- my $filename = shift;
- my $sourcedisksfiles = getSection("sourcedisksfiles");
- if(!$sourcedisksfiles)
- {
- return "";
- }
- my @lines = split("\n", $sourcedisksfiles->{data});
- for(my $i = 0; $i < @lines; $i++)
- {
- my $line = trim(remComment($lines[$i]));
- $line =~ /(.+)=.+,+(.*)/;
- my $file = trim($1);
- my $dir = trim($2);
- if($file and $dir and lc($filename) eq lc($file))
- {
- return $dir;
- }
- }
- return "";
- }
-
- #
- # Find a file in a case-insensitive way.
- #
- sub findfile
- {
- my $dir = shift;
- my $file = shift;
-
- if(!opendir(DIR, "$instdir/$dir"))
- {
- print "Unable to open $instdir\n";
- return "";
- }
-
- my @allfiles = readdir(DIR);
- for(my $i = 0; $i < @allfiles; $i++)
- {
- if(lc($allfiles[$i]) eq lc($file))
- {
- closedir(DIR);
- return $allfiles[$i];
- }
- }
- closedir(DIR);
- return "";
- }
-
-
- #
- # This section contains pointers to the section with the parameters to be
- # added to the registry.
- #
- sub addReg
- {
- my $reg_name = shift;
- my $reg = getSection($reg_name);
- if(!$reg)
- {
- printf "Parse error in inf. Unable to find section $reg_name\n";
- return -1;
- }
-
- my $param;
- my $type;
- my $val;
- my $found;
- my $gotParam = 0;
-
- my @lines = split("\n", $reg->{data});
- for(my $i = 0; $i < @lines; $i++)
- {
- my $line = trim(remComment($lines[$i]));
- if($line)
- {
- $line =~ /([^,]*),([^,]*),([^,]*),([^,]*),(.*)/;
- my $hkr = trim($1);
- my $p1 = stripquotes(substStr(trim($2)));
- my $p2 = stripquotes(substStr(trim($3)));
- my $p3 = stripquotes(substStr(trim($4)));
- my $p4 = stripquotes(substStr(trim($5)));
-
- if($p1)
- {
- if($p1 =~ /ndi\\params\\(.+)/i)
- {
- $1 =~ /(.+)\\.*/;
-
- if($1 ne $param)
- {
- $found = 0;
- $param = $1;
- $type = "";
- $val = "";
- }
- if(lc($p2) eq "type")
- {
- $found++;
- $type = $p4;
- }
- elsif(lc($p2) eq "default")
- {
- $found++;
- $val = $p4;
- }
-
- if($found == 2)
- {
- $gotParam = 1;
- }
- }
- }
- else
- {
- #print "type 2: $reg_name '$p1', '$p2', '$p3', '$p4':'$line'\n";
- $param = $p2;
- $val = $p4;
- $gotParam = 1;
- }
-
-
- if($gotParam and $param ne "BusType" and $param ne "")
- {
- my $s = "$param|$val";
- if($param_fixlist{"$s"})
- {
- my $sOld = $s;
- $s = $param_fixlist{"$s"};
- print "Forcing parameter $sOld to $s\n";
- }
-
- print CONF "$s\n";
- $param = "";
- $gotParam = 0;
- }
- }
- }
- }
-
- sub substStr
- {
- my $s = shift;
- if($s =~ /^\%(.+)$\%/)
- {
- return getString($1);
- }
- return $s;
- }
-
-
- #
- # Parse a device-id line.
- #
- sub parseID
- {
- my $s = uc(shift);
- if($s =~ /PCI\\VEN_(\w+)&DEV_(\w+)&SUBSYS_(\w{4})(\S{4})/)
- {
- return (5, $1, $2, $4, $3);
- }
- elsif($s =~ /PCI\\VEN_(\w+)&DEV_(\w+)/)
- {
- return (5, $1, $2);
- }
- elsif($s =~ /USB\\VID_(\w+)&PID_(\w+)/)
- {
- return (0, $1, $2);
- }
- }
-
- #
- # remove whitsepace at front and end.
- #
- sub trim
- {
- my $s = shift;
- $s =~ s/^\s*//;
- $s =~ s/\s*$//;
- return $s;
- }
-
-
- sub stripquotes
- {
- my $s = shift;
- $s =~ s/"(.*)"/$1/;
- return $s;
- }
-
-
- sub getKeyVal
- {
- my $line = shift;
-
- $line = remComment($line);
- (my $key, my $val) = split("=", $line);
- if($line =~ /(.+)=(.+)/)
- {
- return (trim($1), trim($2));
- }
- }
-
-
- sub remComment
- {
- my $s = shift;
- $s=~ s/([^;]*);.*/$1/;
- return $s;
- }
-
- #
- # Initialize the string symbol table
- #
- sub initStrings
- {
- my $s = getSection("strings");
- if(!$s)
- {
- return;
- }
- my @lines = split("\n", $s->{data});
-
- for(my $i = 0; $i < @lines; $i++)
- {
- (my $key, my $val) = getKeyVal($lines[$i]);
- if($key)
- {
- $val =~ s/"(.+)"/$1/;
- $strings{$key} = $val;
- # print "$key=$val\n";
- }
- }
- }
-
-
- #
- # fetch a string from the symbol table
- #
- sub getString
- {
- my $s = shift;
- return $strings{$s};
- }
-
-
- #
- # Loacate a section.
- #
- sub getSection
- {
- my $needle = shift;
-
- for(my $i = 0; $i < @sections; $i++)
- {
- # print "Searching: '" . lc($sections[$i]->{name}) . "' == '" . lc($needle) . "'\n";
-
- if( lc($sections[$i]->{name}) eq lc($needle))
- {
- # print "found!\n\n";
- return $sections[$i];
- }
- }
- # print "not found!\n\n";
- return 0;
- }
-
-
- #
- # Load inf and split into different sections.
- #
- sub loadinf
- {
- my $filename = shift;
- my %def_section;
- my $section = \%def_section;
-
- if(!open(INF, $filename))
- {
- return -1;
- }
-
- my $i = 0;
- $section->{name} = "none";
- while(my $s = <INF>)
- {
- #Convert from unicode
- $s =~ s/\xff\xfe//;
- $s =~ s/\0//g;
-
- $s =~ s/\s*$//; #Remove trailing whitespace and \r
- $s .= "\n";
- if($s =~ /^\[(.+)\]\s*/)
- {
- $sections[$i++] = $section;
- my %new_section;
- $section = \%new_section;
- $section->{name} = $1;
- }
- else
- {
- $section->{data} .= $s;
- }
- }
-
- $sections[$i++] = $section;
- close(INF);
-
-
- # print "Sections:\n";
- # for(my $i = 0; $i < @sections; $i++)
- # {
- # print $sections[$i]->{name} . "\n";
- # }
- # print "\n";
- }
-
-
-