Contents of a RAR file

How to list the contents of a RAR file.


{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): }

  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');

  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 *}

              b:array[1..7] of byte;
            HostOS:byte; { 0 dos 1 os/2 }

VAR out:outrec;

procedure emsg(message:string);
  {* emsg - Display error message

  writeln('* '+message);

function getbyte(var fp:file):char;
var buf:array[0..0] of char;
  if (not aborted) then begin
    if numread=0 then begin

procedure Process_RAR(var fp:file);

var rar:rarfilerec;
    rha:array[1..100] of byte;
    buf:array[0..25] of byte;


  while (not aborted) do begin
  {* set up infinite loop (exit is within loop) *}
    if numread<>5 then emsg(errmsg[2]);
    if (aborted) then exit;

    if not(rh.b[3]=$74) then exit;
    if numread<>2 then emsg(errmsg[2]);
    if (aborted) then exit;
    if numread<>sizeof(rar) then emsg(errmsg[2]);
    if (aborted) then exit;
    for i:=1 to rar.fnamesize do {* get filename *}
    case rar.method of
      $30:out.typ:=2; {* Stored *}
      $31:out.typ:=17; {* Shrunk *}
    else begin
        out.typ:=1; {* Unknown! *}

    {place call to routine that displays one file list line using the

    {$I-} seek(fp,filepos(fp)+(h-(sizeof(rar)+7+
                length(out.filename)))); {$I+}
    if (ioresult<>0) then emsg(errmsg[4]);
    if (aborted) then exit;
    {$I-} seek(fp,filepos(fp)+(rar.packsize)); {$I+}
    if (ioresult<>0) then emsg(errmsg[4]);
    if (aborted) then exit;

procedure showrar(infile:string);
var rha:array[1..15] of byte;

          {$I-} reset(fp,1); {$I+}
          if ioresult<>0 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))<>$1a) then emsg(errmsg[5]);
                blockread(fp,rha[1],5,numread); if numread<>5 then
                if rha[3]<>$73 then begin
                if numread<>2 then emsg(errmsg[2]);
                if numread<>6 then emsg(errmsg[2]);
                {$I-} seek(fp,filepos(fp)+(h-13)); {$I+}
                if (ioresult<>0) 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 *}


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


Share this article!

Follow us!

Find more helpful articles: