Contributor: GEORGE ROBERTS
{Let me guess, you are trying to list out the files in the RAR archive,
correct? Here's how I do it (this is rough, because I am cleaning it up
from my source because mine handles it a little differently): }
CONST
 errmsg:array[0..5] of string[49] = (
 'Unable to access specified file',
 'Unexpected end of file',
 'Unexpected read error',
 'Invalid header ID encountered',
 'Can''t find next entry in archive',
 'File is not in RAR archive format');
 method:array[0..21] of string[9] = (
 'Directory', {* Directory marker *}
 'Unknown! ', {* Unknown compression type *}
 'Stored ', {* No compression *}
 'Packed ', {* Repeat-byte compression *}
 'Squeezed ', {* Huffman with repeat-byte compression *}
 'crunched ', {* Obsolete LZW compression *}
 'Crunched ', {* LZW 9-12 bit with repeat-byte compression *}
 'Squashed ', {* LZW 9-13 bit compression *}
 'Crushed ', {* LZW 2-13 bit compression *}
 'Shrunk ', {* LZW 9-13 bit compression *}
 'Reduced 1', {* Probabilistic factor 1 compression *}
 'Reduced 2', {* Probabilistic factor 2 compression *}
 'Reduced 3', {* Probabilistic factor 3 compression *}
 'Reduced 4', {* Probabilistic factor 4 compression *}
 'Frozen ', {* Modified LZW/Huffman compression *}
 'Imploded ', {* Shannon-Fano tree compression *}
 'Imploded ', {* Shannon-Fano tree compression *}
 'Fastest ',
 'Fast ',
 'Normal ',
 'Good Comp',
 'Best Comp');
TYPE
 outrec=record {* output information structure *}
 filename:string[255]; {* output filename *}
 date:integer; {* output date *}
 time:integer; {* output time *}
 typ:integer; {* output storage type *}
 csize:longint; {* output compressed size *}
 usize:longint; {* output uncompressed size *}
 end;
 rarheaderrec=record
 b:array[1..7] of byte;
 end;
 rarfilerec=record
 packsize:longint;
 unpacksize:longint;
 HostOS:byte; { 0 dos 1 os/2 }
 FileCRC:longint;
 mod_time:integer;
 mod_date:integer;
 rarver:byte;
 method:byte;
 fnamesize:integer;
 attr:longint;
 end;
VAR out:outrec;
 aborted:boolean;
procedure emsg(message:string);
begin
 {* emsg - Display error message
 *}
 writeln;
 writeln('* '+message);
 aborted:=TRUE;
end;
function getbyte(var fp:file):char;
var buf:array[0..0] of char;
 numread:word;
 c:char;
begin
 if (not aborted) then begin
 blockread(fp,c,1,numread);
 if numread=0 then begin
 close(fp);
 emsg(errmsg[1]);
 end;
 getbyte:=c;
 end;
end;
procedure Process_RAR(var fp:file);
var rar:rarfilerec;
 rh:rarheaderrec;
 rha:array[1..100] of byte;
 buf:array[0..25] of byte;
 h:integer;
 ad:longint;
 numread:word;
 i,stat:integer;
 add2:word;
 c:char;
 add:boolean;
begin
 while (not aborted) do begin
 {* set up infinite loop (exit is within loop) *}
 add:=FALSE;
 blockread(fp,rh.b[1],5,numread);
 if numread5 then emsg(errmsg[2]);
 if (aborted) then exit;
 if not(rh.b[3]=74ドル) then exit;
 blockread(fp,h,2,numread);
 if numread2 then emsg(errmsg[2]);
 if (aborted) then exit;
 blockread(fp,rar,sizeof(rar),numread);
 if numreadsizeof(rar) then emsg(errmsg[2]);
 if (aborted) then exit;
 out.filename:='';
 for i:=1 to rar.fnamesize do {* get filename *}
 out.filename[i]:=getbyte(fp);
 out.filename[0]:=chr(rar.fnamesize);
 out.filename:=stripname(out.filename);
 out.date:=rar.mod_date;
 out.time:=rar.mod_time;
 out.csize:=rar.packsize;
 out.usize:=rar.unpacksize;
 case rar.method of
 30ドル:out.typ:=2; {* Stored *}
 31ドル:out.typ:=17; {* Shrunk *}
 32ドル:out.typ:=18;
 33ドル:out.typ:=19;
 34ドル:out.typ:=20;
 35ドル:out.typ:=21;
 else begin
 out.typ:=1; {* Unknown! *}
 end;
 end;
 {place call to routine that displays one file list line using the
  variable}
 {$I-} seek(fp,filepos(fp)+(h-(sizeof(rar)+7+
 length(out.filename)))); {$I+}
 if (ioresult0) then emsg(errmsg[4]);
 if (aborted) then exit;
 {$I-} seek(fp,filepos(fp)+(rar.packsize)); {$I+}
 if (ioresult0) then emsg(errmsg[4]);
 if (aborted) then exit;
 end;
end;
procedure showrar(infile:string);
var rha:array[1..15] of byte;
 c:char;
 h:word;
 numread:word;
begin
 assign(fp,infile);
 {$I-} reset(fp,1); {$I+}
 if ioresult0 then begin end;
 c:=getbyte(fp); {* determine type of archive *}
 if (c=52ドル) then begin
 if (ord(getbyte(fp))61ドル) then emsg(errmsg[5]);
 if (ord(getbyte(fp))72ドル) then emsg(errmsg[5]);
 if (ord(getbyte(fp))21ドル) then emsg(errmsg[5]);
 if (ord(getbyte(fp))1ドルa) then emsg(errmsg[5]);
 c:=getbyte(fp);
 c:=getbyte(fp);
 blockread(fp,rha[1],5,numread); if numread5 then
 abend(abort,next,errmsg[2]);
 if rha[3]73ドル then begin
 emsg(errmsg[2]);
 end;
 blockread(fp,h,2,numread);
 if numread2 then emsg(errmsg[2]);
 blockread(fp,rha[1],6,numread);
 if numread6 then emsg(errmsg[2]);
 {$I-} seek(fp,filepos(fp)+(h-13)); {$I+}
 if (ioresult0) then emsg(errmsg[4]);
 writeln('Original Compress % Met'+
 'hod Date Time Filename');
 writeln('-------- -------- --- '+
 '--------- -------- ------ ------------');
 process_RAR(fp); {* process RAR entry *}
 { place call to routine that displays any totals or anything
you may have compiled }
 end else reset(fp,1);
 close(fp); {* close file *}
end;
This is not a complete unit or program because it is a cut and paste from
(MANY) different source files of mine... ;) I display a bunch of different
archive types and the display routines are all intertwined, so I had to cut
out the RAR ones to show you here. I would not suggest reading the file
byte by byte and trying to convert it. I would simply do something like
what I have done here, (I meant this to be an example... not necessarily a
cut and paste solution) and use the record and blockread in the record.
Hope this helps somewhat! ;)
George A. Roberts IV
Intuitive Vision Software
ivsoft@ripco.com


AltStyle によって変換されたページ (->オリジナル) /