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