Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | daniel-mar | 1 | #include "stdafx.h" |
2 | #pragma hdrstop |
||
3 | #include "ZipFnc.h" |
||
4 | #include "Helpers.h" |
||
5 | #include <stdlib.h> |
||
6 | #include "dz_errs.h" |
||
7 | |||
8 | #undef _DZ_FILE_ |
||
9 | #define _DZ_FILE_ DZ_ZIPUP_CPP |
||
10 | |||
11 | /* ZipUp.c Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup |
||
12 | Gailly, Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko. This |
||
13 | version modified by Chris Vleghert and Eric Engler for BCB/Delphi Zip. |
||
14 | distributed under LGPL license ** see license.txt for details |
||
15 | |||
16 | Copyright (c) 1990-2007 Info-ZIP. All rights reserved. |
||
17 | |||
18 | See the accompanying file LICENSE, version 2007-Mar-4 or later |
||
19 | (the contents of which are also included in zip.h) for terms of use. |
||
20 | If, for some reason, all these files are missing, the Info-ZIP license |
||
21 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html |
||
22 | |||
23 | parts Copyright (C) 1997 Mike White, Eric W. Engler |
||
24 | ************************************************************************ |
||
25 | Copyright (C) 2009, 2010 by Russell J. Peters, Roger Aelbrecht |
||
26 | |||
27 | This file is part of TZipMaster Version 1.9. |
||
28 | |||
29 | TZipMaster is free software: you can redistribute it and/or modify |
||
30 | it under the terms of the GNU Lesser General Public License as published by |
||
31 | the Free Software Foundation, either version 3 of the License, or |
||
32 | (at your option) any later version. |
||
33 | |||
34 | TZipMaster is distributed in the hope that it will be useful, |
||
35 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
36 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
37 | GNU Lesser General Public License for more details. |
||
38 | |||
39 | You should have received a copy of the GNU Lesser General Public License |
||
40 | along with TZipMaster. If not, see <http://www.gnu.org/licenses/>. |
||
41 | |||
42 | contact: problems@delphizip.org (include ZipMaster in the subject). |
||
43 | updates: http://www.delphizip.org |
||
44 | DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip |
||
45 | ************************************************************************/ |
||
46 | |||
47 | #include <share.h> |
||
48 | |||
49 | // Return the percentage compression from n to m using only integer |
||
50 | // operations. n :: Is the original size. m :: Is the new size. |
||
51 | //int percent(ulg n, ulg m) |
||
52 | int percent(__int64 n, __int64 m) |
||
53 | { |
||
54 | while (n > 0xFFFFFFL) |
||
55 | { |
||
56 | // If n >= 16M |
||
57 | n += 0x80; |
||
58 | n >>= 8; // then divide n and m by 256 |
||
59 | m += 0x80; |
||
60 | m >>= 8; |
||
61 | } |
||
62 | |||
63 | return n > m ? (int)(1 + (200 *(n - m) / n)) / 2 : 0; |
||
64 | } |
||
65 | |||
66 | // Note: a zip "entry" includes a local header (which includes the file |
||
67 | // name), an encryption header if encrypting, the compressed data and |
||
68 | // possibly an extended local header. |
||
69 | // Compress the file z->name into the zip entry described by *z and write it |
||
70 | // to the file. Encrypt if requested. Return an error code in the ZEN_ |
||
71 | // class. Also, update tempzn by the number of bytes written. z :: Zip entry |
||
72 | // to compress. |
||
73 | // writes to fhOutz |
||
74 | #define OPENREADFLAGS (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | \ |
||
75 | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | \ |
||
76 | FILE_FLAG_SEQUENTIAL_SCAN) |
||
77 | //FILE_SHARE_READ |} |
||
78 | int ZipFunc::zipup(ZipItem *z) |
||
79 | { |
||
80 | ulg tim; // Time returned by filetime() |
||
81 | ulg attr = 0L; // Attributes returned by filetime() |
||
82 | int k = 0; // Result of zread |
||
83 | int mthd; // Method for this entry |
||
84 | __int64 o, p; // Offsets in zip file |
||
85 | __int64 fsize = -3; // ZFT_SIZE; // Size returned by filetime |
||
86 | int r; // Temporary variable |
||
87 | __int64 csize = 0L; // Size of compressed data |
||
88 | int isdir; // Set for a directory name |
||
89 | int set_type = 0; // Set if file type (ascii/binary) unknown |
||
90 | unsigned char *tempextra; // to hold pointer returned by user |
||
91 | ZInt64 HChk; // position after local header |
||
92 | AutoStream inz(NULL); |
||
93 | |||
94 | fimax = 0; |
||
95 | isdir = z->IsFolder; |
||
96 | |||
97 | if (Verbose < 0) |
||
98 | Notify(ITRACE, _T("zipup: %s"), z->iname); |
||
99 | |||
100 | { |
||
101 | if ((tim = zfiletime(z->FullPath(), &attr, &fsize, NULL)) == 0) |
||
102 | return DZ_ERM_NO_FILE_OPEN; |
||
103 | } |
||
104 | |||
105 | // fsize is set to -1 if the input file is a device, -2 for a volume label |
||
106 | if (fsize == ZFT_LABEL) |
||
107 | { |
||
108 | isdir = 1; |
||
109 | fsize = 0; |
||
110 | } |
||
111 | else if (isdir != ((attr & MSDOS_DIR_ATTR) != 0)) |
||
112 | // don't overwrite a directory with a file and vice-versa |
||
113 | return DZ_ERM_MISS; |
||
114 | |||
115 | z->att = (ush)UNKNOWN; // will be changed later |
||
116 | z->atx = 0; // may be changed by set_extra_field() |
||
117 | |||
118 | fkey = z->Passw; // 1.73 restore global password |
||
119 | fwindow_size = 0L; |
||
120 | // Select method based on the suffix and the global method |
||
121 | mthd = DEFLATE; // default method |
||
122 | flevel = z->options.level; |
||
123 | |||
124 | if (flevel && !z->options.noext && fSpecials) |
||
125 | { |
||
126 | ZFilter *f = fSpecials->Find(z->xname); |
||
127 | if (f) |
||
128 | { |
||
129 | if (f->Level < flevel) |
||
130 | flevel = f->Level; |
||
131 | } |
||
132 | } |
||
133 | |||
134 | if (!flevel || isdir) |
||
135 | mthd = STORE; |
||
136 | |||
137 | // CHANGE 1.73 RAEL changed RPETERS Code added to generate and handle |
||
138 | // action code 14 file extra data Extra data needs to be delivered |
||
139 | // formatted according to PKZIP appnote.txt |
||
140 | CB->Arg1 = z->ext; // size |
||
141 | CB->Data2 = (const char*)z->extra.begin(); // old data |
||
142 | CB->Arg2 = z->options.level; |
||
143 | int uret = CB->UserCB(zacData, z->FullPath()); |
||
144 | if (uret <= CALLBACK_CANCEL) // TODO: should not happen |
||
145 | Fatal(DZ_ERM_ABORT, 0); |
||
146 | |||
147 | // free any old data - probably obsolete |
||
148 | z->cextra.Empty(); |
||
149 | z->extra.Empty(); |
||
150 | if (z->ntfs) |
||
151 | { |
||
152 | delete z->ntfs; |
||
153 | z->ntfs = NULL; |
||
154 | } |
||
155 | |||
156 | if (uret > 0 && uret & 2) |
||
157 | { |
||
158 | unsigned lvl = CB->Arg2; |
||
159 | |||
160 | if (lvl <= 9) |
||
161 | { |
||
162 | z->options.level = lvl; |
||
163 | z->options.noext = 1; |
||
164 | mthd = lvl ? DEFLATE : STORE; |
||
165 | flevel = lvl; |
||
166 | } |
||
167 | } |
||
168 | |||
169 | if (uret > 0 && uret & 1) |
||
170 | { |
||
171 | // user changed extrafield data |
||
172 | tempextra = (unsigned char*)CB->Data; |
||
173 | |||
174 | if (!tempextra) |
||
175 | CB->Arg1 = 0; |
||
176 | |||
177 | // user changed extrafield data |
||
178 | if (CB->Arg1) |
||
179 | { |
||
180 | z->extra.Assign(tempextra, CB->Arg1); |
||
181 | if (fNTFSStamps) |
||
182 | z->extra -= NTFS_STAMP_TAG; // - most likely wrong stamp |
||
183 | z->cextra = z->extra; |
||
184 | } |
||
185 | } |
||
186 | if (!z->options.dosflag && !z->HName.BadDOS()) // mimic WinZip |
||
187 | z->options.dosflag = 2; // if has no extended chars use MSDOS |
||
188 | |||
189 | // For a FAT file system, we cheat and pretend that the file was not made |
||
190 | // on OS2, but under DOS. unzip is confused otherwise. |
||
191 | // Made under MSDOS by PKZIP 2.0, NTFS by PKZIP 2.2 |
||
192 | z->vem = (ush)(z->options.dosflag ? 20 : OS_NTFS + 22); |
||
193 | if (z->Enc >= zeoUTF8) |
||
194 | z->vem = OUR_VEM; |
||
195 | |||
196 | // Need PKUNZIP 2.0 to extract, unless it is stored |
||
197 | z->ver = (ush)((mthd == STORE) ? 10 : 20); |
||
198 | |||
199 | if (isdir) |
||
200 | { |
||
201 | if (IsNTorAbove && fNTFSStamps) |
||
202 | { |
||
203 | // get folder stamps |
||
204 | HANDLE hFolder = CreateFile(z->FullPath(), GENERIC_WRITE, |
||
205 | FILE_SHARE_READ, NULL, OPEN_EXISTING, |
||
206 | FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS, NULL); |
||
207 | if (hFolder == INVALID_HANDLE_VALUE) |
||
208 | { |
||
209 | if (Verbose < 0) |
||
210 | Notify(IWARNING, _T("Could not get times for %s"), |
||
211 | z->FullPath().c_str()); |
||
212 | } |
||
213 | else |
||
214 | { |
||
215 | // get stamps |
||
216 | XNTFSData stamps; |
||
217 | if (GetFileTime(hFolder, &stamps.CTime, &stamps.ATime, |
||
218 | &stamps.MTime)) |
||
219 | { |
||
220 | z->ntfs = new XNTFSData; |
||
221 | memcpy(z->ntfs, &stamps, sizeof(XNTFSData)); |
||
222 | } |
||
223 | CloseHandle(hFolder); |
||
224 | } |
||
225 | } |
||
226 | // directory |
||
227 | mthd = STORE; |
||
228 | fsize = 0; |
||
229 | } |
||
230 | else |
||
231 | { |
||
232 | // Callback: action, error code, filesize, filename |
||
233 | CB->UserItem(z->len, z->XName); |
||
234 | |||
235 | if (Abort_Flag) |
||
236 | Fatal(DZ_ERM_ABORT, 0); |
||
237 | |||
238 | fZipInfile = NULL; |
||
239 | if (Is_Drv(z->XName) < 0) |
||
240 | fZipInfile = new ZStream(this, z->XName); |
||
241 | else |
||
242 | fZipInfile = new ZFile(this, z->FullPath(), OPENREADFLAGS); |
||
243 | |||
244 | inz.Assign(&fZipInfile); // make certain it is destroyed when finished |
||
245 | if (fZipInfile == NULL) |
||
246 | Notify(ITRACE, _T("no input file")); |
||
247 | |||
248 | if (fZipInfile != NULL && !fZipInfile->IsOpen()) |
||
249 | { |
||
250 | int le = GetLastError(); |
||
251 | if (Verbose < 0) |
||
252 | Notify(IWARNING, _T("Could not open %s [%X]"), |
||
253 | fZipInfile->fname.c_str(), le); |
||
254 | // give zacSkipped |
||
255 | int typ = SKIPPED_NO_OPEN; |
||
256 | if (le == ERROR_SHARING_VIOLATION) |
||
257 | typ = SKIPPED_NO_SHARE; |
||
258 | else if (le == ERROR_ACCESS_DENIED) |
||
259 | typ = SKIPPED_NO_ACCESS; |
||
260 | |||
261 | if (Skipping(z->FullPath(), DZ_ERR_NO_FILE_OPEN, typ)) |
||
262 | Fatal(DZ_ERM_SKIPPING, 2); |
||
263 | |||
264 | return DZ_ERR_NO_FILE_OPEN; |
||
265 | } |
||
266 | if (IsNTorAbove && fNTFSStamps) |
||
267 | { |
||
268 | // get stamps |
||
269 | XNTFSData stamps; |
||
270 | if (fZipInfile->GetTime(&stamps.CTime, &stamps.ATime, |
||
271 | &stamps.MTime)) |
||
272 | { |
||
273 | z->ntfs = new XNTFSData; |
||
274 | memcpy(z->ntfs, &stamps, sizeof(XNTFSData)); |
||
275 | } |
||
276 | else if (Verbose < 0) |
||
277 | Notify(IWARNING, _T("Could not get times for %s"), |
||
278 | fZipInfile->fname.c_str()); |
||
279 | } |
||
280 | } |
||
281 | |||
282 | z->tim = tim; |
||
283 | fFileError = 0; |
||
284 | if (fsize == 0) |
||
285 | mthd = STORE; |
||
286 | |||
287 | // Do not create STORED files with extended local headers if the input |
||
288 | // size is not known, because such files could not be extracted. So if the |
||
289 | // zip file is not seekable and the input file is not on disk, obey the -0 |
||
290 | // option by forcing deflation with stored block. Note however that using |
||
291 | // "zip -0" as filter is not very useful... ??? to be done. |
||
292 | // Fill in header information and write local header to zip file. This |
||
293 | // header will later be re-written since compressed length and crc are not |
||
294 | // yet known. |
||
295 | // (Assume ext, cext, com, and zname already filled in.) |
||
296 | // (RCV Added (ush)(...) |
||
297 | z->flg = FLAG_EXTEND_BIT; // to be updated later |
||
298 | |||
299 | // (RCV Added below (ush) |
||
300 | z->how = (ush)mthd; // may be changed later |
||
301 | |||
302 | if (z->att == (ush)UNKNOWN) |
||
303 | { |
||
304 | z->att = BINARY; // set sensible value in header |
||
305 | set_type = 1; |
||
306 | } |
||
307 | |||
308 | // Attributes from filetime(), flag bits from set_extra_field(): |
||
309 | z->atx = z->options.dosflag ? attr & 0xFF : attr | (z->atx & 0x0000FFFF); |
||
310 | z->crc = 0; // to be updated later |
||
311 | #ifdef _ZDEBUG |
||
312 | Notify(ITRACE, _T("zipup: %s dosflag %i"), z->iname, z->options.dosflag); |
||
313 | #endif |
||
314 | |||
315 | // Assume first that we will need an extended local header: |
||
316 | ulg f_crc = 0; |
||
317 | __int64 fsz = 0; |
||
318 | bool haveCRC = false; |
||
319 | |||
320 | if (fkey && !isdir && fsize) |
||
321 | { |
||
322 | if (!fNoPrecalc) |
||
323 | { |
||
324 | // get CRC before we start |
||
325 | __int64 pos1 = 0; |
||
326 | |||
327 | if (!fZipInfile->IsFile) |
||
328 | pos1 = fZipInfile->SetPosition(0, FILE_CURRENT); |
||
329 | // get start posn |
||
330 | |||
331 | f_crc = crc32(0L, (uch*)NULL, 0); |
||
332 | unsigned long byts; |
||
333 | |||
334 | while (fZipInfile->Read(fwindow, sizeof(fwindow), &byts)) |
||
335 | { |
||
336 | if (!byts) |
||
337 | break; |
||
338 | |||
339 | fsz += byts; |
||
340 | f_crc = crc32(f_crc, (uch*)fwindow, byts); |
||
341 | } |
||
342 | |||
343 | // Check input size |
||
344 | if (fsz != fsize) |
||
345 | { |
||
346 | // Notify(IWARNING, _T(" file size changed while zipping: %s"), |
||
347 | // z->xname); |
||
348 | // |
||
349 | // if (Verbose < 0) |
||
350 | // Notify(ITRACE, _T(" is=%Lu, expected=%Lu "), fsz, fsize); |
||
351 | // fsize = fsz; |
||
352 | // don't Ask skip - may be stable next time |
||
353 | // { |
||
354 | int skip; |
||
355 | int re; |
||
356 | // may be file error |
||
357 | if (fFileError) |
||
358 | { |
||
359 | if (fFileError == ERROR_LOCK_VIOLATION) |
||
360 | Notify(DZ_ERR_LOCKED | IWARNING, z->xname); |
||
361 | else if (fFileError == ERROR_ACCESS_DENIED) |
||
362 | Notify(DZ_ERR_DENIED | IWARNING, z->xname); |
||
363 | else |
||
364 | Notify(DZ_ERR_NO_FILE_OPEN | IWARNING, |
||
365 | _T(" File read error [%d]: %s"), fFileError, z->xname); |
||
366 | |||
367 | re = DZ_ERM_ERROR_READ; |
||
368 | Notify(re, _T(" File error [%d] while zipping: %s"), fFileError, z->xname); |
||
369 | skip = SKIPPED_READ_ERROR; |
||
370 | } |
||
371 | else |
||
372 | { |
||
373 | re = DZ_ERM_SKIPPED; |
||
374 | Notify(IWARNING, _T(" file size changed while zipping: %s"), |
||
375 | z->xname); |
||
376 | |||
377 | if (Verbose < 0) |
||
378 | Notify(ITRACE, _T(" was=%Lu, expected=%Lu "), fisize, fsize); |
||
379 | skip = SKIPPED_SIZE_CHANGE; |
||
380 | } |
||
381 | if (Skipping(z->XName, 0, skip)) |
||
382 | Fatal(DZ_ERM_SKIPPED, 2); |
||
383 | return re; // skip the file |
||
384 | // fsize = fsz; // ignore and try to zip again |
||
385 | // } |
||
386 | } |
||
387 | else |
||
388 | { |
||
389 | z->crc = f_crc; |
||
390 | haveCRC = true; |
||
391 | } |
||
392 | |||
393 | if (fZipInfile->SetPosition(pos1, FILE_BEGIN) != pos1) |
||
394 | { |
||
395 | if (Verbose) |
||
396 | Notify(IVERBOSE, _T("Could not reposition %s [%s]"), |
||
397 | z->FullPath().c_str(), SysMsg().c_str()); |
||
398 | |||
399 | if (fZipInfile->IsFile) |
||
400 | { |
||
401 | inz.Assign(NULL); |
||
402 | fZipInfile = new ZFile(this, z->FullPath(), OPENREADFLAGS); |
||
403 | inz.Assign(&fZipInfile); |
||
404 | |||
405 | if (fZipInfile == NULL || !fZipInfile->IsOpen()) |
||
406 | return DZError(DZ_ERM_ERROR_READ); |
||
407 | } |
||
408 | else |
||
409 | return DZError(DZ_ERM_ERROR_READ); |
||
410 | } |
||
411 | } |
||
412 | |||
413 | z->flg |= FLAG_ENCRYPT_BIT; |
||
414 | // Since we do not yet know the crc here, we pretend that the crc is the |
||
415 | // modification time: |
||
416 | if (!haveCRC) |
||
417 | z->crc = z->tim << 16; |
||
418 | } |
||
419 | |||
420 | fFileError = 0; |
||
421 | if (fsize == 0) |
||
422 | mthd = STORE; |
||
423 | z->how = (ush)mthd; // may be changed later |
||
424 | z->lflg = z->flg; |
||
425 | z->siz = fsize; // not compressed yet |
||
426 | z->len = fsize; // may be changed later |
||
427 | z->dsk = 0; |
||
428 | z->off = fOutPosn; |
||
429 | Assert(fOutPosn == fZipOutfile->SetPosition(0, 1), |
||
430 | _T("invalid out posn 1")); |
||
431 | |||
432 | // now put it in the file |
||
433 | if ((r = PutLocal(z)) != DZ_ERR_GOOD) |
||
434 | return r; |
||
435 | |||
436 | HChk = fOutPosn; // save position after header |
||
437 | if (HChk == -1) |
||
438 | DZError(DZ_ERM_ERROR_WRITE); |
||
439 | |||
440 | if (fkey) |
||
441 | { |
||
442 | crypthead(fkey, z->crc); |
||
443 | z->siz += RAND_HEAD_LEN; // to be updated later |
||
444 | fOutPosn += RAND_HEAD_LEN; |
||
445 | } |
||
446 | |||
447 | // for error checking, ftell can fail on pipes |
||
448 | o = fOutPosn; |
||
449 | // Write stored or deflated file to zip file |
||
450 | fisize = 0; // L; |
||
451 | fcrc = crc32(0L, (uch*)NULL, 0); |
||
452 | |||
453 | if (fsize == 0) |
||
454 | mthd = STORE; |
||
455 | // Need PKUNZIP 2.0 to extract, unless it is stored |
||
456 | z->ver = (ush)((mthd == STORE) ? 10 : 20); |
||
457 | z->how = (ush)mthd; // may be changed later |
||
458 | |||
459 | if (mthd == DEFLATE) |
||
460 | { |
||
461 | bi_init(); |
||
462 | |||
463 | if (set_type) |
||
464 | z->att = (ush)UNKNOWN; |
||
465 | |||
466 | // will be changed in deflate() |
||
467 | ct_init(&z->att, &mthd); |
||
468 | lm_init(flevel, &z->flg); |
||
469 | |||
470 | // PERFORM THE DEFLATE |
||
471 | csize = deflate(); |
||
472 | |||
473 | if (Abort_Flag) |
||
474 | Fatal(DZ_ERM_ABORT, 0); |
||
475 | } |
||
476 | else if (!isdir) |
||
477 | { |
||
478 | if (Verbose) |
||
479 | Notify(IVERBOSE, _T("Storing %s "), z->FullPath().c_str()); |
||
480 | |||
481 | while ((k = read_buf(fwindow, sizeof(fwindow))) > 0 && k != EOF) |
||
482 | { |
||
483 | if (Abort_Flag) |
||
484 | Fatal(DZ_ERM_ABORT, 0); |
||
485 | |||
486 | if (!zfwrite(fwindow, k)) |
||
487 | return DZ_ERM_TEMP_FAILED; |
||
488 | } |
||
489 | |||
490 | csize = fisize; |
||
491 | } |
||
492 | |||
493 | if (!fZipInfile && k == (-1)) |
||
494 | Notify(IWARNING, _T("could not read input file: %s"), z->xname); |
||
495 | |||
496 | if (fZipInfile != NULL) |
||
497 | fZipInfile->Close(); // Close the input file |
||
498 | |||
499 | fOutPosn += csize; |
||
500 | p = fOutPosn; // save for future fseek() |
||
501 | |||
502 | if (haveCRC && f_crc != fcrc) |
||
503 | { |
||
504 | int re = DZ_ERM_ERROR_READ; |
||
505 | Notify(re, _T(" File CRC changed while zipping: %s"), z->xname); |
||
506 | return re; |
||
507 | } |
||
508 | |||
509 | // Check input size |
||
510 | if (fisize != fsize) |
||
511 | { |
||
512 | int skip; |
||
513 | int re; |
||
514 | // may be file error |
||
515 | if (fFileError) |
||
516 | { |
||
517 | if (fFileError == ERROR_LOCK_VIOLATION) |
||
518 | Notify(DZ_ERR_LOCKED | IWARNING, z->xname); |
||
519 | else if (fFileError == ERROR_ACCESS_DENIED) |
||
520 | Notify(DZ_ERR_DENIED | IWARNING, z->xname); |
||
521 | else |
||
522 | Notify(DZ_ERR_NO_FILE_OPEN | IWARNING, |
||
523 | _T(" File read error [%d]: %s"), fFileError, z->xname); |
||
524 | |||
525 | /*int*/ re = DZ_ERM_ERROR_READ; |
||
526 | Notify(re, _T(" File error [%d] while zipping: %s"), fFileError, z->xname); |
||
527 | skip = SKIPPED_READ_ERROR; |
||
528 | // return re; |
||
529 | } |
||
530 | else |
||
531 | { |
||
532 | re = DZ_ERM_SKIPPED; |
||
533 | Notify(IWARNING, _T(" file size changed while zipping: %s"), |
||
534 | z->xname); |
||
535 | |||
536 | if (Verbose < 0) |
||
537 | Notify(ITRACE, _T(" was=%Lu, expected=%Lu "), fisize, fsize); |
||
538 | skip = SKIPPED_SIZE_CHANGE; |
||
539 | } |
||
540 | if (Skipping(z->XName, 0, skip)) |
||
541 | Fatal(DZ_ERM_SKIPPED, 2); |
||
542 | // reposition |
||
543 | if (fZipOutfile->SetPosition(z->off, FILE_BEGIN) == -1) |
||
544 | { |
||
545 | if (Verbose)// < 0) |
||
546 | Notify(ITRACE, _T(" could not reposition file ")); |
||
547 | DZError(DZ_ERM_ERROR_SEEK); |
||
548 | } |
||
549 | fZipOutfile->SetEndOfFile(); |
||
550 | return re; |
||
551 | } |
||
552 | |||
553 | // Try to rewrite the local header with correct information |
||
554 | z->crc = fcrc; |
||
555 | z->siz = csize; // compressed size |
||
556 | z->len = fisize; |
||
557 | |||
558 | if (fkey) |
||
559 | z->siz += RAND_HEAD_LEN; |
||
560 | |||
561 | if (fZipOutfile->SetPosition(z->off, FILE_BEGIN) == -1) |
||
562 | { |
||
563 | if (z->how != (ush)mthd) |
||
564 | DZError(DZ_ERM_ERROR_WRITE); |
||
565 | |||
566 | putextended(z); |
||
567 | z->flg = z->lflg; // if flg modified by inflate |
||
568 | } |
||
569 | else |
||
570 | { |
||
571 | // seek ok, ftell() should work, check compressed size |
||
572 | if (p - o != csize) |
||
573 | { |
||
574 | Notify(IWARNING, _T(" s=%Lu, actual=%Lu "), csize, p - o); |
||
575 | DZError(DZ_ERM_LOGIC_ERROR); |
||
576 | } |
||
577 | |||
578 | // (RCV Added in two lines below (ush)(...) |
||
579 | z->how = (ush)mthd; |
||
580 | |||
581 | if ((z->flg & FLAG_ENCRYPT_BIT) == 0 || haveCRC) |
||
582 | z->flg &= ~FLAG_EXTEND_BIT; |
||
583 | // clear the extended local header flag |
||
584 | z->lflg = z->flg; |
||
585 | |||
586 | // rewrite the local header: |
||
587 | if ((r = UpdateLocal(z)) != DZ_ERR_GOOD) |
||
588 | return r; |
||
589 | |||
590 | if (HChk != fZipOutfile->SetPosition(0, FILE_CURRENT)) |
||
591 | return DZ_ERM_LOGIC_ERROR; // size changed |
||
592 | |||
593 | fOutPosn = fZipOutfile->SetPosition(p, FILE_BEGIN); |
||
594 | |||
595 | if (fOutPosn < p) |
||
596 | return DZ_ERM_ERROR_SEEK; |
||
597 | |||
598 | if ((z->flg & (FLAG_EXTEND_BIT | FLAG_ENCRYPT_BIT)) != 0) |
||
599 | { |
||
600 | // encrypted file, extended header still required |
||
601 | if ((r = putextended(z)) != DZ_ERR_GOOD) |
||
602 | return r; |
||
603 | } |
||
604 | } |
||
605 | |||
606 | // Free the local extra field which is no longer needed |
||
607 | if (z->ext) |
||
608 | { |
||
609 | z->ext = 0; |
||
610 | } |
||
611 | |||
612 | // Display statistics |
||
613 | if (Verbose) |
||
614 | { |
||
615 | Notify(0, _T("%s in=%Lu, out=%Lu, %d%%"), |
||
616 | (mthd == DEFLATE) ? _T("deflated") : _T("stored"), fisize, csize, |
||
617 | percent(fisize, csize)); |
||
618 | } |
||
619 | /* TODO 1 -oRP -cenhancement : Finished Item */ |
||
620 | return DZ_ERR_GOOD; |
||
621 | } |
||
622 | |||
623 | |||
624 | // copy an existing entry with updated name |
||
625 | int ZipFunc::zipVersion(ZipItem *z) |
||
626 | { |
||
627 | int r; // Temporary variable |
||
628 | |||
629 | fwindow_size = 0L; |
||
630 | |||
631 | // Callback: action, error code, filesize, filename |
||
632 | CB->UserItem(z->len, z->IName); |
||
633 | if (Abort_Flag) |
||
634 | Fatal(DZ_ERM_ABORT, 0); |
||
635 | |||
636 | fFileError = 0; |
||
637 | ZInt64 lofs = z->off; // local header offset |
||
638 | lofs += sizeof(ZipLocalHeader) + z->nam + z->ext; |
||
639 | |||
640 | // seek to local data |
||
641 | if (SetFilePointer64(fhInz, lofs, FILE_BEGIN) == -1) |
||
642 | return DZ_ERR_ERROR_READ; |
||
643 | |||
644 | z->off = fOutPosn; |
||
645 | ZInt64 n = z->siz; |
||
646 | |||
647 | // copy the compressed data and the extended local header if there is one |
||
648 | if (z->lflg & FLAG_EXTEND_BIT) |
||
649 | n += (z->ver >= 45 ? 20 : 16); |
||
650 | |||
651 | // write the modified header |
||
652 | if ((r = PutLocal(z)) != DZ_ERR_GOOD) |
||
653 | return r; |
||
654 | |||
655 | fOutPosn += n; |
||
656 | |||
657 | // return fcopy(n); |
||
658 | int err = fcopy(n); |
||
659 | |||
660 | /* TODO 1 -oRP -cenhancement : Finished Item */ |
||
661 | return err; |
||
662 | } |