Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  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. }
  663.