UPD: Unrar - Refactoring

ADD: Unrar - GetBackgroundFlags function (fixes #665)
This commit is contained in:
Alexander Koblov 2022-11-14 18:48:33 +03:00
commit fc8306f639
2 changed files with 157 additions and 379 deletions

View file

@ -1,6 +1,9 @@
library unrar;
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
FPCAdds, SysUtils, DynLibs, UnRARFunc, RarFunc;
exports
@ -8,7 +11,6 @@ exports
OpenArchive,
OpenArchiveW,
ReadHeader,
ReadHeaderEx,
ReadHeaderExW,
ProcessFile,
ProcessFileW,
@ -22,6 +24,7 @@ exports
PackFilesW,
DeleteFilesW,
ConfigurePacker,
GetBackgroundFlags,
PackSetDefaultParams,
{ Extension API }
ExtensionInitialize;
@ -37,18 +40,13 @@ begin
if ModuleHandle = NilHandle then
ModuleHandle := LoadLibrary(GetEnvironmentVariable('COMMANDER_PATH') + PathDelim + _unrar);
if ModuleHandle <> NilHandle then
begin
RAROpenArchive := TRAROpenArchive(GetProcAddress(ModuleHandle, 'RAROpenArchive'));
RAROpenArchiveEx := TRAROpenArchiveEx(GetProcAddress(ModuleHandle, 'RAROpenArchiveEx'));
RARCloseArchive := TRARCloseArchive(GetProcAddress(ModuleHandle, 'RARCloseArchive'));
RARReadHeader := TRARReadHeader(GetProcAddress(ModuleHandle, 'RARReadHeader'));
RARReadHeaderEx := TRARReadHeaderEx(GetProcAddress(ModuleHandle, 'RARReadHeaderEx'));
RARProcessFile := TRARProcessFile(GetProcAddress(ModuleHandle, 'RARProcessFile'));
RARProcessFileW := TRARProcessFileW(GetProcAddress(ModuleHandle, 'RARProcessFileW'));
RARSetCallback := TRARSetCallback(GetProcAddress(ModuleHandle, 'RARSetCallback'));
RARSetChangeVolProc := TRARSetChangeVolProc(GetProcAddress(ModuleHandle, 'RARSetChangeVolProc'));
RARSetProcessDataProc := TRARSetProcessDataProc(GetProcAddress(ModuleHandle, 'RARSetProcessDataProc'));
RARSetPassword := TRARSetPassword(GetProcAddress(ModuleHandle, 'RARSetPassword'));
RARGetDllVersion := TRARGetDllVersion(GetProcAddress(ModuleHandle, 'RARGetDllVersion'));
end;
begin
RAROpenArchiveEx := TRAROpenArchiveEx(GetProcAddress(ModuleHandle, 'RAROpenArchiveEx'));
RARCloseArchive := TRARCloseArchive(GetProcAddress(ModuleHandle, 'RARCloseArchive'));
RARReadHeaderEx := TRARReadHeaderEx(GetProcAddress(ModuleHandle, 'RARReadHeaderEx'));
RARProcessFileW := TRARProcessFileW(GetProcAddress(ModuleHandle, 'RARProcessFileW'));
RARSetCallback := TRARSetCallback(GetProcAddress(ModuleHandle, 'RARSetCallback'));
RARSetPassword := TRARSetPassword(GetProcAddress(ModuleHandle, 'RARSetPassword'));
RARGetDllVersion := TRARGetDllVersion(GetProcAddress(ModuleHandle, 'RARGetDllVersion'));
end;
end.

View file

@ -83,24 +83,6 @@ type
PRarUnicodeChar = ^TRarUnicodeChar;
TRarUnicodeArray = packed array [0..1023] of TRarUnicodeChar;
RARHeaderData = packed record
ArcName: packed array[0..259] of Char;
FileName: packed array[0..259] of Char; // a zero terminated string of the file name in OEM (DOS) encoding.
Flags: LongWord;
PackSize: LongWord;
UnpSize: LongWord;
HostOS: LongWord;
FileCRC: LongWord;
FileTime: LongWord;
UnpVer: LongWord;
Method: LongWord;
FileAttr: LongWord;
CmtBuf: PChar;
CmtBufSize: LongWord;
CmtSize: LongWord;
CmtState: LongWord;
end;
RARHeaderDataEx = packed record
ArcName: packed array [0..1023] of Char;
ArcNameW: TRarUnicodeArray;
@ -124,20 +106,8 @@ type
Reserved: packed array [0..1023] of LongWord;
end;
RAROpenArchiveData = packed record
ArcName: PChar;
OpenMode: LongWord;
OpenResult: LongWord;
CmtBuf: PChar;
CmtBufSize: LongWord;
CmtSize: LongWord;
CmtState: LongWord;
end;
{$IFDEF MSWINDOWS}{$CALLING STDCALL}{$ELSE}{$CALLING CDECL}{$ENDIF}
TUnrarChangeVolProc = function(ArcName: PChar; Mode: Integer): Integer;
TUnrarProcessDataProc = function(BufAddr: Pointer; BufSize: Integer): Integer;
TUnrarCallback = function(Msg: LongWord; UserData, P1: Pointer; P2: PtrInt): Integer;
RAROpenArchiveDataEx = packed record
@ -155,55 +125,50 @@ type
Reserved: packed array [0..27] of LongWord;
end;
TRAROpenArchive = function(var ArchiveData: RAROpenArchiveData) : TArcHandle;
TRAROpenArchiveEx = function(var ArchiveData: RAROpenArchiveDataEx) : TArcHandle;
TRARCloseArchive = function(hArcData: TArcHandle) : Integer;
TRARReadHeader = function(hArcData: TArcHandle; var HeaderData: RARHeaderData) : Integer;
TRARReadHeaderEx = function (hArcData: TArcHandle; var HeaderData: RARHeaderDataEx) : Integer;
TRARProcessFile = function(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PAnsiChar) : Integer;
TRARProcessFileW = function(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PRarUnicodeChar) : Integer;
TRARSetCallback = procedure(hArcData: TArcHandle; UnrarCallback: TUnrarCallback; UserData: PtrInt);
TRARSetChangeVolProc = procedure(hArcData: TArcHandle; ChangeVolProc: TUnrarChangeVolProc);
TRARSetProcessDataProc = procedure(hArcData: TArcHandle; ProcessDataProc: TUnrarProcessDataProc);
TRARSetPassword = procedure(hArcData: TArcHandle; Password: PChar);
TRARGetDllVersion = function: Integer;
{$CALLING DEFAULT}
var
RAROpenArchive : TRAROpenArchive = nil;
RAROpenArchiveEx : TRAROpenArchiveEx = nil;
RARCloseArchive : TRARCloseArchive = nil;
RARReadHeader : TRARReadHeader = nil;
RARReadHeaderEx : TRARReadHeaderEx = nil;
RARProcessFile : TRARProcessFile = nil;
RARProcessFileW : TRARProcessFileW = nil;
RARSetCallback : TRARSetCallback = nil;
RARSetChangeVolProc : TRARSetChangeVolProc = nil;
RARSetProcessDataProc : TRARSetProcessDataProc = nil;
RARSetPassword : TRARSetPassword = nil;
RARGetDllVersion : TRARGetDllVersion = nil;
ModuleHandle : TLibHandle = NilHandle;
function OpenArchive(var ArchiveData: TOpenArchiveData) : TArcHandle;dcpcall;
function OpenArchiveW(var ArchiveData: tOpenArchiveDataW) : TArcHandle;dcpcall;
function ReadHeader(hArcData: TArcHandle; var HeaderData: THeaderData) : Integer;dcpcall;
function ReadHeaderEx(hArcData: TArcHandle; var HeaderData: THeaderDataEx) : Integer;dcpcall;
function ReadHeaderExW(hArcData: TArcHandle; var HeaderData: THeaderDataExW) : Integer;dcpcall;
function ProcessFile(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PChar) : Integer;dcpcall;
function ProcessFileW(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PWideChar) : Integer;dcpcall;
function CloseArchive(hArcData: TArcHandle): Integer;dcpcall;
procedure SetChangeVolProc(hArcData : TArcHandle; pChangeVolProc : TChangeVolProc);dcpcall;
procedure SetChangeVolProcW(hArcData : TArcHandle; pChangeVolProc : TChangeVolProcW);dcpcall;
procedure SetProcessDataProc(hArcData : TArcHandle; pProcessDataProc : TProcessDataProc);dcpcall;
procedure SetProcessDataProcW(hArcData : TArcHandle; pProcessDataProc : TProcessDataProcW);dcpcall;
{ Mandatory }
function OpenArchive(var ArchiveData: TOpenArchiveData) : TArcHandle; dcpcall;
function OpenArchiveW(var ArchiveData: tOpenArchiveDataW) : TArcHandle; dcpcall;
function ReadHeader(hArcData: TArcHandle; var HeaderData: THeaderData) : Integer; dcpcall;
function ReadHeaderExW(hArcData: TArcHandle; var HeaderData: THeaderDataExW) : Integer; dcpcall;
function ProcessFile(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PAnsiChar) : Integer; dcpcall;
function ProcessFileW(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PWideChar) : Integer; dcpcall;
function CloseArchive(hArcData: TArcHandle): Integer; dcpcall;
procedure SetChangeVolProc(hArcData : TArcHandle; pChangeVolProc : TChangeVolProc); dcpcall;
procedure SetChangeVolProcW(hArcData : TArcHandle; pChangeVolProc : TChangeVolProcW); dcpcall;
procedure SetProcessDataProc(hArcData : TArcHandle; pProcessDataProc : TProcessDataProc); dcpcall;
procedure SetProcessDataProcW(hArcData : TArcHandle; pProcessDataProc : TProcessDataProcW); dcpcall;
{ Optional }
function GetPackerCaps : Integer; dcpcall;
function GetBackgroundFlags: Integer; dcpcall;
{ Extension API }
procedure ExtensionInitialize(StartupInfo: PExtensionStartupInfo); dcpcall;
var
gStartupInfo: TExtensionStartupInfo;
ProcessDataProcW : TProcessDataProcW = nil;
threadvar
ProcessDataProcW : TProcessDataProcW;
implementation
@ -222,20 +187,12 @@ type
HOST_MAX
);
var
ChangeVolProc : TChangeVolProc = nil;
ChangeVolProcW : TChangeVolProcW = nil;
ProcessDataProc : TProcessDataProc = nil;
// These variables store currently processed file name.
// They cannot be dynamic strings, because if they are created from the
// main thread of the calling program and then they're freed from another
// thread of the calling program there's a crash.
// It is because currently the library can only be statically linked with RTL
// and so it doesn't know about the main program's multithreading.
ProcessedFileName: array [0..1023] of Char;
ProcessedFileNameW: array [0..1023] of WideChar;
ProcessedFileHostOS: RarHostSystem;
TRARHandle = class
Handle: TArcHandle;
ChangeVolProcW: TChangeVolProcW;
ProcessDataProcW: TProcessDataProcW;
ProcessFileNameW: array [0..1023] of WideChar;
end;
function StrLCopy(Dest, Source: PRarUnicodeChar; MaxLen: SizeInt): PRarUnicodeChar; overload;
var
@ -251,20 +208,6 @@ begin
StrLCopy := Dest;
end;
procedure StringToArrayA(src: AnsiString;
pDst: PAnsiChar;
MaxDstLength: Integer);
begin
if Length(src) < MaxDstLength then
MaxDstLength := Length(src)
else
MaxDstLength := MaxDstLength - 1; // for ending #0
if Length(src) > 0 then
Move(src[1], pDst^, SizeOf(AnsiChar) * MaxDstLength);
pDst[MaxDstLength] := AnsiChar(0);
end;
procedure StringToArrayW(src: UnicodeString;
pDst: PWideChar;
MaxDstLength: Integer);
@ -297,36 +240,6 @@ begin
{$ENDIF}
end;
function GetSystemSpecificFileName(HostOS: RarHostSystem; FileName: AnsiString) : AnsiString;
begin
Result:= FileName;
if HostOS in [HOST_MSDOS, HOST_WIN32] then
begin
Result:= CeOemToSys(Result);
end;
{$IFDEF MSWINDOWS}
if HostOS in [HOST_UNIX, HOST_MACOS] then
begin
Result:= CeUTF8ToAnsi(Result);
end;
{$ENDIF}
end;
function SetSystemSpecificFileName(HostOS: RarHostSystem; FileName: AnsiString) : AnsiString;
begin
Result:= FileName;
{$IFDEF MSWINDOWS}
if HostOS in [HOST_MSDOS, HOST_WIN32] then
begin
Result:= CeSysToOem(Result);
end;
if HostOS in [HOST_UNIX, HOST_MACOS] then
begin
Result:= CeSysToOem(Result);
end;
{$ENDIF}
end;
function GetSystemSpecificFileTime(FileTime: LongInt) : LongInt;
begin
Result := FileTime;
@ -360,30 +273,18 @@ var
VolumeNameA: TRarUnicodeArray;
VolumeNameU: TRarUnicodeString;
PasswordA: array[0..511] of AnsiChar;
AHandle: TRARHandle absolute UserData;
VolumeNameW: array [0..1023] of WideChar;
begin
Result := 0;
case Msg of
UCM_CHANGEVOLUME:
begin
if Assigned(ChangeVolProc) then
begin
if ChangeVolProc(PAnsiChar(P1), LongInt(P2)) = 0 then
Result := -1
else
Result := 1;
end
else begin
Result := -1;
end;
end;
UCM_CHANGEVOLUMEW:
begin
if Assigned(ChangeVolProcW) then
if Assigned(AHandle.ChangeVolProcW) then
begin
Move(PRarUnicodeChar(P1)^, VolumeNameA[0], SizeOf(TRarUnicodeArray));
VolumeNameW := RarUnicodeStringToWideString(VolumeNameA);
if ChangeVolProcW(VolumeNameW, LongInt(P2)) = 0 then
if AHandle.ChangeVolProcW(VolumeNameW, LongInt(P2)) = 0 then
Result := -1
else begin
Result := 1;
@ -402,14 +303,9 @@ begin
begin
// P1 - pointer to data buffer (first param of ProcessDataProc)
// P2 - number of bytes in the buffer (second param of ProcessDataProc)
if Assigned(ProcessDataProcW) then
if Assigned(AHandle.ProcessDataProcW) then
begin
if ProcessDataProcW(PWideChar(ProcessedFileNameW), LongInt(P2)) = 0 then
Result := -1;
end
else if Assigned(ProcessDataProc) then
begin
if ProcessDataProc(PAnsiChar(ProcessedFileName), LongInt(P2)) = 0 then
if AHandle.ProcessDataProcW(PWideChar(AHandle.ProcessFileNameW), LongInt(P2)) = 0 then
Result := -1;
end;
end;
@ -436,291 +332,170 @@ begin
end;
end;
function OpenArchive(var ArchiveData: TOpenArchiveData) : TArcHandle;dcpcall;
var
RarArchiveData: RAROpenArchiveData;
function OpenArchive(var ArchiveData: TOpenArchiveData) : TArcHandle; dcpcall;
begin
if Assigned(RAROpenArchive) then
begin
RarArchiveData.ArcName := ArchiveData.ArcName;
RarArchiveData.OpenMode := ArchiveData.OpenMode;
RarArchiveData.CmtBuf := ArchiveData.CmtBuf;
RarArchiveData.CmtBufSize := ArchiveData.CmtBufSize;
Result := RAROpenArchive(RarArchiveData);
ArchiveData.OpenResult := RarArchiveData.OpenResult;
if Result <> 0 then
begin
ArchiveData.CmtSize := RarArchiveData.CmtSize;
ArchiveData.CmtState := RarArchiveData.CmtState;
RARSetCallback(Result, @UnrarCallback, 0);
end;
end
else
begin
ArchiveData.OpenResult := E_EOPEN;
Result := 0;
end;
Result := 0;
ArchiveData.OpenResult := E_NOT_SUPPORTED;
end;
function OpenArchiveW(var ArchiveData: tOpenArchiveDataW) : TArcHandle;dcpcall;
function OpenArchiveW(var ArchiveData: tOpenArchiveDataW): TArcHandle; dcpcall;
var
RarArchiveData: RAROpenArchiveDataEx;
RarArcName: TRarUnicodeString;
AHandle: TRARHandle absolute Result;
RarArchiveData: RAROpenArchiveDataEx;
begin
if Assigned(RAROpenArchiveEx) then
if (RAROpenArchiveEx = nil) then
begin
Result := 0;
ArchiveData.OpenResult := E_EOPEN;
end
else begin
AHandle:= TRARHandle.Create;
RarArcName := WideStringToRarUnicodeString(ArchiveData.ArcName);
FillChar(RarArchiveData, SizeOf(RAROpenArchiveDataEx), #0);
RarArchiveData := Default(RAROpenArchiveDataEx);
RarArchiveData.ArcNameW := PRarUnicodeChar(RarArcName);
RarArchiveData.OpenMode := ArchiveData.OpenMode;
RarArchiveData.Callback := @UnrarCallback;
RarArchiveData.UserData := PtrInt(Result);
Result := RAROpenArchiveEx(RarArchiveData);
ArchiveData.OpenResult := RarArchiveData.OpenResult;
if Result <> 0 then
begin
AHandle.Handle := RAROpenArchiveEx(RarArchiveData);
ArchiveData.OpenResult := RarArchiveData.OpenResult;
if AHandle.Handle = 0 then
FreeAndNil(AHandle)
else begin
ArchiveData.CmtSize := RarArchiveData.CmtSize;
ArchiveData.CmtState := RarArchiveData.CmtState;
RARSetCallback(Result, @UnrarCallback, 0);
RARSetCallback(AHandle.Handle, @UnrarCallback, PtrInt(Result));
end;
end
else
begin
ArchiveData.OpenResult := E_EOPEN;
Result := 0;
end;
end;
function ReadHeader(hArcData: TArcHandle; var HeaderData: THeaderData) : Integer;dcpcall;
var
RarHeader: RARHeaderData;
function ReadHeader(hArcData: TArcHandle; var HeaderData: THeaderData) : Integer; dcpcall;
begin
if Assigned(RARReadHeader) then
begin
FillChar(RarHeader, SizeOf(RarHeader), 0);
RarHeader.CmtBuf := HeaderData.CmtBuf;
RarHeader.CmtBufSize := HeaderData.CmtBufSize;
Result := RARReadHeader(hArcData, RarHeader);
{$PUSH}
{$Q-}
{$R-}
HeaderData.ArcName := RarHeader.ArcName;
StringToArrayA(
GetSystemSpecificFileName(RarHostSystem(RarHeader.HostOS),
AnsiString(RarHeader.FileName)),
@HeaderData.FileName, SizeOf(HeaderData.FileName)
);
HeaderData.Flags := RarHeader.Flags;
HeaderData.PackSize := RarHeader.PackSize;
HeaderData.UnpSize := RarHeader.UnpSize;
HeaderData.HostOS := RarHeader.HostOS;
HeaderData.FileCRC := RarHeader.FileCRC;
HeaderData.FileTime := RarHeader.FileTime;
HeaderData.UnpVer := RarHeader.UnpVer;
HeaderData.Method := RarHeader.Method;
HeaderData.FileAttr := RarHeader.FileAttr;
HeaderData.CmtSize := RarHeader.CmtSize;
HeaderData.CmtState := RarHeader.CmtState;
HeaderData.FileAttr :=
GetSystemSpecificAttributes(RarHostSystem(HeaderData.HostOS),
HeaderData.FileAttr);
HeaderData.FileTime := GetSystemSpecificFileTime(HeaderData.FileTime);
{$POP}
Move(HeaderData.FileName, ProcessedFileName, SizeOf(HeaderData.FileName));
ProcessedFileNameW := '';
ProcessedFileHostOS:= RarHostSystem(HeaderData.HostOS);
end
else
Result := E_EREAD;
Result := E_NOT_SUPPORTED;
end;
function ReadHeaderEx(hArcData: TArcHandle; var HeaderData: THeaderDataEx) : Integer;dcpcall;
function ReadHeaderExW(hArcData: TArcHandle; var HeaderData: THeaderDataExW) : Integer; dcpcall;
var
RarHeader: RARHeaderDataEx;
AHandle: TRARHandle absolute hArcData;
begin
if Assigned(RARReadHeaderEx) then
begin
FillChar(RarHeader, SizeOf(RarHeader), 0);
if (RARReadHeaderEx = nil) then
Result := E_EREAD
else begin
RarHeader:= Default(RARHeaderDataEx);
RarHeader.CmtBuf := HeaderData.CmtBuf;
RarHeader.CmtBufSize := HeaderData.CmtBufSize;
RarHeader.CmtBuf := HeaderData.CmtBuf;
RarHeader.CmtBufSize := HeaderData.CmtBufSize;
Result := RARReadHeaderEx(hArcData, RarHeader);
Result := RARReadHeaderEx(AHandle.Handle, RarHeader);
{$PUSH}
{$Q-}
{$R-}
HeaderData.ArcName := RarHeader.ArcName;
if Result <> E_SUCCESS then Exit;
StringToArrayA(
GetSystemSpecificFileName(RarHostSystem(RarHeader.HostOS),
AnsiString(RarHeader.FileName)),
@HeaderData.FileName, SizeOf(HeaderData.FileName)
);
{$PUSH}{$Q-}{$R-}
StringToArrayW(
RarUnicodeStringToWideString(TRarUnicodeString(RarHeader.ArcNameW)),
@HeaderData.ArcName, SizeOf(HeaderData.ArcName));
HeaderData.Flags := RarHeader.Flags;
HeaderData.PackSize := RarHeader.PackSize;
HeaderData.PackSizeHigh := RarHeader.PackSizeHigh;
HeaderData.UnpSize := RarHeader.UnpSize;
HeaderData.UnpSizeHigh := RarHeader.UnpSizeHigh;
HeaderData.HostOS := RarHeader.HostOS;
HeaderData.FileCRC := RarHeader.FileCRC;
HeaderData.FileTime := RarHeader.FileTime;
HeaderData.UnpVer := RarHeader.UnpVer;
HeaderData.Method := RarHeader.Method;
HeaderData.FileAttr := RarHeader.FileAttr;
HeaderData.CmtSize := RarHeader.CmtSize;
HeaderData.CmtState := RarHeader.CmtState;
StringToArrayW(
RarUnicodeStringToWideString(TRarUnicodeString(RarHeader.FileNameW)),
@HeaderData.FileName, SizeOf(HeaderData.FileName));
HeaderData.FileAttr :=
GetSystemSpecificAttributes(RarHostSystem(HeaderData.HostOS),
HeaderData.FileAttr);
HeaderData.FileTime := GetSystemSpecificFileTime(HeaderData.FileTime);
HeaderData.Flags := RarHeader.Flags;
HeaderData.PackSize := RarHeader.PackSize;
HeaderData.PackSizeHigh := RarHeader.PackSizeHigh;
HeaderData.UnpSize := RarHeader.UnpSize;
HeaderData.UnpSizeHigh := RarHeader.UnpSizeHigh;
HeaderData.HostOS := RarHeader.HostOS;
HeaderData.FileCRC := RarHeader.FileCRC;
HeaderData.FileTime := RarHeader.FileTime;
HeaderData.UnpVer := RarHeader.UnpVer;
HeaderData.Method := RarHeader.Method;
HeaderData.FileAttr := RarHeader.FileAttr;
HeaderData.CmtSize := RarHeader.CmtSize;
HeaderData.CmtState := RarHeader.CmtState;
HeaderData.FileAttr :=
GetSystemSpecificAttributes(RarHostSystem(HeaderData.HostOS),
HeaderData.FileAttr);
HeaderData.FileTime := GetSystemSpecificFileTime(HeaderData.FileTime);
{$POP}
ProcessedFileName := HeaderData.FileName;
ProcessedFileNameW := '';
ProcessedFileHostOS:= RarHostSystem(HeaderData.HostOS);
end
else
Result := E_EREAD;
AHandle.ProcessFileNameW := HeaderData.FileName;
end;
end;
function ReadHeaderExW(hArcData: TArcHandle; var HeaderData: THeaderDataExW) : Integer;dcpcall;
var
RarHeader: RARHeaderDataEx;
function ProcessFile(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PAnsiChar) : Integer; dcpcall;
begin
if Assigned(RARReadHeaderEx) then
begin
FillChar(RarHeader, SizeOf(RarHeader), 0);
RarHeader.CmtBuf := HeaderData.CmtBuf;
RarHeader.CmtBufSize := HeaderData.CmtBufSize;
Result := RARReadHeaderEx(hArcData, RarHeader);
{$PUSH}
{$Q-}
{$R-}
StringToArrayW(
RarUnicodeStringToWideString(TRarUnicodeString(RarHeader.ArcNameW)),
@HeaderData.ArcName, SizeOf(HeaderData.ArcName));
StringToArrayW(
RarUnicodeStringToWideString(TRarUnicodeString(RarHeader.FileNameW)),
@HeaderData.FileName, SizeOf(HeaderData.FileName));
HeaderData.Flags := RarHeader.Flags;
HeaderData.PackSize := RarHeader.PackSize;
HeaderData.PackSizeHigh := RarHeader.PackSizeHigh;
HeaderData.UnpSize := RarHeader.UnpSize;
HeaderData.UnpSizeHigh := RarHeader.UnpSizeHigh;
HeaderData.HostOS := RarHeader.HostOS;
HeaderData.FileCRC := RarHeader.FileCRC;
HeaderData.FileTime := RarHeader.FileTime;
HeaderData.UnpVer := RarHeader.UnpVer;
HeaderData.Method := RarHeader.Method;
HeaderData.FileAttr := RarHeader.FileAttr;
HeaderData.CmtSize := RarHeader.CmtSize;
HeaderData.CmtState := RarHeader.CmtState;
HeaderData.FileAttr :=
GetSystemSpecificAttributes(RarHostSystem(HeaderData.HostOS),
HeaderData.FileAttr);
HeaderData.FileTime := GetSystemSpecificFileTime(HeaderData.FileTime);
{$POP}
ProcessedFileName := RarHeader.FileName;
ProcessedFileNameW := HeaderData.FileName;
end
else
Result := E_EREAD;
Result := E_NOT_SUPPORTED;
end;
function ProcessFile(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PChar) : Integer;dcpcall;
var
pacDestPath: PAnsiChar = nil;
pacDestName: PAnsiChar = nil;
SysSpecDestPath, SysSpecDestName: AnsiString;
begin
if Assigned(RARProcessFile) then
begin
// Both DestPath and DestName must be in OEM encoding
// if HostOS is MS DOS or MS Windows and archive is open under MS Windows.
if DestPath <> nil then
begin
SysSpecDestPath:= SetSystemSpecificFileName(ProcessedFileHostOS, DestPath);
pacDestPath := PAnsiChar(SysSpecDestPath);
end;
if DestName <> nil then
begin
SysSpecDestName:= SetSystemSpecificFileName(ProcessedFileHostOS, DestName);
pacDestName := PAnsiChar(SysSpecDestName);
end;
Result := RARProcessFile(hArcData, Operation, pacDestPath, pacDestName);
end
else
Result := E_EREAD;
end;
function ProcessFileW(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PWideChar) : Integer;dcpcall;
function ProcessFileW(hArcData: TArcHandle; Operation: Integer; DestPath, DestName: PWideChar) : Integer; dcpcall;
var
pwcDestPath: PRarUnicodeChar = nil;
pwcDestName: PRarUnicodeChar = nil;
AHandle: TRARHandle absolute hArcData;
SysSpecDestPath, SysSpecDestName: TRarUnicodeString;
begin
if Assigned(RARProcessFileW) then
if (RARProcessFileW = nil) then
Result := E_EREAD
else begin
if DestPath <> nil then
begin
if DestPath <> nil then
begin
SysSpecDestPath:= WideStringToRarUnicodeString(DestPath);
pwcDestPath := PRarUnicodeChar(SysSpecDestPath);
end;
if DestName <> nil then
begin
SysSpecDestName:= WideStringToRarUnicodeString(DestName);
pwcDestName := PRarUnicodeChar(SysSpecDestName);
end;
Result := RARProcessFileW(hArcData, Operation, pwcDestPath, pwcDestName);
end
else
Result := E_EREAD;
SysSpecDestPath:= WideStringToRarUnicodeString(DestPath);
pwcDestPath := PRarUnicodeChar(SysSpecDestPath);
end;
if DestName <> nil then
begin
SysSpecDestName:= WideStringToRarUnicodeString(DestName);
pwcDestName := PRarUnicodeChar(SysSpecDestName);
end;
Result := RARProcessFileW(AHandle.Handle, Operation, pwcDestPath, pwcDestName);
end;
end;
function CloseArchive(hArcData: TArcHandle) : Integer;dcpcall;
var
AHandle: TRARHandle absolute hArcData;
begin
if Assigned(RARCloseArchive) then
Result := RARCloseArchive(hArcData)
else
Result := E_ECLOSE;
if (RARCloseArchive = nil) then
Result := E_ECLOSE
else begin
Result := RARCloseArchive(AHandle.Handle);
end;
AHandle.Free;
end;
procedure SetChangeVolProc(hArcData : TArcHandle; pChangeVolProc : TChangeVolProc);dcpcall;
procedure SetChangeVolProc(hArcData: TArcHandle; pChangeVolProc: TChangeVolProc); dcpcall;
begin
ChangeVolProc := pChangeVolProc;
end;
procedure SetChangeVolProcW(hArcData : TArcHandle; pChangeVolProc : TChangeVolProcW);dcpcall;
procedure SetProcessDataProc(hArcData : TArcHandle; pProcessDataProc : TProcessDataProc); dcpcall;
begin
ChangeVolProcW := pChangeVolProc;
end;
procedure SetProcessDataProc(hArcData : TArcHandle; pProcessDataProc : TProcessDataProc);dcpcall;
procedure SetChangeVolProcW(hArcData: TArcHandle; pChangeVolProc: TChangeVolProcW); dcpcall;
var
AHandle: TRARHandle absolute hArcData;
begin
ProcessDataProc := pProcessDataProc;
if (hArcData <> wcxInvalidHandle) then
AHandle.ChangeVolProcW := pChangeVolProc
end;
procedure SetProcessDataProcW(hArcData : TArcHandle; pProcessDataProc : TProcessDataProcW);dcpcall;
procedure SetProcessDataProcW(hArcData : TArcHandle; pProcessDataProc : TProcessDataProcW); dcpcall;
var
AHandle: TRARHandle absolute hArcData;
begin
ProcessDataProcW := pProcessDataProc;
if (hArcData <> wcxInvalidHandle) then
AHandle.ProcessDataProcW := pProcessDataProc
else begin
ProcessDataProcW := pProcessDataProc;
end;
end;
function GetPackerCaps: Integer; dcpcall;
@ -730,6 +505,11 @@ begin
or PK_CAPS_OPTIONS or PK_CAPS_ENCRYPT;
end;
function GetBackgroundFlags: Integer; dcpcall;
begin
Result:= BACKGROUND_UNPACK or BACKGROUND_PACK;
end;
procedure ExtensionInitialize(StartupInfo: PExtensionStartupInfo); dcpcall;
begin
gStartupInfo := StartupInfo^;