ADD: Unicode support for WCX plugins

This commit is contained in:
Alexander Koblov 2010-01-27 11:16:26 +00:00
commit 736e257fe4
5 changed files with 163 additions and 65 deletions

View file

@ -60,28 +60,43 @@ var
// (There may be other running concurrently, but only one may report progress.)
WcxCopyInOperation: TWcxArchiveCopyInOperation = nil;
function ChangeVolProc(ArcName : PAnsiChar; Mode:Longint):Longint; stdcall;
var
sArcName: UTF8String;
function ChangeVolProc(var ArcName : UTF8String; Mode: LongInt): LongInt;
begin
Result:= 1;
sArcName:= SysToUTF8(ArcName);
case Mode of
PK_VOL_ASK:
begin
// Use operation UI for this?
if ShowInputQuery('Double Commander', rsMsgSelLocNextVol, sArcName) then
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH)
else
if not ShowInputQuery('Double Commander', rsMsgSelLocNextVol, ArcName) then
Result := 0; // Abort operation
end;
PK_VOL_NOTIFY:
if log_arc_op in gLogOptions then
LogWrite(rsMsgNextVolUnpack + #32 + sArcName);
LogWrite(rsMsgNextVolUnpack + #32 + ArcName);
end;
end;
function ProcessDataProc(FileName: PChar; Size: Integer): Integer; stdcall;
function ChangeVolProcA(ArcName : PAnsiChar; Mode: LongInt): LongInt; stdcall;
var
sArcName: UTF8String;
begin
sArcName:= SysToUTF8(StrPas(ArcName));
Result:= ChangeVolProc(sArcName, Mode);
if Result <> 0 then
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH);
end;
function ChangeVolProcW(ArcName : PWideChar; Mode: LongInt): LongInt; stdcall;
var
sArcName: UTF8String;
begin
sArcName:= UTF8Encode(WideString(ArcName));
Result:= ChangeVolProc(sArcName, Mode);
if Result <> 0 then
StrPLCopyW(ArcName, UTF8Decode(sArcName), MAX_PATH);
end;
function ProcessDataProc(FileName: UTF8String; Size: LongInt): LongInt;
begin
//DebugLn('Working ' + FileName + ' Size = ' + IntToStr(Size));
@ -126,6 +141,16 @@ begin
end;
end;
function ProcessDataProcA(FileName: PAnsiChar; Size: LongInt): LongInt; stdcall;
begin
Result:= ProcessDataProc(SysToUTF8(StrPas(FileName)), Size);
end;
function ProcessDataProcW(FileName: PWideChar; Size: LongInt): LongInt; stdcall;
begin
Result:= ProcessDataProc(UTF8Encode(WideString(FileName)), Size);
end;
// ----------------------------------------------------------------------------
constructor TWcxArchiveCopyInOperation.Create(aSourceFileSource: IFileSource;
@ -167,7 +192,6 @@ end;
procedure TWcxArchiveCopyInOperation.MainExecute;
var
pDestPath: PChar;
sDestPath: String;
WcxModule: TWcxModule;
iResult: Longint;
@ -176,21 +200,16 @@ begin
sDestPath := ExcludeFrontPathDelimiter(TargetPath);
sDestPath := ExcludeTrailingPathDelimiter(sDestPath);
sDestPath := UTF8ToSys(sDestPath);
sDestPath := sDestPath;
if sDestPath = '' then
pDestPath := nil
else
pDestPath := PAnsiChar(sDestPath); // Make pointer to local variable
WcxModule.WcxSetChangeVolProc(wcxInvalidHandle, @ChangeVolProcA, @ChangeVolProcW);
WcxModule.WcxSetProcessDataProc(wcxInvalidHandle, @ProcessDataProcA, @ProcessDataProcW);
WcxModule.SetChangeVolProc(wcxInvalidHandle, @ChangeVolProc);
WcxModule.SetProcessDataProc(wcxInvalidHandle, @ProcessDataProc);
iResult := WcxModule.PackFiles(
PAnsiChar(UTF8ToSys(FWcxArchiveFileSource.ArchiveFileName)),
pDestPath, // no trailing path delimiter here
PAnsiChar(UTF8ToSys(IncludeTrailingPathDelimiter(FFullFilesTree.Path))), // end with path delimiter here
PAnsiChar(UTF8ToSys(GetFileList(FFullFilesTree))), // Convert TFiles into PAnsiChar
iResult := WcxModule.WcxPackFiles(
FWcxArchiveFileSource.ArchiveFileName,
sDestPath, // no trailing path delimiter here
IncludeTrailingPathDelimiter(FFullFilesTree.Path), // end with path delimiter here
GetFileList(FFullFilesTree), // Convert TFiles into UTF8String
FWcxArchiveFileSource.PluginFlags);
// Check for errors.

View file

@ -82,28 +82,43 @@ var
// (There may be other running concurrently, but only one may report progress.)
WcxCopyOutOperation: TWcxArchiveCopyOutOperation = nil;
function ChangeVolProc(ArcName : PAnsiChar; Mode:Longint):Longint; stdcall;
var
sArcName: UTF8String;
function ChangeVolProc(var ArcName : UTF8String; Mode: LongInt): LongInt;
begin
Result:= 1;
sArcName:= SysToUTF8(ArcName);
case Mode of
PK_VOL_ASK:
begin
// Use operation UI for this?
if ShowInputQuery('Double Commander', rsMsgSelLocNextVol, sArcName) then
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH)
else
if not ShowInputQuery('Double Commander', rsMsgSelLocNextVol, ArcName) then
Result := 0; // Abort operation
end;
PK_VOL_NOTIFY:
if log_arc_op in gLogOptions then
LogWrite(rsMsgNextVolUnpack + #32 + sArcName);
LogWrite(rsMsgNextVolUnpack + #32 + ArcName);
end;
end;
function ProcessDataProc(FileName: PChar; Size: Integer): Integer; stdcall;
function ChangeVolProcA(ArcName : PAnsiChar; Mode: LongInt): LongInt; stdcall;
var
sArcName: UTF8String;
begin
sArcName:= SysToUTF8(StrPas(ArcName));
Result:= ChangeVolProc(sArcName, Mode);
if Result <> 0 then
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH);
end;
function ChangeVolProcW(ArcName : PWideChar; Mode: LongInt): LongInt; stdcall;
var
sArcName: UTF8String;
begin
sArcName:= UTF8Encode(WideString(ArcName));
Result:= ChangeVolProc(sArcName, Mode);
if Result <> 0 then
StrPLCopyW(ArcName, UTF8Decode(sArcName), MAX_PATH);
end;
function ProcessDataProc(FileName: UTF8String; Size: LongInt): LongInt;
begin
//DebugLn('Working ' + FileName + ' Size = ' + IntToStr(Size));
@ -148,6 +163,16 @@ begin
end;
end;
function ProcessDataProcA(FileName: PAnsiChar; Size: LongInt): LongInt; stdcall;
begin
Result:= ProcessDataProc(SysToUTF8(StrPas(FileName)), Size);
end;
function ProcessDataProcW(FileName: PWideChar; Size: LongInt): LongInt; stdcall;
begin
Result:= ProcessDataProc(UTF8Encode(WideString(FileName)), Size);
end;
// ----------------------------------------------------------------------------
constructor TWcxArchiveCopyOutOperation.Create(aSourceFileSource: IFileSource;
@ -221,14 +246,14 @@ begin
// Operation allowed to run, but not to report progress.
if WcxCopyOutOperation <> Self then
begin
WcxModule.SetChangeVolProc(ArcHandle, nil);
WcxModule.SetProcessDataProc(ArcHandle, nil);
WcxModule.WcxSetChangeVolProc(ArcHandle, nil, nil);
WcxModule.WcxSetProcessDataProc(ArcHandle, nil, nil);
end
else
{$ENDIF}
begin
WcxModule.SetChangeVolProc(ArcHandle, @ChangeVolProc);
WcxModule.SetProcessDataProc(ArcHandle, @ProcessDataProc);
WcxModule.WcxSetChangeVolProc(ArcHandle, @ChangeVolProcA, @ChangeVolProcW);
WcxModule.WcxSetProcessDataProc(ArcHandle, @ProcessDataProcA, @ProcessDataProcW);
end;
while (WcxModule.ReadWCXHeader(ArcHandle, Header) = E_SUCCESS) do
@ -256,7 +281,7 @@ begin
FCurrentFileSize := Header.UnpSize;
end;
iResult := WcxModule.ProcessFile(ArcHandle, PK_EXTRACT, nil, PAnsiChar(UTF8ToSys(TargetFileName)));
iResult := WcxModule.WcxProcessFile(ArcHandle, PK_EXTRACT, EmptyStr, TargetFileName);
if iResult <> E_SUCCESS then
begin

View file

@ -61,28 +61,43 @@ var
// (There may be other running concurrently, but only one may report progress.)
WcxDeleteOperation: TWcxArchiveDeleteOperation = nil;
function ChangeVolProc(ArcName : PAnsiChar; Mode:Longint):Longint; stdcall;
var
sArcName: UTF8String;
function ChangeVolProc(var ArcName : UTF8String; Mode: LongInt): LongInt;
begin
Result:= 1;
sArcName:= SysToUTF8(ArcName);
case Mode of
PK_VOL_ASK:
begin
// Use operation UI for this?
if ShowInputQuery('Double Commander', rsMsgSelLocNextVol, sArcName) then
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH)
else
if not ShowInputQuery('Double Commander', rsMsgSelLocNextVol, ArcName) then
Result := 0; // Abort operation
end;
PK_VOL_NOTIFY:
if log_arc_op in gLogOptions then
LogWrite(rsMsgNextVolUnpack + #32 + sArcName);
LogWrite(rsMsgNextVolUnpack + #32 + ArcName);
end;
end;
function ProcessDataProc(FileName: PChar; Size: Integer): Integer; stdcall;
function ChangeVolProcA(ArcName : PAnsiChar; Mode: LongInt): LongInt; stdcall;
var
sArcName: UTF8String;
begin
sArcName:= SysToUTF8(StrPas(ArcName));
Result:= ChangeVolProc(sArcName, Mode);
if Result <> 0 then
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH);
end;
function ChangeVolProcW(ArcName : PWideChar; Mode: LongInt): LongInt; stdcall;
var
sArcName: UTF8String;
begin
sArcName:= UTF8Encode(WideString(ArcName));
Result:= ChangeVolProc(sArcName, Mode);
if Result <> 0 then
StrPLCopyW(ArcName, UTF8Decode(sArcName), MAX_PATH);
end;
function ProcessDataProc(FileName: UTF8String; Size: LongInt): LongInt;
begin
//DebugLn('Working ' + FileName + ' Size = ' + IntToStr(Size));
@ -95,7 +110,7 @@ begin
with WcxDeleteOperation.FStatistics do
begin
CurrentFile := SysToUTF8(FileName);
CurrentFile := FileName;
if Size >= 0 then
begin
@ -128,6 +143,16 @@ begin
end;
end;
function ProcessDataProcA(FileName: PAnsiChar; Size: LongInt): LongInt; stdcall;
begin
Result:= ProcessDataProc(SysToUTF8(StrPas(FileName)), Size);
end;
function ProcessDataProcW(FileName: PWideChar; Size: LongInt): LongInt; stdcall;
begin
Result:= ProcessDataProc(UTF8Encode(WideString(FileName)), Size);
end;
// ----------------------------------------------------------------------------
constructor TWcxArchiveDeleteOperation.Create(aTargetFileSource: IFileSource;
@ -164,12 +189,11 @@ var
begin
WcxModule := FWcxArchiveFileSource.WcxModule;
WcxModule.SetChangeVolProc(wcxInvalidHandle, @ChangeVolProc);
WcxModule.SetProcessDataProc(wcxInvalidHandle, @ProcessDataProc);
WcxModule.WcxSetChangeVolProc(wcxInvalidHandle, @ChangeVolProcA, @ChangeVolProcW);
WcxModule.WcxSetProcessDataProc(wcxInvalidHandle, @ProcessDataProcA, @ProcessDataProcW);
iResult := WcxModule.DeleteFiles(
PAnsiChar(UTF8ToSys(FWcxArchiveFileSource.ArchiveFileName)),
PAnsiChar(UTF8ToSys(GetFileList(FilesToDelete))));
iResult := WcxModule.WcxDeleteFiles(FWcxArchiveFileSource.ArchiveFileName,
GetFileList(FilesToDelete));
// Check for errors.
if iResult <> E_SUCCESS then

View file

@ -387,9 +387,9 @@ begin
Exit;
end;
if bCanYouHandleThisFile and Assigned(WcxModule.CanYouHandleThisFile) then
if bCanYouHandleThisFile and (Assigned(WcxModule.CanYouHandleThisFile) or Assigned(WcxModule.CanYouHandleThisFileW)) then
begin
Result := WcxModule.CanYouHandleThisFile(PChar(UTF8ToSys(ArchiveFileName)));
Result := WcxModule.WcxCanYouHandleThisFile(ArchiveFileName);
if not Result then Exit;
end;
@ -441,7 +441,7 @@ begin
FArcFileList.Add(Header);
// get next file
iResult := WcxModule.ProcessFile(ArcHandle, PK_SKIP, nil, nil);
iResult := WcxModule.WcxProcessFile(ArcHandle, PK_SKIP, EmptyStr, EmptyStr);
//Check for errors
{if iResult <> E_SUCCESS then

View file

@ -186,7 +186,7 @@ var
begin
if (anOpenMode >= PK_OM_LIST) and (anOpenMode <= PK_OM_EXTRACT) then
begin
{if Assigned(OpenArchiveW) then
if Assigned(OpenArchiveW) then
begin
FillChar(ArcFileW, SizeOf(ArcFileW), #0);
WideFileName := UTF8Decode(FileName);
@ -198,7 +198,7 @@ begin
else
OpenResult := E_SUCCESS;
end
else} if Assigned(OpenArchive) then
else if Assigned(OpenArchive) then
begin
FillChar(ArcFile, SizeOf(ArcFile), #0);
AnsiFileName := UTF8ToSys(FileName);
@ -217,22 +217,52 @@ end;
function TWCXModule.WcxProcessFile(hArcData: TArcHandle; Operation: LongInt;
DestPath, DestName: UTF8String): LongInt;
var
pwcDestPath: PWideChar;
pacDestPath: PAnsiChar;
begin
if Assigned(ProcessFileW) then
Result:= ProcessFileW(hArcData, Operation, PWideChar(UTF8Decode(DestPath)), PWideChar(UTF8Decode(DestName)))
begin
if DestPath = EmptyStr then
pwcDestPath:= nil
else
pwcDestPath:= PWideChar(UTF8Decode(DestPath));
Result:= ProcessFileW(hArcData, Operation, pwcDestPath, PWideChar(UTF8Decode(DestName)));
end
else if Assigned(ProcessFile) then
Result:= ProcessFile(hArcData, Operation, PAnsiChar(UTF8ToSys(DestPath)), PAnsiChar(UTF8ToSys(DestName)));
begin
if DestPath = EmptyStr then
pacDestPath:= nil
else
pacDestPath:= PAnsiChar(UTF8ToSys(DestPath));
Result:= ProcessFile(hArcData, Operation, pacDestPath, PAnsiChar(UTF8ToSys(DestName)));
end;
end;
function TWCXModule.WcxPackFiles(PackedFile, SubPath, SrcPath,
AddList: UTF8String; Flags: LongInt): LongInt;
var
pwcSubPath: PWideChar;
pacSubPath: PAnsiChar;
begin
if Assigned(PackFilesW) then
Result:= PackFilesW(PWideChar(UTF8Decode(PackedFile)), PWideChar(UTF8Decode(SubPath)),
PWideChar(UTF8Decode(SrcPath)), PWideChar(UTF8Decode(AddList)), Flags)
begin
if SubPath = EmptyStr then
pwcSubPath:= nil
else
pwcSubPath:= PWideChar(UTF8Decode(SubPath));
Result:= PackFilesW(PWideChar(UTF8Decode(PackedFile)), pwcSubPath,
PWideChar(UTF8Decode(SrcPath)), PWideChar(UTF8Decode(AddList)), Flags);
end
else if Assigned(PackFiles) then
Result:= PackFiles(PAnsiChar(UTF8ToSys(PackedFile)), PAnsiChar(UTF8ToSys(SubPath)),
PAnsiChar(UTF8ToSys(SrcPath)), PAnsiChar(UTF8ToSys(AddList)), Flags)
begin
if SubPath = EmptyStr then
pacSubPath:= nil
else
pacSubPath:= PAnsiChar(UTF8ToSys(SubPath));
Result:= PackFiles(PAnsiChar(UTF8ToSys(PackedFile)), pacSubPath,
PAnsiChar(UTF8ToSys(SrcPath)), PAnsiChar(UTF8ToSys(AddList)), Flags);
end;
end;
function TWCXModule.WcxDeleteFiles(PackedFile, DeleteList: UTF8String): LongInt;
@ -446,7 +476,7 @@ var
begin
HeaderData := nil;
{if Assigned(ReadHeaderExW) then
if Assigned(ReadHeaderExW) then
begin
FillChar(ArcHeaderExW, SizeOf(ArcHeaderExW), #0);
Result := ReadHeaderExW(hArcData, ArcHeaderExW);
@ -455,7 +485,7 @@ begin
HeaderData := TWCXHeader.Create(PHeaderDataExW(@ArcHeaderExW));
end;
end
else} if Assigned(ReadHeaderEx) then
else if Assigned(ReadHeaderEx) then
begin
FillChar(ArcHeaderEx, SizeOf(ArcHeaderEx), #0);
Result := ReadHeaderEx(hArcData, ArcHeaderEx);