Subversion Repositories decoder

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit KAZip;
  2.  
  3. // Verändert für (De)Coder 4.x
  4. // Veränderungen gekennzeichnet mit "Marschall"
  5. // Keine Compilerwarnungen mehr...
  6.  
  7. // Schutz von freiem Speicherplatz
  8. // Gekennzeichnet mit "Sicherheitsbestimmung"
  9.  
  10. // Marschall
  11. {$WARN SYMBOL_PLATFORM OFF}
  12.  
  13. interface
  14. {$DEFINE USE_BZIP2}
  15. uses
  16.   Windows,
  17.   SysUtils,
  18.   Classes,
  19.   Masks,
  20.   TypInfo,
  21.   {$IFDEF USE_BZIP2}
  22.   BZip2,
  23.   {$ENDIF}
  24.   ZLib,
  25.   // Sicherheitsbestimmung
  26.   decutil;
  27.  
  28. type
  29.   TKAZipEntries         = class;
  30.   TKAZip                = class;
  31.   TBytes                = Array of Byte;
  32.   TZipSaveMethod        = (FastSave, RebuildAll);
  33.   TZipCompressionType   = (ctNormal, ctMaximum, ctFast, ctSuperFast, ctNone, ctUnknown);
  34.   TZipCompressionMethod = (cmStored, cmShrunk, cmReduced1, cmReduced2, cmReduced3, cmReduced4, cmImploded, cmTokenizingReserved, cmDeflated, cmDeflated64, cmDCLImploding, cmPKWAREReserved);
  35.   TOverwriteAction      = (oaSkip,oaSkipAll,oaOverwrite,oaOverwriteAll);
  36.  
  37.   TOnDecompressFile=Procedure(Sender:TObject; Current, Total : Integer) of Object;
  38.   TOnCompressFile=Procedure(Sender:TObject; Current, Total : Integer) of Object;
  39.   TOnZipOpen=Procedure(Sender:TObject; Current, Total : Integer) of Object;
  40.   TOnZipChange=Procedure(Sender:TObject; ChangeType : Integer) of Object;
  41.   TOnAddItem=Procedure(Sender:TObject; ItemName : String) of Object;
  42.   TOnRebuildZip=Procedure(Sender:TObject; Current, Total : Integer) of Object;
  43.   TOnRemoveItems=Procedure(Sender:TObject; Current, Total : Integer) of Object;
  44.   TOnOverwriteFile=Procedure(Sender:TObject; Var FileName : String; Var Action : TOverwriteAction) of Object;
  45.  
  46.   {
  47.           0 - The file is stored (no compression)
  48.           1 - The file is Shrunk
  49.           2 - The file is Reduced with compression factor 1
  50.           3 - The file is Reduced with compression factor 2
  51.           4 - The file is Reduced with compression factor 3
  52.           5 - The file is Reduced with compression factor 4
  53.           6 - The file is Imploded
  54.           7 - Reserved for Tokenizing compression algorithm
  55.           8 - The file is Deflated
  56.           9 - Enhanced Deflating using Deflate64(tm)
  57.          10 - PKWARE Data Compression Library Imploding
  58.          11 - Reserved by PKWARE
  59.          12 - File is compressed using BZIP2 algorithm
  60.    }
  61.  
  62.   {DoChange Events
  63.     0 - Zip is Closed;
  64.     1 - Zip is Opened;
  65.     2 - Item is added to the zip
  66.     3 - Item is removed from the Zip
  67.     4 - Item comment changed
  68.     5 - Item name changed
  69.     6 - Item name changed
  70.   }
  71.  
  72.   TZLibStreamHeader = packed record
  73.      CMF : Byte;
  74.      FLG : Byte;
  75.   end;
  76.  
  77.   TLocalFile = packed record
  78.     LocalFileHeaderSignature       : Cardinal;   //    4 bytes  (0x04034b50)
  79.     VersionNeededToExtract         : WORD;       //    2 bytes
  80.     GeneralPurposeBitFlag          : WORD;       //    2 bytes
  81.     CompressionMethod              : WORD;       //    2 bytes
  82.     LastModFileTimeDate            : Cardinal;   //    4 bytes
  83.     Crc32                          : Cardinal;   //    4 bytes
  84.     CompressedSize                 : Cardinal;   //    4 bytes
  85.     UncompressedSize               : Cardinal;   //    4 bytes
  86.     FilenameLength                 : WORD;       //    2 bytes
  87.     ExtraFieldLength               : WORD;       //    2 bytes
  88.     FileName                       : AnsiString; //    variable size
  89.     ExtraField                     : AnsiString; //    variable size
  90.     CompressedData                 : AnsiString; //    variable size
  91.   end;
  92.  
  93.   TDataDescriptor = packed record
  94.     DescriptorSignature            : Cardinal;   //    4 bytes UNDOCUMENTED
  95.     Crc32                          : Cardinal;   //    4 bytes
  96.     CompressedSize                 : Cardinal;   //    4 bytes
  97.     UncompressedSize               : Cardinal;   //    4 bytes
  98.   End;
  99.  
  100.   TCentralDirectoryFile = packed record
  101.     CentralFileHeaderSignature     : Cardinal;   //    4 bytes  (0x02014b50)
  102.     VersionMadeBy                  : WORD;       //    2 bytes
  103.     VersionNeededToExtract         : WORD;       //    2 bytes
  104.     GeneralPurposeBitFlag          : WORD;       //    2 bytes
  105.     CompressionMethod              : WORD;       //    2 bytes
  106.     LastModFileTimeDate            : Cardinal;   //    4 bytes
  107.     Crc32                          : Cardinal;   //    4 bytes
  108.     CompressedSize                 : Cardinal;   //    4 bytes
  109.     UncompressedSize               : Cardinal;   //    4 bytes
  110.     FilenameLength                 : WORD;       //    2 bytes
  111.     ExtraFieldLength               : WORD;       //    2 bytes
  112.     FileCommentLength              : WORD;       //    2 bytes
  113.     DiskNumberStart                : WORD;       //    2 bytes
  114.     InternalFileAttributes         : WORD;       //    2 bytes
  115.     ExternalFileAttributes         : Cardinal;   //    4 bytes
  116.     RelativeOffsetOfLocalHeader    : Cardinal;   //    4 bytes
  117.     FileName                       : AnsiString; //    variable size
  118.     ExtraField                     : AnsiString; //    variable size
  119.     FileComment                    : AnsiString; //    variable size
  120.   end;
  121.  
  122.   TEndOfCentralDir = packed record
  123.     EndOfCentralDirSignature        : Cardinal;  //    4 bytes  (0x06054b50)
  124.     NumberOfThisDisk                : WORD;      //    2 bytes
  125.     NumberOfTheDiskWithTheStart     : WORD;      //    2 bytes
  126.     TotalNumberOfEntriesOnThisDisk  : WORD;      //    2 bytes
  127.     TotalNumberOfEntries            : WORD;      //    2 bytes
  128.     SizeOfTheCentralDirectory       : Cardinal;  //    4 bytes
  129.     OffsetOfStartOfCentralDirectory : Cardinal;  //    4 bytes
  130.     ZipfileCommentLength            : WORD;      //    2 bytes
  131.   end;
  132.  
  133.  
  134.  
  135.   TKAZipEntriesEntry = Class(TCollectionItem)
  136.   private
  137.     { Private declarations }
  138.     FParent               : TKAZipEntries;
  139.     FCentralDirectoryFile : TCentralDirectoryFile;
  140.     FLocalFile            : TLocalFile;
  141.     FIsEncrypted          : Boolean;
  142.     FIsFolder             : Boolean;
  143.     FDate                 : TDateTime;
  144.     FCompressionType      : TZipCompressionType;
  145.     FSelected             : Boolean;
  146.  
  147.     procedure  SetSelected(const Value: Boolean);
  148.     function   GetLocalEntrySize: Cardinal;
  149.     function   GetCentralEntrySize: Cardinal;
  150.     procedure  SetComment(const Value: String);
  151.     procedure  SetFileName(const Value: String);
  152.   protected
  153.     { Protected declarations }
  154.   public
  155.     { Public declarations }
  156.     constructor Create(Collection: TCollection); override;
  157.     destructor  Destroy; override;
  158.     Function    GetCompressedData : String;Overload;
  159.     Function    GetCompressedData(Stream : TStream) : Integer;Overload;
  160.     procedure   ExtractToFile(FileName: String);
  161.     procedure   ExtractToStream(Stream: TStream);
  162.     procedure   SaveToFile(FileName: String);
  163.     procedure   SaveToStream(Stream: TStream);
  164.     Function    Test:Boolean;
  165.  
  166.     Property    FileName          : String               Read FCentralDirectoryFile.FileName                     Write SetFileName;
  167.     Property    Comment           : String               Read FCentralDirectoryFile.FileComment                  Write SetComment;
  168.     Property    SizeUncompressed  : Cardinal             Read FCentralDirectoryFile.UncompressedSize;
  169.     Property    SizeCompressed    : Cardinal             Read FCentralDirectoryFile.CompressedSize;
  170.     Property    Date              : TDateTime            Read FDate;
  171.     Property    CRC32             : Cardinal             Read FCentralDirectoryFile.CRC32;
  172.     Property    Attributes        : Cardinal             Read FCentralDirectoryFile.ExternalFileAttributes;
  173.     Property    LocalOffset       : Cardinal             Read FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
  174.     Property    IsEncrypted       : Boolean              Read FIsEncrypted;
  175.     Property    IsFolder          : Boolean              Read FIsFolder;
  176.     Property    BitFlag           : Word                 Read FCentralDirectoryFile.GeneralPurposeBitFlag;
  177.     Property    CompressionMethod : Word                 Read FCentralDirectoryFile.CompressionMethod;
  178.     Property    CompressionType   : TZipCompressionType  Read FCompressionType;
  179.     Property    LocalEntrySize    : Cardinal             Read GetLocalEntrySize;
  180.     Property    CentralEntrySize  : Cardinal             Read GetCentralEntrySize;
  181.     Property    Selected          : Boolean              Read FSelected                                          Write  SetSelected;
  182.   End;
  183.  
  184.   TKAZipEntries = class(TCollection)
  185.   private
  186.     { Private declarations }
  187.     FParent              : TKAZip;
  188.     FIsZipFile           : Boolean;
  189.     FLocalHeaderNumFiles : Integer;
  190.  
  191.     function    GetHeaderEntry(Index: Integer): TKAZipEntriesEntry;
  192.     procedure   SetHeaderEntry(Index: Integer; const Value: TKAZipEntriesEntry);
  193.   protected
  194.     { Protected declarations }
  195.     Function    ReadBA(MS: TStream;Sz,Poz:Integer): TBytes;
  196.     function    Adler32(adler : uLong; buf : pByte; len : uInt) : uLong;
  197.     function    CalcCRC32(const UncompressedData : string): Cardinal;
  198.     function    CalculateCRCFromStream(Stream: TStream): Cardinal;
  199.     Function    RemoveRootName(Const FileName, RootName : String):String;
  200.     Procedure   SortList(List : TList);
  201.     function    FileTime2DateTime(FileTime: TFileTime): TDateTime;
  202.     //**************************************************************************
  203.     Function    FindCentralDirectory(MS:TStream):Boolean;
  204.     function    ParseCentralHeaders(MS: TStream): Boolean;
  205.     function    GetLocalEntry(MS: TStream; Offset : Integer; HeaderOnly : Boolean): TLocalFile;
  206.     Procedure   LoadLocalHeaders(MS: TStream);
  207.     Function    ParseLocalHeaders(MS:TStream):Boolean;
  208.  
  209.     //**************************************************************************
  210.     procedure   Remove(ItemIndex: Integer; Flush : Boolean);Overload;
  211.     procedure   RemoveBatch(Files : TList);
  212.     procedure   InternalExtractToFile(Item: TKAZipEntriesEntry; FileName: String);
  213.     //**************************************************************************
  214.     Function    AddStreamFast(ItemName:String; FileAttr : Word; FileDate : TDateTime; Stream:TStream):TKAZipEntriesEntry;Overload;
  215.     Function    AddStreamRebuild(ItemName:String; FileAttr : Word; FileDate : TDateTime; Stream:TStream):TKAZipEntriesEntry;
  216.     Function    AddFolderChain(ItemName:String):Boolean;Overload;
  217.     Function    AddFolderChain(ItemName:String; FileAttr : Word; FileDate : TDateTime):Boolean;Overload;
  218.     Function    AddFolderEx(FolderName:String; RootFolder:String; WildCard:String; WithSubFolders : Boolean):Boolean;
  219.     //**************************************************************************
  220.   public
  221.     { Public declarations }
  222.     Procedure   ParseZip(MS:TStream);
  223.     Constructor Create(AOwner : TKAZip; MS : TStream);Overload;
  224.     Constructor Create(AOwner : TKAZip);Overload;
  225.     Destructor  Destroy; Override;
  226.     //**************************************************************************
  227.     Function    IndexOf(Const FileName:String):Integer;
  228.     //**************************************************************************
  229.     Function    AddFile(FileName, NewFileName: String):TKAZipEntriesEntry;Overload;
  230.     Function    AddFile(FileName:String):TKAZipEntriesEntry;Overload;
  231.     Function    AddFiles(FileNames:TStrings):Boolean;
  232.     Function    AddFolder(FolderName:String; RootFolder:String; WildCard:String; WithSubFolders : Boolean):Boolean;
  233.     Function    AddFilesAndFolders(FileNames:TStrings; RootFolder:String; WithSubFolders : Boolean):Boolean;
  234.     Function    AddStream(FileName:String; FileAttr : Word; FileDate : TDateTime; Stream:TStream):TKAZipEntriesEntry;Overload;
  235.     Function    AddStream(FileName: String; Stream : TStream):TKAZipEntriesEntry;Overload;
  236.     //**************************************************************************
  237.     Procedure   Remove(ItemIndex:Integer);Overload;
  238.     Procedure   Remove(Item:TKAZipEntriesEntry);Overload;
  239.     Procedure   Remove(FileName:String);Overload;
  240.     Procedure   RemoveFiles(List : TList);
  241.     Procedure   RemoveSelected;
  242.     Procedure   Rebuild;
  243.    //**************************************************************************
  244.     Procedure   Select(WildCard : String);
  245.     Procedure   SelectAll;
  246.     Procedure   DeSelectAll;
  247.     Procedure   InvertSelection;
  248.     //**************************************************************************
  249.     Procedure   Rename(Item : TKAZipEntriesEntry; NewFileName: String);Overload;
  250.     Procedure   Rename(ItemIndex : Integer; NewFileName: String);Overload;
  251.     Procedure   Rename(FileName: String; NewFileName: String);Overload;
  252.     procedure   CreateFolder(FolderName: String; FolderDate: TDateTime);
  253.     procedure   RenameFolder(FolderName : String; NewFolderName : String);
  254.     procedure   RenameMultiple(Names : TStringList; NewNames : TStringList);
  255.  
  256.     //**************************************************************************
  257.     procedure   ExtractToFile  (Item : TKAZipEntriesEntry; FileName: String);Overload;
  258.     procedure   ExtractToFile  (ItemIndex : Integer; FileName: String);Overload;
  259.     procedure   ExtractToFile  (FileName, DestinationFileName:String);Overload;
  260.     procedure   ExtractToStream(Item : TKAZipEntriesEntry; Stream: TStream);
  261.     procedure   ExtractAll(TargetDirectory:String);
  262.     procedure   ExtractSelected(TargetDirectory:String);
  263.     //**************************************************************************
  264.     Property    Items[Index : Integer] : TKAZipEntriesEntry read GetHeaderEntry write SetHeaderEntry;
  265.   end;
  266.  
  267.   TKAZip = class(TComponent)
  268.   private
  269.     { Private declarations }
  270.     FZipHeader            : TKAZipEntries;
  271.     FIsDirty              : Boolean;
  272.     FEndOfCentralDirPos   : Cardinal;
  273.     FEndOfCentralDir      : TEndOfCentralDir;
  274.  
  275.     FZipCommentPos        : Cardinal;
  276.     FZipComment           : TStringList;
  277.  
  278.     FRebuildECDP          : Cardinal;
  279.     FRebuildCP            : Cardinal;
  280.  
  281.     FIsZipFile            : Boolean;
  282.     FHasBadEntries        : Boolean;
  283.     FFileName             : String;
  284.     FFileNames            : TStringList;
  285.     FZipSaveMethod        : TZipSaveMethod;
  286.  
  287.     FExternalStream       : Boolean;
  288.     FStoreRelativePath    : Boolean;
  289.     FZipCompressionType   : TZipCompressionType;
  290.  
  291.     FCurrentDFS           : Cardinal;
  292.     FOnDecompressFile     : TOnDecompressFile;
  293.     FOnCompressFile       : TOnCompressFile;
  294.     FOnZipChange          : TOnZipChange;
  295.     FBatchMode            : Boolean;
  296.  
  297.     NewLHOffsets          : Array of Cardinal;
  298.     NewEndOfCentralDir    : TEndOfCentralDir;
  299.     FOnZipOpen            : TOnZipOpen;
  300.     FUseTempFiles         : Boolean;
  301.     FStoreFolders         : Boolean;
  302.     FOnAddItem            : TOnAddItem;
  303.     FComponentVersion     : String;
  304.     FOnRebuildZip         : TOnRebuildZip;
  305.     FOnRemoveItems        : TOnRemoveItems;
  306.     FOverwriteAction      : TOverwriteAction;
  307.     FOnOverwriteFile      : TOnOverwriteFile;
  308.     FReadOnly             : Boolean;
  309.     FApplyAttributes      : Boolean;
  310.  
  311.     procedure   SetFileName(const Value: String);
  312.     procedure   SetIsZipFile(const Value: Boolean);
  313.     function    GetComment: TStrings;
  314.     procedure   SetComment(const Value: TStrings);
  315.     procedure   SetZipSaveMethod(const Value: TZipSaveMethod);
  316.     procedure   SetActive(const Value: Boolean);
  317.     procedure   SetZipCompressionType(const Value: TZipCompressionType);
  318.     function    GetFileNames: TStrings;
  319.     procedure   SetFileNames(const Value: TStrings);
  320.     procedure   SetUseTempFiles(const Value: Boolean);
  321.     procedure   SetStoreFolders(const Value: Boolean);
  322.     procedure   SetOnAddItem(const Value: TOnAddItem);
  323.     procedure   SetComponentVersion(const Value: String);
  324.     procedure   SetOnRebuildZip(const Value: TOnRebuildZip);
  325.     procedure   SetOnRemoveItems(const Value: TOnRemoveItems);
  326.     procedure   SetOverwriteAction(const Value: TOverwriteAction);
  327.     procedure   SetOnOverwriteFile(const Value: TOnOverwriteFile);
  328.     procedure SetReadOnly(const Value: Boolean);
  329.     procedure SetApplyAtributes(const Value: Boolean);
  330.   protected
  331.     { Protected declarations }
  332.     FZipStream  : TStream;
  333.     //**************************************************************************
  334.     Procedure   LoadFromFile(FileName:String);
  335.     Procedure   LoadFromStream(MS : TStream);
  336.     //**************************************************************************
  337.     Procedure   RebuildLocalFiles(MS : TStream);
  338.     Procedure   RebuildCentralDirectory(MS : TStream);
  339.     Procedure   RebuildEndOfCentralDirectory(MS : TStream);
  340.     //**************************************************************************
  341.     procedure   OnDecompress(Sender:TObject);
  342.     procedure   OnCompress(Sender:TObject);
  343.     Procedure   DoChange(Sender:TObject; Const ChangeType : Integer);Virtual;
  344.     //**************************************************************************
  345.   public
  346.     { Public declarations }
  347.     Constructor Create(AOwner:TComponent);Override;
  348.     Destructor  Destroy; Override;
  349.     //**************************************************************************
  350.     function    GetDelphiTempFileName: String;
  351.     function    GetFileName(S: String): String;
  352.     function    GetFilePath(S: String): String;
  353.     //**************************************************************************
  354.     Procedure   CreateZip(Stream:TStream);Overload;
  355.     Procedure   CreateZip(FileName:String);Overload;
  356.     Procedure   Open(FileName:String);Overload;
  357.     Procedure   Open(MS : TStream);Overload;
  358.     Procedure   SaveToStream(Stream:TStream);
  359.     Procedure   Rebuild;
  360.     Procedure   FixZip(MS : TStream);
  361.     Procedure   Close;
  362.     //**************************************************************************
  363.     Function    AddFile(FileName, NewFileName: String):TKAZipEntriesEntry;Overload;
  364.     Function    AddFile(FileName:String):TKAZipEntriesEntry;Overload;
  365.     Function    AddFiles(FileNames:TStrings):Boolean;
  366.     Function    AddFolder(FolderName:String; RootFolder:String; WildCard:String; WithSubFolders : Boolean):Boolean;
  367.     Function    AddFilesAndFolders(FileNames:TStrings; RootFolder:String; WithSubFolders : Boolean):Boolean;
  368.     Function    AddStream(FileName:String; FileAttr : Word; FileDate : TDateTime; Stream:TStream):TKAZipEntriesEntry;Overload;
  369.     Function    AddStream(FileName: String; Stream : TStream):TKAZipEntriesEntry;Overload;
  370.     //**************************************************************************
  371.     Procedure   Remove(ItemIndex:Integer);Overload;
  372.     Procedure   Remove(Item:TKAZipEntriesEntry);Overload;
  373.     Procedure   Remove(FileName:String);Overload;
  374.     Procedure   RemoveFiles(List : TList);
  375.     Procedure   RemoveSelected;
  376.     //**************************************************************************
  377.     Procedure   Select(WildCard : String);
  378.     Procedure   SelectAll;
  379.     Procedure   DeSelectAll;
  380.     Procedure   InvertSelection;
  381.     //**************************************************************************
  382.     Procedure   Rename(Item : TKAZipEntriesEntry; NewFileName: String);Overload;
  383.     Procedure   Rename(ItemIndex : Integer; NewFileName: String);Overload;
  384.     Procedure   Rename(FileName : String; NewFileName: String);Overload;
  385.     Procedure   CreateFolder(FolderName : String; FolderDate : TDateTime);
  386.     Procedure   RenameFolder(FolderName : String; NewFolderName : String);
  387.     procedure   RenameMultiple(Names : TStringList; NewNames : TStringList);
  388.     //**************************************************************************
  389.     procedure   ExtractToFile  (Item      : TKAZipEntriesEntry; FileName: String);Overload;
  390.     procedure   ExtractToFile  (ItemIndex : Integer; FileName: String);Overload;
  391.     procedure   ExtractToFile  (FileName, DestinationFileName:String);Overload;
  392.     procedure   ExtractToStream(Item      : TKAZipEntriesEntry; Stream: TStream);
  393.     procedure   ExtractAll(TargetDirectory: String);
  394.     procedure   ExtractSelected(TargetDirectory: String);
  395.     //**************************************************************************
  396.     Property    Entries         : TKAZipEntries Read FZipHeader;
  397.     Property    HasBadEntries   : Boolean       Read FHasBadEntries;
  398.   published
  399.     { Published declarations }
  400.     Property    FileName          : String              Read FFileName           Write SetFileName;
  401.     Property    IsZipFile         : Boolean             Read FIsZipFile          Write SetIsZipFile;
  402.     Property    SaveMethod        : TZipSaveMethod      Read FZipSaveMethod      Write SetZipSaveMethod;
  403.     Property    StoreRelativePath : Boolean             Read FStoreRelativePath  Write FStoreRelativePath;
  404.     Property    StoreFolders      : Boolean             read FStoreFolders       write SetStoreFolders;
  405.     Property    CompressionType   : TZipCompressionType Read FZipCompressionType Write SetZipCompressionType;
  406.     Property    Comment           : TStrings            Read GetComment          Write SetComment;
  407.     Property    FileNames         : TStrings            Read GetFileNames        Write SetFileNames;
  408.     Property    UseTempFiles      : Boolean             read FUseTempFiles       write SetUseTempFiles;
  409.     Property    OverwriteAction   : TOverwriteAction    read FOverwriteAction    write SetOverwriteAction;
  410.     Property    ComponentVersion  : String              read FComponentVersion   write SetComponentVersion;
  411.     Property    ReadOnly          : Boolean             read FReadOnly           write SetReadOnly;
  412.     Property    ApplyAtributes    : Boolean             read FApplyAttributes    write SetApplyAtributes;
  413.     Property    OnDecompressFile  : TOnDecompressFile   Read FOnDecompressFile   Write FOnDecompressFile;
  414.     Property    OnCompressFile    : TOnCompressFile     Read FOnCompressFile     Write FOnCompressFile;
  415.     Property    OnZipChange       : TOnZipChange        Read FOnZipChange        Write FOnZipChange;
  416.     Property    OnZipOpen         : TOnZipOpen          Read FOnZipOpen          Write FOnZipOpen;
  417.     Property    OnAddItem         : TOnAddItem          read FOnAddItem          write SetOnAddItem;
  418.     Property    OnRebuildZip      : TOnRebuildZip       read FOnRebuildZip       write SetOnRebuildZip;
  419.     Property    OnRemoveItems     : TOnRemoveItems      read FOnRemoveItems      write SetOnRemoveItems;
  420.     Property    OnOverwriteFile   : TOnOverwriteFile    read FOnOverwriteFile    write SetOnOverwriteFile;
  421.     Property    Active            : Boolean             Read FIsZipFile          Write SetActive;
  422.   end;
  423.  
  424. procedure Register;
  425. Function ToZipName(FileName:String):String;
  426. Function ToDosName(FileName:String):String;
  427.  
  428. implementation
  429.  
  430. Const
  431.   ZL_DEF_COMPRESSIONMETHOD  = $8;  { Deflate }
  432.   ZL_ENCH_COMPRESSIONMETHOD = $9;  { Enchanced Deflate }
  433.   ZL_DEF_COMPRESSIONINFO    = $7;  { 32k window for Deflate }
  434.   ZL_PRESET_DICT            = $20;
  435.  
  436.   ZL_FASTEST_COMPRESSION    = $0;
  437.   ZL_FAST_COMPRESSION       = $1;
  438.   ZL_DEFAULT_COMPRESSION    = $2;
  439.   ZL_MAXIMUM_COMPRESSION    = $3;
  440.  
  441.   ZL_FCHECK_MASK            = $1F;
  442.   ZL_CINFO_MASK             = $F0; { mask out leftmost 4 bits }
  443.   ZL_FLEVEL_MASK            = $C0; { mask out leftmost 2 bits }
  444.   ZL_CM_MASK                = $0F; { mask out rightmost 4 bits }
  445.  
  446.  
  447.   ZL_MULTIPLE_DISK_SIG      = $08074b50; // 'PK'#7#8
  448.   ZL_DATA_DESCRIPT_SIG      = $08074b50; // 'PK'#7#8
  449.   ZL_LOCAL_HEADERSIG        = $04034b50; // 'PK'#3#4
  450.   ZL_CENTRAL_HEADERSIG      = $02014b50; // 'PK'#1#2
  451.   ZL_EOC_HEADERSIG          = $06054b50; // 'PK'#5#6
  452.  
  453.   const
  454.   CRCTable: array[0..255] of Cardinal = (
  455.     $00000000, $77073096, $EE0E612C, $990951BA, $076DC419, $706AF48F, $E963A535,
  456.     $9E6495A3, $0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988, $09B64C2B, $7EB17CBD,
  457.     $E7B82D07, $90BF1D91, $1DB71064, $6AB020F2, $F3B97148, $84BE41DE, $1ADAD47D,
  458.     $6DDDE4EB, $F4D4B551, $83D385C7, $136C9856, $646BA8C0, $FD62F97A, $8A65C9EC,
  459.     $14015C4F, $63066CD9, $FA0F3D63, $8D080DF5, $3B6E20C8, $4C69105E, $D56041E4,
  460.     $A2677172, $3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B, $35B5A8FA, $42B2986C,
  461.     $DBBBC9D6, $ACBCF940, $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59, $26D930AC,
  462.     $51DE003A, $C8D75180, $BFD06116, $21B4F4B5, $56B3C423, $CFBA9599, $B8BDA50F,
  463.     $2802B89E, $5F058808, $C60CD9B2, $B10BE924, $2F6F7C87, $58684C11, $C1611DAB,
  464.     $B6662D3D, $76DC4190, $01DB7106, $98D220BC, $EFD5102A, $71B18589, $06B6B51F,
  465.     $9FBFE4A5, $E8B8D433, $7807C9A2, $0F00F934, $9609A88E, $E10E9818, $7F6A0DBB,
  466.     $086D3D2D, $91646C97, $E6635C01, $6B6B51F4, $1C6C6162, $856530D8, $F262004E,
  467.     $6C0695ED, $1B01A57B, $8208F4C1, $F50FC457, $65B0D9C6, $12B7E950, $8BBEB8EA,
  468.     $FCB9887C, $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65, $4DB26158, $3AB551CE,
  469.     $A3BC0074, $D4BB30E2, $4ADFA541, $3DD895D7, $A4D1C46D, $D3D6F4FB, $4369E96A,
  470.     $346ED9FC, $AD678846, $DA60B8D0, $44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9,
  471.     $5005713C, $270241AA, $BE0B1010, $C90C2086, $5768B525, $206F85B3, $B966D409,
  472.     $CE61E49F, $5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4, $59B33D17, $2EB40D81,
  473.     $B7BD5C3B, $C0BA6CAD, $EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A, $EAD54739,
  474.     $9DD277AF, $04DB2615, $73DC1683, $E3630B12, $94643B84, $0D6D6A3E, $7A6A5AA8,
  475.     $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1, $F00F9344, $8708A3D2, $1E01F268,
  476.     $6906C2FE, $F762575D, $806567CB, $196C3671, $6E6B06E7, $FED41B76, $89D32BE0,
  477.     $10DA7A5A, $67DD4ACC, $F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5, $D6D6A3E8,
  478.     $A1D1937E, $38D8C2C4, $4FDFF252, $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B,
  479.     $D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60, $DF60EFC3, $A867DF55, $316E8EEF,
  480.     $4669BE79, $CB61B38C, $BC66831A, $256FD2A0, $5268E236, $CC0C7795, $BB0B4703,
  481.     $220216B9, $5505262F, $C5BA3BBE, $B2BD0B28, $2BB45A92, $5CB36A04, $C2D7FFA7,
  482.     $B5D0CF31, $2CD99E8B, $5BDEAE1D, $9B64C2B0, $EC63F226, $756AA39C, $026D930A,
  483.     $9C0906A9, $EB0E363F, $72076785, $05005713, $95BF4A82, $E2B87A14, $7BB12BAE,
  484.     $0CB61B38, $92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21, $86D3D2D4, $F1D4E242,
  485.     $68DDB3F8, $1FDA836E, $81BE16CD, $F6B9265B, $6FB077E1, $18B74777, $88085AE6,
  486.     $FF0F6A70, $66063BCA, $11010B5C, $8F659EFF, $F862AE69, $616BFFD3, $166CCF45,
  487.     $A00AE278, $D70DD2EE, $4E048354, $3903B3C2, $A7672661, $D06016F7, $4969474D,
  488.     $3E6E77DB, $AED16A4A, $D9D65ADC, $40DF0B66, $37D83BF0, $A9BCAE53, $DEBB9EC5,
  489.     $47B2CF7F, $30B5FFE9, $BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6, $BAD03605,
  490.     $CDD70693, $54DE5729, $23D967BF, $B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94,
  491.     $B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D);
  492.  
  493.  
  494. // Sicherheitsbestimmung
  495.  
  496. procedure dc_deletefile(Filename: string);
  497. const
  498.   buf = 1024;
  499. var
  500.   S: TStream;
  501.   size: int64;
  502.   abbruch: boolean;
  503.   lAttributes: integer;
  504. begin
  505.   if fileexists(filename) then
  506.   begin
  507.     try
  508.       lAttributes := FileGetAttr(Filename);
  509.       if lAttributes and SysUtils.faReadOnly <> 0 then
  510.       begin
  511.         lAttributes := lAttributes - SysUtils.faReadOnly;
  512.         FileSetAttr(Filename, lAttributes);
  513.       end;
  514.       S := TFileStream.Create(Filename, fmOpenWrite or fmShareExclusive);
  515.       try
  516.         size := S.Size;
  517.         //mainform.progress_position(wartenform.pbr_progress.min);
  518.         //mainform.progress_text(mainform.GetLangEntry('deletefile'), filename);
  519.         abbruch := false;
  520.         while not abbruch do
  521.         begin
  522.           size := size - buf;
  523.           if size > 0 then
  524.           begin
  525.             ProtectStream(S, buf);
  526.             //mainform.progress_position(floor((s.size-size) / s.Size * wartenform.pbr_progress.max));
  527.           end
  528.           else
  529.           begin
  530.             if size < 0 then
  531.               ProtectStream(S, s.size-s.Position); // wenn nicht size = 0
  532.  
  533.             //mainform.progress_position(wartenform.pbr_progress.min);
  534.  
  535.             abbruch := true;
  536.           end;
  537.         end;
  538.       finally
  539.         S.Free;
  540.       end;
  541.       deletefile(pchar(filename));
  542.     except
  543.  
  544.     end;
  545.   end;
  546. end;
  547.  
  548. // Ende Sicherheitsbestimmung
  549.  
  550. procedure Register;
  551. begin
  552.   RegisterComponents('KA', [TKAZip]);
  553. end;
  554.  
  555. Function ToZipName(FileName:String):String;
  556. Var
  557.  P : Integer;
  558. Begin
  559.   Result := FileName;
  560.   Result := StringReplace(Result,'\','/',[rfReplaceAll]);
  561.   P := Pos(':/',Result);
  562.   if P > 0 Then
  563.      Begin
  564.        System.Delete(Result,1,P+1);
  565.      End;
  566.   P := Pos('//',Result);
  567.   if P > 0 Then
  568.      Begin
  569.        System.Delete(Result,1,P+1);
  570.        P := Pos('/',Result);
  571.        if P > 0 Then
  572.           Begin
  573.              System.Delete(Result,1,P);
  574.              P := Pos('/',Result);
  575.              if P > 0 Then System.Delete(Result,1,P);
  576.           End;
  577.      End;
  578. End;
  579.  
  580.  
  581. Function ToDosName(FileName:String):String;
  582. Var
  583.  P : Integer;
  584. Begin
  585.   Result := FileName;
  586.   Result := StringReplace(Result,'\','/',[rfReplaceAll]);
  587.   P := Pos(':/',Result);
  588.   if P > 0 Then
  589.      Begin
  590.        System.Delete(Result,1,P+1);
  591.      End;
  592.   P := Pos('//',Result);
  593.   if P > 0 Then
  594.      Begin
  595.        System.Delete(Result,1,P+1);
  596.        P := Pos('/',Result);
  597.        if P > 0 Then
  598.           Begin
  599.              System.Delete(Result,1,P);
  600.              P := Pos('/',Result);
  601.              if P > 0 Then System.Delete(Result,1,P);
  602.           End;
  603.      End;
  604.   Result := StringReplace(Result,'/','\',[rfReplaceAll]);
  605. End;
  606.  
  607. { TKAZipEntriesEntry }
  608.  
  609. constructor TKAZipEntriesEntry.Create(Collection: TCollection);
  610. begin
  611.   inherited Create(Collection);
  612.   FParent   := TKAZipEntries(Collection);
  613.   FSelected := False;
  614. end;
  615.  
  616. destructor TKAZipEntriesEntry.Destroy;
  617. begin
  618.  
  619.   inherited Destroy;
  620. end;
  621.  
  622. procedure TKAZipEntriesEntry.ExtractToFile(FileName: String);
  623. begin
  624.   FParent.ExtractToFile(Self,FileName);
  625. end;
  626.  
  627. procedure TKAZipEntriesEntry.ExtractToStream(Stream: TStream);
  628. begin
  629.   FParent.ExtractToStream(Self,Stream);
  630. end;
  631.  
  632. procedure TKAZipEntriesEntry.SaveToFile(FileName: String);
  633. begin
  634.   ExtractToFile(FileName);
  635. end;
  636.  
  637. procedure TKAZipEntriesEntry.SaveToStream(Stream: TStream);
  638. begin
  639.   ExtractToStream(Stream);
  640. end;
  641.  
  642.  
  643. function TKAZipEntriesEntry.GetCompressedData(Stream: TStream): Integer;
  644. Var
  645.   FZLHeader : TZLibStreamHeader;
  646.   BA        : TLocalFile;
  647.   ZLH       : Word;
  648.   Compress  : Byte;
  649. begin
  650.   Result := 0;
  651.   if (CompressionMethod=8) Then
  652.      Begin
  653.        FZLHeader.CMF := (ZL_DEF_COMPRESSIONINFO shl 4);               { 32k Window size }
  654.        FZLHeader.CMF := FZLHeader.CMF or ZL_DEF_COMPRESSIONMETHOD;    { Deflate }
  655.        Compress := ZL_DEFAULT_COMPRESSION;
  656.        Case BitFlag AND 6 of
  657.             0 : Compress := ZL_DEFAULT_COMPRESSION;
  658.             2 : Compress := ZL_MAXIMUM_COMPRESSION;
  659.             4 : Compress := ZL_FAST_COMPRESSION;
  660.             6 : Compress := ZL_FASTEST_COMPRESSION;
  661.        End;
  662.        FZLHeader.FLG := FZLHeader.FLG or (Compress shl 6);
  663.        FZLHeader.FLG := FZLHeader.FLG and not ZL_PRESET_DICT;         { no preset dictionary}
  664.        FZLHeader.FLG := FZLHeader.FLG and not ZL_FCHECK_MASK;
  665.        ZLH           := (FZLHeader.CMF * 256) + FZLHeader.FLG;
  666.        Inc(FZLHeader.FLG, 31 - (ZLH mod 31));
  667.        Result := Result + Stream.Write(FZLHeader,SizeOf(FZLHeader));
  668.      End;
  669.   BA     := FParent.GetLocalEntry(FParent.FParent.FZipStream,LocalOffset,False);
  670.   if BA.LocalFileHeaderSignature<>$04034b50 Then
  671.      Begin
  672.         Result := 0;
  673.         Exit;
  674.      End;
  675.   if SizeCompressed > 0 Then
  676.      Result := Result + Stream.Write(BA.CompressedData[1],SizeCompressed);
  677. end;
  678.  
  679. function TKAZipEntriesEntry.GetCompressedData: String;
  680. Var
  681.   BA        : TLocalFile;
  682.   FZLHeader : TZLibStreamHeader;
  683.   ZLH       : Word;
  684.   Compress  : Byte;
  685. begin
  686.   Result := '';
  687.   if (CompressionMethod=0) or (CompressionMethod=8) Then
  688.      Begin
  689.        BA     := FParent.GetLocalEntry(FParent.FParent.FZipStream,LocalOffset,False);
  690.        if BA.LocalFileHeaderSignature<>$04034b50 Then Exit;
  691.        if (CompressionMethod=8) Then
  692.           Begin
  693.             FZLHeader.CMF := (ZL_DEF_COMPRESSIONINFO shl 4);               { 32k Window size }
  694.             FZLHeader.CMF := FZLHeader.CMF or ZL_DEF_COMPRESSIONMETHOD;    { Deflate }
  695.             Compress := ZL_DEFAULT_COMPRESSION;
  696.             Case BitFlag AND 6 of
  697.                  0 : Compress := ZL_DEFAULT_COMPRESSION;
  698.                  2 : Compress := ZL_MAXIMUM_COMPRESSION;
  699.                  4 : Compress := ZL_FAST_COMPRESSION;
  700.                  6 : Compress := ZL_FASTEST_COMPRESSION;
  701.             End;
  702.             FZLHeader.FLG := FZLHeader.FLG or (Compress shl 6);
  703.             FZLHeader.FLG := FZLHeader.FLG and not ZL_PRESET_DICT;         { no preset dictionary}
  704.             FZLHeader.FLG := FZLHeader.FLG and not ZL_FCHECK_MASK;
  705.             ZLH           := (FZLHeader.CMF * 256) + FZLHeader.FLG;
  706.             Inc(FZLHeader.FLG, 31 - (ZLH mod 31));
  707.             SetLength(Result,SizeOf(FZLHeader));
  708.             SetString(Result,PChar(@FZLHeader),SizeOf(FZLHeader));
  709.           End;
  710.        Result := Result + BA.CompressedData;
  711.      End
  712.   Else
  713.      Begin
  714.        SetLength(Result,0);
  715.      End;
  716. End;
  717.  
  718. procedure TKAZipEntriesEntry.SetSelected(const Value: Boolean);
  719. begin
  720.   FSelected := Value;
  721. end;
  722.  
  723. function TKAZipEntriesEntry.GetLocalEntrySize: Cardinal;
  724. begin
  725.  Result := SizeOf(TLocalFile) - 3*SizeOf(String)+
  726.            FCentralDirectoryFile.CompressedSize+
  727.            FCentralDirectoryFile.FilenameLength+
  728.            FCentralDirectoryFile.ExtraFieldLength;
  729.  if (FCentralDirectoryFile.GeneralPurposeBitFlag And (1 SHL 3)) > 0 Then
  730.     Begin
  731.       Result := Result + SizeOf(TDataDescriptor);
  732.     End;
  733. end;
  734.  
  735. function TKAZipEntriesEntry.GetCentralEntrySize: Cardinal;
  736. begin
  737.   Result := SizeOf(TCentralDirectoryFile) - 3*SizeOf(String)+
  738.                    FCentralDirectoryFile.FilenameLength+
  739.                    FCentralDirectoryFile.ExtraFieldLength+
  740.                    FCentralDirectoryFile.FileCommentLength;
  741. end;
  742.  
  743. function TKAZipEntriesEntry.Test: Boolean;
  744. Var
  745.   FS : TFileStream;
  746.   MS : TMemoryStream;
  747.   FN : String;
  748. begin
  749.   Result  := True;
  750.   Try
  751.     if NOT FIsEncrypted Then
  752.        Begin
  753.          if FParent.FParent.FUseTempFiles  Then
  754.             Begin
  755.               FN := FParent.FParent.GetDelphiTempFileName;
  756.               FS := TFileStream.Create(FN,fmOpenReadWrite or FmCreate);
  757.               Try
  758.                 ExtractToStream(FS);
  759.                 FS.Position := 0;
  760.                 Result      := FParent.CalculateCRCFromStream(FS) = CRC32;
  761.               Finally
  762.                 FS.Free;
  763.  
  764.                 // Sicherheitsbestimmung
  765.                 dc_deletefile(FN); // DeleteFile(FN);
  766.               End;
  767.             End
  768.          Else
  769.             Begin
  770.               MS := TMemoryStream.Create;
  771.               Try
  772.                 ExtractToStream(MS);
  773.                 MS.Position := 0;
  774.                 Result      := FParent.CalculateCRCFromStream(MS) = CRC32;
  775.               Finally
  776.                 MS.Free;
  777.               End;
  778.             End;
  779.        End;
  780.   Except
  781.     Result  := False;
  782.   End;
  783. end;
  784.  
  785. procedure TKAZipEntriesEntry.SetComment(const Value: String);
  786. begin
  787.   FCentralDirectoryFile.FileComment := Value;
  788.   FCentralDirectoryFile.FileCommentLength := Length(FCentralDirectoryFile.FileComment);
  789.   FParent.Rebuild;
  790.   if NOT FParent.FParent.FBatchMode Then
  791.      Begin
  792.        FParent.FParent.DoChange(FParent,4);
  793.      End;
  794. end;
  795.  
  796. procedure TKAZipEntriesEntry.SetFileName(const Value: String);
  797. Var
  798.   FN : String;
  799. begin
  800.   FN := ToZipName(Value);
  801.   if FParent.IndexOf(FN) > -1 Then Raise Exception.Create('File with same name already exists in Archive!');
  802.   FCentralDirectoryFile.FileName         := ToZipName(Value);
  803.   FCentralDirectoryFile.FilenameLength   := Length(FCentralDirectoryFile.FileName);
  804.   if NOT FParent.FParent.FBatchMode Then
  805.      Begin
  806.        FParent.Rebuild;
  807.        FParent.FParent.DoChange(FParent,5);
  808.      End;
  809. end;
  810.  
  811. { TKAZipEntries }
  812. constructor TKAZipEntries.Create(AOwner : TKAZip);
  813. begin
  814.   Inherited Create(TKAZipEntriesEntry);
  815.   FParent    := AOwner;
  816.   FIsZipFile := False;
  817. end;
  818.  
  819. constructor TKAZipEntries.Create(AOwner : TKAZip; MS : TStream);
  820. begin
  821.   Inherited Create(TKAZipEntriesEntry);
  822.   FParent               := AOwner;
  823.   FIsZipFile            := False;
  824.   FLocalHeaderNumFiles  := 0;
  825.   ParseZip(MS);
  826. end;
  827.  
  828. destructor TKAZipEntries.Destroy;
  829. begin
  830.  
  831.   inherited Destroy;
  832. end;
  833.  
  834. function TKAZipEntries.Adler32(adler : uLong; buf : pByte; len : uInt) : uLong;
  835. const
  836.   BASE = uLong(65521);
  837.   NMAX = 3854;
  838. var
  839.   s1, s2 : uLong;
  840.   k      : Integer;
  841. begin
  842.   s1 := adler and $ffff;
  843.   s2 := (adler shr 16) and $ffff;
  844.  
  845.   if not Assigned(buf) then
  846.   begin
  847.     adler32 := uLong(1);
  848.     exit;
  849.   end;
  850.  
  851.   while (len > 0) do
  852.   begin
  853.     if len < NMAX then
  854.       k := len
  855.     else
  856.       k := NMAX;
  857.     Dec(len, k);
  858.     while (k > 0) do
  859.     begin
  860.       Inc(s1, buf^);
  861.       Inc(s2, s1);
  862.       Inc(buf);
  863.       Dec(k);
  864.     end;
  865.     s1 := s1 mod BASE;
  866.     s2 := s2 mod BASE;
  867.   end;
  868.   adler32 := (s2 shl 16) or s1;
  869. end;
  870.  
  871. function TKAZipEntries.CalcCRC32(const UncompressedData : string): Cardinal;
  872. var
  873.   X : Integer;
  874. begin
  875.   Result := $FFFFFFFF;
  876.   for X := 0 to Length(UncompressedData) - 1 do
  877.       Begin
  878.         Result := (Result SHR 8) XOR (CRCTable[Byte(Result) XOR Ord(UncompressedData[X+1])]);
  879.       End;
  880.   Result := Result XOR $FFFFFFFF;
  881. end;
  882.  
  883.  
  884. function TKAZipEntries.CalculateCRCFromStream(Stream: TStream): Cardinal;
  885. var
  886.   Buffer: array[1..8192] of Byte;
  887.   I, ReadCount: Integer;
  888.   TempResult: Longword;
  889. begin
  890.   TempResult := $FFFFFFFF;
  891.   while (Stream.Position <> Stream.Size) do begin
  892.     ReadCount := Stream.Read(Buffer, SizeOf(Buffer));
  893.     for I := 1 to ReadCount do
  894.       TempResult := ((TempResult shr 8) and $FFFFFF) xor CRCTable[(TempResult xor Longword(Buffer[I])) and $FF];
  895.   end;
  896.   Result := not TempResult;
  897. end;
  898.  
  899. Function TKAZipEntries.RemoveRootName(Const FileName, RootName : String):String;
  900. Var
  901.   P : Integer;
  902.   S : String;
  903. Begin
  904.   Result := FileName;
  905.   P      := Pos(AnsiLowerCase(RootName),AnsiLowerCase(FileName));
  906.   if P=1 Then
  907.      Begin
  908.        System.Delete(Result,1,Length(RootName));
  909.        S := Result;
  910.        if (Length(S) > 0) AND (S[1]='\') Then
  911.           Begin
  912.              System.Delete(S,1,1);
  913.              Result := S;
  914.           End;
  915.      End;
  916. End;
  917.  
  918. Procedure TKAZipEntries.SortList(List : TList);
  919. Var
  920.   X        : Integer;
  921.   I1       : Cardinal;
  922.   I2       : Cardinal;
  923.   NoChange : Boolean;
  924. Begin
  925.   if List.Count=1 Then Exit;
  926.   Repeat
  927.     NoChange := True;
  928.     For X := 0 To List.Count-2 Do
  929.       Begin
  930.         I1 := Integer(List.Items[X]);
  931.         I2 := Integer(List.Items[X+1]);
  932.         if I1 > I2 Then
  933.            Begin
  934.              List.Exchange(X,X+1);
  935.              NoChange := False;
  936.            End;
  937.       End;
  938.   Until NoChange;
  939. End;
  940.  
  941.  
  942.  
  943.  
  944. function TKAZipEntries.FileTime2DateTime(FileTime: TFileTime): TDateTime;
  945. var
  946.    LocalFileTime: TFileTime;
  947.    SystemTime: TSystemTime;
  948. begin
  949.    FileTimeToLocalFileTime(FileTime, LocalFileTime) ;
  950.    FileTimeToSystemTime(LocalFileTime, SystemTime) ;
  951.    Result := SystemTimeToDateTime(SystemTime) ;
  952. end;
  953.  
  954. function TKAZipEntries.GetHeaderEntry(Index: Integer): TKAZipEntriesEntry;
  955. begin
  956.   Result := TKAZipEntriesEntry(Inherited Items[Index]);
  957. end;
  958.  
  959. procedure TKAZipEntries.SetHeaderEntry(Index: Integer; const Value: TKAZipEntriesEntry);
  960. begin
  961.   Inherited Items[Index] := TCollectionItem(Value);
  962. end;
  963.  
  964. Function TKAZipEntries.ReadBA(MS: TStream; Sz, Poz:Integer): TBytes;
  965. Begin
  966.   SetLength(Result,SZ);
  967.   MS.Position := Poz;
  968.   MS.Read(Result[0],SZ);
  969. End;
  970.  
  971. function TKAZipEntries.FindCentralDirectory(MS: TStream): Boolean;
  972. Var
  973.   SeekStart : Integer;
  974.   Poz       : Integer;
  975.   BR        : Integer;
  976.   Byte_     : Array[0..3] of Byte;
  977.  
  978. begin
  979.   Result     := False;
  980.   if MS.Size < 22 Then Exit;
  981.   if MS.Size < 256 Then
  982.      SeekStart := MS.Size
  983.   Else
  984.      SeekStart := 256;
  985.   Poz       := MS.Size-22;
  986.   BR        := SeekStart;
  987.   Repeat
  988.     MS.Position := Poz;
  989.     MS.Read(Byte_,4);
  990.     If Byte_[0]=$50 Then
  991.        Begin
  992.          if  (Byte_[1]=$4B)
  993.          And (Byte_[2]=$05)
  994.          And (Byte_[3]=$06) Then
  995.              Begin
  996.                MS.Position                  := Poz;
  997.                FParent.FEndOfCentralDirPos  := MS.Position;
  998.                MS.Read(FParent.FEndOfCentralDir,SizeOf(FParent.FEndOfCentralDir));
  999.                FParent.FZipCommentPos       := MS.Position;
  1000.                FParent.FZipComment.Clear;
  1001.                Result  := True;
  1002.              End
  1003.          Else
  1004.              Begin
  1005.                Dec(Poz,4);
  1006.                Dec(BR ,4);
  1007.              End;
  1008.        End
  1009.     Else
  1010.        Begin
  1011.          Dec(Poz);
  1012.          Dec(BR)
  1013.        End;
  1014.     if BR < 0 Then
  1015.        Begin
  1016.          Case SeekStart of
  1017.                256   : Begin
  1018.                         SeekStart := 1024;
  1019.                         Poz       := MS.Size-(256+22);
  1020.                         BR        := SeekStart;
  1021.                       End;
  1022.               1024  : Begin
  1023.                         SeekStart := 65536;
  1024.                         Poz       := MS.Size-(1024+22);
  1025.                         BR        := SeekStart;
  1026.                       End;
  1027.               65536 : Begin
  1028.                         SeekStart := -1;
  1029.                       End;
  1030.          End;
  1031.        End;
  1032.     if BR < 0              Then SeekStart := -1;
  1033.     if MS.Size < SeekStart Then SeekStart := -1;
  1034.   Until (Result) or (SeekStart=-1);
  1035. end;
  1036.  
  1037.  
  1038. function TKAZipEntries.ParseCentralHeaders(MS: TStream): Boolean;
  1039. Var
  1040.   X                 : Integer;
  1041.   Entry             : TKAZipEntriesEntry;
  1042.   CDFile            : TCentralDirectoryFile;
  1043. begin
  1044.   Result            := False;
  1045.   Try
  1046.     MS.Position     := FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
  1047.     For X := 0 To FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk-1 do
  1048.         Begin
  1049.           FillChar(CDFile,SizeOf(TCentralDirectoryFile),0);
  1050.           MS.Read(CDFile,SizeOf(TCentralDirectoryFile)-3*SizeOf(String));
  1051.           Entry                       := TKAZipEntriesEntry.Create(Self);
  1052.           Entry.FDate                 := FileDateToDateTime(CDFile.LastModFileTimeDate);
  1053.           if (CDFile.GeneralPurposeBitFlag And 1) > 0 Then
  1054.               Entry.FIsEncrypted := True
  1055.           Else
  1056.               Entry.FIsEncrypted := False;
  1057.           If CDFile.FilenameLength > 0 Then
  1058.              Begin
  1059.                SetLength(CDFile.FileName,CDFile.FilenameLength);
  1060.                MS.Read(CDFile.FileName[1],   CDFile.FilenameLength)
  1061.              End;
  1062.           If CDFile.ExtraFieldLength > 0 Then
  1063.              Begin
  1064.                SetLength(CDFile.ExtraField,CDFile.ExtraFieldLength);
  1065.                MS.Read(CDFile.ExtraField[1], CDFile.ExtraFieldLength);
  1066.              End;
  1067.           If CDFile.FileCommentLength > 0 Then
  1068.              Begin
  1069.                SetLength(CDFile.FileComment,CDFile.FileCommentLength);
  1070.                MS.Read(CDFile.FileComment[1],CDFile.FileCommentLength);
  1071.              End;
  1072.           Entry.FIsFolder          := (CDFile.ExternalFileAttributes and faDirectory) > 0;
  1073.  
  1074.           Entry.FCompressionType   := ctUnknown;
  1075.           if (CDFile.CompressionMethod=8) or (CDFile.CompressionMethod=9) Then
  1076.              Begin
  1077.                Case CDFile.GeneralPurposeBitFlag AND 6 of
  1078.                     0 : Entry.FCompressionType := ctNormal;
  1079.                     2 : Entry.FCompressionType := ctMaximum;
  1080.                     4 : Entry.FCompressionType := ctFast;
  1081.                     6 : Entry.FCompressionType := ctSuperFast
  1082.                End;
  1083.              End;
  1084.           Entry.FCentralDirectoryFile := CDFile;
  1085.           If Assigned(FParent.FOnZipOpen) Then FParent.FOnZipOpen(FParent,X,FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
  1086.         End;
  1087.    Except
  1088.      Exit;
  1089.    End;
  1090.    Result := Count=FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk;
  1091. end;
  1092.  
  1093.  
  1094. procedure TKAZipEntries.ParseZip(MS: TStream);
  1095. begin
  1096.   FIsZipFile := False;
  1097.   Clear;
  1098.   if FindCentralDirectory(MS) Then
  1099.     Begin
  1100.       if ParseCentralHeaders(MS) Then
  1101.          Begin
  1102.            FIsZipFile := True;
  1103.            LoadLocalHeaders(MS);
  1104.          End;
  1105.     End
  1106.   Else
  1107.     Begin
  1108.       if ParseLocalHeaders(MS) Then
  1109.          Begin
  1110.            FIsZipFile := Count > 0;
  1111.            if FIsZipFile Then FParent.FHasBadEntries := True;
  1112.          End;
  1113.     End;
  1114. end;
  1115.  
  1116.  
  1117. function TKAZipEntries.GetLocalEntry(MS: TStream; Offset : Integer; HeaderOnly : Boolean): TLocalFile;
  1118. Var
  1119.   Byte_             : Array[0..4] of Byte;
  1120.   DataDescriptor    : TDataDescriptor;
  1121. begin
  1122.   FillChar(Result,SizeOf(Result),0);
  1123.   MS.Position := Offset;
  1124.   MS.Read(Byte_,4);
  1125.   if  (Byte_[0]  = $50)
  1126.   And (Byte_[1]  = $4B)
  1127.   And (Byte_[2]  = $03)
  1128.   And (Byte_[3]  = $04) Then
  1129.     Begin
  1130.       MS.Position := Offset;
  1131.       MS.Read(Result,SizeOf(Result)-3*SizeOf(AnsiString));
  1132.       if Result.FilenameLength > 0 Then
  1133.          Begin
  1134.            SetLength(Result.FileName,Result.FilenameLength);
  1135.            MS.Read(Result.FileName[1],Result.FilenameLength);
  1136.          End;
  1137.       if Result.ExtraFieldLength > 0 Then
  1138.          Begin
  1139.            SetLength(Result.ExtraField,Result.ExtraFieldLength);
  1140.            MS.Read(Result.ExtraField[1],Result.ExtraFieldLength);
  1141.          End;
  1142.       if (Result.GeneralPurposeBitFlag And (1 SHL 3)) > 0 Then
  1143.          Begin
  1144.            MS.Read(DataDescriptor,SizeOf(TDataDescriptor));
  1145.            Result.Crc32            := DataDescriptor.Crc32;
  1146.            Result.CompressedSize   := DataDescriptor.CompressedSize;
  1147.            Result.UnCompressedSize := DataDescriptor.UnCompressedSize;
  1148.          End;
  1149.       if Not HeaderOnly Then
  1150.          Begin
  1151.            if Result.CompressedSize > 0 Then
  1152.               Begin
  1153.                 SetLength(Result.CompressedData,Result.CompressedSize);
  1154.                 MS.Read(Result.CompressedData[1],Result.CompressedSize);
  1155.               End;
  1156.          End;
  1157.     End
  1158.   Else
  1159.     Begin
  1160.     End;
  1161. end;
  1162.  
  1163. procedure TKAZipEntries.LoadLocalHeaders(MS: TStream);
  1164. Var
  1165.   X : Integer;
  1166. begin
  1167.   FParent.FHasBadEntries := False;
  1168.   For X := 0 To Count-1 do
  1169.       Begin
  1170.         If Assigned(FParent.FOnZipOpen) Then FParent.FOnZipOpen(FParent,X,FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
  1171.         Items[X].FLocalFile := GetLocalEntry(MS,Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader,True);
  1172.         if Items[X].FLocalFile.LocalFileHeaderSignature<>$04034b50 Then FParent.FHasBadEntries := True;
  1173.       End;
  1174. end;
  1175.  
  1176. function TKAZipEntries.ParseLocalHeaders(MS: TStream): Boolean;
  1177. Var
  1178.   Poz                 : Integer;
  1179.   NLE                 : Integer;
  1180.   Byte_               : Array[0..4] of Byte;
  1181.   LocalFile           : TLocalFile;
  1182.   DataDescriptor      : TDataDescriptor;
  1183.   Entry               : TKAZipEntriesEntry;
  1184.   CDFile              : TCentralDirectoryFile;
  1185.   CDSize              : Cardinal;
  1186.   L                   : Integer;
  1187.   NoMore              : Boolean;
  1188. begin
  1189.   Result               := False;
  1190.   FLocalHeaderNumFiles := 0;
  1191.   Clear;
  1192.   Try
  1193.       Poz    := 0;
  1194.       NLE    := 0;
  1195.       CDSize := 0;
  1196.       Repeat
  1197.         NoMore      := True;
  1198.         MS.Position := Poz;
  1199.         MS.Read(Byte_,4);
  1200.         if  (Byte_[0]  = $50)
  1201.         And (Byte_[1]  = $4B)
  1202.         And (Byte_[2]  = $03)
  1203.         And (Byte_[3]  = $04) Then
  1204.             Begin
  1205.               Result := True;
  1206.               Inc(FLocalHeaderNumFiles);
  1207.               NoMore      := False;
  1208.               MS.Position := Poz;
  1209.               MS.Read(LocalFile,SizeOf(TLocalFile)-3*SizeOf(String));
  1210.               if LocalFile.FilenameLength > 0 Then
  1211.                  Begin
  1212.                    SetLength(LocalFile.FileName,LocalFile.FilenameLength);
  1213.                    MS.Read(LocalFile.FileName[1],LocalFile.FilenameLength);
  1214.                  End;
  1215.               if LocalFile.ExtraFieldLength > 0 Then
  1216.                  Begin
  1217.                    SetLength(LocalFile.ExtraField,LocalFile.ExtraFieldLength);
  1218.                    MS.Read(LocalFile.ExtraField[1],LocalFile.ExtraFieldLength);
  1219.                  End;
  1220.               if (LocalFile.GeneralPurposeBitFlag And (1 SHL 3)) > 0 Then
  1221.                  Begin
  1222.                    MS.Read(DataDescriptor,SizeOf(TDataDescriptor));
  1223.                    LocalFile.Crc32            := DataDescriptor.Crc32;
  1224.                    LocalFile.CompressedSize   := DataDescriptor.CompressedSize;
  1225.                    LocalFile.UncompressedSize := DataDescriptor.UncompressedSize;
  1226.                  End;
  1227.               MS.Position := MS.Position+LocalFile.CompressedSize;
  1228.  
  1229.               FillChar(CDFile,SizeOf(TCentralDirectoryFile),0);
  1230.               CDFile.CentralFileHeaderSignature     := $02014B50;
  1231.               CDFile.VersionMadeBy                  := 20;
  1232.               CDFile.VersionNeededToExtract         := LocalFile.VersionNeededToExtract;
  1233.               CDFile.GeneralPurposeBitFlag          := LocalFile.GeneralPurposeBitFlag;
  1234.               CDFile.CompressionMethod              := LocalFile.CompressionMethod;
  1235.               CDFile.LastModFileTimeDate            := LocalFile.LastModFileTimeDate;
  1236.               CDFile.Crc32                          := LocalFile.Crc32;
  1237.               CDFile.CompressedSize                 := LocalFile.CompressedSize;
  1238.               CDFile.UncompressedSize               := LocalFile.UncompressedSize;
  1239.               CDFile.FilenameLength                 := LocalFile.FilenameLength;
  1240.               CDFile.ExtraFieldLength               := LocalFile.ExtraFieldLength;
  1241.               CDFile.FileCommentLength              := 0;
  1242.               CDFile.DiskNumberStart                := 0;
  1243.               CDFile.InternalFileAttributes         := LocalFile.VersionNeededToExtract;
  1244.               CDFile.ExternalFileAttributes         := faArchive;
  1245.               CDFile.RelativeOffsetOfLocalHeader    := Poz;
  1246.               CDFile.FileName                       := LocalFile.FileName;
  1247.               L := Length(CDFile.FileName);
  1248.               if L > 0 Then
  1249.                  Begin
  1250.                    if CDFile.FileName[L]='/' Then CDFile.ExternalFileAttributes := faDirectory;
  1251.                  End;
  1252.               CDFile.ExtraField                     := LocalFile.ExtraField;
  1253.               CDFile.FileComment                    := '';
  1254.  
  1255.               Entry                                 := TKAZipEntriesEntry.Create(Self);
  1256.               Entry.FDate                           := FileDateToDateTime(CDFile.LastModFileTimeDate);
  1257.               if (CDFile.GeneralPurposeBitFlag And 1) > 0 Then
  1258.                  Entry.FIsEncrypted    := True
  1259.               Else
  1260.                  Entry.FIsEncrypted    := False;
  1261.               Entry.FIsFolder          := (CDFile.ExternalFileAttributes and faDirectory) > 0;
  1262.               Entry.FCompressionType   := ctUnknown;
  1263.               if (CDFile.CompressionMethod=8) or (CDFile.CompressionMethod=9) Then
  1264.                  Begin
  1265.                    Case CDFile.GeneralPurposeBitFlag AND 6 of
  1266.                         0 : Entry.FCompressionType := ctNormal;
  1267.                         2 : Entry.FCompressionType := ctMaximum;
  1268.                         4 : Entry.FCompressionType := ctFast;
  1269.                         6 : Entry.FCompressionType := ctSuperFast
  1270.                    End;
  1271.                  End;
  1272.               Entry.FCentralDirectoryFile := CDFile;
  1273.               Poz         := MS.Position;
  1274.               Inc(NLE);
  1275.               CDSize      := CDSize+Entry.CentralEntrySize;
  1276.             End;
  1277.       Until NoMore;
  1278.  
  1279.       FParent.FEndOfCentralDir.EndOfCentralDirSignature        := $06054b50;
  1280.       FParent.FEndOfCentralDir.NumberOfThisDisk                := 0;
  1281.       FParent.FEndOfCentralDir.NumberOfTheDiskWithTheStart     := 0;
  1282.       FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk  := NLE;
  1283.       FParent.FEndOfCentralDir.SizeOfTheCentralDirectory       := CDSize;
  1284.       FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory := MS.Position;
  1285.       FParent.FEndOfCentralDir.ZipfileCommentLength            := 0;
  1286.   Except
  1287.     Exit;
  1288.   End;
  1289. end;
  1290.  
  1291. procedure TKAZipEntries.Remove(ItemIndex: Integer; Flush : Boolean);
  1292. Var
  1293.   TempStream          : TFileStream;
  1294.   TempMSStream        : TMemoryStream;
  1295.   TempFileName        : String;
  1296.   BUF                 : String;
  1297.   ZipComment          : String;
  1298.   OSL                 : Cardinal;
  1299.   //*********************************************
  1300.   X                   : Integer;
  1301.   TargetPos           : Cardinal;
  1302.   Border              : Cardinal;
  1303.  
  1304.   //Marschall: NR                  : Integer;
  1305.   //Marschall: NW                  : Integer;
  1306.   BufStart            : Integer;
  1307.   BufLen              : Integer;
  1308.   ShiftSize           : Cardinal;
  1309.   NewSize             : Cardinal;
  1310. begin
  1311.  TargetPos          := Items[ItemIndex].FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
  1312.  ShiftSize          := Items[ItemIndex].LocalEntrySize;
  1313.  BufStart           := TargetPos+ShiftSize;
  1314.  BufLen             := FParent.FZipStream.Size-BufStart;
  1315.  Border             := TargetPos;
  1316.  Delete(ItemIndex);
  1317.  if (FParent.FZipSaveMethod=FastSave) AND (Count > 0) Then
  1318.     Begin
  1319.        ZipComment := FParent.Comment.Text;
  1320.  
  1321.        SetLength(BUF,BufLen);
  1322.        FParent.FZipStream.Position := BufStart;
  1323.        FParent.FZipStream.Read(BUF[1],BufLen); //Marschall: NR := FParent.FZipStream.Read(BUF[1],BufLen);
  1324.        FParent.FZipStream.Position := TargetPos;
  1325.        FParent.FZipStream.Write(BUF[1],BufLen); //Marschall: NW := FParent.FZipStream.Write(BUF[1],BufLen);
  1326.        SetLength(BUF,0);
  1327.  
  1328.        For X := 0 to Count-1 do
  1329.            Begin
  1330.              if Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader > Border Then
  1331.                 Begin
  1332.                   Dec(Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader, ShiftSize);
  1333.                   TargetPos := TargetPos+Items[X].LocalEntrySize;
  1334.                 End
  1335.            End;
  1336.  
  1337.        FParent.FZipStream.Position := TargetPos;
  1338.        //************************************ MARK START OF CENTRAL DIRECTORY
  1339.        FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory := FParent.FZipStream.Position;
  1340.        //************************************ SAVE CENTRAL DIRECTORY
  1341.        For X := 0 To Count-1 do
  1342.            Begin
  1343.              FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile,SizeOf(Self.Items[X].FCentralDirectoryFile)-3*SizeOf(String));
  1344.              if Self.Items[X].FCentralDirectoryFile.FilenameLength > 0 Then
  1345.                 FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileName[1],Self.Items[X].FCentralDirectoryFile.FilenameLength);
  1346.              if Self.Items[X].FCentralDirectoryFile.ExtraFieldLength > 0 Then
  1347.                 FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.ExtraField[1],Self.Items[X].FCentralDirectoryFile.ExtraFieldLength);
  1348.              if Self.Items[X].FCentralDirectoryFile.FileCommentLength > 0 Then
  1349.                 FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileComment[1],Self.Items[X].FCentralDirectoryFile.FileCommentLength);
  1350.            End;
  1351.      //************************************ SAVE END CENTRAL DIRECTORY RECORD
  1352.      FParent.FEndOfCentralDirPos := FParent.FZipStream.Position;
  1353.      FParent.FEndOfCentralDir.SizeOfTheCentralDirectory := FParent.FEndOfCentralDirPos-FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
  1354.      Dec(FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
  1355.      Dec(FParent.FEndOfCentralDir.TotalNumberOfEntries);
  1356.      FParent.FZipStream.Write(FParent.FEndOfCentralDir, SizeOf(TEndOfCentralDir));
  1357.      //************************************ SAVE ZIP COMMENT IF ANY
  1358.      FParent.FZipCommentPos := FParent.FZipStream.Position;
  1359.      if Length(ZipComment) > 0 Then
  1360.         Begin
  1361.           FParent.FZipStream.Write(ZipComment[1],Length(ZipComment));
  1362.         End;
  1363.      FParent.FZipStream.Size     := FParent.FZipStream.Position;
  1364.     End
  1365.  Else
  1366.     Begin
  1367.        if FParent.FUseTempFiles Then
  1368.           Begin
  1369.              TempFileName := FParent.GetDelphiTempFileName;
  1370.              TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
  1371.              Try
  1372.                FParent.SaveToStream(TempStream);
  1373.                TempStream.Position := 0;
  1374.                OSL                 := FParent.FZipStream.Size;
  1375.  
  1376.                // Sicherheitsbestimmung
  1377.                ProtectStream(FParent.FZipStream);
  1378.  
  1379.                Try
  1380.                  FParent.FZipStream.Size := TempStream.Size;
  1381.                Except
  1382.                  FParent.FZipStream.Size := OSL;
  1383.                  Raise;
  1384.                End;
  1385.                FParent.FZipStream.Position := 0;
  1386.  
  1387.                FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
  1388.                //*********************************************************************
  1389.                FParent.FZipHeader.ParseZip(FParent.FZipStream);
  1390.                //*********************************************************************
  1391.              Finally
  1392.                TempStream.Free;
  1393.                // Sicherheitsbestimmung
  1394.                dc_deletefile(tempfilename); // DeleteFile(TempFileName)
  1395.              End;
  1396.           End
  1397.        Else
  1398.           Begin
  1399.             NewSize := 0;
  1400.             For X := 0 To Count-1 do
  1401.                 Begin
  1402.                   NewSize := NewSize+Items[X].LocalEntrySize+Items[X].CentralEntrySize;
  1403.                   if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,X,Count-1);
  1404.                 End;
  1405.             NewSize := NewSize+SizeOf(FParent.FEndOfCentralDir)+FParent.FEndOfCentralDir.ZipfileCommentLength;
  1406.             TempMSStream := TMemoryStream.Create;
  1407.             Try
  1408.                TempMSStream.SetSize(NewSize);
  1409.                TempMSStream.Position := 0;
  1410.                FParent.SaveToStream(TempMSStream);
  1411.                TempMSStream.Position := 0;
  1412.                OSL                   := FParent.FZipStream.Size;
  1413.  
  1414.                // Sicherheitsbestimmung
  1415.                ProtectStream(FParent.FZipStream);
  1416.  
  1417.                Try
  1418.                  FParent.FZipStream.Size := TempMSStream.Size;
  1419.                Except
  1420.                  FParent.FZipStream.Size := OSL;
  1421.                  Raise;
  1422.                End;
  1423.                FParent.FZipStream.Position := 0;
  1424.  
  1425.                FParent.FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
  1426.                //*********************************************************************
  1427.                FParent.FZipHeader.ParseZip(FParent.FZipStream);
  1428.                //*********************************************************************
  1429.              Finally
  1430.                TempMSStream.Free;
  1431.              End;
  1432.           End;
  1433.     End;
  1434.  FParent.FIsDirty := True;
  1435.  if NOT FParent.FBatchMode Then
  1436.     Begin
  1437.        FParent.DoChange(FParent,3);
  1438.     End;
  1439. end;
  1440.  
  1441. procedure TKAZipEntries.Remove(ItemIndex: Integer);
  1442. Begin
  1443.   Remove(ItemIndex,True);
  1444. End;
  1445.  
  1446. procedure TKAZipEntries.Remove(Item: TKAZipEntriesEntry);
  1447. Var
  1448.  X : Integer;
  1449. begin
  1450.  For X := 0 To Count-1 do
  1451.      Begin
  1452.        if Self.Items[X]=Item Then
  1453.           Begin
  1454.             Remove(X);
  1455.             Exit;
  1456.           End;
  1457.      End;
  1458. end;
  1459.  
  1460. procedure TKAZipEntries.Remove(FileName: String);
  1461. Var
  1462.   I : Integer;
  1463. begin
  1464.   I := IndexOf(FileName);
  1465.   if I <> -1 Then Remove(I);
  1466. end;
  1467.  
  1468. procedure TKAZipEntries.RemoveBatch(Files:TList);
  1469. Var
  1470.   X             : Integer;
  1471.   OSL           : Integer;
  1472.   NewSize       : Cardinal;
  1473.   TempStream    : TFileStream;
  1474.   TempMSStream  : TMemoryStream;
  1475.   TempFileName  : String;
  1476. Begin
  1477.   For X := Files.Count-1 DownTo 0 do
  1478.       Begin
  1479.         Delete(Integer(Files.Items[X]));
  1480.         if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,Files.Count-X,Files.Count);
  1481.       End;
  1482.   NewSize := 0;
  1483.   if FParent.FUseTempFiles Then
  1484.       Begin
  1485.          TempFileName := FParent.GetDelphiTempFileName;
  1486.          TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
  1487.          Try
  1488.            FParent.SaveToStream(TempStream);
  1489.            TempStream.Position := 0;
  1490.            OSL                 := FParent.FZipStream.Size;
  1491.  
  1492.            // Sicherheitsbestimmung
  1493.            ProtectStream(FParent.FZipStream);
  1494.  
  1495.            Try
  1496.              FParent.FZipStream.Size := TempStream.Size;
  1497.            Except
  1498.              FParent.FZipStream.Size := OSL;
  1499.              Raise;
  1500.            End;
  1501.            FParent.FZipStream.Position := 0;
  1502.  
  1503.            FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
  1504.            //*********************************************************************
  1505.            FParent.FZipHeader.ParseZip(FParent.FZipStream);
  1506.            //*********************************************************************
  1507.          Finally
  1508.            TempStream.Free;
  1509.            // Sicherheitsbestimmung
  1510.            dc_deletefile(tempfilename); // DeleteFile(TempFileName)
  1511.          End;
  1512.       End
  1513.    Else
  1514.       Begin
  1515.         For X := 0 To Count-1 do
  1516.             Begin
  1517.               NewSize := NewSize+Items[X].LocalEntrySize+Items[X].CentralEntrySize;
  1518.               if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,X,Count-1);
  1519.             End;
  1520.         NewSize := NewSize+SizeOf(FParent.FEndOfCentralDir)+FParent.FEndOfCentralDir.ZipfileCommentLength;
  1521.         TempMSStream := TMemoryStream.Create;
  1522.         Try
  1523.            TempMSStream.SetSize(NewSize);
  1524.            TempMSStream.Position := 0;
  1525.            FParent.SaveToStream(TempMSStream);
  1526.            TempMSStream.Position := 0;
  1527.            OSL                   := FParent.FZipStream.Size;
  1528.  
  1529.            // Sicherheitsbestimmung
  1530.            ProtectStream(FParent.FZipStream);
  1531.  
  1532.            Try
  1533.              FParent.FZipStream.Size := TempMSStream.Size;
  1534.            Except
  1535.              FParent.FZipStream.Size := OSL;
  1536.              Raise;
  1537.            End;
  1538.            FParent.FZipStream.Position := 0;
  1539.  
  1540.            FParent.FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
  1541.            //*********************************************************************
  1542.            FParent.FZipHeader.ParseZip(FParent.FZipStream);
  1543.            //*********************************************************************
  1544.          Finally
  1545.            TempMSStream.Free;
  1546.          End;
  1547.       End;
  1548. End;
  1549.  
  1550. Function TKAZipEntries.IndexOf(Const FileName:String):Integer;
  1551. Var
  1552.   X   : Integer;
  1553.   FN  : String;
  1554. Begin
  1555.   Result := -1;
  1556.   FN     := ToZipName(FileName);
  1557.   For X := 0 To Count-1 do
  1558.       Begin
  1559.         if AnsiCompareText(FN,ToZipName(Items[X].FCentralDirectoryFile.FileName))=0 Then
  1560.            Begin
  1561.              Result := X;
  1562.              Exit;
  1563.            End;
  1564.       End;
  1565. End;
  1566.  
  1567.  
  1568. Function TKAZipEntries.AddStreamFast( ItemName  : String;
  1569.                                       FileAttr  : Word;
  1570.                                       FileDate  : TDateTime;
  1571.                                       Stream    : TStream):TKAZipEntriesEntry;
  1572. Var
  1573.   Compressor   : TCompressionStream;
  1574.   CS           : TStringStream;
  1575.   CM           : WORD;
  1576.   S            : String;
  1577.   X            : Integer;
  1578.   I            : Integer;
  1579.   UL           : Integer;
  1580.   CL           : Integer;
  1581.   FCRC32       : Cardinal;
  1582.   SizeToAppend : Integer;
  1583.   ZipComment   : String;
  1584.   Level        : TCompressionLevel;
  1585.   OBM          : Boolean;
  1586. begin
  1587.   //*********************************** COMPRESS DATA
  1588.   ZipComment              := FParent.Comment.Text;
  1589.  
  1590.   if NOT FParent.FStoreRelativePath Then
  1591.      ItemName             := ExtractFileName(ItemName);
  1592.  
  1593.   ItemName                := ToZipName(ItemName);
  1594.   I   := IndexOf(ItemName);
  1595.   if I > -1 Then
  1596.      Begin
  1597.        OBM := FParent.FBatchMode;
  1598.        Try
  1599.          if OBM=False Then FParent.FBatchMode := True;
  1600.          Remove(I);
  1601.        Finally
  1602.          FParent.FBatchMode := OBM;
  1603.        End;
  1604.      End;
  1605.  
  1606.   CS                      := TStringStream.Create('');
  1607.   CS.Position             := 0;
  1608.   Try
  1609.     UL                    := Stream.Size-Stream.Position;
  1610.     SetLength(S,UL);
  1611.     CM                    := 0;
  1612.     if UL > 0 Then
  1613.        Begin
  1614.          Stream.Read(S[1],UL);
  1615.          CM               := 8;
  1616.        End;
  1617.     FCRC32                := CalcCRC32(S);
  1618.     FParent.FCurrentDFS   := UL;
  1619.  
  1620.  
  1621.     Level                 := clDefault;
  1622.     Case FParent.FZipCompressionType of
  1623.          ctNormal    : Level := clDefault;
  1624.          ctMaximum   : Level := clMax;
  1625.          ctFast      : Level := clFastest;
  1626.          ctSuperFast : Level := clFastest;
  1627.          ctNone      : Level := clNone;
  1628.     End;
  1629.  
  1630.     if CM = 8 Then
  1631.        Begin
  1632.          Compressor            := TCompressionStream.Create(Level,CS);
  1633.          Try
  1634.            Compressor.OnProgress := FParent.OnCompress;
  1635.            Compressor.Write(S[1],UL);
  1636.          Finally
  1637.            Compressor.Free;
  1638.          End;
  1639.          S                     := Copy(CS.DataString, 3, Length(CS.DataString)-6);
  1640.        End;
  1641.   Finally
  1642.     CS.Free;
  1643.   End;
  1644.   //***********************************
  1645.   CL  := Length(S);
  1646.   //*********************************** FILL RECORDS
  1647.   Result := TKAZipEntriesEntry(Self.Add);
  1648.   With Result.FLocalFile do
  1649.     Begin
  1650.       LocalFileHeaderSignature := $04034B50;
  1651.       VersionNeededToExtract   := 20;
  1652.       GeneralPurposeBitFlag    := 0;
  1653.       CompressionMethod        := CM;
  1654.       LastModFileTimeDate      := DateTimeToFileDate(FileDate);
  1655.       Crc32                    := FCRC32;
  1656.       CompressedSize           := CL;
  1657.       UncompressedSize         := UL;
  1658.       FilenameLength           := Length(ItemName);
  1659.       ExtraFieldLength         := 0;
  1660.       FileName                 := ItemName;
  1661.       ExtraField               := '';
  1662.       CompressedData           := '';
  1663.     End;
  1664.  
  1665.  With Result.FCentralDirectoryFile Do
  1666.    Begin
  1667.       CentralFileHeaderSignature     := $02014B50;
  1668.       VersionMadeBy                  := 20;
  1669.       VersionNeededToExtract         := 20;
  1670.       GeneralPurposeBitFlag          := 0;
  1671.       CompressionMethod              := CM;
  1672.       LastModFileTimeDate            := DateTimeToFileDate(FileDate);
  1673.       Crc32                          := FCRC32;
  1674.       CompressedSize                 := CL;
  1675.       UncompressedSize               := UL;
  1676.       FilenameLength                 := Length(ItemName);
  1677.       ExtraFieldLength               := 0;
  1678.       FileCommentLength              := 0;
  1679.       DiskNumberStart                := 0;
  1680.       InternalFileAttributes         := 0;
  1681.       ExternalFileAttributes         := FileAttr;
  1682.       RelativeOffsetOfLocalHeader    := FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
  1683.       FileName                       := ItemName;
  1684.       ExtraField                     := '';
  1685.       FileComment                    := '';
  1686.    End;
  1687.  
  1688.  //************************************ EXPAND ZIP STREAM SIZE
  1689.  SizeToAppend := 0;
  1690.  SizeToAppend := SizeToAppend+SizeOf(Result.FLocalFile)-3*SizeOf(String);
  1691.  SizeToAppend := SizeToAppend+Result.FLocalFile.FilenameLength;
  1692.  SizeToAppend := SizeToAppend+CL;
  1693.  SizeToAppend := SizeToAppend+SizeOf(Result.FCentralDirectoryFile)-3*SizeOf(String);
  1694.  SizeToAppend := SizeToAppend+Result.FCentralDirectoryFile.FilenameLength;
  1695.  FParent.FZipStream.Size := FParent.FZipStream.Size+SizeToAppend;
  1696.  
  1697.  //************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
  1698.  FParent.FZipStream.Position := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
  1699.  FParent.FZipStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
  1700.  if Result.FLocalFile.FilenameLength > 0 Then FParent.FZipStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
  1701.  if CL > 0 Then FParent.FZipStream.Write(S[1],CL);
  1702.  
  1703.  //************************************ MARK START OF CENTRAL DIRECTORY
  1704.  FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory := FParent.FZipStream.Position;
  1705.  
  1706.  //************************************ SAVE CENTRAL DIRECTORY
  1707.  For X := 0 To Count-1 do
  1708.      Begin
  1709.        FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile,SizeOf(Self.Items[X].FCentralDirectoryFile)-3*SizeOf(String));
  1710.        if Self.Items[X].FCentralDirectoryFile.FilenameLength > 0 Then
  1711.           FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileName[1],Self.Items[X].FCentralDirectoryFile.FilenameLength);
  1712.        if Self.Items[X].FCentralDirectoryFile.ExtraFieldLength > 0 Then
  1713.           FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.ExtraField[1],Self.Items[X].FCentralDirectoryFile.ExtraFieldLength);
  1714.        if Self.Items[X].FCentralDirectoryFile.FileCommentLength > 0 Then
  1715.           FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileComment[1],Self.Items[X].FCentralDirectoryFile.FileCommentLength);
  1716.      End;
  1717.  
  1718.  //************************************ SAVE END CENTRAL DIRECTORY RECORD
  1719.  FParent.FEndOfCentralDirPos := FParent.FZipStream.Position;
  1720.  FParent.FEndOfCentralDir.SizeOfTheCentralDirectory := FParent.FEndOfCentralDirPos-FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
  1721.  Inc(FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
  1722.  Inc(FParent.FEndOfCentralDir.TotalNumberOfEntries);
  1723.  FParent.FZipStream.Write(FParent.FEndOfCentralDir, SizeOf(TEndOfCentralDir));
  1724.  
  1725.  //************************************ SAVE ZIP COMMENT IF ANY
  1726.  FParent.FZipCommentPos := FParent.FZipStream.Position;
  1727.  if Length(ZipComment) > 0 Then
  1728.     Begin
  1729.       FParent.FZipStream.Write(ZipComment[1],Length(ZipComment));
  1730.     End;
  1731.  
  1732.   Result.FDate   := FileDate;
  1733.  
  1734.   if (Result.FCentralDirectoryFile.GeneralPurposeBitFlag And 1) > 0 Then
  1735.       Result.FIsEncrypted := True
  1736.   Else
  1737.       Result.FIsEncrypted := False;
  1738.   Result.FIsFolder          := (Result.FCentralDirectoryFile.ExternalFileAttributes and faDirectory) > 0;
  1739.   Result.FCompressionType   := ctUnknown;
  1740.   if (Result.FCentralDirectoryFile.CompressionMethod=8) or (Result.FCentralDirectoryFile.CompressionMethod=9) Then
  1741.      Begin
  1742.        Case Result.FCentralDirectoryFile.GeneralPurposeBitFlag AND 6 of
  1743.             0 : Result.FCompressionType := ctNormal;
  1744.             2 : Result.FCompressionType := ctMaximum;
  1745.             4 : Result.FCompressionType := ctFast;
  1746.             6 : Result.FCompressionType := ctSuperFast
  1747.        End;
  1748.      End;
  1749.   FParent.FIsDirty := True;
  1750.   if NOT FParent.FBatchMode Then
  1751.     Begin
  1752.       FParent.DoChange(FParent,2);
  1753.     End;
  1754. end;
  1755.  
  1756. Function TKAZipEntries.AddStreamRebuild( ItemName  : String;
  1757.                                          FileAttr  : Word;
  1758.                                          FileDate  : TDateTime;
  1759.                                          Stream    : TStream):TKAZipEntriesEntry;
  1760. Var
  1761.   Compressor   : TCompressionStream;
  1762.   CS           : TStringStream;
  1763.   CM           : Word;
  1764.   S            : String;
  1765.   UL           : Integer;
  1766.   CL           : Integer;
  1767.   I            : Integer;
  1768.   X            : Integer;
  1769.   FCRC32       : Cardinal;
  1770.   OSL          : Cardinal;
  1771.   NewSize      : Cardinal;
  1772.   ZipComment   : String;
  1773.   TempStream   : TFileStream;
  1774.   TempMSStream : TMemoryStream;
  1775.   TempFileName : String;
  1776.   Level        : TCompressionLevel;
  1777.   OBM          : Boolean;
  1778. Begin
  1779.   if FParent.FUseTempFiles Then
  1780.      Begin
  1781.         TempFileName := FParent.GetDelphiTempFileName;
  1782.         TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
  1783.         Try
  1784.             //*********************************** SAVE ALL OLD LOCAL ITEMS
  1785.             FParent.RebuildLocalFiles(TempStream);
  1786.             //*********************************** COMPRESS DATA
  1787.             ZipComment              := FParent.Comment.Text;
  1788.             if NOT FParent.FStoreRelativePath Then
  1789.                ItemName             := ExtractFileName(ItemName);
  1790.             ItemName                := ToZipName(ItemName);
  1791.             I := IndexOf(ItemName);
  1792.             if I > -1 Then
  1793.                Begin
  1794.                  OBM := FParent.FBatchMode;
  1795.                  Try
  1796.                    if OBM=False Then FParent.FBatchMode := True;
  1797.                    Remove(I);
  1798.                  Finally
  1799.                    FParent.FBatchMode := OBM;
  1800.                  End;
  1801.                End;
  1802.  
  1803.             CM                      := 0;
  1804.             CS                      := TStringStream.Create('');
  1805.             CS.Position             := 0;
  1806.             Try
  1807.               UL                    := Stream.Size-Stream.Position;
  1808.               SetLength(S,UL);
  1809.               if UL > 0 Then
  1810.                  Begin
  1811.                    Stream.Read(S[1],UL);
  1812.                    CM               := 8;
  1813.                  End;
  1814.               FCRC32                := CalcCRC32(S);
  1815.               FParent.FCurrentDFS   := UL;
  1816.  
  1817.               Level                 := clDefault;
  1818.               Case FParent.FZipCompressionType of
  1819.                    ctNormal    : Level := clDefault;
  1820.                    ctMaximum   : Level := clMax;
  1821.                    ctFast      : Level := clFastest;
  1822.                    ctSuperFast : Level := clFastest;
  1823.                    ctNone      : Level := clNone;
  1824.               End;
  1825.  
  1826.               if CM=8 Then
  1827.                  Begin
  1828.                     Compressor            := TCompressionStream.Create(Level,CS);
  1829.                     Try
  1830.                        Compressor.OnProgress := FParent.OnCompress;
  1831.                        Compressor.Write(S[1],UL);
  1832.                     Finally
  1833.                        Compressor.Free;
  1834.                     End;
  1835.                     S                     := Copy(CS.DataString, 3, Length(CS.DataString)-6);
  1836.                  End;
  1837.             Finally
  1838.               CS.Free;
  1839.             End;
  1840.             //************************************************************************
  1841.             CL := Length(S);
  1842.             //*********************************** FILL RECORDS
  1843.             Result := TKAZipEntriesEntry(Self.Add);
  1844.             With Result.FLocalFile do
  1845.               Begin
  1846.                 LocalFileHeaderSignature := $04034B50;
  1847.                 VersionNeededToExtract   := 20;
  1848.                 GeneralPurposeBitFlag    := 0;
  1849.                 CompressionMethod        := CM;
  1850.                 LastModFileTimeDate      := DateTimeToFileDate(FileDate);
  1851.                 Crc32                    := FCRC32;
  1852.                 CompressedSize           := CL;
  1853.                 UncompressedSize         := UL;
  1854.                 FilenameLength           := Length(ItemName);
  1855.                 ExtraFieldLength         := 0;
  1856.                 FileName                 := ItemName;
  1857.                 ExtraField               := '';
  1858.                 CompressedData           := '';
  1859.               End;
  1860.  
  1861.             With Result.FCentralDirectoryFile Do
  1862.              Begin
  1863.                 CentralFileHeaderSignature     := $02014B50;
  1864.                 VersionMadeBy                  := 20;
  1865.                 VersionNeededToExtract         := 20;
  1866.                 GeneralPurposeBitFlag          := 0;
  1867.                 CompressionMethod              := CM;
  1868.                 LastModFileTimeDate            := DateTimeToFileDate(FileDate);
  1869.                 Crc32                          := FCRC32;
  1870.                 CompressedSize                 := CL;
  1871.                 UncompressedSize               := UL;
  1872.                 FilenameLength                 := Length(ItemName);
  1873.                 ExtraFieldLength               := 0;
  1874.                 FileCommentLength              := 0;
  1875.                 DiskNumberStart                := 0;
  1876.                 InternalFileAttributes         := 0;
  1877.                 ExternalFileAttributes         := FileAttr;
  1878.                 RelativeOffsetOfLocalHeader    := TempStream.Position;
  1879.                 FileName                       := ItemName;
  1880.                 ExtraField                     := '';
  1881.                 FileComment                    := '';
  1882.              End;
  1883.  
  1884.            //************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
  1885.            TempStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
  1886.            if Result.FLocalFile.FilenameLength > 0 Then TempStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
  1887.            if CL > 0 Then TempStream.Write(S[1],CL);
  1888.            //************************************
  1889.            FParent.NewLHOffsets[Count-1] := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
  1890.            FParent.RebuildCentralDirectory(TempStream);
  1891.            FParent.RebuildEndOfCentralDirectory(TempStream);
  1892.            //************************************
  1893.            TempStream.Position := 0;
  1894.            OSL                 := FParent.FZipStream.Size;
  1895.  
  1896.            // Sicherheitsbestimmung
  1897.            ProtectStream(FParent.FZipStream);
  1898.  
  1899.            Try
  1900.              FParent.FZipStream.Size := TempStream.Size;
  1901.            Except
  1902.              FParent.FZipStream.Size := OSL;
  1903.              Raise;
  1904.            End;
  1905.            FParent.FZipStream.Position := 0;
  1906.  
  1907.            FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
  1908.        Finally
  1909.          TempStream.Free;
  1910.          // Sicherheitsbestimmung
  1911.          dc_deletefile(tempfilename); // DeleteFile(TempFileName)
  1912.        End;
  1913.      End
  1914.   Else
  1915.      Begin
  1916.         TempMSStream := TMemoryStream.Create;
  1917.         NewSize := 0;
  1918.         For X := 0 To Count-1 do
  1919.             Begin
  1920.               NewSize := NewSize+Items[X].LocalEntrySize+Items[X].CentralEntrySize;
  1921.               if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,X,Count-1);
  1922.             End;
  1923.         NewSize := NewSize+SizeOf(FParent.FEndOfCentralDir)+FParent.FEndOfCentralDir.ZipfileCommentLength;
  1924.         Try
  1925.             TempMSStream.SetSize(NewSize);
  1926.             TempMSStream.Position := 0;
  1927.             //*********************************** SAVE ALL OLD LOCAL ITEMS
  1928.             FParent.RebuildLocalFiles(TempMSStream);
  1929.             //*********************************** COMPRESS DATA
  1930.             ZipComment              := FParent.Comment.Text;
  1931.             if NOT FParent.FStoreRelativePath Then
  1932.                ItemName             := ExtractFileName(ItemName);
  1933.             ItemName                := ToZipName(ItemName);
  1934.             I := IndexOf(ItemName);
  1935.             if I > -1 Then
  1936.                Begin
  1937.                  OBM := FParent.FBatchMode;
  1938.                  Try
  1939.                    if OBM=False Then FParent.FBatchMode := True;
  1940.                    Remove(I);
  1941.                  Finally
  1942.                    FParent.FBatchMode := OBM;
  1943.                  End;
  1944.                End;
  1945.  
  1946.             CM                      := 0;
  1947.             CS                      := TStringStream.Create('');
  1948.             CS.Position             := 0;
  1949.             Try
  1950.               UL                    := Stream.Size-Stream.Position;
  1951.               SetLength(S,UL);
  1952.               if UL > 0 Then
  1953.                  Begin
  1954.                    Stream.Read(S[1],UL);
  1955.                    CM               := 8;
  1956.                  End;
  1957.               FCRC32                := CalcCRC32(S);
  1958.               FParent.FCurrentDFS   := UL;
  1959.  
  1960.               Level                 := clDefault;
  1961.               Case FParent.FZipCompressionType of
  1962.                    ctNormal    : Level := clDefault;
  1963.                    ctMaximum   : Level := clMax;
  1964.                    ctFast      : Level := clFastest;
  1965.                    ctSuperFast : Level := clFastest;
  1966.                    ctNone      : Level := clNone;
  1967.               End;
  1968.  
  1969.               if CM=8 Then
  1970.                  Begin
  1971.                     Compressor            := TCompressionStream.Create(Level,CS);
  1972.                     Try
  1973.                        Compressor.OnProgress := FParent.OnCompress;
  1974.                        Compressor.Write(S[1],UL);
  1975.                     Finally
  1976.                        Compressor.Free;
  1977.                     End;
  1978.                     S                     := Copy(CS.DataString, 3, Length(CS.DataString)-6);
  1979.                  End;
  1980.             Finally
  1981.               CS.Free;
  1982.             End;
  1983.             //************************************************************************
  1984.             CL := Length(S);
  1985.             //*********************************** FILL RECORDS
  1986.             Result := TKAZipEntriesEntry(Self.Add);
  1987.             With Result.FLocalFile do
  1988.               Begin
  1989.                 LocalFileHeaderSignature := $04034B50;
  1990.                 VersionNeededToExtract   := 20;
  1991.                 GeneralPurposeBitFlag    := 0;
  1992.                 CompressionMethod        := CM;
  1993.                 LastModFileTimeDate      := DateTimeToFileDate(FileDate);
  1994.                 Crc32                    := FCRC32;
  1995.                 CompressedSize           := CL;
  1996.                 UncompressedSize         := UL;
  1997.                 FilenameLength           := Length(ItemName);
  1998.                 ExtraFieldLength         := 0;
  1999.                 FileName                 := ItemName;
  2000.                 ExtraField               := '';
  2001.                 CompressedData           := '';
  2002.               End;
  2003.  
  2004.             With Result.FCentralDirectoryFile Do
  2005.              Begin
  2006.                 CentralFileHeaderSignature     := $02014B50;
  2007.                 VersionMadeBy                  := 20;
  2008.                 VersionNeededToExtract         := 20;
  2009.                 GeneralPurposeBitFlag          := 0;
  2010.                 CompressionMethod              := CM;
  2011.                 LastModFileTimeDate            := DateTimeToFileDate(FileDate);
  2012.                 Crc32                          := FCRC32;
  2013.                 CompressedSize                 := CL;
  2014.                 UncompressedSize               := UL;
  2015.                 FilenameLength                 := Length(ItemName);
  2016.                 ExtraFieldLength               := 0;
  2017.                 FileCommentLength              := 0;
  2018.                 DiskNumberStart                := 0;
  2019.                 InternalFileAttributes         := 0;
  2020.                 ExternalFileAttributes         := FileAttr;
  2021.                 RelativeOffsetOfLocalHeader    := TempMSStream.Position;
  2022.                 FileName                       := ItemName;
  2023.                 ExtraField                     := '';
  2024.                 FileComment                    := '';
  2025.              End;
  2026.  
  2027.            //************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
  2028.            TempMSStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
  2029.            if Result.FLocalFile.FilenameLength > 0 Then TempMSStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
  2030.            if CL > 0 Then TempMSStream.Write(S[1],CL);
  2031.            //************************************
  2032.            FParent.NewLHOffsets[Count-1] := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
  2033.            FParent.RebuildCentralDirectory(TempMSStream);
  2034.            FParent.RebuildEndOfCentralDirectory(TempMSStream);
  2035.            //************************************
  2036.            TempMSStream.Position := 0;
  2037.            OSL                 := FParent.FZipStream.Size;
  2038.  
  2039.            // Sicherheitsbestimmung
  2040.            ProtectStream(FParent.FZipStream);
  2041.  
  2042.            Try
  2043.              FParent.FZipStream.Size := TempMSStream.Size;
  2044.            Except
  2045.              FParent.FZipStream.Size := OSL;
  2046.              Raise;
  2047.            End;
  2048.            FParent.FZipStream.Position := 0;
  2049.  
  2050.            FParent.FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
  2051.        Finally
  2052.          TempMSStream.Free;
  2053.        End;
  2054.      End;
  2055.  
  2056.   Result.FDate              := FileDateToDateTime(Result.FCentralDirectoryFile.LastModFileTimeDate);
  2057.   if (Result.FCentralDirectoryFile.GeneralPurposeBitFlag And 1) > 0 Then
  2058.       Result.FIsEncrypted := True
  2059.   Else
  2060.       Result.FIsEncrypted := False;
  2061.   Result.FIsFolder          := (Result.FCentralDirectoryFile.ExternalFileAttributes and faDirectory) > 0;
  2062.   Result.FCompressionType   := ctUnknown;
  2063.   if (Result.FCentralDirectoryFile.CompressionMethod=8) or (Result.FCentralDirectoryFile.CompressionMethod=9) Then
  2064.      Begin
  2065.        Case Result.FCentralDirectoryFile.GeneralPurposeBitFlag AND 6 of
  2066.             0 : Result.FCompressionType := ctNormal;
  2067.             2 : Result.FCompressionType := ctMaximum;
  2068.             4 : Result.FCompressionType := ctFast;
  2069.             6 : Result.FCompressionType := ctSuperFast
  2070.        End;
  2071.      End;
  2072.  FParent.FIsDirty := True;
  2073.  if NOT FParent.FBatchMode Then
  2074.     Begin
  2075.       FParent.DoChange(FParent,2);
  2076.     End;
  2077. End;
  2078.  
  2079. function TKAZipEntries.AddFolderChain(ItemName: String; FileAttr: Word;
  2080.   FileDate: TDateTime): Boolean;
  2081. Var
  2082.  FN     : String;
  2083.  TN     : String;
  2084.  INCN   : String;
  2085.  P      : Integer;
  2086.  MS     : TMemoryStream;
  2087.  NoMore : Boolean;
  2088. Begin
  2089.   //Marschall: Result := False;
  2090.   FN     := ExtractFilePath(ToDosName(ToZipName(ItemName)));
  2091.   TN     := FN;
  2092.   INCN   := '';
  2093.   MS     := TMemoryStream.Create;
  2094.   Try
  2095.     Repeat
  2096.       NoMore := True;
  2097.       P      := Pos('\',TN);
  2098.       if P > 0 Then
  2099.          Begin
  2100.             INCN        := INCN+Copy(TN,1,P);
  2101.             System.Delete(TN,1,P);
  2102.             MS.Position := 0;
  2103.             MS.Size     := 0;
  2104.             If IndexOf(INCN) = -1 Then
  2105.                Begin
  2106.                   if FParent.FZipSaveMethod = FastSave Then
  2107.                      AddStreamFast(INCN,FileAttr,FileDate,MS)
  2108.                   Else
  2109.                   if FParent.FZipSaveMethod = RebuildAll Then
  2110.                      AddStreamRebuild(INCN,FileAttr,FileDate,MS);
  2111.                End;
  2112.             NoMore := False;
  2113.          End;
  2114.     Until NoMore;
  2115.     Result := True;
  2116.   Finally
  2117.     MS.Free;
  2118.   End;
  2119. End;
  2120.  
  2121. Function TKAZipEntries.AddFolderChain(ItemName : String):Boolean;
  2122. begin
  2123.   Result := AddFolderChain(ItemName,faDirectory,Now);
  2124. end;
  2125.  
  2126. function TKAZipEntries.AddStream(FileName : String; FileAttr : Word; FileDate : TDateTime; Stream : TStream):TKAZipEntriesEntry;
  2127. Begin
  2128.   Result := Nil;
  2129.   if (FParent.FStoreFolders) AND (FParent.FStoreRelativePath) Then AddFolderChain(FileName);
  2130.   if FParent.FZipSaveMethod = FastSave Then
  2131.      Result := AddStreamFast(FileName,FileAttr,FileDate,Stream)
  2132.   Else
  2133.   if FParent.FZipSaveMethod = RebuildAll Then
  2134.      Result := AddStreamRebuild(FileName,FileAttr,FileDate,Stream);
  2135.   if Assigned(FParent.FOnAddItem) Then FParent.FOnAddItem(FParent,FileName);
  2136. End;
  2137.  
  2138. Function TKAZipEntries.AddStream(FileName: String; Stream : TStream):TKAZipEntriesEntry;
  2139. begin
  2140.   Result := AddStream(FileName,faArchive,Now,Stream);
  2141. end;
  2142.  
  2143. Function TKAZipEntries.AddFile(FileName, NewFileName: String):TKAZipEntriesEntry;
  2144. Var
  2145.  FS  : TFileStream;
  2146.  Dir : TSearchRec;
  2147.  Res : Integer;
  2148. begin
  2149.  Result := Nil;
  2150.  Res    := FindFirst(FileName,faAnyFile,Dir);
  2151.  if Res=0 Then
  2152.     Begin
  2153.       FS := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
  2154.       Try
  2155.         FS.Position := 0;
  2156.         Result := AddStream(NewFileName,Dir.Attr,FileDateToDateTime(Dir.Time),FS)
  2157.       Finally
  2158.         FS.Free;
  2159.       End;
  2160.     End;
  2161.  FindClose(Dir);
  2162. end;
  2163.  
  2164. Function TKAZipEntries.AddFile(FileName: String):TKAZipEntriesEntry;
  2165. begin
  2166.   Result := AddFile(FileName,FileName);
  2167. end;
  2168.  
  2169. function TKAZipEntries.AddFiles(FileNames: TStrings): Boolean;
  2170. Var
  2171.   X : Integer;
  2172. begin
  2173.   Result     := False;
  2174.   FParent.FBatchMode := True;
  2175.   Try
  2176.     For X := 0 To FileNames.Count-1 do AddFile(FileNames.Strings[X]);
  2177.   Except
  2178.     FParent.FBatchMode := False;
  2179.     FParent.DoChange(FParent,2);
  2180.     Exit;
  2181.   End;
  2182.   FParent.FBatchMode := False;
  2183.   FParent.DoChange(FParent,2);
  2184.   Result     := True;
  2185. end;
  2186.  
  2187. Function  TKAZipEntries.AddFolderEx(FolderName:String; RootFolder:String; WildCard : String; WithSubFolders : Boolean):Boolean;
  2188. Var
  2189.   Res : Integer;
  2190.   Dir : TSearchRec;
  2191.   FN  : String;
  2192. Begin
  2193.   Res := FindFirst(FolderName+'\*.*',faAnyFile,Dir);
  2194.   While Res=0 Do
  2195.      Begin
  2196.         if (Dir.Attr and faDirectory) > 0 Then
  2197.             Begin
  2198.               if (Dir.Name <> '..') And (Dir.Name <> '.') Then
  2199.                  Begin
  2200.                    FN := FolderName+'\'+Dir.Name;
  2201.                    if (FParent.FStoreFolders) AND (FParent.FStoreRelativePath) Then
  2202.                       AddFolderChain(RemoveRootName(FN+'\',RootFolder),Dir.Attr,FileDateToDateTime(Dir.Time));
  2203.                    if WithSubFolders Then
  2204.                       Begin
  2205.                         AddFolderEx(FN, RootFolder, WildCard, WithSubFolders);
  2206.                       End;
  2207.                  End
  2208.               Else
  2209.                  Begin
  2210.                    if (Dir.Name = '.') Then AddFolderChain(RemoveRootName(FolderName+'\',RootFolder),Dir.Attr,FileDateToDateTime(Dir.Time));
  2211.                  End;
  2212.             End
  2213.         Else
  2214.             Begin
  2215.               FN := FolderName+'\'+Dir.Name;
  2216.               if MatchesMask(FN,WildCard) Then
  2217.                  Begin
  2218.                    AddFile(FN,RemoveRootName(FN,RootFolder));
  2219.                  End;
  2220.             End;
  2221.         Res := FindNext(Dir);
  2222.      End;
  2223.   FindClose(Dir);
  2224.   Result := True;
  2225. End;
  2226.  
  2227. Function  TKAZipEntries.AddFolder(FolderName:String; RootFolder:String; WildCard : String; WithSubFolders : Boolean):Boolean;
  2228. Begin
  2229.   FParent.FBatchMode := True;
  2230.   Try
  2231.     Result := AddFolderEx(FolderName,RootFolder,WildCard,WithSubFolders);
  2232.   Finally
  2233.     FParent.FBatchMode := False;
  2234.     FParent.DoChange(FParent,2);
  2235.   End;
  2236. End;
  2237.  
  2238. Function TKAZipEntries.AddFilesAndFolders(FileNames:TStrings; RootFolder:String; WithSubFolders : Boolean):Boolean;
  2239. Var
  2240.   X   : Integer;
  2241.   Res : Integer;
  2242.   Dir : TSearchRec;
  2243. Begin
  2244.   FParent.FBatchMode := True;
  2245.   Try
  2246.     For X := 0 To FileNames.Count-1 do
  2247.         Begin
  2248.            Res := FindFirst(FileNames.Strings[X],faAnyFile,Dir);
  2249.            if Res=0 Then
  2250.               Begin
  2251.                 if (Dir.Attr and faDirectory) > 0 Then
  2252.                    Begin
  2253.                      if (Dir.Name <> '..') And (Dir.Name <> '.') Then
  2254.                         Begin
  2255.                           AddFolderEx(FileNames.Strings[X],RootFolder,'*.*',WithSubFolders);
  2256.                         End;  
  2257.                    End
  2258.                 Else
  2259.                    Begin
  2260.                      AddFile(FileNames.Strings[X],RemoveRootName(FileNames.Strings[X],RootFolder));
  2261.                    End;
  2262.               End;
  2263.            FindClose(Dir);
  2264.         End;
  2265.   Finally
  2266.     FParent.FBatchMode := False;
  2267.     FParent.DoChange(FParent,2);
  2268.   End;
  2269.   Result := True;
  2270. End;
  2271.  
  2272.  
  2273. procedure TKAZipEntries.RemoveFiles(List: TList);
  2274. begin
  2275.   if List.Count=1 Then
  2276.      Begin
  2277.        Remove(Integer(List.Items[0]));
  2278.      End
  2279.   Else
  2280.      Begin
  2281.        SortList(List);
  2282.        FParent.FBatchMode := True;
  2283.        Try
  2284.          RemoveBatch(List);
  2285.        Finally
  2286.          FParent.FBatchMode := False;
  2287.          FParent.DoChange(Self,3);
  2288.        End;
  2289.      End;
  2290. end;
  2291.  
  2292. Procedure TKAZipEntries.RemoveSelected;
  2293. Var
  2294.  X    : Integer;
  2295.  List : TList;
  2296. Begin
  2297.  FParent.FBatchMode := True;
  2298.  List               := TList.Create;
  2299.  Try
  2300.     For X := 0 to Count-1 do
  2301.        Begin
  2302.          if Self.Items[X].Selected Then List.Add(Pointer(X));
  2303.        End;
  2304.     RemoveBatch(List);
  2305.  Finally
  2306.    List.Free;
  2307.    FParent.FBatchMode := False;
  2308.    FParent.DoChange(Self,3);
  2309.  End;
  2310. End;
  2311.  
  2312.  
  2313. procedure TKAZipEntries.ExtractToStream(Item : TKAZipEntriesEntry; Stream: TStream);
  2314. Var
  2315.   SFS             : TMemoryStream;
  2316.   TFS             : TStream;
  2317.   BUF             : String;
  2318.   NR              : Cardinal;
  2319.   Decompressor    : TDecompressionStream;
  2320.   {$IFDEF USE_BZIP2}
  2321.   DecompressorBZ2 : TBZDecompressionStream;
  2322.   {$ENDIF}
  2323. begin
  2324.   if  (
  2325.        (Item.CompressionMethod=8) or
  2326.        {$IFDEF USE_BZIP2}
  2327.        (Item.CompressionMethod=12) or
  2328.        {$ENDIF}
  2329.        (Item.CompressionMethod=0)
  2330.        )
  2331.   And (NOT Item.FIsEncrypted) Then
  2332.      Begin
  2333.         SFS := TMemoryStream.Create;
  2334.         TFS := Stream;
  2335.         Try
  2336.           if Item.GetCompressedData(SFS) > 0 Then
  2337.              Begin
  2338.                 SFS.Position  := 0;
  2339.                 FParent.FCurrentDFS   := Item.SizeUncompressed;
  2340.                 //****************************************************** DEFLATE
  2341.                 if (Item.CompressionMethod=8) Then
  2342.                    Begin
  2343.                       Decompressor  := TDecompressionStream.Create(SFS);
  2344.                       Decompressor.OnProgress := FParent.OnDecompress;
  2345.                       SetLength(BUF,FParent.FCurrentDFS);
  2346.                       Try
  2347.                         NR := Decompressor.Read(BUF[1],FParent.FCurrentDFS);
  2348.                         if NR=FParent.FCurrentDFS Then TFS.Write(BUF[1],FParent.FCurrentDFS);
  2349.                       Finally
  2350.                         Decompressor.Free;
  2351.                       End;
  2352.                    End
  2353.                 //******************************************************* BZIP2
  2354.                 {$IFDEF USE_BZIP2}
  2355.                 Else
  2356.                 If Item.CompressionMethod=12 Then
  2357.                    Begin
  2358.                       DecompressorBZ2  := TBZDecompressionStream.Create(SFS);
  2359.                       DecompressorBZ2.OnProgress := FParent.OnDecompress;
  2360.                       SetLength(BUF,FParent.FCurrentDFS);
  2361.                       Try
  2362.                         NR := DecompressorBZ2.Read(BUF[1],FParent.FCurrentDFS);
  2363.                         if NR=FParent.FCurrentDFS Then TFS.Write(BUF[1],FParent.FCurrentDFS);
  2364.                       Finally
  2365.                         DecompressorBZ2.Free;
  2366.                       End;
  2367.                    End
  2368.                 {$ENDIF}
  2369.                 //****************************************************** STORED
  2370.                 Else
  2371.                 If Item.CompressionMethod=0 Then
  2372.                    Begin
  2373.                      TFS.CopyFrom(SFS,FParent.FCurrentDFS);
  2374.                    End;
  2375.              End;
  2376.         Finally
  2377.           SFS.Free;
  2378.         End;
  2379.      End
  2380.   Else
  2381.      Begin
  2382.        Raise Exception.Create('Cannot process this file: '+Item.FileName+' ');
  2383.      End;
  2384. end;
  2385.  
  2386. procedure TKAZipEntries.InternalExtractToFile(Item: TKAZipEntriesEntry;
  2387.   FileName: String);
  2388. Var
  2389.   TFS           : TFileStream;
  2390.   Attr          : Integer;
  2391. begin
  2392.   if Item.IsFolder Then
  2393.      Begin
  2394.        ForceDirectories(FileName);
  2395.      End
  2396.   Else
  2397.      Begin
  2398.         TFS := TFileStream.Create(FileName,fmCreate or fmOpenReadWrite or fmShareDenyNone);
  2399.         Try
  2400.           ExtractToStream(Item,TFS);
  2401.         Finally
  2402.           TFS.Free;
  2403.         End;
  2404.         If FParent.FApplyAttributes Then
  2405.            Begin
  2406.              Attr := faArchive;
  2407.              if Item.FCentralDirectoryFile.ExternalFileAttributes And faHidden   > 0 Then Attr := Attr Or faHidden;
  2408.              if Item.FCentralDirectoryFile.ExternalFileAttributes And faSysFile  > 0 Then Attr := Attr Or faSysFile;
  2409.              if Item.FCentralDirectoryFile.ExternalFileAttributes And faReadOnly > 0 Then Attr := Attr Or faReadOnly;
  2410.              FileSetAttr(FileName,Attr);
  2411.            End;
  2412.      End;
  2413. end;
  2414.  
  2415.  
  2416. procedure TKAZipEntries.ExtractToFile(Item: TKAZipEntriesEntry; FileName: String);
  2417. var
  2418.   Can : Boolean;
  2419.   OA  : TOverwriteAction;
  2420. Begin
  2421.   OA  := FParent.FOverwriteAction;
  2422.   Can := True;
  2423.   if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
  2424.    Begin
  2425.       if FileExists(FileName) Then
  2426.          Begin
  2427.            FParent.FOnOverwriteFile(FParent,FileName,OA);
  2428.          End
  2429.       Else
  2430.          Begin
  2431.            OA := oaOverwrite;
  2432.          End;
  2433.    End;
  2434.    Case OA Of
  2435.      oaSkip          : Can := False;
  2436.      oaSkipAll       : Can := False;
  2437.      oaOverwrite     : Can := True;
  2438.      oaOverwriteAll  : Can := True;
  2439.    End;
  2440.    if Can Then InternalExtractToFile(Item, FileName);
  2441. End;
  2442.  
  2443. procedure TKAZipEntries.ExtractToFile(ItemIndex: Integer; FileName: String);
  2444. var
  2445.   Can       : Boolean;
  2446.   OA        : TOverwriteAction;                                                    
  2447. Begin
  2448.   OA  := FParent.FOverwriteAction;
  2449.   Can := True;
  2450.   if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
  2451.    Begin
  2452.       if FileExists(FileName) Then
  2453.          Begin
  2454.            FParent.FOnOverwriteFile(FParent,FileName,OA);
  2455.          End
  2456.       Else
  2457.          Begin
  2458.            OA := oaOverwrite;
  2459.          End;
  2460.    End;
  2461.    Case OA Of
  2462.      oaSkip          : Can := False;
  2463.      oaSkipAll       : Can := False;
  2464.      oaOverwrite     : Can := True;
  2465.      oaOverwriteAll  : Can := True;
  2466.    End;
  2467.    if Can Then InternalExtractToFile(Items[ItemIndex],FileName);
  2468. end;
  2469.  
  2470. procedure TKAZipEntries.ExtractToFile(FileName, DestinationFileName: String);
  2471. Var
  2472.   I   : Integer;
  2473.   Can : Boolean;
  2474.   OA  : TOverwriteAction;
  2475. Begin
  2476.   OA  := FParent.FOverwriteAction;
  2477.   Can := True;
  2478.   if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
  2479.    Begin
  2480.       if FileExists(DestinationFileName) Then
  2481.          Begin
  2482.            FParent.FOnOverwriteFile(FParent,DestinationFileName,OA);
  2483.          End
  2484.       Else
  2485.          Begin
  2486.            OA := oaOverwrite;
  2487.          End;
  2488.    End;
  2489.    Case OA Of
  2490.      oaSkip          : Can := False;
  2491.      oaSkipAll       : Can := False;
  2492.      oaOverwrite     : Can := True;
  2493.      oaOverwriteAll  : Can := True;
  2494.    End;
  2495.    if Can Then
  2496.       Begin
  2497.         I := IndexOf(FileName);
  2498.         InternalExtractToFile(Items[I],DestinationFileName);
  2499.       End;
  2500. end;
  2501.  
  2502. procedure TKAZipEntries.ExtractAll(TargetDirectory: String);
  2503. Var
  2504.   FN        : String;
  2505.   DN        : String;
  2506.   X         : Integer;
  2507.   Can       : Boolean;
  2508.   OA        : TOverwriteAction;
  2509.   FileName  : String;
  2510. begin
  2511.   OA    := FParent.FOverwriteAction;
  2512.   Can   := True;
  2513.   Try
  2514.     For X := 0 To Count-1 do
  2515.         Begin
  2516.           FN := FParent.GetFileName(Items[X].FileName);
  2517.           DN := FParent.GetFilePath(Items[X].FileName);
  2518.           if DN <> '' Then ForceDirectories(TargetDirectory+'\'+DN);
  2519.           FileName := TargetDirectory+'\'+DN+FN;
  2520.           if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
  2521.              Begin
  2522.                 if FileExists(FileName) Then
  2523.                    Begin
  2524.                      FParent.FOnOverwriteFile(FParent,FileName,OA);
  2525.                    End;
  2526.              End;
  2527.           Case OA Of
  2528.             oaSkip          : Can := False;
  2529.             oaSkipAll       : Can := False;
  2530.             oaOverwrite     : Can := True;
  2531.             oaOverwriteAll  : Can := True;
  2532.           End;
  2533.           if Can Then InternalExtractToFile(Items[X],FileName);
  2534.         End;
  2535.   Finally
  2536.   End;
  2537. end;
  2538.  
  2539. procedure TKAZipEntries.ExtractSelected(TargetDirectory: String);
  2540. Var
  2541.   FN        : String;
  2542.   DN        : String;
  2543.   X         : Integer;
  2544.   OA        : TOverwriteAction;
  2545.   Can       : Boolean;
  2546.   FileName  : String;
  2547. begin
  2548.   OA    := FParent.FOverwriteAction;
  2549.   Can   := True;
  2550.   Try
  2551.     For X := 0 To Count-1 do
  2552.       Begin
  2553.         if Items[X].FSelected Then
  2554.            Begin
  2555.               FN := FParent.GetFileName(Items[X].FileName);
  2556.               DN := FParent.GetFilePath(Items[X].FileName);
  2557.               if DN <> '' Then ForceDirectories(TargetDirectory+'\'+DN);
  2558.               FileName := TargetDirectory+'\'+DN+FN;
  2559.               if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
  2560.                  Begin
  2561.                     if FileExists(FileName) Then
  2562.                        Begin
  2563.                          FParent.FOnOverwriteFile(FParent,FileName,OA);
  2564.                        End;
  2565.                  End;
  2566.               Case OA Of
  2567.                 oaSkip          : Can := False;
  2568.                 oaSkipAll       : Can := False;
  2569.                 oaOverwrite     : Can := True;
  2570.                 oaOverwriteAll  : Can := True;
  2571.               End;
  2572.              if Can Then InternalExtractToFile(Items[X],TargetDirectory+'\'+DN+FN);
  2573.            End;
  2574.       End;
  2575.   Finally
  2576.   End;
  2577. end;
  2578.  
  2579.  
  2580.  
  2581. procedure TKAZipEntries.DeSelectAll;
  2582. Var
  2583.   X : Integer;
  2584. begin
  2585.   For X := 0 To Count-1 do Items[X].Selected := False;
  2586. end;
  2587.  
  2588. procedure TKAZipEntries.InvertSelection;
  2589. Var
  2590.   X : Integer;
  2591. begin
  2592.   For X := 0 To Count-1 do Items[X].Selected := Not Items[X].Selected;
  2593. end;
  2594.  
  2595. procedure TKAZipEntries.SelectAll;
  2596. Var
  2597.   X : Integer;
  2598. begin
  2599.   For X := 0 To Count-1 do Items[X].Selected := True;
  2600. end;
  2601.  
  2602. procedure TKAZipEntries.Select(WildCard: String);
  2603. Var
  2604.   X : Integer;
  2605. begin
  2606.   For X := 0 To Count-1 do
  2607.       Begin
  2608.         if MatchesMask(ToDosName(Items[X].FileName),WildCard) Then
  2609.            Items[X].Selected := True;
  2610.       End;
  2611. end;
  2612.  
  2613.  
  2614. procedure TKAZipEntries.Rebuild;
  2615. begin
  2616.   FParent.Rebuild;
  2617. end;
  2618.  
  2619. procedure TKAZipEntries.Rename(Item: TKAZipEntriesEntry; NewFileName: String);
  2620. begin
  2621.   Item.FileName := NewFileName;
  2622. end;
  2623.  
  2624. procedure TKAZipEntries.Rename(ItemIndex: Integer; NewFileName: String);
  2625. begin
  2626.   Rename(Items[ItemIndex],NewFileName);
  2627. end;
  2628.  
  2629. procedure TKAZipEntries.Rename(FileName, NewFileName: String);
  2630. Var
  2631.   I    : Integer;
  2632. begin
  2633.   I := IndexOf(FileName);
  2634.   Rename(I,NewFileName);
  2635. end;
  2636.  
  2637.  
  2638. procedure TKAZipEntries.CreateFolder(FolderName: String; FolderDate: TDateTime);
  2639. Var
  2640.   FN : String;
  2641. begin
  2642.   FN       := IncludeTrailingBackslash(FolderName);
  2643.   AddFolderChain(FN,faDirectory,FolderDate);
  2644.   FParent.FIsDirty := True;
  2645. end;
  2646.  
  2647. procedure TKAZipEntries.RenameFolder(FolderName : String; NewFolderName : String);
  2648. Var
  2649.   FN  : String;
  2650.   NFN : String;
  2651.   S   : String;
  2652.   X   : Integer;
  2653.   L   : Integer;
  2654. begin
  2655.   FN  := ToZipName(IncludeTrailingBackslash(FolderName));
  2656.   NFN := ToZipName(IncludeTrailingBackslash(NewFolderName));
  2657.   L   := Length(FN);
  2658.   if IndexOf(NFN) = -1 Then
  2659.      Begin
  2660.        For X := 0 To Count-1 do
  2661.            Begin
  2662.              S := Items[X].FileName;
  2663.              if Pos(FN,S) = 1 Then
  2664.                 Begin
  2665.                   System.Delete(S,1,L);
  2666.                   S := NFN+S;
  2667.                   Items[X].FileName := S;
  2668.                   FParent.FIsDirty := True;
  2669.                 End;
  2670.            End;
  2671.        If (FParent.FIsDirty) And (FParent.FBatchMode=False) Then Rebuild;
  2672.      End;
  2673. end;
  2674.  
  2675. procedure TKAZipEntries.RenameMultiple(Names : TStringList; NewNames : TStringList);
  2676. Var
  2677.   X    : Integer;
  2678.   BR   : Integer;
  2679.   L    : Integer;
  2680. Begin
  2681.   BR := 0; // Marschall
  2682.   If Names.Count <> NewNames.Count Then
  2683.      Begin
  2684.        Raise Exception.Create('Names and NewNames must have equal count');
  2685.      End
  2686.   Else
  2687.      Begin
  2688.        FParent.FBatchMode := True;
  2689.        Try
  2690.          For X := 0 To Names.Count-1 do
  2691.              Begin
  2692.                L := Length(Names.Strings[X]);
  2693.                if (L>0) And ((Names.Strings[X][L]='\') or (Names.Strings[X][L]='/')) Then
  2694.                   Begin
  2695.                     RenameFolder(Names.Strings[X],NewNames.Strings[X]);
  2696.                     Inc(BR);
  2697.                   End
  2698.                Else
  2699.                   Begin
  2700.                     Rename(Names.Strings[X],NewNames.Strings[X]);
  2701.                     Inc(BR);
  2702.                   End;
  2703.              End;
  2704.        Finally
  2705.          FParent.FBatchMode := False;
  2706.        End;
  2707.        If BR > 0 Then
  2708.           Begin
  2709.             Rebuild;
  2710.             FParent.DoChange(FParent,6);
  2711.           End;
  2712.      End;
  2713. End;
  2714.  
  2715.  
  2716. { TKAZip }
  2717. constructor TKAZip.Create(AOwner: TComponent);
  2718. begin
  2719.  Inherited Create(AOwner);
  2720.  FZipStream          := Nil;
  2721.  FOnDecompressFile   := Nil;
  2722.  FOnCompressFile     := Nil;
  2723.  FOnZipChange        := Nil;
  2724.  FOnZipOpen          := Nil;
  2725.  FOnAddItem          := Nil;
  2726.  FOnOverwriteFile    := Nil;
  2727.  FComponentVersion   := '2.0';
  2728.  FBatchMode          := False;
  2729.  FFileNames          := TStringList.Create;
  2730.  FZipHeader          := TKAZipEntries.Create(Self);
  2731.  FZipComment         := TStringList.Create;
  2732.  FIsZipFile          := False;
  2733.  FFileName           := '';
  2734.  FCurrentDFS         := 0;
  2735.  FExternalStream     := False;
  2736.  FIsDirty            := True;
  2737.  FHasBadEntries      := False;
  2738.  FReadOnly           := False;
  2739.  
  2740.  FApplyAttributes     := True;
  2741.  FOverwriteAction    := oaSkip;
  2742.  FZipSaveMethod      := FastSave;
  2743.  FUseTempFiles       := False;
  2744.  FStoreRelativePath  := True;
  2745.  FStoreFolders       := True;
  2746.  FZipCompressionType := ctMaximum;
  2747. end;
  2748.  
  2749.  
  2750. destructor TKAZip.Destroy;
  2751. begin
  2752.   if Assigned(FZipStream) AND (NOT FExternalStream) Then FZipStream.Free;
  2753.   FZipHeader.Free;
  2754.   FZipComment.Free;
  2755.   FFileNames.Free;
  2756.   inherited Destroy;
  2757. end;
  2758.  
  2759. procedure TKAZip.DoChange(Sender: TObject; Const ChangeType : Integer);
  2760. begin
  2761.   if Assigned(FOnZipChange) Then FOnZipChange(Self, ChangeType);
  2762. end;
  2763.  
  2764.  
  2765. function TKAZip.GetFileName(S: String): String;
  2766. Var
  2767.  FN : String;
  2768.  P  : Integer;
  2769. begin
  2770.  FN := S;
  2771.  FN := StringReplace(FN,'//','\',[rfReplaceAll]);
  2772.  FN := StringReplace(FN,'/','\',[rfReplaceAll]);
  2773.  P := Pos(':\',FN);
  2774.  if P > 0 Then System.Delete(FN,1,P+1);
  2775.  Result := ExtractFileName(StringReplace(FN,'/','\',[rfReplaceAll]));
  2776. end;
  2777.  
  2778. function TKAZip.GetFilePath(S: String): String;
  2779. Var
  2780.  FN : String;
  2781.  P  : Integer;
  2782. begin
  2783.  FN := S;
  2784.  FN := StringReplace(FN,'//','\',[rfReplaceAll]);
  2785.  FN := StringReplace(FN,'/','\',[rfReplaceAll]);
  2786.  P := Pos(':\',FN);
  2787.  if P > 0 Then System.Delete(FN,1,P+1);
  2788.  Result := ExtractFilePath(StringReplace(FN,'/','\',[rfReplaceAll]));
  2789. end;
  2790.  
  2791.  
  2792. procedure TKAZip.LoadFromFile(FileName: String);
  2793. Var
  2794.    Res : Integer;
  2795.    Dir : TSearchRec;
  2796. begin
  2797.    Res := FindFirst(FileName,faAnyFile,Dir);
  2798.    If Res=0 Then
  2799.       Begin
  2800.          if Dir.Attr And faReadOnly > 0 Then
  2801.             Begin
  2802.               FZipStream := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
  2803.               FReadOnly  := True;
  2804.             End
  2805.          Else
  2806.             Begin
  2807.               FZipStream := TFileStream.Create(FileName,fmOpenReadWrite or fmShareDenyNone);
  2808.               FReadOnly  := False;
  2809.             End;
  2810.          LoadFromStream(FZipStream);
  2811.       End
  2812.    Else
  2813.       Begin
  2814.         Raise Exception.Create('File "'+FileName+'" not found!');
  2815.       End;
  2816. end;
  2817.  
  2818. procedure TKAZip.LoadFromStream(MS : TStream);
  2819. begin
  2820.   FZipStream := MS;
  2821.   FZipHeader.ParseZip(MS);
  2822.   FIsZipFile := FZipHeader.FIsZipFile;
  2823.   if Not FIsZipFile Then Close;
  2824.   FIsDirty := True;
  2825.   DoChange(Self,1);
  2826. end;
  2827.  
  2828. procedure TKAZip.Close;
  2829. begin
  2830.   Entries.Clear;
  2831.   if Assigned(FZipStream) AND (NOT FExternalStream) Then FZipStream.Free;
  2832.   FExternalStream := False;
  2833.   FZipStream      := Nil;
  2834.   FIsZipFile      := False;
  2835.   FIsDirty        := True;
  2836.   FReadOnly       := False;
  2837.   DoChange(Self,0);
  2838. end;
  2839.  
  2840. procedure TKAZip.SetFileName(const Value: String);
  2841. begin
  2842.   FFileName := Value;
  2843. end;
  2844.  
  2845. procedure TKAZip.Open(FileName: String);
  2846. begin
  2847.   Close;
  2848.   LoadFromFile(FileName);
  2849.   FFileName := FileName;
  2850. end;
  2851.  
  2852. procedure TKAZip.Open(MS: TStream);
  2853. begin
  2854.  Try
  2855.    Close;
  2856.    LoadFromStream(MS);
  2857.  Finally
  2858.    FExternalStream   := True;
  2859.  End;
  2860. end;
  2861.  
  2862. procedure TKAZip.SetIsZipFile(const Value: Boolean);
  2863. begin
  2864.   //****************************************************************************
  2865. end;
  2866.  
  2867. function TKAZip.GetDelphiTempFileName: String;
  2868. Var
  2869.  TmpDir : Array[0..1000] of Char;
  2870.  TmpFN  : Array[0..1000] of Char;
  2871. Begin
  2872.  Result := GetCurrentDir;
  2873.  if GetTempPath(1000,TmpDir) <> 0 Then
  2874.     Begin
  2875.      if GetTempFileName(TmpDir,'',0,TmpFN) <> 0 Then Result := StrPas(TmpFN);
  2876.     End;
  2877. End;
  2878.  
  2879. procedure TKAZip.OnDecompress(Sender: TObject);
  2880. Var
  2881.   DS : TStream;
  2882. begin
  2883.   DS := TStream(Sender);
  2884.   if Assigned(FOnDecompressFile) Then FOnDecompressFile(Self,DS.Position,FCurrentDFS);
  2885. end;
  2886.  
  2887. procedure TKAZip.OnCompress(Sender: TObject);
  2888. Var
  2889.   CS : TStream;
  2890. begin
  2891.   CS := TStream(Sender);
  2892.   if Assigned(FOnCompressFile) Then FOnCompressFile(Self,CS.Position,FCurrentDFS);
  2893. end;
  2894.  
  2895. procedure TKAZip.ExtractToFile(Item : TKAZipEntriesEntry; FileName: String);
  2896. begin
  2897.   Entries.ExtractToFile(Item,FileName);
  2898. end;
  2899.  
  2900. procedure TKAZip.ExtractToFile(ItemIndex: Integer; FileName: String);
  2901. begin
  2902.   Entries.ExtractToFile(ItemIndex,FileName);
  2903. end;
  2904.  
  2905. procedure TKAZip.ExtractToFile(FileName, DestinationFileName: String);
  2906. begin
  2907.   Entries.ExtractToFile(FileName,DestinationFileName);
  2908. end;
  2909.  
  2910. procedure TKAZip.ExtractToStream(Item : TKAZipEntriesEntry; Stream: TStream);
  2911. begin
  2912.   Entries.ExtractToStream(Item,Stream);
  2913. end;
  2914.  
  2915. procedure TKAZip.ExtractAll(TargetDirectory: String);
  2916. begin
  2917.   Entries.ExtractAll(TargetDirectory);
  2918. end;
  2919.  
  2920. procedure TKAZip.ExtractSelected(TargetDirectory: String);
  2921. Begin
  2922.   Entries.ExtractSelected(TargetDirectory);
  2923. End;
  2924.  
  2925. function TKAZip.AddFile(FileName, NewFileName: String): TKAZipEntriesEntry;
  2926. begin
  2927.   Result := Entries.AddFile(FileName, NewFileName);
  2928. end;
  2929.  
  2930. function TKAZip.AddFile(FileName: String): TKAZipEntriesEntry;
  2931. begin
  2932.   Result := Entries.AddFile(FileName);
  2933. end;
  2934.  
  2935. function TKAZip.AddFiles(FileNames: TStrings): Boolean;
  2936. begin
  2937.   Result := Entries.AddFiles(FileNames);
  2938. end;
  2939.  
  2940. function TKAZip.AddFolder(FolderName, RootFolder, WildCard: String;
  2941.   WithSubFolders: Boolean): Boolean;
  2942. begin
  2943.   Result := Entries.AddFolder(FolderName,RootFolder,WildCard,WithSubFolders);
  2944. end;
  2945.  
  2946. function TKAZip.AddFilesAndFolders(FileNames: TStrings; RootFolder: String;
  2947.   WithSubFolders: Boolean): Boolean;
  2948. begin
  2949.   Result := Entries.AddFilesAndFolders(FileNames,RootFolder,WithSubFolders);
  2950. end;
  2951.  
  2952. function TKAZip.AddStream(FileName: String; FileAttr: Word;  FileDate: TDateTime; Stream: TStream): TKAZipEntriesEntry;
  2953. begin
  2954.   Result := Entries.AddStream(FileName,FileAttr,FileDate,Stream);
  2955. end;
  2956.  
  2957. function TKAZip.AddStream(FileName: String;  Stream: TStream): TKAZipEntriesEntry;
  2958. begin
  2959.   Result := Entries.AddStream(FileName,Stream);
  2960. end;
  2961.  
  2962.  
  2963. procedure TKAZip.Remove(Item: TKAZipEntriesEntry);
  2964. begin
  2965.   Entries.Remove(Item);
  2966. end;
  2967.  
  2968. procedure TKAZip.Remove(ItemIndex: Integer);
  2969. begin
  2970.   Entries.Remove(ItemIndex);
  2971. end;
  2972.  
  2973. procedure TKAZip.Remove(FileName: String);
  2974. begin
  2975.   Entries.Remove(FileName);
  2976. end;
  2977.  
  2978. procedure TKAZip.RemoveFiles(List: TList);
  2979. begin
  2980.   Entries.RemoveFiles(List);
  2981. end;
  2982.  
  2983. procedure TKAZip.RemoveSelected;
  2984. begin
  2985.   Entries.RemoveSelected;;
  2986. end;
  2987.  
  2988. function TKAZip.GetComment: TStrings;
  2989. Var
  2990.  S : String;
  2991. begin
  2992.   Result := FZipComment;
  2993.   FZipComment.Clear;
  2994.   if FIsZipFile Then
  2995.      Begin
  2996.        if FEndOfCentralDir.ZipfileCommentLength > 0 Then
  2997.           Begin
  2998.             FZipStream.Position := FZipCommentPos;
  2999.             SetLength(S,FEndOfCentralDir.ZipfileCommentLength);
  3000.             FZipStream.Read(S[1],FEndOfCentralDir.ZipfileCommentLength);
  3001.             FZipComment.Text    := S;
  3002.           End;
  3003.      End;
  3004. end;
  3005.  
  3006. procedure TKAZip.SetComment(const Value: TStrings);
  3007. Var
  3008.   Comment : String;
  3009.   L       : Integer;
  3010. begin
  3011.   //****************************************************************************
  3012.   if FZipComment.Text=Value.Text Then Exit;
  3013.   FZipComment.Clear;
  3014.   if FIsZipFile Then
  3015.      Begin
  3016.        FZipComment.Assign(Value);
  3017.        Comment                               := FZipComment.Text;
  3018.        L                                     := Length(Comment);
  3019.        FEndOfCentralDir.ZipfileCommentLength := L;
  3020.        FZipStream.Position                   := FEndOfCentralDirPos;
  3021.        FZipStream.Write(FEndOfCentralDir,SizeOf(TEndOfCentralDir));
  3022.        FZipCommentPos                        := FZipStream.Position;
  3023.        if L > 0 Then
  3024.           Begin
  3025.             FZipStream.Write(Comment[1],L)
  3026.           End
  3027.        Else
  3028.           Begin
  3029.             FZipStream.Size := FZipStream.Position;
  3030.           End;
  3031.      End;
  3032. end;
  3033.  
  3034. procedure TKAZip.DeSelectAll;
  3035. begin
  3036.   Entries.DeSelectAll;
  3037. end;
  3038.  
  3039. procedure TKAZip.Select(WildCard : String);
  3040. begin
  3041.   Entries.Select(WildCard);
  3042. end;
  3043.  
  3044. procedure TKAZip.InvertSelection;
  3045. begin
  3046.   Entries.InvertSelection;
  3047. end;
  3048.  
  3049. procedure TKAZip.SelectAll;
  3050. begin
  3051.   Entries.SelectAll;
  3052. end;
  3053.  
  3054. procedure TKAZip.RebuildLocalFiles(MS: TStream);
  3055. Var
  3056.   X    : Integer;
  3057.   LF   : TLocalFile;
  3058. begin
  3059.   //************************************************* RESAVE ALL LOCAL BLOCKS
  3060.   SetLength(NewLHOffsets,Entries.Count+1);
  3061.   For X := 0 To Entries.Count-1 do
  3062.       Begin
  3063.         NewLHOffsets[X] := MS.Position;
  3064.         LF  := Entries.GetLocalEntry(FZipStream,Entries.Items[X].LocalOffset,False);
  3065.         MS.Write(LF, SizeOf(LF)-3*SizeOf(String));
  3066.         if LF.FilenameLength   > 0 Then MS.Write(LF.FileName[1]  ,LF.FilenameLength);
  3067.         if LF.ExtraFieldLength > 0 Then MS.Write(LF.ExtraField[1],LF.ExtraFieldLength);
  3068.         if LF.CompressedSize   > 0 Then MS.Write(LF.CompressedData[1],LF.CompressedSize);
  3069.         if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
  3070.       End;
  3071. end;
  3072.  
  3073. procedure TKAZip.RebuildCentralDirectory(MS: TStream);
  3074. Var
  3075.   X    : Integer;
  3076.   CDF  : TCentralDirectoryFile;
  3077. begin
  3078.   NewEndOfCentralDir := FEndOfCentralDir;
  3079.   NewEndOfCentralDir.TotalNumberOfEntriesOnThisDisk  := Entries.Count;
  3080.   NewEndOfCentralDir.TotalNumberOfEntries            := Entries.Count;
  3081.   NewEndOfCentralDir.OffsetOfStartOfCentralDirectory := MS.Position;
  3082.   For X := 0 To Entries.Count-1 do
  3083.       Begin
  3084.         CDF := Entries.Items[X].FCentralDirectoryFile;
  3085.         CDF.RelativeOffsetOfLocalHeader := NewLHOffsets[X];
  3086.         MS.Write(CDF,SizeOf(CDF)-3*SizeOf(String));
  3087.         if CDF.FilenameLength > 0 Then
  3088.            MS.Write(CDF.FileName[1],CDF.FilenameLength);
  3089.         if CDF.ExtraFieldLength > 0 Then
  3090.            MS.Write(CDF.ExtraField[1],CDF.ExtraFieldLength);
  3091.         if CDF.FileCommentLength > 0 Then
  3092.            MS.Write(CDF.FileComment[1],CDF.FileCommentLength);
  3093.         if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
  3094.       End;
  3095.   NewEndOfCentralDir.SizeOfTheCentralDirectory := MS.Position-NewEndOfCentralDir.OffsetOfStartOfCentralDirectory;
  3096. end;
  3097.  
  3098. procedure TKAZip.RebuildEndOfCentralDirectory(MS: TStream);
  3099. Var
  3100.   ZipComment : String;
  3101. begin
  3102.   ZipComment   := Comment.Text;
  3103.   FRebuildECDP := MS.Position;
  3104.   MS.Write(NewEndOfCentralDir,SizeOf(NewEndOfCentralDir));
  3105.   FRebuildCP   := MS.Position;
  3106.   if NewEndOfCentralDir.ZipfileCommentLength > 0 Then
  3107.      Begin
  3108.        MS.Write(ZipComment[1],NewEndOfCentralDir.ZipfileCommentLength);
  3109.      End;
  3110.   if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,100,100);
  3111. end;
  3112.  
  3113. Procedure TKAZip.FixZip(MS : TStream);
  3114. Var
  3115.   X          : Integer;
  3116.   Y          : Integer;
  3117.   NewCount   : Integer;
  3118.   LF         : TLocalFile;
  3119.   CDF        : TCentralDirectoryFile;
  3120.   ZipComment : String;
  3121. Begin
  3122.   ZipComment   := Comment.Text;
  3123.   Y            := 0;
  3124.   SetLength(NewLHOffsets,Entries.Count+1);
  3125.   For X := 0 To Entries.Count-1 do
  3126.       Begin
  3127.         LF  := Entries.GetLocalEntry(FZipStream,Entries.Items[X].LocalOffset,False);
  3128.         if (LF.LocalFileHeaderSignature=$04034b50) And (Entries.Items[X].Test) Then
  3129.            Begin
  3130.              NewLHOffsets[Y] := MS.Position;
  3131.              MS.Write(LF, SizeOf(LF)-3*SizeOf(String));
  3132.              if LF.FilenameLength   > 0 Then MS.Write(LF.FileName[1]  ,LF.FilenameLength);
  3133.              if LF.ExtraFieldLength > 0 Then MS.Write(LF.ExtraField[1],LF.ExtraFieldLength);
  3134.              if LF.CompressedSize   > 0 Then MS.Write(LF.CompressedData[1],LF.CompressedSize);
  3135.              if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
  3136.              Inc(Y);
  3137.            End
  3138.         Else
  3139.            Begin
  3140.              Entries.Items[X].FCentralDirectoryFile.CentralFileHeaderSignature := 0;
  3141.              if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
  3142.            End;
  3143.       End;
  3144.  
  3145.   NewCount := Y;
  3146.   Y        := 0;
  3147.   NewEndOfCentralDir := FEndOfCentralDir;
  3148.   NewEndOfCentralDir.TotalNumberOfEntriesOnThisDisk  := NewCount;
  3149.   NewEndOfCentralDir.TotalNumberOfEntries            := NewCount;
  3150.   NewEndOfCentralDir.OffsetOfStartOfCentralDirectory := MS.Position;
  3151.   For X := 0 To Entries.Count-1 do
  3152.       Begin
  3153.         CDF := Entries.Items[X].FCentralDirectoryFile;
  3154.         if CDF.CentralFileHeaderSignature=$02014b50 Then
  3155.            Begin
  3156.              CDF.RelativeOffsetOfLocalHeader := NewLHOffsets[Y];
  3157.              MS.Write(CDF,SizeOf(CDF)-3*SizeOf(String));
  3158.              if CDF.FilenameLength > 0 Then
  3159.                 MS.Write(CDF.FileName[1],CDF.FilenameLength);
  3160.              if CDF.ExtraFieldLength > 0 Then
  3161.                 MS.Write(CDF.ExtraField[1],CDF.ExtraFieldLength);
  3162.              if CDF.FileCommentLength > 0 Then
  3163.                 MS.Write(CDF.FileComment[1],CDF.FileCommentLength);
  3164.              if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
  3165.              Inc(Y);
  3166.            End;
  3167.       End;
  3168.   NewEndOfCentralDir.SizeOfTheCentralDirectory := MS.Position-NewEndOfCentralDir.OffsetOfStartOfCentralDirectory;
  3169.  
  3170.   FRebuildECDP := MS.Position;
  3171.   MS.Write(NewEndOfCentralDir,SizeOf(NewEndOfCentralDir));
  3172.   FRebuildCP   := MS.Position;
  3173.   if NewEndOfCentralDir.ZipfileCommentLength > 0 Then
  3174.      Begin
  3175.        MS.Write(ZipComment[1],NewEndOfCentralDir.ZipfileCommentLength);
  3176.      End;
  3177.   if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,100,100);
  3178. End;
  3179.  
  3180.  
  3181. Procedure TKAZip.SaveToStream(Stream:TStream);
  3182. Begin
  3183.   RebuildLocalFiles(Stream);
  3184.   RebuildCentralDirectory(Stream);
  3185.   RebuildEndOfCentralDirectory(Stream);
  3186. End;
  3187.  
  3188. Procedure TKAZip.Rebuild;
  3189. var
  3190.   TempStream          : TFileStream;
  3191.   TempMSStream        : TMemoryStream;
  3192.   TempFileName        : String;
  3193. Begin
  3194.   if FUseTempFiles Then
  3195.      Begin
  3196.         TempFileName := GetDelphiTempFileName;
  3197.         TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
  3198.         Try
  3199.           SaveToStream(TempStream);
  3200.  
  3201.           // Sicherheitsbestimmung
  3202.           ProtectStream(FZipStream);
  3203.  
  3204.           FZipStream.Position := 0;
  3205.           FZipStream.Size     := 0;
  3206.           TempStream.Position := 0;
  3207.           FZipStream.CopyFrom(TempStream,TempStream.Size);
  3208.           Entries.ParseZip(FZipStream);
  3209.         Finally
  3210.           TempStream.Free;
  3211.           // Sicherheitsbestimmung
  3212.           dc_deletefile(tempfilename); // DeleteFile(TempFileName)
  3213.         End;
  3214.      End
  3215.   Else
  3216.      Begin
  3217.         TempMSStream   := TMemoryStream.Create;
  3218.         Try
  3219.           SaveToStream(TempMSStream);
  3220.  
  3221.           // Sicherheitsbestimmung
  3222.           ProtectStream(FZipStream);
  3223.  
  3224.           FZipStream.Position   := 0;
  3225.           FZipStream.Size       := 0;
  3226.           TempMSStream.Position := 0;
  3227.           FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
  3228.           Entries.ParseZip(FZipStream);
  3229.         Finally
  3230.           TempMSStream.Free;
  3231.         End;
  3232.      End;
  3233.   FIsDirty := True;  
  3234. End;
  3235.  
  3236. Procedure TKAZip.CreateZip(Stream:TStream);
  3237. Var
  3238.   ECD : TEndOfCentralDir;
  3239. Begin
  3240.   ECD.EndOfCentralDirSignature        := $06054b50;
  3241.   ECD.NumberOfThisDisk                := 0;
  3242.   ECD.NumberOfTheDiskWithTheStart     := 0;
  3243.   ECD.TotalNumberOfEntriesOnThisDisk  := 0;
  3244.   ECD.TotalNumberOfEntries            := 0;
  3245.   ECD.SizeOfTheCentralDirectory       := 0;
  3246.   ECD.OffsetOfStartOfCentralDirectory := 0;
  3247.   ECD.ZipfileCommentLength            := 0;
  3248.   Stream.Write(ECD,SizeOf(ECD));
  3249. End;
  3250.  
  3251.  
  3252. Procedure TKAZip.CreateZip(FileName:String);
  3253. var
  3254.   FS : TFileStream;
  3255. Begin
  3256.   FS := TFileStream.Create(FileName,fmOpenReadWrite or FmCreate);
  3257.   Try
  3258.     CreateZip(FS);
  3259.   Finally
  3260.     FS.Free;
  3261.   End;
  3262. End;
  3263.  
  3264. procedure TKAZip.SetZipSaveMethod(const Value: TZipSaveMethod);
  3265. begin
  3266.   FZipSaveMethod := Value;
  3267. end;
  3268.  
  3269. procedure TKAZip.SetActive(const Value: Boolean);
  3270. begin
  3271.   if FFileName='' Then Exit;
  3272.   if Value Then Open(FFileName) Else Close;
  3273. end;
  3274.  
  3275. procedure TKAZip.SetZipCompressionType(const Value: TZipCompressionType);
  3276. begin
  3277.   FZipCompressionType := Value;
  3278.   if FZipCompressionType = ctUnknown Then FZipCompressionType := ctNormal;
  3279. end;
  3280.  
  3281. function TKAZip.GetFileNames: TStrings;
  3282. Var
  3283.   X : Integer;
  3284. begin
  3285.   if FIsDirty Then
  3286.      Begin
  3287.        FFileNames.Clear;
  3288.        For X := 0 To Entries.Count-1 do
  3289.            Begin
  3290.              FFileNames.Add(GetFilePath(Entries.Items[X].FileName)+GetFileName(Entries.Items[X].FileName));
  3291.            End;
  3292.        FIsDirty := False;
  3293.      End;
  3294.   Result := FFileNames;
  3295. end;
  3296.  
  3297. procedure TKAZip.SetFileNames(const Value: TStrings);
  3298. begin
  3299.   //*************************************************** READ ONLY
  3300. end;
  3301.  
  3302.  
  3303. procedure TKAZip.SetUseTempFiles(const Value: Boolean);
  3304. begin
  3305.   FUseTempFiles := Value;
  3306. end;
  3307.  
  3308. procedure TKAZip.Rename(Item: TKAZipEntriesEntry; NewFileName: String);
  3309. begin
  3310.   Entries.Rename(Item,NewFileName);
  3311. end;
  3312.  
  3313. procedure TKAZip.Rename(ItemIndex: Integer; NewFileName: String);
  3314. begin
  3315.   Entries.Rename(ItemIndex,NewFileName);
  3316. end;
  3317.  
  3318. procedure TKAZip.Rename(FileName, NewFileName: String);
  3319. begin
  3320.   Entries.Rename(FileName, NewFileName);
  3321. end;
  3322.  
  3323. procedure TKAZip.RenameMultiple(Names, NewNames: TStringList);
  3324. begin
  3325.   Entries.RenameMultiple(Names, NewNames);
  3326. end;
  3327.  
  3328.  
  3329. procedure TKAZip.SetStoreFolders(const Value: Boolean);
  3330. begin
  3331.   FStoreFolders := Value;
  3332. end;
  3333.  
  3334. procedure TKAZip.SetOnAddItem(const Value: TOnAddItem);
  3335. begin
  3336.   FOnAddItem := Value;
  3337. end;
  3338.  
  3339. procedure TKAZip.SetComponentVersion(const Value: String);
  3340. begin
  3341.   //****************************************************************************
  3342. end;
  3343.  
  3344. procedure TKAZip.SetOnRebuildZip(const Value: TOnRebuildZip);
  3345. begin
  3346.   FOnRebuildZip := Value;
  3347. end;
  3348.  
  3349. procedure TKAZip.SetOnRemoveItems(const Value: TOnRemoveItems);
  3350. begin
  3351.   FOnRemoveItems := Value;
  3352. end;
  3353.  
  3354. procedure TKAZip.SetOverwriteAction(const Value: TOverwriteAction);
  3355. begin
  3356.   FOverwriteAction := Value;
  3357. end;
  3358.  
  3359. procedure TKAZip.SetOnOverwriteFile(const Value: TOnOverwriteFile);
  3360. begin
  3361.   FOnOverwriteFile := Value;
  3362. end;
  3363.  
  3364. procedure TKAZip.CreateFolder(FolderName: String; FolderDate: TDateTime);
  3365. begin
  3366.   Entries.CreateFolder(FolderName,FolderDate);
  3367. end;
  3368.  
  3369. procedure TKAZip.RenameFolder(FolderName : String; NewFolderName : String);
  3370. begin
  3371.   Entries.RenameFolder(FolderName,NewFolderName);
  3372. end;
  3373.  
  3374. procedure TKAZip.SetReadOnly(const Value: Boolean);
  3375. begin
  3376.   FReadOnly := Value;
  3377. end;
  3378.  
  3379. procedure TKAZip.SetApplyAtributes(const Value: Boolean);
  3380. begin
  3381.   FApplyAttributes := Value;
  3382. end;
  3383.  
  3384.  
  3385. end.
  3386.  
  3387.