#!/usr/bin/perl sub sanehead { my $blocktype = shift; my $offset = shift; my $dlen = shift; my $count = shift; if($blocktype > 0x300) { return 0 }; if($offset > 0x10000) { return 0 }; if($dlen > 20000) { return 0} return 1; } if($#ARGV < 0) { print "EM8300 microcode extractor\n"; print "Written by Henrik Johansson 2000-04-10\n\n"; print "Usage:\n\tmicrocode_extract.pl FILE [NAMEBASE]\n\n"; print "FILE refers to the VXD file which comes with the Windows drivers and is found in the Windows\\System folder. The file is usually called rmquasar.vxd (H+) or enc2dev.vxd (Creative Labs). \n\n"; print "NAMEBASE is the prefix of the saved microcode files.\n\n"; } open(VXD,"<$ARGV[0]"); undef $/; $vxd = ; close(VXD); $namebase=$ARGV[1]; if(length($prefix) == 0) { $namebase="microcode" }; $ucnt = 0; for($i=0; $i < length($vxd); $i++) { if(unpack('S',substr($vxd,$i,2)) == 2) { $savei = $i; $ok = 1; $blocktype = -1; $count=0; while($blocktype != 0) { ($blocktype, $offset, $dlen) = unpack('SII',substr($vxd,$i,11)); if($blocktype == 0) { last; } if(($blocktype == 2) && (($lastblocktype&0xf00) == 0x200)) { $i--; last; } $dlen *= 2; if(!sanehead($blocktype,$offset,$dlen,$count)) { $ok = 0; last; } $i+=10+$dlen; $lastblocktype = $blocktype; $count++; } $lastblocktype = -1; if($ok && $count > 20) { $ucodelen = $i - $savei; $filename = "$namebase$ucnt.bin"; open UCODE,">$filename" or die("Can't open microcode file"); print UCODE substr($vxd,$savei,$ucodelen); print pack('SII',(0,0,0)); close UCODE; print "Found microcode block (length=$ucodelen), "; print "saving to $filename \n"; $ucnt++; } else { $i = $savei; } } }