View Issue Details

IDProjectCategoryView StatusLast Update
0005477JEDI VCL00 JVCL Componentspublic2011-09-21 14:10
ReporterPerhunAndreyAssigned Toobones 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.39 
Target VersionFixed in Version3.45 
Summary0005477: JvCabFile does not extract files from archive's subdirectory
DescriptionIf 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 Informationdiff --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
TagsNo tags attached.

Activities

PerhunAndrey

2011-02-11 20:43

reporter   ~0018332

Used function EndsText from unit StrUtils.

obones

2011-02-15 13:52

administrator   ~0018359

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.

PerhunAndrey

2011-02-15 17:46

reporter   ~0018370

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)

PerhunAndrey

2011-02-15 17:55

reporter   ~0018371

Here is the test function in test_function_for_CAB.pas

obones

2011-06-08 14:09

administrator   ~0018666

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

PerhunAndrey

2011-06-10 08:58

reporter   ~0018716

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.

obones

2011-06-10 09:04

administrator   ~0018717

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.

obones

2011-06-10 09:07

administrator   ~0018718

This is now in SVN

Issue History

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