Subversion Repositories autosfx

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 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