#Wrapper for unrar.dll in Perl.Interacts with dll using the Win32::API
+ module
#To do for next version : better error description instead of just 'dy
+ing'
use Win32::API;
use Cwd;
sub declare_win32_functions {
$RAROpenArchiveEx=new Win32::API('unrar.dll','RAROpenArchiveEx','P
+','N');
$RARCloseArchive=new Win32::API('unrar.dll','RARCloseArchive','N',
+'N');
$RAROpenArchive=new Win32::API('unrar.dll','RAROpenArchive','P','N
+');
$RARReadHeader=new Win32::API('unrar.dll','RARReadHeader','NP','N'
+);
$RARReadHeaderEx=new Win32::API('unrar.dll','RARReadHeaderEx','NP'
+,'N');
$RARProcessFile=new Win32::API('unrar.dll','RARProcessFile','NNPP'
+,'N');
$RARSetPassword=new Win32::API('unrar.dll','RARSetPassword','NP','
+N');
}
sub extract_headers {
my $file=@_[0];
my $CmtBuf = pack('x16384');
my $RAROpenArchiveDataEx=pack('ppLLPLLLLx32',$file,undef,2,0,$CmtB
+uf,16384,0,0,0);
my $RAROpenArchiveData=pack('pLLpLLL',$file,2,0,undef,0,0,0);
my $RARHeaderData=pack('x260x260LLLLLLLLLLpLL',0,0,0,0,0,0,0,0,0,0
+,0,undef,0,0);
my $handle = $RAROpenArchiveEx->Call($RAROpenArchiveDataEx)||die "
+RAROpenArchiveEx failed";
my ($arcname,undef,undef,undef,$CmtBuf1,undef,$CmtSize,$CmtState,$
+flagsEX)=unpack('ppLLP16384LLLLL',$RAROpenArchiveDataEx);
!$RARCloseArchive->Call($handle)||die "RARCloseArchive failed";
my $handle = $RAROpenArchive->Call($RAROpenArchiveData)||die "RARO
+penArchive failed";
$flagsEX & 128 || !$RARReadHeader->Call($handle,$RARHeaderData) |
+| die "RARCloseArchive failed";
my ($arcname,$filename,$flags,$packsize)=unpack('A260A260LL',$RARH
+eaderData);
$CmtBuf1=unpack('A'.$CmtSize,$CmtBuf1);
printf("\nComments :%s\n",$CmtBuf1) ;
printf("\nArchive %s\n",$arcname);
printf("\nVolume:\t\t%s",($flagsEX & 1) ? "yes":"no");
printf("\nComment:\t%s",($flagsEX & 2) ? "yes":"no");
printf("\nLocked:\t\t%s",($flagsEX & 4) ? "yes":"no");
printf("\nSolid:\t\t%s",($flagsEX & 8) ? "yes":"no");
printf("\nNew naming:\t%s",($flagsEX & 16) ? "yes":"no");
printf("\nAuthenticity:\t%s",($flagsEX & 32) ? "yes":"no");
printf("\nRecovery:\t%s",($flagsEX & 64) ? "yes":"no");
printf("\nEncr.headers:\t%s",($flagsEX & 128) ? "yes":"no");
printf("\nFirst volume:\t%s\n\n",($flagsEX & 256) ? "yes":"no or ol
+der than 3.0");
!$RARCloseArchive->Call($handle);
return ($flagsEX & 128,$flags & 4);
}
sub list_files_in_archive {
my $file =@_[0];
my ($blockencrypted,$locked) = extract_headers($file);
my $password;
my $RAROpenArchiveDataEx_for_extracting=pack('ppLLpLLLLx32',$file,unde
+f,2,0,undef,0,0,0,0);
my $handle = $RAROpenArchiveEx->Call($RAROpenArchiveDataEx_for_extract
+ing)||die "RAROpenArchiveEx failed";
my $RARHeaderData=pack('x260x260LLLLLLLLLLpLL',0,0,0,0,0,0,0,0,0,0,0,u
+ndef,0,0,0);
if ($blockencrypted){
print ("Encrypted headers,enter password: "),chomp ($password=<STD
+IN>);
if ($password) {
$RARSetPassword->Call($handle,$password);
}
else {
die "\nshould had entered password!!exiting....\n";
}
}
while (($RARReadHeader->Call($handle,$RARHeaderData))==0) {
my $processresult=$RARProcessFile->Call($ha
+ndle,0,undef,undef);
if ($processresult!=0) {
last;
}
else {
my @files=unpack('A260A260LLLLLLLLLLpLL',$RARH
+eaderData);
print "File\t\t\t\t\tSize\n";
print "-----------------------
+--------------------\n";
print "$files[0]\\$files[1]\t\
+t$files[4]\n\n";
}
}
!$RARCloseArchive->Call($handle)||die "$RARCloseArchive failed";
}
sub process_file {
my $file=@_[0];
my ($blockencrypted,$locked) = extract_headers($file);
my $errorstatus;
my $password;
my $RAROpenArchiveDataEx_for_extracting=pack('ppLLpLLLLx32',$file,unde
+f,1,0,undef,0,0,0,0);
my $RARHeaderData=pack('x260x260LLLLLLLLLLpLL',0,0,0,0,0,0,0,0,0,0,0,u
+ndef,0,0);
my $handle = $RAROpenArchiveEx->Call($RAROpenArchiveDataEx_for_extract
+ing)||die "RAROpenArchiveEx failed";
if ($blockencrypted || $locked){
print ("Enter password: "),chomp ($password=<STDIN>);
if ($password) {
$RARSetPassword->Call($handle,$password);
}
else {
die "\nshould had entered password!!exiting....\n";
}
}
while (($RARReadHeader->Call($handle,$RARHeaderData))==0) {
my $processresult=$RARProcessFile->Call($h
+andle,2,undef,undef);
if ($processresult!=0) {
$errorstatus=$processresult;
last;
}
}
print "#Error# : $errorstatus" if $errorstatus;
!$RARCloseArchive->Call($handle)||die "RRARCloseArchive failed";
}
my $file;
if ($ARGV[1]) {
$file=$ARGV[1]; }
else {
print ("No filename!") && exit;
}
declare_win32_functions();
if ($ARGV[0] eq "L") {
list_files_in_archive($file);
}
elsif ($ARGV[0] eq "X") {
process_file($file);
}
else {
print "Enter mode L or X\n";
}
|