Subversion Repositories decoder

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 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
 
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
 
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
 
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
 
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
 
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
 
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
               Try
1376
                 FParent.FZipStream.Size := TempStream.Size;
1377
               Except
1378
                 FParent.FZipStream.Size := OSL;
1379
                 Raise;
1380
               End;
1381
               FParent.FZipStream.Position := 0;
1382
 
1383
               // Sicherheitsbestimmung
1384
               ProtectStream(FParent.FZipStream);
1385
 
1386
               FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
1387
               //*********************************************************************
1388
               FParent.FZipHeader.ParseZip(FParent.FZipStream);
1389
               //*********************************************************************
1390
             Finally
1391
               TempStream.Free;
1392
               // Sicherheitsbestimmung
1393
               dc_deletefile(tempfilename); // DeleteFile(TempFileName)
1394
             End;
1395
          End
1396
       Else
1397
          Begin
1398
            NewSize := 0;
1399
            For X := 0 To Count-1 do
1400
                Begin
1401
                  NewSize := NewSize+Items[X].LocalEntrySize+Items[X].CentralEntrySize;
1402
                  if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,X,Count-1);
1403
                End;
1404
            NewSize := NewSize+SizeOf(FParent.FEndOfCentralDir)+FParent.FEndOfCentralDir.ZipfileCommentLength;
1405
            TempMSStream := TMemoryStream.Create;
1406
            Try
1407
               TempMSStream.SetSize(NewSize);
1408
               TempMSStream.Position := 0;
1409
               FParent.SaveToStream(TempMSStream);
1410
               TempMSStream.Position := 0;
1411
               OSL                   := FParent.FZipStream.Size;
1412
               Try
1413
                 FParent.FZipStream.Size := TempMSStream.Size;
1414
               Except
1415
                 FParent.FZipStream.Size := OSL;
1416
                 Raise;
1417
               End;
1418
               FParent.FZipStream.Position := 0;
1419
 
1420
               // Sicherheitsbestimmung
1421
               ProtectStream(FParent.FZipStream);
1422
 
1423
               FParent.FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
1424
               //*********************************************************************
1425
               FParent.FZipHeader.ParseZip(FParent.FZipStream);
1426
               //*********************************************************************
1427
             Finally
1428
               TempMSStream.Free;
1429
             End;
1430
          End;
1431
    End;
1432
 FParent.FIsDirty := True;
1433
 if NOT FParent.FBatchMode Then
1434
    Begin
1435
       FParent.DoChange(FParent,3);
1436
    End;
1437
end;
1438
 
1439
procedure TKAZipEntries.Remove(ItemIndex: Integer);
1440
Begin
1441
  Remove(ItemIndex,True);
1442
End;
1443
 
1444
procedure TKAZipEntries.Remove(Item: TKAZipEntriesEntry);
1445
Var
1446
 X : Integer;
1447
begin
1448
 For X := 0 To Count-1 do
1449
     Begin
1450
       if Self.Items[X]=Item Then
1451
          Begin
1452
            Remove(X);
1453
            Exit;
1454
          End;
1455
     End;
1456
end;
1457
 
1458
procedure TKAZipEntries.Remove(FileName: String);
1459
Var
1460
  I : Integer;
1461
begin
1462
  I := IndexOf(FileName);
1463
  if I <> -1 Then Remove(I);
1464
end;
1465
 
1466
procedure TKAZipEntries.RemoveBatch(Files:TList);
1467
Var
1468
  X             : Integer;
1469
  OSL           : Integer;
1470
  NewSize       : Cardinal;
1471
  TempStream    : TFileStream;
1472
  TempMSStream  : TMemoryStream;
1473
  TempFileName  : String;
1474
Begin
1475
  For X := Files.Count-1 DownTo 0 do
1476
      Begin
1477
        Delete(Integer(Files.Items[X]));
1478
        if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,Files.Count-X,Files.Count);
1479
      End;
1480
  NewSize := 0;
1481
  if FParent.FUseTempFiles Then
1482
      Begin
1483
         TempFileName := FParent.GetDelphiTempFileName;
1484
         TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
1485
         Try
1486
           FParent.SaveToStream(TempStream);
1487
           TempStream.Position := 0;
1488
           OSL                 := FParent.FZipStream.Size;
1489
           Try
1490
             FParent.FZipStream.Size := TempStream.Size;
1491
           Except
1492
             FParent.FZipStream.Size := OSL;
1493
             Raise;
1494
           End;
1495
           FParent.FZipStream.Position := 0;
1496
 
1497
           // Sicherheitsbestimmung
1498
           ProtectStream(FParent.FZipStream);
1499
 
1500
           FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
1501
           //*********************************************************************
1502
           FParent.FZipHeader.ParseZip(FParent.FZipStream);
1503
           //*********************************************************************
1504
         Finally
1505
           TempStream.Free;
1506
           // Sicherheitsbestimmung
1507
           dc_deletefile(tempfilename); // DeleteFile(TempFileName)
1508
         End;
1509
      End
1510
   Else
1511
      Begin
1512
        For X := 0 To Count-1 do
1513
            Begin
1514
              NewSize := NewSize+Items[X].LocalEntrySize+Items[X].CentralEntrySize;
1515
              if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,X,Count-1);
1516
            End;
1517
        NewSize := NewSize+SizeOf(FParent.FEndOfCentralDir)+FParent.FEndOfCentralDir.ZipfileCommentLength;
1518
        TempMSStream := TMemoryStream.Create;
1519
        Try
1520
           TempMSStream.SetSize(NewSize);
1521
           TempMSStream.Position := 0;
1522
           FParent.SaveToStream(TempMSStream);
1523
           TempMSStream.Position := 0;
1524
           OSL                   := FParent.FZipStream.Size;
1525
           Try
1526
             FParent.FZipStream.Size := TempMSStream.Size;
1527
           Except
1528
             FParent.FZipStream.Size := OSL;
1529
             Raise;
1530
           End;
1531
           FParent.FZipStream.Position := 0;
1532
 
1533
           // Sicherheitsbestimmung
1534
           ProtectStream(FParent.FZipStream);
1535
 
1536
           FParent.FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
1537
           //*********************************************************************
1538
           FParent.FZipHeader.ParseZip(FParent.FZipStream);
1539
           //*********************************************************************
1540
         Finally
1541
           TempMSStream.Free;
1542
         End;
1543
      End;
1544
End;
1545
 
1546
Function TKAZipEntries.IndexOf(Const FileName:String):Integer;
1547
Var
1548
  X   : Integer;
1549
  FN  : String;
1550
Begin
1551
  Result := -1;
1552
  FN     := ToZipName(FileName);
1553
  For X := 0 To Count-1 do
1554
      Begin
1555
        if AnsiCompareText(FN,ToZipName(Items[X].FCentralDirectoryFile.FileName))=0 Then
1556
           Begin
1557
             Result := X;
1558
             Exit;
1559
           End;
1560
      End;
1561
End;
1562
 
1563
 
1564
Function TKAZipEntries.AddStreamFast( ItemName  : String;
1565
                                      FileAttr  : Word;
1566
                                      FileDate  : TDateTime;
1567
                                      Stream    : TStream):TKAZipEntriesEntry;
1568
Var
1569
  Compressor   : TCompressionStream;
1570
  CS           : TStringStream;
1571
  CM           : WORD;
1572
  S            : String;
1573
  X            : Integer;
1574
  I            : Integer;
1575
  UL           : Integer;
1576
  CL           : Integer;
1577
  FCRC32       : Cardinal;
1578
  SizeToAppend : Integer;
1579
  ZipComment   : String;
1580
  Level        : TCompressionLevel;
1581
  OBM          : Boolean;
1582
begin
1583
  //*********************************** COMPRESS DATA
1584
  ZipComment              := FParent.Comment.Text;
1585
 
1586
  if NOT FParent.FStoreRelativePath Then
1587
     ItemName             := ExtractFileName(ItemName);
1588
 
1589
  ItemName                := ToZipName(ItemName);
1590
  I   := IndexOf(ItemName);
1591
  if I > -1 Then
1592
     Begin
1593
       OBM := FParent.FBatchMode;
1594
       Try
1595
         if OBM=False Then FParent.FBatchMode := True;
1596
         Remove(I);
1597
       Finally
1598
         FParent.FBatchMode := OBM;
1599
       End;
1600
     End;
1601
 
1602
  CS                      := TStringStream.Create('');
1603
  CS.Position             := 0;
1604
  Try
1605
    UL                    := Stream.Size-Stream.Position;
1606
    SetLength(S,UL);
1607
    CM                    := 0;
1608
    if UL > 0 Then
1609
       Begin
1610
         Stream.Read(S[1],UL);
1611
         CM               := 8;
1612
       End;
1613
    FCRC32                := CalcCRC32(S);
1614
    FParent.FCurrentDFS   := UL;
1615
 
1616
 
1617
    Level                 := clDefault;
1618
    Case FParent.FZipCompressionType of
1619
         ctNormal    : Level := clDefault;
1620
         ctMaximum   : Level := clMax;
1621
         ctFast      : Level := clFastest;
1622
         ctSuperFast : Level := clFastest;
1623
         ctNone      : Level := clNone;
1624
    End;
1625
 
1626
    if CM = 8 Then
1627
       Begin
1628
         Compressor            := TCompressionStream.Create(Level,CS);
1629
         Try
1630
           Compressor.OnProgress := FParent.OnCompress;
1631
           Compressor.Write(S[1],UL);
1632
         Finally
1633
           Compressor.Free;
1634
         End;
1635
         S                     := Copy(CS.DataString, 3, Length(CS.DataString)-6);
1636
       End;
1637
  Finally
1638
    CS.Free;
1639
  End;
1640
  //***********************************
1641
  CL  := Length(S);
1642
  //*********************************** FILL RECORDS
1643
  Result := TKAZipEntriesEntry(Self.Add);
1644
  With Result.FLocalFile do
1645
    Begin
1646
      LocalFileHeaderSignature := $04034B50;
1647
      VersionNeededToExtract   := 20;
1648
      GeneralPurposeBitFlag    := 0;
1649
      CompressionMethod        := CM;
1650
      LastModFileTimeDate      := DateTimeToFileDate(FileDate);
1651
      Crc32                    := FCRC32;
1652
      CompressedSize           := CL;
1653
      UncompressedSize         := UL;
1654
      FilenameLength           := Length(ItemName);
1655
      ExtraFieldLength         := 0;
1656
      FileName                 := ItemName;
1657
      ExtraField               := '';
1658
      CompressedData           := '';
1659
    End;
1660
 
1661
 With Result.FCentralDirectoryFile Do
1662
   Begin
1663
      CentralFileHeaderSignature     := $02014B50;
1664
      VersionMadeBy                  := 20;
1665
      VersionNeededToExtract         := 20;
1666
      GeneralPurposeBitFlag          := 0;
1667
      CompressionMethod              := CM;
1668
      LastModFileTimeDate            := DateTimeToFileDate(FileDate);
1669
      Crc32                          := FCRC32;
1670
      CompressedSize                 := CL;
1671
      UncompressedSize               := UL;
1672
      FilenameLength                 := Length(ItemName);
1673
      ExtraFieldLength               := 0;
1674
      FileCommentLength              := 0;
1675
      DiskNumberStart                := 0;
1676
      InternalFileAttributes         := 0;
1677
      ExternalFileAttributes         := FileAttr;
1678
      RelativeOffsetOfLocalHeader    := FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
1679
      FileName                       := ItemName;
1680
      ExtraField                     := '';
1681
      FileComment                    := '';
1682
   End;
1683
 
1684
 //************************************ EXPAND ZIP STREAM SIZE
1685
 SizeToAppend := 0;
1686
 SizeToAppend := SizeToAppend+SizeOf(Result.FLocalFile)-3*SizeOf(String);
1687
 SizeToAppend := SizeToAppend+Result.FLocalFile.FilenameLength;
1688
 SizeToAppend := SizeToAppend+CL;
1689
 SizeToAppend := SizeToAppend+SizeOf(Result.FCentralDirectoryFile)-3*SizeOf(String);
1690
 SizeToAppend := SizeToAppend+Result.FCentralDirectoryFile.FilenameLength;
1691
 FParent.FZipStream.Size := FParent.FZipStream.Size+SizeToAppend;
1692
 
1693
 //************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
1694
 FParent.FZipStream.Position := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
1695
 FParent.FZipStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
1696
 if Result.FLocalFile.FilenameLength > 0 Then FParent.FZipStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
1697
 if CL > 0 Then FParent.FZipStream.Write(S[1],CL);
1698
 
1699
 //************************************ MARK START OF CENTRAL DIRECTORY
1700
 FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory := FParent.FZipStream.Position;
1701
 
1702
 //************************************ SAVE CENTRAL DIRECTORY
1703
 For X := 0 To Count-1 do
1704
     Begin
1705
       FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile,SizeOf(Self.Items[X].FCentralDirectoryFile)-3*SizeOf(String));
1706
       if Self.Items[X].FCentralDirectoryFile.FilenameLength > 0 Then
1707
          FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileName[1],Self.Items[X].FCentralDirectoryFile.FilenameLength);
1708
       if Self.Items[X].FCentralDirectoryFile.ExtraFieldLength > 0 Then
1709
          FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.ExtraField[1],Self.Items[X].FCentralDirectoryFile.ExtraFieldLength);
1710
       if Self.Items[X].FCentralDirectoryFile.FileCommentLength > 0 Then
1711
          FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileComment[1],Self.Items[X].FCentralDirectoryFile.FileCommentLength);
1712
     End;
1713
 
1714
 //************************************ SAVE END CENTRAL DIRECTORY RECORD
1715
 FParent.FEndOfCentralDirPos := FParent.FZipStream.Position;
1716
 FParent.FEndOfCentralDir.SizeOfTheCentralDirectory := FParent.FEndOfCentralDirPos-FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
1717
 Inc(FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
1718
 Inc(FParent.FEndOfCentralDir.TotalNumberOfEntries);
1719
 FParent.FZipStream.Write(FParent.FEndOfCentralDir, SizeOf(TEndOfCentralDir));
1720
 
1721
 //************************************ SAVE ZIP COMMENT IF ANY
1722
 FParent.FZipCommentPos := FParent.FZipStream.Position;
1723
 if Length(ZipComment) > 0 Then
1724
    Begin
1725
      FParent.FZipStream.Write(ZipComment[1],Length(ZipComment));
1726
    End;
1727
 
1728
  Result.FDate   := FileDate;
1729
 
1730
  if (Result.FCentralDirectoryFile.GeneralPurposeBitFlag And 1) > 0 Then
1731
      Result.FIsEncrypted := True
1732
  Else
1733
      Result.FIsEncrypted := False;
1734
  Result.FIsFolder          := (Result.FCentralDirectoryFile.ExternalFileAttributes and faDirectory) > 0;
1735
  Result.FCompressionType   := ctUnknown;
1736
  if (Result.FCentralDirectoryFile.CompressionMethod=8) or (Result.FCentralDirectoryFile.CompressionMethod=9) Then
1737
     Begin
1738
       Case Result.FCentralDirectoryFile.GeneralPurposeBitFlag AND 6 of
1739
 
1740
            2 : Result.FCompressionType := ctMaximum;
1741
            4 : Result.FCompressionType := ctFast;
1742
            6 : Result.FCompressionType := ctSuperFast
1743
       End;
1744
     End;
1745
  FParent.FIsDirty := True;
1746
  if NOT FParent.FBatchMode Then
1747
    Begin
1748
      FParent.DoChange(FParent,2);
1749
    End;
1750
end;
1751
 
1752
Function TKAZipEntries.AddStreamRebuild( ItemName  : String;
1753
                                         FileAttr  : Word;
1754
                                         FileDate  : TDateTime;
1755
                                         Stream    : TStream):TKAZipEntriesEntry;
1756
Var
1757
  Compressor   : TCompressionStream;
1758
  CS           : TStringStream;
1759
  CM           : Word;
1760
  S            : String;
1761
  UL           : Integer;
1762
  CL           : Integer;
1763
  I            : Integer;
1764
  X            : Integer;
1765
  FCRC32       : Cardinal;
1766
  OSL          : Cardinal;
1767
  NewSize      : Cardinal;
1768
  ZipComment   : String;
1769
  TempStream   : TFileStream;
1770
  TempMSStream : TMemoryStream;
1771
  TempFileName : String;
1772
  Level        : TCompressionLevel;
1773
  OBM          : Boolean;
1774
Begin
1775
  if FParent.FUseTempFiles Then
1776
     Begin
1777
        TempFileName := FParent.GetDelphiTempFileName;
1778
        TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
1779
        Try
1780
            //*********************************** SAVE ALL OLD LOCAL ITEMS
1781
            FParent.RebuildLocalFiles(TempStream);
1782
            //*********************************** COMPRESS DATA
1783
            ZipComment              := FParent.Comment.Text;
1784
            if NOT FParent.FStoreRelativePath Then
1785
               ItemName             := ExtractFileName(ItemName);
1786
            ItemName                := ToZipName(ItemName);
1787
            I := IndexOf(ItemName);
1788
            if I > -1 Then
1789
               Begin
1790
                 OBM := FParent.FBatchMode;
1791
                 Try
1792
                   if OBM=False Then FParent.FBatchMode := True;
1793
                   Remove(I);
1794
                 Finally
1795
                   FParent.FBatchMode := OBM;
1796
                 End;
1797
               End;
1798
 
1799
            CM                      := 0;
1800
            CS                      := TStringStream.Create('');
1801
            CS.Position             := 0;
1802
            Try
1803
              UL                    := Stream.Size-Stream.Position;
1804
              SetLength(S,UL);
1805
              if UL > 0 Then
1806
                 Begin
1807
                   Stream.Read(S[1],UL);
1808
                   CM               := 8;
1809
                 End;
1810
              FCRC32                := CalcCRC32(S);
1811
              FParent.FCurrentDFS   := UL;
1812
 
1813
              Level                 := clDefault;
1814
              Case FParent.FZipCompressionType of
1815
                   ctNormal    : Level := clDefault;
1816
                   ctMaximum   : Level := clMax;
1817
                   ctFast      : Level := clFastest;
1818
                   ctSuperFast : Level := clFastest;
1819
                   ctNone      : Level := clNone;
1820
              End;
1821
 
1822
              if CM=8 Then
1823
                 Begin
1824
                    Compressor            := TCompressionStream.Create(Level,CS);
1825
                    Try
1826
                       Compressor.OnProgress := FParent.OnCompress;
1827
                       Compressor.Write(S[1],UL);
1828
                    Finally
1829
                       Compressor.Free;
1830
                    End;
1831
                    S                     := Copy(CS.DataString, 3, Length(CS.DataString)-6);
1832
                 End;
1833
            Finally
1834
              CS.Free;
1835
            End;
1836
            //************************************************************************
1837
            CL := Length(S);
1838
            //*********************************** FILL RECORDS
1839
            Result := TKAZipEntriesEntry(Self.Add);
1840
            With Result.FLocalFile do
1841
              Begin
1842
                LocalFileHeaderSignature := $04034B50;
1843
                VersionNeededToExtract   := 20;
1844
                GeneralPurposeBitFlag    := 0;
1845
                CompressionMethod        := CM;
1846
                LastModFileTimeDate      := DateTimeToFileDate(FileDate);
1847
                Crc32                    := FCRC32;
1848
                CompressedSize           := CL;
1849
                UncompressedSize         := UL;
1850
                FilenameLength           := Length(ItemName);
1851
                ExtraFieldLength         := 0;
1852
                FileName                 := ItemName;
1853
                ExtraField               := '';
1854
                CompressedData           := '';
1855
              End;
1856
 
1857
            With Result.FCentralDirectoryFile Do
1858
             Begin
1859
                CentralFileHeaderSignature     := $02014B50;
1860
                VersionMadeBy                  := 20;
1861
                VersionNeededToExtract         := 20;
1862
                GeneralPurposeBitFlag          := 0;
1863
                CompressionMethod              := CM;
1864
                LastModFileTimeDate            := DateTimeToFileDate(FileDate);
1865
                Crc32                          := FCRC32;
1866
                CompressedSize                 := CL;
1867
                UncompressedSize               := UL;
1868
                FilenameLength                 := Length(ItemName);
1869
                ExtraFieldLength               := 0;
1870
                FileCommentLength              := 0;
1871
                DiskNumberStart                := 0;
1872
                InternalFileAttributes         := 0;
1873
                ExternalFileAttributes         := FileAttr;
1874
                RelativeOffsetOfLocalHeader    := TempStream.Position;
1875
                FileName                       := ItemName;
1876
                ExtraField                     := '';
1877
                FileComment                    := '';
1878
             End;
1879
 
1880
           //************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
1881
           TempStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
1882
           if Result.FLocalFile.FilenameLength > 0 Then TempStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
1883
           if CL > 0 Then TempStream.Write(S[1],CL);
1884
           //************************************
1885
           FParent.NewLHOffsets[Count-1] := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
1886
           FParent.RebuildCentralDirectory(TempStream);
1887
           FParent.RebuildEndOfCentralDirectory(TempStream);
1888
           //************************************
1889
           TempStream.Position := 0;
1890
           OSL                 := FParent.FZipStream.Size;
1891
           Try
1892
             FParent.FZipStream.Size := TempStream.Size;
1893
           Except
1894
             FParent.FZipStream.Size := OSL;
1895
             Raise;
1896
           End;
1897
           FParent.FZipStream.Position := 0;
1898
 
1899
           // Sicherheitsbestimmung
1900
           ProtectStream(FParent.FZipStream);
1901
 
1902
           FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
1903
       Finally
1904
         TempStream.Free;
1905
         // Sicherheitsbestimmung
1906
         dc_deletefile(tempfilename); // DeleteFile(TempFileName)
1907
       End;
1908
     End
1909
  Else
1910
     Begin
1911
        TempMSStream := TMemoryStream.Create;
1912
        NewSize := 0;
1913
        For X := 0 To Count-1 do
1914
            Begin
1915
              NewSize := NewSize+Items[X].LocalEntrySize+Items[X].CentralEntrySize;
1916
              if Assigned(FParent.FOnRemoveItems) Then FParent.FOnRemoveItems(FParent,X,Count-1);
1917
            End;
1918
        NewSize := NewSize+SizeOf(FParent.FEndOfCentralDir)+FParent.FEndOfCentralDir.ZipfileCommentLength;
1919
        Try
1920
            TempMSStream.SetSize(NewSize);
1921
            TempMSStream.Position := 0;
1922
            //*********************************** SAVE ALL OLD LOCAL ITEMS
1923
            FParent.RebuildLocalFiles(TempMSStream);
1924
            //*********************************** COMPRESS DATA
1925
            ZipComment              := FParent.Comment.Text;
1926
            if NOT FParent.FStoreRelativePath Then
1927
               ItemName             := ExtractFileName(ItemName);
1928
            ItemName                := ToZipName(ItemName);
1929
            I := IndexOf(ItemName);
1930
            if I > -1 Then
1931
               Begin
1932
                 OBM := FParent.FBatchMode;
1933
                 Try
1934
                   if OBM=False Then FParent.FBatchMode := True;
1935
                   Remove(I);
1936
                 Finally
1937
                   FParent.FBatchMode := OBM;
1938
                 End;
1939
               End;
1940
 
1941
            CM                      := 0;
1942
            CS                      := TStringStream.Create('');
1943
            CS.Position             := 0;
1944
            Try
1945
              UL                    := Stream.Size-Stream.Position;
1946
              SetLength(S,UL);
1947
              if UL > 0 Then
1948
                 Begin
1949
                   Stream.Read(S[1],UL);
1950
                   CM               := 8;
1951
                 End;
1952
              FCRC32                := CalcCRC32(S);
1953
              FParent.FCurrentDFS   := UL;
1954
 
1955
              Level                 := clDefault;
1956
              Case FParent.FZipCompressionType of
1957
                   ctNormal    : Level := clDefault;
1958
                   ctMaximum   : Level := clMax;
1959
                   ctFast      : Level := clFastest;
1960
                   ctSuperFast : Level := clFastest;
1961
                   ctNone      : Level := clNone;
1962
              End;
1963
 
1964
              if CM=8 Then
1965
                 Begin
1966
                    Compressor            := TCompressionStream.Create(Level,CS);
1967
                    Try
1968
                       Compressor.OnProgress := FParent.OnCompress;
1969
                       Compressor.Write(S[1],UL);
1970
                    Finally
1971
                       Compressor.Free;
1972
                    End;
1973
                    S                     := Copy(CS.DataString, 3, Length(CS.DataString)-6);
1974
                 End;
1975
            Finally
1976
              CS.Free;
1977
            End;
1978
            //************************************************************************
1979
            CL := Length(S);
1980
            //*********************************** FILL RECORDS
1981
            Result := TKAZipEntriesEntry(Self.Add);
1982
            With Result.FLocalFile do
1983
              Begin
1984
                LocalFileHeaderSignature := $04034B50;
1985
                VersionNeededToExtract   := 20;
1986
                GeneralPurposeBitFlag    := 0;
1987
                CompressionMethod        := CM;
1988
                LastModFileTimeDate      := DateTimeToFileDate(FileDate);
1989
                Crc32                    := FCRC32;
1990
                CompressedSize           := CL;
1991
                UncompressedSize         := UL;
1992
                FilenameLength           := Length(ItemName);
1993
                ExtraFieldLength         := 0;
1994
                FileName                 := ItemName;
1995
                ExtraField               := '';
1996
                CompressedData           := '';
1997
              End;
1998
 
1999
            With Result.FCentralDirectoryFile Do
2000
             Begin
2001
                CentralFileHeaderSignature     := $02014B50;
2002
                VersionMadeBy                  := 20;
2003
                VersionNeededToExtract         := 20;
2004
                GeneralPurposeBitFlag          := 0;
2005
                CompressionMethod              := CM;
2006
                LastModFileTimeDate            := DateTimeToFileDate(FileDate);
2007
                Crc32                          := FCRC32;
2008
                CompressedSize                 := CL;
2009
                UncompressedSize               := UL;
2010
                FilenameLength                 := Length(ItemName);
2011
                ExtraFieldLength               := 0;
2012
                FileCommentLength              := 0;
2013
                DiskNumberStart                := 0;
2014
                InternalFileAttributes         := 0;
2015
                ExternalFileAttributes         := FileAttr;
2016
                RelativeOffsetOfLocalHeader    := TempMSStream.Position;
2017
                FileName                       := ItemName;
2018
                ExtraField                     := '';
2019
                FileComment                    := '';
2020
             End;
2021
 
2022
           //************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
2023
           TempMSStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
2024
           if Result.FLocalFile.FilenameLength > 0 Then TempMSStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
2025
           if CL > 0 Then TempMSStream.Write(S[1],CL);
2026
           //************************************
2027
           FParent.NewLHOffsets[Count-1] := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
2028
           FParent.RebuildCentralDirectory(TempMSStream);
2029
           FParent.RebuildEndOfCentralDirectory(TempMSStream);
2030
           //************************************
2031
           TempMSStream.Position := 0;
2032
           OSL                 := FParent.FZipStream.Size;
2033
           Try
2034
             FParent.FZipStream.Size := TempMSStream.Size;
2035
           Except
2036
             FParent.FZipStream.Size := OSL;
2037
             Raise;
2038
           End;
2039
           FParent.FZipStream.Position := 0;
2040
 
2041
           // Sicherheitsbestimmung
2042
           ProtectStream(FParent.FZipStream);
2043
 
2044
           FParent.FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
2045
       Finally
2046
         TempMSStream.Free;
2047
       End;
2048
     End;
2049
 
2050
  Result.FDate              := FileDateToDateTime(Result.FCentralDirectoryFile.LastModFileTimeDate);
2051
  if (Result.FCentralDirectoryFile.GeneralPurposeBitFlag And 1) > 0 Then
2052
      Result.FIsEncrypted := True
2053
  Else
2054
      Result.FIsEncrypted := False;
2055
  Result.FIsFolder          := (Result.FCentralDirectoryFile.ExternalFileAttributes and faDirectory) > 0;
2056
  Result.FCompressionType   := ctUnknown;
2057
  if (Result.FCentralDirectoryFile.CompressionMethod=8) or (Result.FCentralDirectoryFile.CompressionMethod=9) Then
2058
     Begin
2059
       Case Result.FCentralDirectoryFile.GeneralPurposeBitFlag AND 6 of
2060
 
2061
            2 : Result.FCompressionType := ctMaximum;
2062
            4 : Result.FCompressionType := ctFast;
2063
            6 : Result.FCompressionType := ctSuperFast
2064
       End;
2065
     End;
2066
 FParent.FIsDirty := True;
2067
 if NOT FParent.FBatchMode Then
2068
    Begin
2069
      FParent.DoChange(FParent,2);
2070
    End;
2071
End;
2072
 
2073
function TKAZipEntries.AddFolderChain(ItemName: String; FileAttr: Word;
2074
  FileDate: TDateTime): Boolean;
2075
Var
2076
 FN     : String;
2077
 TN     : String;
2078
 INCN   : String;
2079
 P      : Integer;
2080
 MS     : TMemoryStream;
2081
 NoMore : Boolean;
2082
Begin
2083
  //Marschall: Result := False;
2084
  FN     := ExtractFilePath(ToDosName(ToZipName(ItemName)));
2085
  TN     := FN;
2086
  INCN   := '';
2087
  MS     := TMemoryStream.Create;
2088
  Try
2089
    Repeat
2090
      NoMore := True;
2091
      P      := Pos('\',TN);
2092
      if P > 0 Then
2093
         Begin
2094
            INCN        := INCN+Copy(TN,1,P);
2095
            System.Delete(TN,1,P);
2096
            MS.Position := 0;
2097
            MS.Size     := 0;
2098
            If IndexOf(INCN) = -1 Then
2099
               Begin
2100
                  if FParent.FZipSaveMethod = FastSave Then
2101
                     AddStreamFast(INCN,FileAttr,FileDate,MS)
2102
                  Else
2103
                  if FParent.FZipSaveMethod = RebuildAll Then
2104
                     AddStreamRebuild(INCN,FileAttr,FileDate,MS);
2105
               End;
2106
            NoMore := False;
2107
         End;
2108
    Until NoMore;
2109
    Result := True;
2110
  Finally
2111
    MS.Free;
2112
  End;
2113
End;
2114
 
2115
Function TKAZipEntries.AddFolderChain(ItemName : String):Boolean;
2116
begin
2117
  Result := AddFolderChain(ItemName,faDirectory,Now);
2118
end;
2119
 
2120
function TKAZipEntries.AddStream(FileName : String; FileAttr : Word; FileDate : TDateTime; Stream : TStream):TKAZipEntriesEntry;
2121
Begin
2122
  Result := Nil;
2123
  if (FParent.FStoreFolders) AND (FParent.FStoreRelativePath) Then AddFolderChain(FileName);
2124
  if FParent.FZipSaveMethod = FastSave Then
2125
     Result := AddStreamFast(FileName,FileAttr,FileDate,Stream)
2126
  Else
2127
  if FParent.FZipSaveMethod = RebuildAll Then
2128
     Result := AddStreamRebuild(FileName,FileAttr,FileDate,Stream);
2129
  if Assigned(FParent.FOnAddItem) Then FParent.FOnAddItem(FParent,FileName);
2130
End;
2131
 
2132
Function TKAZipEntries.AddStream(FileName: String; Stream : TStream):TKAZipEntriesEntry;
2133
begin
2134
  Result := AddStream(FileName,faArchive,Now,Stream);
2135
end;
2136
 
2137
Function TKAZipEntries.AddFile(FileName, NewFileName: String):TKAZipEntriesEntry;
2138
Var
2139
 FS  : TFileStream;
2140
 Dir : TSearchRec;
2141
 Res : Integer;
2142
begin
2143
 Result := Nil;
2144
 Res    := FindFirst(FileName,faAnyFile,Dir);
2145
 if Res=0 Then
2146
    Begin
2147
      FS := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
2148
      Try
2149
        FS.Position := 0;
2150
        Result := AddStream(NewFileName,Dir.Attr,FileDateToDateTime(Dir.Time),FS)
2151
      Finally
2152
        FS.Free;
2153
      End;
2154
    End;
2155
 FindClose(Dir);
2156
end;
2157
 
2158
Function TKAZipEntries.AddFile(FileName: String):TKAZipEntriesEntry;
2159
begin
2160
  Result := AddFile(FileName,FileName);
2161
end;
2162
 
2163
function TKAZipEntries.AddFiles(FileNames: TStrings): Boolean;
2164
Var
2165
  X : Integer;
2166
begin
2167
  Result     := False;
2168
  FParent.FBatchMode := True;
2169
  Try
2170
    For X := 0 To FileNames.Count-1 do AddFile(FileNames.Strings[X]);
2171
  Except
2172
    FParent.FBatchMode := False;
2173
    FParent.DoChange(FParent,2);
2174
    Exit;
2175
  End;
2176
  FParent.FBatchMode := False;
2177
  FParent.DoChange(FParent,2);
2178
  Result     := True;
2179
end;
2180
 
2181
Function  TKAZipEntries.AddFolderEx(FolderName:String; RootFolder:String; WildCard : String; WithSubFolders : Boolean):Boolean;
2182
Var
2183
  Res : Integer;
2184
  Dir : TSearchRec;
2185
  FN  : String;
2186
Begin
2187
  Res := FindFirst(FolderName+'\*.*',faAnyFile,Dir);
2188
  While Res=0 Do
2189
     Begin
2190
        if (Dir.Attr and faDirectory) > 0 Then
2191
            Begin
2192
              if (Dir.Name <> '..') And (Dir.Name <> '.') Then
2193
                 Begin
2194
                   FN := FolderName+'\'+Dir.Name;
2195
                   if (FParent.FStoreFolders) AND (FParent.FStoreRelativePath) Then
2196
                      AddFolderChain(RemoveRootName(FN+'\',RootFolder),Dir.Attr,FileDateToDateTime(Dir.Time));
2197
                   if WithSubFolders Then
2198
                      Begin
2199
                        AddFolderEx(FN, RootFolder, WildCard, WithSubFolders);
2200
                      End;
2201
                 End
2202
              Else
2203
                 Begin
2204
                   if (Dir.Name = '.') Then AddFolderChain(RemoveRootName(FolderName+'\',RootFolder),Dir.Attr,FileDateToDateTime(Dir.Time));
2205
                 End;
2206
            End
2207
        Else
2208
            Begin
2209
              FN := FolderName+'\'+Dir.Name;
2210
              if MatchesMask(FN,WildCard) Then
2211
                 Begin
2212
                   AddFile(FN,RemoveRootName(FN,RootFolder));
2213
                 End;
2214
            End;
2215
        Res := FindNext(Dir);
2216
     End;
2217
  FindClose(Dir);
2218
  Result := True;
2219
End;
2220
 
2221
Function  TKAZipEntries.AddFolder(FolderName:String; RootFolder:String; WildCard : String; WithSubFolders : Boolean):Boolean;
2222
Begin
2223
  FParent.FBatchMode := True;
2224
  Try
2225
    Result := AddFolderEx(FolderName,RootFolder,WildCard,WithSubFolders);
2226
  Finally
2227
    FParent.FBatchMode := False;
2228
    FParent.DoChange(FParent,2);
2229
  End;
2230
End;
2231
 
2232
Function TKAZipEntries.AddFilesAndFolders(FileNames:TStrings; RootFolder:String; WithSubFolders : Boolean):Boolean;
2233
Var
2234
  X   : Integer;
2235
  Res : Integer;
2236
  Dir : TSearchRec;
2237
Begin
2238
  FParent.FBatchMode := True;
2239
  Try
2240
    For X := 0 To FileNames.Count-1 do
2241
        Begin
2242
           Res := FindFirst(FileNames.Strings[X],faAnyFile,Dir);
2243
           if Res=0 Then
2244
              Begin
2245
                if (Dir.Attr and faDirectory) > 0 Then
2246
                   Begin
2247
                     if (Dir.Name <> '..') And (Dir.Name <> '.') Then
2248
                        Begin
2249
                          AddFolderEx(FileNames.Strings[X],RootFolder,'*.*',WithSubFolders);
2250
                        End;  
2251
                   End
2252
                Else
2253
                   Begin
2254
                     AddFile(FileNames.Strings[X],RemoveRootName(FileNames.Strings[X],RootFolder));
2255
                   End;
2256
              End;
2257
           FindClose(Dir);
2258
        End;
2259
  Finally
2260
    FParent.FBatchMode := False;
2261
    FParent.DoChange(FParent,2);
2262
  End;
2263
  Result := True;
2264
End;
2265
 
2266
 
2267
procedure TKAZipEntries.RemoveFiles(List: TList);
2268
begin
2269
  if List.Count=1 Then
2270
     Begin
2271
       Remove(Integer(List.Items[0]));
2272
     End
2273
  Else
2274
     Begin
2275
       SortList(List);
2276
       FParent.FBatchMode := True;
2277
       Try
2278
         RemoveBatch(List);
2279
       Finally
2280
         FParent.FBatchMode := False;
2281
         FParent.DoChange(Self,3);
2282
       End;
2283
     End;
2284
end;
2285
 
2286
Procedure TKAZipEntries.RemoveSelected;
2287
Var
2288
 X    : Integer;
2289
 List : TList;
2290
Begin
2291
 FParent.FBatchMode := True;
2292
 List               := TList.Create;
2293
 Try
2294
    For X := 0 to Count-1 do
2295
       Begin
2296
         if Self.Items[X].Selected Then List.Add(Pointer(X));
2297
       End;
2298
    RemoveBatch(List);
2299
 Finally
2300
   List.Free;
2301
   FParent.FBatchMode := False;
2302
   FParent.DoChange(Self,3);
2303
 End;
2304
End;
2305
 
2306
 
2307
procedure TKAZipEntries.ExtractToStream(Item : TKAZipEntriesEntry; Stream: TStream);
2308
Var
2309
  SFS             : TMemoryStream;
2310
  TFS             : TStream;
2311
  BUF             : String;
2312
  NR              : Cardinal;
2313
  Decompressor    : TDecompressionStream;
2314
  {$IFDEF USE_BZIP2}
2315
  DecompressorBZ2 : TBZDecompressionStream;
2316
  {$ENDIF}
2317
begin
2318
  if  (
2319
       (Item.CompressionMethod=8) or
2320
       {$IFDEF USE_BZIP2}
2321
       (Item.CompressionMethod=12) or
2322
       {$ENDIF}
2323
       (Item.CompressionMethod=0)
2324
       )
2325
  And (NOT Item.FIsEncrypted) Then
2326
     Begin
2327
        SFS := TMemoryStream.Create;
2328
        TFS := Stream;
2329
        Try
2330
          if Item.GetCompressedData(SFS) > 0 Then
2331
             Begin
2332
                SFS.Position  := 0;
2333
                FParent.FCurrentDFS   := Item.SizeUncompressed;
2334
                //****************************************************** DEFLATE
2335
                if (Item.CompressionMethod=8) Then
2336
                   Begin
2337
                      Decompressor  := TDecompressionStream.Create(SFS);
2338
                      Decompressor.OnProgress := FParent.OnDecompress;
2339
                      SetLength(BUF,FParent.FCurrentDFS);
2340
                      Try
2341
                        NR := Decompressor.Read(BUF[1],FParent.FCurrentDFS);
2342
                        if NR=FParent.FCurrentDFS Then TFS.Write(BUF[1],FParent.FCurrentDFS);
2343
                      Finally
2344
                        Decompressor.Free;
2345
                      End;
2346
                   End
2347
                //******************************************************* BZIP2
2348
                {$IFDEF USE_BZIP2}
2349
                Else
2350
                If Item.CompressionMethod=12 Then
2351
                   Begin
2352
                      DecompressorBZ2  := TBZDecompressionStream.Create(SFS);
2353
                      DecompressorBZ2.OnProgress := FParent.OnDecompress;
2354
                      SetLength(BUF,FParent.FCurrentDFS);
2355
                      Try
2356
                        NR := DecompressorBZ2.Read(BUF[1],FParent.FCurrentDFS);
2357
                        if NR=FParent.FCurrentDFS Then TFS.Write(BUF[1],FParent.FCurrentDFS);
2358
                      Finally
2359
                        DecompressorBZ2.Free;
2360
                      End;
2361
                   End
2362
                {$ENDIF}
2363
                //****************************************************** STORED
2364
                Else
2365
                If Item.CompressionMethod=0 Then
2366
                   Begin
2367
                     TFS.CopyFrom(SFS,FParent.FCurrentDFS);
2368
                   End;
2369
             End;
2370
        Finally
2371
          SFS.Free;
2372
        End;
2373
     End
2374
  Else
2375
     Begin
2376
       Raise Exception.Create('Cannot process this file: '+Item.FileName+' ');
2377
     End;
2378
end;
2379
 
2380
procedure TKAZipEntries.InternalExtractToFile(Item: TKAZipEntriesEntry;
2381
  FileName: String);
2382
Var
2383
  TFS           : TFileStream;
2384
  Attr          : Integer;
2385
begin
2386
  if Item.IsFolder Then
2387
     Begin
2388
       ForceDirectories(FileName);
2389
     End
2390
  Else
2391
     Begin
2392
        TFS := TFileStream.Create(FileName,fmCreate or fmOpenReadWrite or fmShareDenyNone);
2393
        Try
2394
          ExtractToStream(Item,TFS);
2395
        Finally
2396
          TFS.Free;
2397
        End;
2398
        If FParent.FApplyAttributes Then
2399
           Begin
2400
             Attr := faArchive;
2401
             if Item.FCentralDirectoryFile.ExternalFileAttributes And faHidden   > 0 Then Attr := Attr Or faHidden;
2402
             if Item.FCentralDirectoryFile.ExternalFileAttributes And faSysFile  > 0 Then Attr := Attr Or faSysFile;
2403
             if Item.FCentralDirectoryFile.ExternalFileAttributes And faReadOnly > 0 Then Attr := Attr Or faReadOnly;
2404
             FileSetAttr(FileName,Attr);
2405
           End;
2406
     End;
2407
end;
2408
 
2409
 
2410
procedure TKAZipEntries.ExtractToFile(Item: TKAZipEntriesEntry; FileName: String);
2411
var
2412
  Can : Boolean;
2413
  OA  : TOverwriteAction;
2414
Begin
2415
  OA  := FParent.FOverwriteAction;
2416
  Can := True;
2417
  if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
2418
   Begin
2419
      if FileExists(FileName) Then
2420
         Begin
2421
           FParent.FOnOverwriteFile(FParent,FileName,OA);
2422
         End
2423
      Else
2424
         Begin
2425
           OA := oaOverwrite;
2426
         End;
2427
   End;
2428
   Case OA Of
2429
     oaSkip          : Can := False;
2430
     oaSkipAll       : Can := False;
2431
     oaOverwrite     : Can := True;
2432
     oaOverwriteAll  : Can := True;
2433
   End;
2434
   if Can Then InternalExtractToFile(Item, FileName);
2435
End;
2436
 
2437
procedure TKAZipEntries.ExtractToFile(ItemIndex: Integer; FileName: String);
2438
var
2439
  Can       : Boolean;
2440
  OA        : TOverwriteAction;                                                    
2441
Begin
2442
  OA  := FParent.FOverwriteAction;
2443
  Can := True;
2444
  if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
2445
   Begin
2446
      if FileExists(FileName) Then
2447
         Begin
2448
           FParent.FOnOverwriteFile(FParent,FileName,OA);
2449
         End
2450
      Else
2451
         Begin
2452
           OA := oaOverwrite;
2453
         End;
2454
   End;
2455
   Case OA Of
2456
     oaSkip          : Can := False;
2457
     oaSkipAll       : Can := False;
2458
     oaOverwrite     : Can := True;
2459
     oaOverwriteAll  : Can := True;
2460
   End;
2461
   if Can Then InternalExtractToFile(Items[ItemIndex],FileName);
2462
end;
2463
 
2464
procedure TKAZipEntries.ExtractToFile(FileName, DestinationFileName: String);
2465
Var
2466
  I   : Integer;
2467
  Can : Boolean;
2468
  OA  : TOverwriteAction;
2469
Begin
2470
  OA  := FParent.FOverwriteAction;
2471
  Can := True;
2472
  if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
2473
   Begin
2474
      if FileExists(DestinationFileName) Then
2475
         Begin
2476
           FParent.FOnOverwriteFile(FParent,DestinationFileName,OA);
2477
         End
2478
      Else
2479
         Begin
2480
           OA := oaOverwrite;
2481
         End;
2482
   End;
2483
   Case OA Of
2484
     oaSkip          : Can := False;
2485
     oaSkipAll       : Can := False;
2486
     oaOverwrite     : Can := True;
2487
     oaOverwriteAll  : Can := True;
2488
   End;
2489
   if Can Then
2490
      Begin
2491
        I := IndexOf(FileName);
2492
        InternalExtractToFile(Items[I],DestinationFileName);
2493
      End;
2494
end;
2495
 
2496
procedure TKAZipEntries.ExtractAll(TargetDirectory: String);
2497
Var
2498
  FN        : String;
2499
  DN        : String;
2500
  X         : Integer;
2501
  Can       : Boolean;
2502
  OA        : TOverwriteAction;
2503
  FileName  : String;
2504
begin
2505
  OA    := FParent.FOverwriteAction;
2506
  Can   := True;
2507
  Try
2508
    For X := 0 To Count-1 do
2509
        Begin
2510
          FN := FParent.GetFileName(Items[X].FileName);
2511
          DN := FParent.GetFilePath(Items[X].FileName);
2512
          if DN <> '' Then ForceDirectories(TargetDirectory+'\'+DN);
2513
          FileName := TargetDirectory+'\'+DN+FN;
2514
          if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
2515
             Begin
2516
                if FileExists(FileName) Then
2517
                   Begin
2518
                     FParent.FOnOverwriteFile(FParent,FileName,OA);
2519
                   End;
2520
             End;
2521
          Case OA Of
2522
            oaSkip          : Can := False;
2523
            oaSkipAll       : Can := False;
2524
            oaOverwrite     : Can := True;
2525
            oaOverwriteAll  : Can := True;
2526
          End;
2527
          if Can Then InternalExtractToFile(Items[X],FileName);
2528
        End;
2529
  Finally
2530
  End;
2531
end;
2532
 
2533
procedure TKAZipEntries.ExtractSelected(TargetDirectory: String);
2534
Var
2535
  FN        : String;
2536
  DN        : String;
2537
  X         : Integer;
2538
  OA        : TOverwriteAction;
2539
  Can       : Boolean;
2540
  FileName  : String;
2541
begin
2542
  OA    := FParent.FOverwriteAction;
2543
  Can   := True;
2544
  Try
2545
    For X := 0 To Count-1 do
2546
      Begin
2547
        if Items[X].FSelected Then
2548
           Begin
2549
              FN := FParent.GetFileName(Items[X].FileName);
2550
              DN := FParent.GetFilePath(Items[X].FileName);
2551
              if DN <> '' Then ForceDirectories(TargetDirectory+'\'+DN);
2552
              FileName := TargetDirectory+'\'+DN+FN;
2553
              if ((OA<>oaOverwriteAll) And (OA<>oaSkipAll)) And (Assigned(FParent.FOnOverwriteFile)) Then
2554
                 Begin
2555
                    if FileExists(FileName) Then
2556
                       Begin
2557
                         FParent.FOnOverwriteFile(FParent,FileName,OA);
2558
                       End;
2559
                 End;
2560
              Case OA Of
2561
                oaSkip          : Can := False;
2562
                oaSkipAll       : Can := False;
2563
                oaOverwrite     : Can := True;
2564
                oaOverwriteAll  : Can := True;
2565
              End;
2566
             if Can Then InternalExtractToFile(Items[X],TargetDirectory+'\'+DN+FN);
2567
           End;
2568
      End;
2569
  Finally
2570
  End;
2571
end;
2572
 
2573
 
2574
 
2575
procedure TKAZipEntries.DeSelectAll;
2576
Var
2577
  X : Integer;
2578
begin
2579
  For X := 0 To Count-1 do Items[X].Selected := False;
2580
end;
2581
 
2582
procedure TKAZipEntries.InvertSelection;
2583
Var
2584
  X : Integer;
2585
begin
2586
  For X := 0 To Count-1 do Items[X].Selected := Not Items[X].Selected;
2587
end;
2588
 
2589
procedure TKAZipEntries.SelectAll;
2590
Var
2591
  X : Integer;
2592
begin
2593
  For X := 0 To Count-1 do Items[X].Selected := True;
2594
end;
2595
 
2596
procedure TKAZipEntries.Select(WildCard: String);
2597
Var
2598
  X : Integer;
2599
begin
2600
  For X := 0 To Count-1 do
2601
      Begin
2602
        if MatchesMask(ToDosName(Items[X].FileName),WildCard) Then
2603
           Items[X].Selected := True;
2604
      End;
2605
end;
2606
 
2607
 
2608
procedure TKAZipEntries.Rebuild;
2609
begin
2610
  FParent.Rebuild;
2611
end;
2612
 
2613
procedure TKAZipEntries.Rename(Item: TKAZipEntriesEntry; NewFileName: String);
2614
begin
2615
  Item.FileName := NewFileName;
2616
end;
2617
 
2618
procedure TKAZipEntries.Rename(ItemIndex: Integer; NewFileName: String);
2619
begin
2620
  Rename(Items[ItemIndex],NewFileName);
2621
end;
2622
 
2623
procedure TKAZipEntries.Rename(FileName, NewFileName: String);
2624
Var
2625
  I    : Integer;
2626
begin
2627
  I := IndexOf(FileName);
2628
  Rename(I,NewFileName);
2629
end;
2630
 
2631
 
2632
procedure TKAZipEntries.CreateFolder(FolderName: String; FolderDate: TDateTime);
2633
Var
2634
  FN : String;
2635
begin
2636
  FN       := IncludeTrailingBackslash(FolderName);
2637
  AddFolderChain(FN,faDirectory,FolderDate);
2638
  FParent.FIsDirty := True;
2639
end;
2640
 
2641
procedure TKAZipEntries.RenameFolder(FolderName : String; NewFolderName : String);
2642
Var
2643
  FN  : String;
2644
  NFN : String;
2645
  S   : String;
2646
  X   : Integer;
2647
  L   : Integer;
2648
begin
2649
  FN  := ToZipName(IncludeTrailingBackslash(FolderName));
2650
  NFN := ToZipName(IncludeTrailingBackslash(NewFolderName));
2651
  L   := Length(FN);
2652
  if IndexOf(NFN) = -1 Then
2653
     Begin
2654
       For X := 0 To Count-1 do
2655
           Begin
2656
             S := Items[X].FileName;
2657
             if Pos(FN,S) = 1 Then
2658
                Begin
2659
                  System.Delete(S,1,L);
2660
                  S := NFN+S;
2661
                  Items[X].FileName := S;
2662
                  FParent.FIsDirty := True;
2663
                End;
2664
           End;
2665
       If (FParent.FIsDirty) And (FParent.FBatchMode=False) Then Rebuild;
2666
     End;
2667
end;
2668
 
2669
procedure TKAZipEntries.RenameMultiple(Names : TStringList; NewNames : TStringList);
2670
Var
2671
  X    : Integer;
2672
  BR   : Integer;
2673
  L    : Integer;
2674
Begin
2675
  BR := 0; // Marschall
2676
  If Names.Count <> NewNames.Count Then
2677
     Begin
2678
       Raise Exception.Create('Names and NewNames must have equal count');
2679
     End
2680
  Else
2681
     Begin
2682
       FParent.FBatchMode := True;
2683
       Try
2684
         For X := 0 To Names.Count-1 do
2685
             Begin
2686
               L := Length(Names.Strings[X]);
2687
               if (L>0) And ((Names.Strings[X][L]='\') or (Names.Strings[X][L]='/')) Then
2688
                  Begin
2689
                    RenameFolder(Names.Strings[X],NewNames.Strings[X]);
2690
                    Inc(BR);
2691
                  End
2692
               Else
2693
                  Begin
2694
                    Rename(Names.Strings[X],NewNames.Strings[X]);
2695
                    Inc(BR);
2696
                  End;
2697
             End;
2698
       Finally
2699
         FParent.FBatchMode := False;
2700
       End;
2701
       If BR > 0 Then
2702
          Begin
2703
            Rebuild;
2704
            FParent.DoChange(FParent,6);
2705
          End;
2706
     End;
2707
End;
2708
 
2709
 
2710
{ TKAZip }
2711
constructor TKAZip.Create(AOwner: TComponent);
2712
begin
2713
 Inherited Create(AOwner);
2714
 FZipStream          := Nil;
2715
 FOnDecompressFile   := Nil;
2716
 FOnCompressFile     := Nil;
2717
 FOnZipChange        := Nil;
2718
 FOnZipOpen          := Nil;
2719
 FOnAddItem          := Nil;
2720
 FOnOverwriteFile    := Nil;
2721
 FComponentVersion   := '2.0';
2722
 FBatchMode          := False;
2723
 FFileNames          := TStringList.Create;
2724
 FZipHeader          := TKAZipEntries.Create(Self);
2725
 FZipComment         := TStringList.Create;
2726
 FIsZipFile          := False;
2727
 FFileName           := '';
2728
 FCurrentDFS         := 0;
2729
 FExternalStream     := False;
2730
 FIsDirty            := True;
2731
 FHasBadEntries      := False;
2732
 FReadOnly           := False;
2733
 
2734
 FApplyAttributes     := True;
2735
 FOverwriteAction    := oaSkip;
2736
 FZipSaveMethod      := FastSave;
2737
 FUseTempFiles       := False;
2738
 FStoreRelativePath  := True;
2739
 FStoreFolders       := True;
2740
 FZipCompressionType := ctMaximum;
2741
end;
2742
 
2743
 
2744
destructor TKAZip.Destroy;
2745
begin
2746
  if Assigned(FZipStream) AND (NOT FExternalStream) Then FZipStream.Free;
2747
  FZipHeader.Free;
2748
  FZipComment.Free;
2749
  FFileNames.Free;
2750
  inherited Destroy;
2751
end;
2752
 
2753
procedure TKAZip.DoChange(Sender: TObject; Const ChangeType : Integer);
2754
begin
2755
  if Assigned(FOnZipChange) Then FOnZipChange(Self, ChangeType);
2756
end;
2757
 
2758
 
2759
function TKAZip.GetFileName(S: String): String;
2760
Var
2761
 FN : String;
2762
 P  : Integer;
2763
begin
2764
 FN := S;
2765
 FN := StringReplace(FN,'//','\',[rfReplaceAll]);
2766
 FN := StringReplace(FN,'/','\',[rfReplaceAll]);
2767
 P := Pos(':\',FN);
2768
 if P > 0 Then System.Delete(FN,1,P+1);
2769
 Result := ExtractFileName(StringReplace(FN,'/','\',[rfReplaceAll]));
2770
end;
2771
 
2772
function TKAZip.GetFilePath(S: String): String;
2773
Var
2774
 FN : String;
2775
 P  : Integer;
2776
begin
2777
 FN := S;
2778
 FN := StringReplace(FN,'//','\',[rfReplaceAll]);
2779
 FN := StringReplace(FN,'/','\',[rfReplaceAll]);
2780
 P := Pos(':\',FN);
2781
 if P > 0 Then System.Delete(FN,1,P+1);
2782
 Result := ExtractFilePath(StringReplace(FN,'/','\',[rfReplaceAll]));
2783
end;
2784
 
2785
 
2786
procedure TKAZip.LoadFromFile(FileName: String);
2787
Var
2788
   Res : Integer;
2789
   Dir : TSearchRec;
2790
begin
2791
   Res := FindFirst(FileName,faAnyFile,Dir);
2792
   If Res=0 Then
2793
      Begin
2794
         if Dir.Attr And faReadOnly > 0 Then
2795
            Begin
2796
              FZipStream := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
2797
              FReadOnly  := True;
2798
            End
2799
         Else
2800
            Begin
2801
              FZipStream := TFileStream.Create(FileName,fmOpenReadWrite or fmShareDenyNone);
2802
              FReadOnly  := False;
2803
            End;
2804
         LoadFromStream(FZipStream);
2805
      End
2806
   Else
2807
      Begin
2808
        Raise Exception.Create('File "'+FileName+'" not found!');
2809
      End;
2810
end;
2811
 
2812
procedure TKAZip.LoadFromStream(MS : TStream);
2813
begin
2814
  FZipStream := MS;
2815
  FZipHeader.ParseZip(MS);
2816
  FIsZipFile := FZipHeader.FIsZipFile;
2817
  if Not FIsZipFile Then Close;
2818
  FIsDirty := True;
2819
  DoChange(Self,1);
2820
end;
2821
 
2822
procedure TKAZip.Close;
2823
begin
2824
  Entries.Clear;
2825
  if Assigned(FZipStream) AND (NOT FExternalStream) Then FZipStream.Free;
2826
  FExternalStream := False;
2827
  FZipStream      := Nil;
2828
  FIsZipFile      := False;
2829
  FIsDirty        := True;
2830
  FReadOnly       := False;
2831
  DoChange(Self,0);
2832
end;
2833
 
2834
procedure TKAZip.SetFileName(const Value: String);
2835
begin
2836
  FFileName := Value;
2837
end;
2838
 
2839
procedure TKAZip.Open(FileName: String);
2840
begin
2841
  Close;
2842
  LoadFromFile(FileName);
2843
  FFileName := FileName;
2844
end;
2845
 
2846
procedure TKAZip.Open(MS: TStream);
2847
begin
2848
 Try
2849
   Close;
2850
   LoadFromStream(MS);
2851
 Finally
2852
   FExternalStream   := True;
2853
 End;
2854
end;
2855
 
2856
procedure TKAZip.SetIsZipFile(const Value: Boolean);
2857
begin
2858
  //****************************************************************************
2859
end;
2860
 
2861
function TKAZip.GetDelphiTempFileName: String;
2862
Var
2863
 TmpDir : Array[0..1000] of Char;
2864
 TmpFN  : Array[0..1000] of Char;
2865
Begin
2866
 Result := GetCurrentDir;
2867
 if GetTempPath(1000,TmpDir) <> 0 Then
2868
    Begin
2869
     if GetTempFileName(TmpDir,'',0,TmpFN) <> 0 Then Result := StrPas(TmpFN);
2870
    End;
2871
End;
2872
 
2873
procedure TKAZip.OnDecompress(Sender: TObject);
2874
Var
2875
  DS : TStream;
2876
begin
2877
  DS := TStream(Sender);
2878
  if Assigned(FOnDecompressFile) Then FOnDecompressFile(Self,DS.Position,FCurrentDFS);
2879
end;
2880
 
2881
procedure TKAZip.OnCompress(Sender: TObject);
2882
Var
2883
  CS : TStream;
2884
begin
2885
  CS := TStream(Sender);
2886
  if Assigned(FOnCompressFile) Then FOnCompressFile(Self,CS.Position,FCurrentDFS);
2887
end;
2888
 
2889
procedure TKAZip.ExtractToFile(Item : TKAZipEntriesEntry; FileName: String);
2890
begin
2891
  Entries.ExtractToFile(Item,FileName);
2892
end;
2893
 
2894
procedure TKAZip.ExtractToFile(ItemIndex: Integer; FileName: String);
2895
begin
2896
  Entries.ExtractToFile(ItemIndex,FileName);
2897
end;
2898
 
2899
procedure TKAZip.ExtractToFile(FileName, DestinationFileName: String);
2900
begin
2901
  Entries.ExtractToFile(FileName,DestinationFileName);
2902
end;
2903
 
2904
procedure TKAZip.ExtractToStream(Item : TKAZipEntriesEntry; Stream: TStream);
2905
begin
2906
  Entries.ExtractToStream(Item,Stream);
2907
end;
2908
 
2909
procedure TKAZip.ExtractAll(TargetDirectory: String);
2910
begin
2911
  Entries.ExtractAll(TargetDirectory);
2912
end;
2913
 
2914
procedure TKAZip.ExtractSelected(TargetDirectory: String);
2915
Begin
2916
  Entries.ExtractSelected(TargetDirectory);
2917
End;
2918
 
2919
function TKAZip.AddFile(FileName, NewFileName: String): TKAZipEntriesEntry;
2920
begin
2921
  Result := Entries.AddFile(FileName, NewFileName);
2922
end;
2923
 
2924
function TKAZip.AddFile(FileName: String): TKAZipEntriesEntry;
2925
begin
2926
  Result := Entries.AddFile(FileName);
2927
end;
2928
 
2929
function TKAZip.AddFiles(FileNames: TStrings): Boolean;
2930
begin
2931
  Result := Entries.AddFiles(FileNames);
2932
end;
2933
 
2934
function TKAZip.AddFolder(FolderName, RootFolder, WildCard: String;
2935
  WithSubFolders: Boolean): Boolean;
2936
begin
2937
  Result := Entries.AddFolder(FolderName,RootFolder,WildCard,WithSubFolders);
2938
end;
2939
 
2940
function TKAZip.AddFilesAndFolders(FileNames: TStrings; RootFolder: String;
2941
  WithSubFolders: Boolean): Boolean;
2942
begin
2943
  Result := Entries.AddFilesAndFolders(FileNames,RootFolder,WithSubFolders);
2944
end;
2945
 
2946
function TKAZip.AddStream(FileName: String; FileAttr: Word;  FileDate: TDateTime; Stream: TStream): TKAZipEntriesEntry;
2947
begin
2948
  Result := Entries.AddStream(FileName,FileAttr,FileDate,Stream);
2949
end;
2950
 
2951
function TKAZip.AddStream(FileName: String;  Stream: TStream): TKAZipEntriesEntry;
2952
begin
2953
  Result := Entries.AddStream(FileName,Stream);
2954
end;
2955
 
2956
 
2957
procedure TKAZip.Remove(Item: TKAZipEntriesEntry);
2958
begin
2959
  Entries.Remove(Item);
2960
end;
2961
 
2962
procedure TKAZip.Remove(ItemIndex: Integer);
2963
begin
2964
  Entries.Remove(ItemIndex);
2965
end;
2966
 
2967
procedure TKAZip.Remove(FileName: String);
2968
begin
2969
  Entries.Remove(FileName);
2970
end;
2971
 
2972
procedure TKAZip.RemoveFiles(List: TList);
2973
begin
2974
  Entries.RemoveFiles(List);
2975
end;
2976
 
2977
procedure TKAZip.RemoveSelected;
2978
begin
2979
  Entries.RemoveSelected;;
2980
end;
2981
 
2982
function TKAZip.GetComment: TStrings;
2983
Var
2984
 S : String;
2985
begin
2986
  Result := FZipComment;
2987
  FZipComment.Clear;
2988
  if FIsZipFile Then
2989
     Begin
2990
       if FEndOfCentralDir.ZipfileCommentLength > 0 Then
2991
          Begin
2992
            FZipStream.Position := FZipCommentPos;
2993
            SetLength(S,FEndOfCentralDir.ZipfileCommentLength);
2994
            FZipStream.Read(S[1],FEndOfCentralDir.ZipfileCommentLength);
2995
            FZipComment.Text    := S;
2996
          End;
2997
     End;
2998
end;
2999
 
3000
procedure TKAZip.SetComment(const Value: TStrings);
3001
Var
3002
  Comment : String;
3003
  L       : Integer;
3004
begin
3005
  //****************************************************************************
3006
  if FZipComment.Text=Value.Text Then Exit;
3007
  FZipComment.Clear;
3008
  if FIsZipFile Then
3009
     Begin
3010
       FZipComment.Assign(Value);
3011
       Comment                               := FZipComment.Text;
3012
       L                                     := Length(Comment);
3013
       FEndOfCentralDir.ZipfileCommentLength := L;
3014
       FZipStream.Position                   := FEndOfCentralDirPos;
3015
       FZipStream.Write(FEndOfCentralDir,SizeOf(TEndOfCentralDir));
3016
       FZipCommentPos                        := FZipStream.Position;
3017
       if L > 0 Then
3018
          Begin
3019
            FZipStream.Write(Comment[1],L)
3020
          End
3021
       Else
3022
          Begin
3023
            FZipStream.Size := FZipStream.Position;
3024
          End;
3025
     End;
3026
end;
3027
 
3028
procedure TKAZip.DeSelectAll;
3029
begin
3030
  Entries.DeSelectAll;
3031
end;
3032
 
3033
procedure TKAZip.Select(WildCard : String);
3034
begin
3035
  Entries.Select(WildCard);
3036
end;
3037
 
3038
procedure TKAZip.InvertSelection;
3039
begin
3040
  Entries.InvertSelection;
3041
end;
3042
 
3043
procedure TKAZip.SelectAll;
3044
begin
3045
  Entries.SelectAll;
3046
end;
3047
 
3048
procedure TKAZip.RebuildLocalFiles(MS: TStream);
3049
Var
3050
  X    : Integer;
3051
  LF   : TLocalFile;
3052
begin
3053
  //************************************************* RESAVE ALL LOCAL BLOCKS
3054
  SetLength(NewLHOffsets,Entries.Count+1);
3055
  For X := 0 To Entries.Count-1 do
3056
      Begin
3057
        NewLHOffsets[X] := MS.Position;
3058
        LF  := Entries.GetLocalEntry(FZipStream,Entries.Items[X].LocalOffset,False);
3059
        MS.Write(LF, SizeOf(LF)-3*SizeOf(String));
3060
        if LF.FilenameLength   > 0 Then MS.Write(LF.FileName[1]  ,LF.FilenameLength);
3061
        if LF.ExtraFieldLength > 0 Then MS.Write(LF.ExtraField[1],LF.ExtraFieldLength);
3062
        if LF.CompressedSize   > 0 Then MS.Write(LF.CompressedData[1],LF.CompressedSize);
3063
        if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
3064
      End;
3065
end;
3066
 
3067
procedure TKAZip.RebuildCentralDirectory(MS: TStream);
3068
Var
3069
  X    : Integer;
3070
  CDF  : TCentralDirectoryFile;
3071
begin
3072
  NewEndOfCentralDir := FEndOfCentralDir;
3073
  NewEndOfCentralDir.TotalNumberOfEntriesOnThisDisk  := Entries.Count;
3074
  NewEndOfCentralDir.TotalNumberOfEntries            := Entries.Count;
3075
  NewEndOfCentralDir.OffsetOfStartOfCentralDirectory := MS.Position;
3076
  For X := 0 To Entries.Count-1 do
3077
      Begin
3078
        CDF := Entries.Items[X].FCentralDirectoryFile;
3079
        CDF.RelativeOffsetOfLocalHeader := NewLHOffsets[X];
3080
        MS.Write(CDF,SizeOf(CDF)-3*SizeOf(String));
3081
        if CDF.FilenameLength > 0 Then
3082
           MS.Write(CDF.FileName[1],CDF.FilenameLength);
3083
        if CDF.ExtraFieldLength > 0 Then
3084
           MS.Write(CDF.ExtraField[1],CDF.ExtraFieldLength);
3085
        if CDF.FileCommentLength > 0 Then
3086
           MS.Write(CDF.FileComment[1],CDF.FileCommentLength);
3087
        if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
3088
      End;
3089
  NewEndOfCentralDir.SizeOfTheCentralDirectory := MS.Position-NewEndOfCentralDir.OffsetOfStartOfCentralDirectory;
3090
end;
3091
 
3092
procedure TKAZip.RebuildEndOfCentralDirectory(MS: TStream);
3093
Var
3094
  ZipComment : String;
3095
begin
3096
  ZipComment   := Comment.Text;
3097
  FRebuildECDP := MS.Position;
3098
  MS.Write(NewEndOfCentralDir,SizeOf(NewEndOfCentralDir));
3099
  FRebuildCP   := MS.Position;
3100
  if NewEndOfCentralDir.ZipfileCommentLength > 0 Then
3101
     Begin
3102
       MS.Write(ZipComment[1],NewEndOfCentralDir.ZipfileCommentLength);
3103
     End;
3104
  if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,100,100);
3105
end;
3106
 
3107
Procedure TKAZip.FixZip(MS : TStream);
3108
Var
3109
  X          : Integer;
3110
  Y          : Integer;
3111
  NewCount   : Integer;
3112
  LF         : TLocalFile;
3113
  CDF        : TCentralDirectoryFile;
3114
  ZipComment : String;
3115
Begin
3116
  ZipComment   := Comment.Text;
3117
  Y            := 0;
3118
  SetLength(NewLHOffsets,Entries.Count+1);
3119
  For X := 0 To Entries.Count-1 do
3120
      Begin
3121
        LF  := Entries.GetLocalEntry(FZipStream,Entries.Items[X].LocalOffset,False);
3122
        if (LF.LocalFileHeaderSignature=$04034b50) And (Entries.Items[X].Test) Then
3123
           Begin
3124
             NewLHOffsets[Y] := MS.Position;
3125
             MS.Write(LF, SizeOf(LF)-3*SizeOf(String));
3126
             if LF.FilenameLength   > 0 Then MS.Write(LF.FileName[1]  ,LF.FilenameLength);
3127
             if LF.ExtraFieldLength > 0 Then MS.Write(LF.ExtraField[1],LF.ExtraFieldLength);
3128
             if LF.CompressedSize   > 0 Then MS.Write(LF.CompressedData[1],LF.CompressedSize);
3129
             if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
3130
             Inc(Y);
3131
           End
3132
        Else
3133
           Begin
3134
             Entries.Items[X].FCentralDirectoryFile.CentralFileHeaderSignature := 0;
3135
             if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
3136
           End;
3137
      End;
3138
 
3139
  NewCount := Y;
3140
  Y        := 0;
3141
  NewEndOfCentralDir := FEndOfCentralDir;
3142
  NewEndOfCentralDir.TotalNumberOfEntriesOnThisDisk  := NewCount;
3143
  NewEndOfCentralDir.TotalNumberOfEntries            := NewCount;
3144
  NewEndOfCentralDir.OffsetOfStartOfCentralDirectory := MS.Position;
3145
  For X := 0 To Entries.Count-1 do
3146
      Begin
3147
        CDF := Entries.Items[X].FCentralDirectoryFile;
3148
        if CDF.CentralFileHeaderSignature=$02014b50 Then
3149
           Begin
3150
             CDF.RelativeOffsetOfLocalHeader := NewLHOffsets[Y];
3151
             MS.Write(CDF,SizeOf(CDF)-3*SizeOf(String));
3152
             if CDF.FilenameLength > 0 Then
3153
                MS.Write(CDF.FileName[1],CDF.FilenameLength);
3154
             if CDF.ExtraFieldLength > 0 Then
3155
                MS.Write(CDF.ExtraField[1],CDF.ExtraFieldLength);
3156
             if CDF.FileCommentLength > 0 Then
3157
                MS.Write(CDF.FileComment[1],CDF.FileCommentLength);
3158
             if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,X,Entries.Count-1);
3159
             Inc(Y);
3160
           End;
3161
      End;
3162
  NewEndOfCentralDir.SizeOfTheCentralDirectory := MS.Position-NewEndOfCentralDir.OffsetOfStartOfCentralDirectory;
3163
 
3164
  FRebuildECDP := MS.Position;
3165
  MS.Write(NewEndOfCentralDir,SizeOf(NewEndOfCentralDir));
3166
  FRebuildCP   := MS.Position;
3167
  if NewEndOfCentralDir.ZipfileCommentLength > 0 Then
3168
     Begin
3169
       MS.Write(ZipComment[1],NewEndOfCentralDir.ZipfileCommentLength);
3170
     End;
3171
  if Assigned(FOnRebuildZip) Then FOnRebuildZip(Self,100,100);
3172
End;
3173
 
3174
 
3175
Procedure TKAZip.SaveToStream(Stream:TStream);
3176
Begin
3177
  RebuildLocalFiles(Stream);
3178
  RebuildCentralDirectory(Stream);
3179
  RebuildEndOfCentralDirectory(Stream);
3180
End;
3181
 
3182
Procedure TKAZip.Rebuild;
3183
var
3184
  TempStream          : TFileStream;
3185
  TempMSStream        : TMemoryStream;
3186
  TempFileName        : String;
3187
Begin
3188
  if FUseTempFiles Then
3189
     Begin
3190
        TempFileName := GetDelphiTempFileName;
3191
        TempStream   := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
3192
        Try
3193
          SaveToStream(TempStream);
3194
          FZipStream.Position := 0;
3195
          FZipStream.Size     := 0;
3196
          TempStream.Position := 0;
3197
 
3198
          // Sicherheitsbestimmung
3199
          ProtectStream(FZipStream);
3200
 
3201
          FZipStream.CopyFrom(TempStream,TempStream.Size);
3202
          Entries.ParseZip(FZipStream);
3203
        Finally
3204
          TempStream.Free;
3205
          // Sicherheitsbestimmung
3206
          dc_deletefile(tempfilename); // DeleteFile(TempFileName)
3207
        End;
3208
     End
3209
  Else
3210
     Begin
3211
        TempMSStream   := TMemoryStream.Create;
3212
        Try
3213
          SaveToStream(TempMSStream);
3214
          FZipStream.Position   := 0;
3215
          FZipStream.Size       := 0;
3216
          TempMSStream.Position := 0;
3217
 
3218
          // Sicherheitsbestimmung
3219
          ProtectStream(FZipStream);
3220
 
3221
          FZipStream.CopyFrom(TempMSStream,TempMSStream.Size);
3222
          Entries.ParseZip(FZipStream);
3223
        Finally
3224
          TempMSStream.Free;
3225
        End;
3226
     End;
3227
  FIsDirty := True;  
3228
End;
3229
 
3230
Procedure TKAZip.CreateZip(Stream:TStream);
3231
Var
3232
  ECD : TEndOfCentralDir;
3233
Begin
3234
  ECD.EndOfCentralDirSignature        := $06054b50;
3235
  ECD.NumberOfThisDisk                := 0;
3236
  ECD.NumberOfTheDiskWithTheStart     := 0;
3237
  ECD.TotalNumberOfEntriesOnThisDisk  := 0;
3238
  ECD.TotalNumberOfEntries            := 0;
3239
  ECD.SizeOfTheCentralDirectory       := 0;
3240
  ECD.OffsetOfStartOfCentralDirectory := 0;
3241
  ECD.ZipfileCommentLength            := 0;
3242
  Stream.Write(ECD,SizeOf(ECD));
3243
End;
3244
 
3245
 
3246
Procedure TKAZip.CreateZip(FileName:String);
3247
var
3248
  FS : TFileStream;
3249
Begin
3250
  FS := TFileStream.Create(FileName,fmOpenReadWrite or FmCreate);
3251
  Try
3252
    CreateZip(FS);
3253
  Finally
3254
    FS.Free;
3255
  End;
3256
End;
3257
 
3258
procedure TKAZip.SetZipSaveMethod(const Value: TZipSaveMethod);
3259
begin
3260
  FZipSaveMethod := Value;
3261
end;
3262
 
3263
procedure TKAZip.SetActive(const Value: Boolean);
3264
begin
3265
  if FFileName='' Then Exit;
3266
  if Value Then Open(FFileName) Else Close;
3267
end;
3268
 
3269
procedure TKAZip.SetZipCompressionType(const Value: TZipCompressionType);
3270
begin
3271
  FZipCompressionType := Value;
3272
  if FZipCompressionType = ctUnknown Then FZipCompressionType := ctNormal;
3273
end;
3274
 
3275
function TKAZip.GetFileNames: TStrings;
3276
Var
3277
  X : Integer;
3278
begin
3279
  if FIsDirty Then
3280
     Begin
3281
       FFileNames.Clear;
3282
       For X := 0 To Entries.Count-1 do
3283
           Begin
3284
             FFileNames.Add(GetFilePath(Entries.Items[X].FileName)+GetFileName(Entries.Items[X].FileName));
3285
           End;
3286
       FIsDirty := False;
3287
     End;
3288
  Result := FFileNames;
3289
end;
3290
 
3291
procedure TKAZip.SetFileNames(const Value: TStrings);
3292
begin
3293
  //*************************************************** READ ONLY
3294
end;
3295
 
3296
 
3297
procedure TKAZip.SetUseTempFiles(const Value: Boolean);
3298
begin
3299
  FUseTempFiles := Value;
3300
end;
3301
 
3302
procedure TKAZip.Rename(Item: TKAZipEntriesEntry; NewFileName: String);
3303
begin
3304
  Entries.Rename(Item,NewFileName);
3305
end;
3306
 
3307
procedure TKAZip.Rename(ItemIndex: Integer; NewFileName: String);
3308
begin
3309
  Entries.Rename(ItemIndex,NewFileName);
3310
end;
3311
 
3312
procedure TKAZip.Rename(FileName, NewFileName: String);
3313
begin
3314
  Entries.Rename(FileName, NewFileName);
3315
end;
3316
 
3317
procedure TKAZip.RenameMultiple(Names, NewNames: TStringList);
3318
begin
3319
  Entries.RenameMultiple(Names, NewNames);
3320
end;
3321
 
3322
 
3323
procedure TKAZip.SetStoreFolders(const Value: Boolean);
3324
begin
3325
  FStoreFolders := Value;
3326
end;
3327
 
3328
procedure TKAZip.SetOnAddItem(const Value: TOnAddItem);
3329
begin
3330
  FOnAddItem := Value;
3331
end;
3332
 
3333
procedure TKAZip.SetComponentVersion(const Value: String);
3334
begin
3335
  //****************************************************************************
3336
end;
3337
 
3338
procedure TKAZip.SetOnRebuildZip(const Value: TOnRebuildZip);
3339
begin
3340
  FOnRebuildZip := Value;
3341
end;
3342
 
3343
procedure TKAZip.SetOnRemoveItems(const Value: TOnRemoveItems);
3344
begin
3345
  FOnRemoveItems := Value;
3346
end;
3347
 
3348
procedure TKAZip.SetOverwriteAction(const Value: TOverwriteAction);
3349
begin
3350
  FOverwriteAction := Value;
3351
end;
3352
 
3353
procedure TKAZip.SetOnOverwriteFile(const Value: TOnOverwriteFile);
3354
begin
3355
  FOnOverwriteFile := Value;
3356
end;
3357
 
3358
procedure TKAZip.CreateFolder(FolderName: String; FolderDate: TDateTime);
3359
begin
3360
  Entries.CreateFolder(FolderName,FolderDate);
3361
end;
3362
 
3363
procedure TKAZip.RenameFolder(FolderName : String; NewFolderName : String);
3364
begin
3365
  Entries.RenameFolder(FolderName,NewFolderName);
3366
end;
3367
 
3368
procedure TKAZip.SetReadOnly(const Value: Boolean);
3369
begin
3370
  FReadOnly := Value;
3371
end;
3372
 
3373
procedure TKAZip.SetApplyAtributes(const Value: Boolean);
3374
begin
3375
  FApplyAttributes := Value;
3376
end;
3377
 
3378
 
3379
end.
3380