Создаём собственный UnRar, используя unrar.dll

Материал из DRKB


// Объявления


function RAROpenArchive(ArchiveData: Pointer): Integer; stdcall;
  external 'unrar.dll' name 'RAROpenArchive';

function RARCloseArchive(hArcData: Integer): Integer; stdcall;
  external 'unrar.dll' name 'RARCloseArchive';

function RARReadHeader(hArcData: Integer; HeaderData: Pointer): Integer; stdcall;
  external 'unrar.dll' name 'RARReadHeader';

function RARProcessFile(hArcData: Integer; Operation: Integer; DestPath: Pointer;
  DestName: Pointer): Integer; stdcall;
  external 'unrar.dll' name 'RARProcessFile';


const
  ERAR_END_ARCHIVE = 10;
  ERAR_NO_MEMORY = 11;
  ERAR_BAD_DATA = 12;
  ERAR_BAD_ARCHIVE = 13;
  ERAR_UNKNOWN_FORMAT = 14;
  ERAR_EOPEN = 15;
  ERAR_ECREATE = 16;
  ERAR_ECLOSE = 17;
  ERAR_EREAD = 18;
  ERAR_EWRITE = 19;
  ERAR_SMALL_BUF = 20;

  RAR_OM_LIST = 0;
  RAR_OM_EXTRACT = 1;
  RAR_SKIP = 0;
  RAR_TEST = 1;
  RAR_EXTRACT = 2;
  RAR_VOL_ASK = 0;
  RAR_VOL_NOTIFY = 1;


type
  Char260 = Array [1..260] of Char;

  TRAROpenArchiveData = record
   ArcName: PChar; // в C++ это будет выглядеть как: char *ArcName
   OpenMode: Cardinal;
   OpenResult: Cardinal;
   CmtBuf: PChar;
   CmtBufSize: Cardinal;
   CmtSize: Cardinal;
   CmtState: Cardinal;
  end;

  TRARHeaderData = record
   ArcName: Char260;
   FileName: Char260;
   Flags: Cardinal;
   PackSize: Cardinal;
   UnpSize: Cardinal;
   HostOS: Cardinal;
   FileCRC: Cardinal;
   FileTime: Cardinal;
   UnpVer: Cardinal;
   Method: Cardinal;
   FileAttr: Cardinal;
   CmtBuf: PChar;
   CmtBufSize: Cardinal;
   CmtSize: Cardinal;
   CmtState: Cardinal;
  end;


var
  RARExtract: boolean;
  RAROpenArchiveData: TRAROpenArchiveData;
  RARComment: array [1..256] of Char;
  RARHeaderData: TRARHeaderData;

implementation

procedure ExtractRARArchive;
var
  sDir: string;
  s: string;
  sTest: string;
  iTest: integer;
  bTestDone: boolean;
  RARhnd: Integer;
  RARrc: Integer;
  PDestPath: Char260;
begin
  RARExtract := TRUE;
  lKBWritten := 0;
  ProgressBar2.Position := 0;
  ProgressBar2.Max := lTotalSize;
  RARStartTime := Time;

  RAROpenArchiveData.OpenResult := 99;
  RAROpenArchiveData.OpenMode := RAR_OM_EXTRACT; // открываем для распаковки
  RAROpenArchiveData.ArcName := @RARFileName;
  RAROpenArchiveData.CmtBuf := @RARComment;
  RAROpenArchiveData.CmtBufSize := 255;

  // Открываем RAR архив и выделяем память
  RARhnd := RAROpenArchive (@RAROpenArchiveData);
  If RAROpenArchiveData.OpenResult <> 0 then
  begin
    case RAROpenArchiveData.OpenResult of
      ERAR_NO_MEMORY: s := 'Not enough memory to initialize data structures';
      ERAR_BAD_DATA: s := 'Archive header broken';
      ERAR_BAD_ARCHIVE: s := 'File is not valid RAR archive';
      ERAR_EOPEN: s := 'File open error';
    end;
    MessageDlg('Unable to open rar archive: ' + s + '!',mtError, [mbOK], 0);
  end;

  RARSetProcessDataProc(RARhnd, @Form.OnRarStatus);
  StrPCopy(@PDestPath, EInstallPath.Text);

  repeat
    RARrc := RARReadHeader(RARhnd, @RARHeaderData); // Читаем заголовок
    if RARrc <> ERAR_END_ARCHIVE then
    begin
      ProgressBar1.Position := 0;
      ProgressBar1.Max := RARHeaderData.UnpSize;
      s := RARHeaderData.FileName;
      lblCurrentFile.Caption := s;
      lKBytesDone := 0;
    end;

    if RARrc = 0 then
      RARrc := RARProcessFile(RARhnd, RAR_EXTRACT, @PDestPath, nil);
    if (RARrc <> 0) and (RARrc <> ERAR_END_ARCHIVE) then
    begin
      MessageDlg('An Error occured during extracting of ' + sTest + '!' + #13#10 +
        'RARProcessFile: ' + MakeItAString(RARrc), mtError, [mbOK], 0);
    end;
  until RARrc <> 0;

  // закрываем RAR архив и освобождаем память
  if RARCloseArchive(RARhnd) <> 0 then
  begin
    MessageDlg('Unable to close rar archive!', mtError, [mbOK], 0);
  end;
end;


Source: Взято из http://forum.sources.ru
ID: 03190