Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3.  
  4. #include "common.h"
  5. #include "DZOper.h"
  6. #include "Helpers.h"
  7. #include "dz_errs.h"
  8.  
  9. #undef _DZ_FILE_
  10. #define _DZ_FILE_ DZ_HELPERS_CPP
  11. /*
  12.   Helpers.cpp - internal 'stream' like helpers
  13. ************************************************************************
  14.  Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
  15.  
  16.    This file is part of TZipMaster Version 1.9.
  17.  
  18.     TZipMaster is free software: you can redistribute it and/or modify
  19.     it under the terms of the GNU Lesser General Public License as published by
  20.     the Free Software Foundation, either version 3 of the License, or
  21.     (at your option) any later version.
  22.  
  23.     TZipMaster is distributed in the hope that it will be useful,
  24.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  25.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26.     GNU Lesser General Public License for more details.
  27.  
  28.     You should have received a copy of the GNU Lesser General Public License
  29.     along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
  30.  
  31.     contact: problems@delphizip.org (include ZipMaster in the subject).
  32.     updates: http://www.delphizip.org
  33.     DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
  34. ************************************************************************/
  35.  
  36. ZStreamIO::ZStreamIO(DZOp *theOwner, const DZStrW& filename)
  37. {
  38.     Owner = theOwner;
  39.     fFile = false;
  40.     if (Is_Drv(filename) < 0)
  41.                 ffname = filename.Mid(DriveLen(filename)); // only filename
  42.     else
  43.         ffname = filename;
  44.     fIsTemp = false;
  45.         canseek = -1; // untested
  46. }
  47.  
  48. ZStreamIO::~ZStreamIO()
  49. {
  50. //
  51. }
  52.  
  53. bool ZStreamIO::operator!() const
  54. {
  55.     return !IsOpen();
  56. }
  57.  
  58.  
  59. bool __fastcall ZStreamIO::GetIsSeekable(void)
  60. {
  61.     if (!IsOpen())
  62.         return false;
  63.  
  64.     if (canseek >= 0)
  65.         return canseek > 0;
  66.  
  67.     __int64 curpos = SetPosition(0, FILE_CURRENT);
  68.     if (curpos < 1)
  69.         return DefSeekable();   // cannot test at beginning
  70.  
  71.     canseek = 0;
  72.  
  73.     if (SetPosition(-1, FILE_CURRENT) == -1)
  74.     {
  75.         if (Owner->Verbose < 0)
  76.             Owner->Notify(-555, _T("Seek- failed for %s"), fname.c_str());
  77.  
  78.         return false;
  79.         }
  80.  
  81.     if (SetPosition(curpos, FILE_BEGIN) == -1)
  82.     {
  83.         if (Owner->Verbose < 0)
  84.             Owner->Notify(-555, _T("Seek+ failed for %s"), fname.c_str());
  85.  
  86.         return false;
  87.     }
  88.  
  89.     canseek = 1;      // 1.75 can seek
  90.  
  91.     return true;
  92. }
  93.  
  94. bool ZStreamIO::SetEndOfFile(void)
  95. {
  96.     return false;// set length = position
  97. }
  98.  
  99. ZFile::ZFile(DZOp *theOwner, const DZStrW& lpFileName, DWORD dwDesiredAccess,
  100.                                 DWORD dwShareMode,  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  101.              DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes) : ZStreamIO(theOwner, lpFileName)
  102. {
  103.     fHandle = CreateFile(lpFileName, dwDesiredAccess, dwShareMode,
  104.                          lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
  105.                          NULL);
  106.     fFile = true;
  107. }
  108.              
  109. ZFile::ZFile(DZOp *theOwner, const DZStrW& lpFileName, DWORD Flags) :
  110.                         ZStreamIO(theOwner, lpFileName)
  111. {    
  112.   fHandle = CreateFile(lpFileName, GENERIC_READ, 0, NULL,
  113.                                 OPEN_EXISTING, Flags, NULL);
  114.   if (fHandle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_SHARING_VIOLATION )
  115.   {
  116.           fHandle = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  117.                                 OPEN_EXISTING, Flags, NULL);
  118.           if (fHandle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_SHARING_VIOLATION )
  119.           {
  120.                 fHandle = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  121.                         NULL, OPEN_EXISTING, Flags, NULL);
  122.           }
  123.   }            
  124.   if (fHandle == INVALID_HANDLE_VALUE && Owner->Verbose < 0)
  125.         Owner->Notify(ITRACE, _T("open read failed; filename=%s [%d]"), lpFileName.c_str(),
  126.                         GetLastError());
  127.     fFile = true;
  128.  
  129. }
  130.  
  131. ZFile::~ZFile()
  132. {
  133.     Close();
  134.  
  135.     if (IsTemp && !fname.IsEmpty())
  136.     {
  137.         // remove temporary
  138.         Owner->EraseFile(ffname, true);
  139.  
  140.         if (Owner->Verbose < 0)
  141.             Owner->Notify(ITRACE, _T("Erased %s"), fname.c_str());
  142.     }
  143. }
  144.  
  145. bool __fastcall ZFile::DefSeekable(void)
  146. {
  147.     return false;
  148. }
  149.  
  150. bool ZFile::Read(LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
  151.                  LPDWORD lpNumberOfBytesRead)
  152. {
  153.     return ReadFile(fHandle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL);
  154. }
  155.  
  156. bool ZFile::Write(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
  157.                   LPDWORD lpNumberOfBytesWritten)
  158. {
  159.     return WriteFile(fHandle, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
  160. }
  161.  
  162. __int64 ZFile::SetPosition(__int64 ofs, int from)
  163. {
  164.     typedef union
  165.     {
  166.         __int64 i64;
  167.  
  168.         struct
  169.         {
  170.             unsigned lo;
  171.             int hi;
  172.         };
  173.     }_I64;
  174.  
  175.     _I64 o;
  176.     o.i64 = ofs;
  177.     o.lo = ::SetFilePointer(fHandle, o.lo, (LONG*) & o.hi, from);
  178.  
  179.     if (o.lo == INVALID_SET_FILE_POINTER  && GetLastError())
  180.         return -1;
  181.  
  182.     return o.i64;
  183. }
  184.  
  185. bool ZFile::SetEndOfFile(void)
  186. {
  187.     return ::SetEndOfFile(fHandle);
  188. }
  189.  
  190. bool ZFile::Close()
  191. {
  192.     bool was = IsOpen();
  193.  
  194.     if (was)
  195.     {
  196.         HANDLE tmp = fHandle;
  197.         fHandle = INVALID_HANDLE_VALUE;
  198.         CloseHandle(tmp);
  199.     }
  200.  
  201.     return was;
  202. }
  203.  
  204. bool ZFile::IsOpen() const
  205. {
  206.     return fHandle != INVALID_HANDLE_VALUE;
  207. }
  208.  
  209. bool ZFile::SetTime(const FILETIME* lpCreationTime,
  210.                     const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime)
  211. {
  212.     return SetFileTime(fHandle, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
  213. }
  214.  
  215. bool ZFile::GetTime(FILETIME* lpCreationTime,
  216.                     FILETIME* lpLastAccessTime,
  217.                     FILETIME* lpLastWriteTime)
  218. {
  219.     return GetFileTime(fHandle, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
  220. }
  221.  
  222.  
  223.  
  224. //ALL interface structures BYTE ALIGNED
  225. /* stream operation arg usage
  226.    zacStIdentify,
  227. //      IN BufP = name
  228.       IN Number = number
  229.      OUT ArgLL = size, ArgD = Date, ArgA = Attrs
  230.    zacStCreate,
  231. //      IN BufP = name
  232.       IN Number = number
  233.      OUT StrmP = stream
  234.    zacStClose,
  235.       IN Number = number
  236.       IN StrmP = stream
  237.      OUT StrmP = stream (= NULL)
  238.    zacStPosition,
  239.       IN Number = number
  240.       IN StrmP = stream, ArgLL = offset, ArgI = from
  241.      OUT ArgLL = position
  242.    zacStRead,
  243.       IN Number = number
  244.       IN StrmP = stream, BufP = buf, ArgI = count
  245.      OUT ArgI = bytes read
  246.    zacStWrite
  247.       IN Number = number
  248.       IN StrmP = stream, BufP = buf, ArgI = count
  249.      OUT ArgI = bytes written
  250. */
  251. ZStream::ZStream(DZOp *theOwner, const DZStrW& filename) :
  252.         ZStreamIO(theOwner, filename)
  253. {
  254.     SetLastError(0);
  255.     CanClose = true;
  256.     zHandle = NULL;
  257.     fFile = false;
  258.     Number = (-Is_Drv(filename)) -2;
  259.     // cannot use for path
  260.     if (Number < 0 || filename.LastChar() == '\\' || filename.LastChar() == '/')
  261.     {
  262.         SetLastError(DZ_STREAM_NO_OPEN);
  263.         return;
  264.     }
  265.     ZS_Rec *cb = &Owner->ZSData;
  266.     cb->StrmP = NULL;
  267.         cb->OpCode = zsaCreate;
  268.         cb->Number = Number;
  269.     int r = Owner->StreamCB();
  270.  
  271.     if (r == CALLBACK_TRUE)
  272.         zHandle = cb->StrmP;
  273.     else
  274.         SetLastError(DZ_STREAM_NO_OPEN);
  275. }
  276.  
  277. ZStream::ZStream(DZOp *theOwner, const DZStrW& filename, void* astream):
  278.         ZStreamIO(theOwner, filename)
  279. {
  280.     Number = 0;
  281.     zHandle = astream;
  282.     fFile = false;
  283.     CanClose = false;
  284. }
  285.  
  286. ZStream::~ZStream()
  287. {
  288.     if (CanClose)
  289.         Close();
  290. }
  291.  
  292. bool __fastcall ZStream::DefSeekable(void)
  293. {
  294.     return true;
  295. }
  296.  
  297. //const int CHUNK = 0x400000;    // limit
  298. // problem TStream uses integer count
  299. bool ZStream::Read(LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
  300.                    LPDWORD lpNumberOfBytesRead)
  301. {
  302.     SetLastError(0);
  303.  
  304.     if ((int)nNumberOfBytesToRead < 0)
  305.     {
  306.         // failed
  307.         SetLastError(DZ_STREAM_NO_READ);
  308.         return false;
  309.         }
  310.  
  311.     ZS_Rec *cb = &Owner->ZSData;
  312.     cb->StrmP = zHandle;
  313.     cb->Number = Number;
  314.     cb->ArgI = nNumberOfBytesToRead;
  315.     cb->BufP = (unsigned char*)lpBuffer;
  316.     cb->OpCode = zsaRead;
  317.     int r = Owner->StreamCB();
  318.  
  319.     if (r != CALLBACK_TRUE)
  320.     {
  321.         // failed
  322.         SetLastError(DZ_STREAM_NO_READ);
  323.         return false;
  324.     }
  325.  
  326.         DWORD res = cb->ArgI;  // bytes read
  327.  
  328.     if (lpNumberOfBytesRead)
  329.         *lpNumberOfBytesRead = res;
  330.  
  331.     return true;
  332. }
  333.  
  334. bool ZStream::Write(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
  335.                     LPDWORD lpNumberOfBytesWritten)
  336. {
  337.     SetLastError(0);
  338.  
  339.     if ((int)nNumberOfBytesToWrite < 0)
  340.     {
  341.         // failed
  342.         SetLastError(DZ_STREAM_NO_WRITE);
  343.         return false;
  344.         }
  345.  
  346.     ZS_Rec *cb = &Owner->ZSData;
  347.     cb->StrmP = zHandle;
  348.     cb->Number = Number;
  349.     cb->ArgI = nNumberOfBytesToWrite;
  350.     cb->BufP = (unsigned char*)lpBuffer;
  351.     cb->OpCode = zsaWrite;
  352.     int r = Owner->StreamCB();
  353.  
  354.     if (r != CALLBACK_TRUE)
  355.     {
  356.         // failed
  357.         SetLastError(DZ_STREAM_NO_WRITE);
  358.         return false;
  359.     }
  360.  
  361.         DWORD res = cb->ArgI;  // bytes written
  362.  
  363.     if (lpNumberOfBytesWritten)
  364.         *lpNumberOfBytesWritten = res;
  365.  
  366.     if (res == nNumberOfBytesToWrite)
  367.         return true;
  368.  
  369.     return false;
  370. }
  371.  
  372. __int64 ZStream::SetPosition(__int64 ofs, int from)
  373. {
  374.     SetLastError(0);
  375.     ZS_Rec *cb = &Owner->ZSData;
  376.     cb->StrmP = zHandle;
  377.     cb->Number = Number;
  378.     cb->ArgI = from;
  379.     cb->ArgLL = ofs;
  380.     cb->OpCode = zsaPosition;
  381.     int r = Owner->StreamCB();
  382.  
  383.     if (r == CALLBACK_TRUE)
  384.         return cb->ArgLL;
  385.  
  386.     SetLastError(DZ_STREAM_NO_SEEK);
  387.  
  388.     return -1;
  389. }
  390.  
  391. bool ZStream::Close()
  392. {
  393.     bool was = IsOpen();
  394.     SetLastError(0);
  395.  
  396.     if (CanClose && was)
  397.     {
  398.         ZS_Rec *cb = &Owner->ZSData;
  399.         cb->StrmP = zHandle;
  400.         cb->Number = Number;
  401.         cb->OpCode = zsaClose;
  402.         int r = Owner->StreamCB();
  403.  
  404.         if (r == CALLBACK_TRUE)
  405.             zHandle = 0;//cb->StrmP;
  406.         else
  407.             SetLastError(DZ_STREAM_NOT_OPEN);
  408.     }
  409.  
  410.     return was;
  411. }
  412.  
  413. bool ZStream::IsOpen() const
  414. {
  415.     return zHandle != 0;// && Owner != NULL;
  416. }
  417.  
  418. bool ZStream::SetTime(const FILETIME* lpCreationTime,
  419.                       const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime)
  420. {
  421. #pragma argsused
  422.     return true; // ignore
  423. }
  424.  
  425. bool ZStream::GetTime(FILETIME* lpCreationTime,
  426.                       FILETIME* lpLastAccessTime, FILETIME* lpLastWriteTime)
  427. {
  428. #pragma argsused
  429.     return true; // ignore
  430. }
  431.  
  432. AutoStream::AutoStream(ZStreamIO **zs)
  433. {
  434.     theStream = zs;
  435. }
  436.  
  437. AutoStream::~AutoStream()
  438. {
  439.     if (theStream)
  440.     {
  441.         ZStreamIO *tmp = *theStream;
  442.         *theStream = NULL;
  443.         theStream = NULL;
  444.  
  445.         if (tmp)
  446.             delete tmp;
  447.     }
  448. }
  449.  
  450. void AutoStream::Assign(ZStreamIO **zs)
  451. {
  452.     if (theStream)
  453.     {
  454.         ZStreamIO *tmp = *theStream;
  455.         *theStream = NULL;
  456.         theStream = NULL;
  457.  
  458.         if (tmp)
  459.             delete tmp;
  460.     }
  461.  
  462.     theStream = zs;
  463. }
  464.  
  465.  
  466.