View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005477 | JEDI VCL | 00 JVCL Components | public | 2011-02-11 20:38 | 2011-09-21 14:10 |
Reporter | PerhunAndrey | Assigned To | obones | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 3.39 | ||||
Target Version | Fixed in Version | 3.45 | |||
Summary | 0005477: JvCabFile does not extract files from archive's subdirectory | ||||
Description | If archive contains subdirectories one cannot extract files from that subdirectory. I have resolved that issue by correction in jvcl\run\JvCabFile.pas::CExtract - it is needed to check not just a filename but relational path of a file. Diff is attached in Additional Information. | ||||
Additional Information | diff --git a/jvcl/run/JvCabFile.pas b/jvcl/run/JvCabFile.pas index 061b486..2327d2e 100644 --- a/jvcl/run/JvCabFile.pas +++ b/jvcl/run/JvCabFile.pas @@ -172,85 +172,85 @@ end; function CExtract(Context: Pointer; Notification: UINT; Param1, Param2: UINT_PTR): UINT; stdcall; type PUINT_PTR = ^UINT_PTR; var CAB: PFileInCabinetInfo; Sender: TJvCABFile; CABInfo: TCABInfo; Cont: Boolean; Pathes: TFilePaths; Path: string; I: Integer; begin Result := ERROR_BAD_COMMAND; if Context <> nil then Sender := TJvCABFile(Context^) else Exit; // this callback is only for listing files in a Cabinet ... if Notification = SPFILENOTIFY_CABINETINFO then Result := 0 else if Notification = SPFILENOTIFY_FILEINCABINET then // found a file in the Cabinet begin try Result := FILEOP_DOIT; CAB := PFileInCabinetInfo(Param1); if Sender.FDestPath[Length(Sender.FDestPath)] = '\' then begin // extract all Path := Sender.FDestPath + StrPas(CAB^.NameInCabinet); for I := 1 to Length(Path) do CAB^.FullTargetName[I-1] := Path[I]; CAB^.FullTargetName[Length(Path)] := #0; if Assigned(Sender.FOnExtractFile) then Sender.FOnExtractFile(Sender, CAB^.FullTargetName, Sender.FDestPath); end else begin // Extract specific file - if UpperCase(ExtractFileName(Sender.FDestPath)) = UpperCase(StrPas(CAB^.NameInCabinet)) then + if EndsText(StrPas(CAB^.NameInCabinet), Sender.FDestPath) then begin Path := Sender.FDestPath; for I := 1 to Length(Path) do CAB^.FullTargetName[I-1] := Path[I]; CAB^.FullTargetName[Length(Path)] := #0; if Assigned(Sender.FOnExtractFile) then Sender.FOnExtractFile(Sender, CAB^.FullTargetName, Sender.FDestPath); end else Result := FILEOP_SKIP; end; except Result := FILEOP_SKIP; end; end else if Notification = SPFILENOTIFY_FILEEXTRACTED then begin Cont := True; if Param1 <> 0 then Pathes := PFilePaths(Param1)^; if Assigned(Sender.FOnExtracted) then Sender.FOnExtracted(Sender, (Pathes.Win32Error = NO_ERROR), Cont, StrPas(Pathes.Source), StrPas(Pathes.Target)); if Cont then Result := NO_ERROR else Result := ERROR_BAD_COMMAND; end else if Notification = SPFILENOTIFY_NEEDNEWCABINET then begin if Param1 <> 0 then begin CABInfo.CabinetPath := StrPas(PCabinetInfo(Param1)^.CabinetPath); CABInfo.CabinetFile := StrPas(PCabinetInfo(Param1)^.CabinetFile); CABInfo.DiskName := StrPas(PCabinetInfo(Param1)^.DiskName); CABInfo.Id := PCabinetInfo(Param1)^.SetId; CABInfo.CabinetNumber := PCabinetInfo(Param1)^.CabinetNumber; Cont := True; Path := ''; if Assigned(Sender.FOnNeed) then | ||||
Tags | No tags attached. | ||||
|
Used function EndsText from unit StrUtils. |
|
Thanks for the diffs, could you please provide the zipped sources of a sample application showing this? This would make testing and integration much easier. |
|
I wish I have such a program. But the program that i have is too complex for testing purposes. |
2011-02-15 17:54
|
test_function_for_CAB.pas (1,744 bytes) |
|
Here is the test function in test_function_for_CAB.pas |
|
Where is EndsText coming from? It does not exist here. Is that equivalent to StrHasSuffix from the JCL? If yes, please provide the correct code using that function |
|
As I already have said early, that function is in the Delphi`s RTL Library in the StrUtils unit. I do not understand the necessity of use of non-standard function from JVCL. |
|
Ah yes, didn't see that. Well, using "non standard" as you say is required because not all units are available on all versions of Delphi and C++ Builder. StrUtils appears to be available from D6 onward, so we are in luck, but out of habit we tend not to rely on functions inside units that are not available everywhere. |
|
This is now in SVN |
Date Modified | Username | Field | Change |
---|---|---|---|
2011-02-11 20:38 | PerhunAndrey | New Issue | |
2011-02-11 20:43 | PerhunAndrey | Note Added: 0018332 | |
2011-02-15 13:52 | obones | Note Added: 0018359 | |
2011-02-15 13:52 | obones | Status | new => feedback |
2011-02-15 17:46 | PerhunAndrey | Note Added: 0018370 | |
2011-02-15 17:54 | PerhunAndrey | File Added: test_function_for_CAB.pas | |
2011-02-15 17:55 | PerhunAndrey | Note Added: 0018371 | |
2011-06-07 17:39 | obones | Status | feedback => acknowledged |
2011-06-08 14:09 | obones | Note Added: 0018666 | |
2011-06-08 14:09 | obones | Status | acknowledged => feedback |
2011-06-10 08:58 | PerhunAndrey | Note Added: 0018716 | |
2011-06-10 09:04 | obones | Note Added: 0018717 | |
2011-06-10 09:07 | obones | Note Added: 0018718 | |
2011-06-10 09:07 | obones | Status | feedback => resolved |
2011-06-10 09:07 | obones | Fixed in Version | => Daily / SVN |
2011-06-10 09:07 | obones | Resolution | open => fixed |
2011-06-10 09:07 | obones | Assigned To | => obones |
2011-09-21 14:10 | obones | Fixed in Version | Daily / SVN => 3.45 |