~ubuntu-branches/ubuntu/precise/p7zip/precise-updates

« back to all changes in this revision

Viewing changes to CPP/7zip/Archive/Zip/ZipHandler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mohammed Adnène Trojette
  • Date: 2009-02-14 20:12:27 UTC
  • mfrom: (1.1.11 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090214201227-go63qxm9ozfdma60
Tags: 4.65~dfsg.1-1
* New upstream release.
* Remove wx2.8 Build-Depends added by mistakes (7zG is not yet
  intended to be built).
* Use dh_clean without -k.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
#include "StdAfx.h"
4
4
 
5
 
#include "ZipHandler.h"
6
 
 
 
5
#include "Common/ComTry.h"
7
6
#include "Common/Defs.h"
 
7
#include "Common/IntToString.h"
8
8
#include "Common/StringConvert.h"
9
 
#include "Common/ComTry.h"
10
 
#include "Common/IntToString.h"
11
9
 
 
10
#include "Windows/PropVariant.h"
12
11
#include "Windows/Time.h"
13
 
#include "Windows/PropVariant.h"
14
12
 
15
13
#include "../../IPassword.h"
16
14
 
 
15
#include "../../Common/CreateCoder.h"
 
16
#include "../../Common/FilterCoder.h"
17
17
#include "../../Common/ProgressUtils.h"
18
18
#include "../../Common/StreamObjects.h"
19
 
#include "../../Common/CreateCoder.h"
20
 
#include "../../Common/FilterCoder.h"
21
 
 
22
 
#include "../../Compress/Copy/CopyCoder.h"
 
19
#include "../../Common/StreamUtils.h"
 
20
 
 
21
#include "../../Compress/CopyCoder.h"
 
22
#include "../../Compress/LzmaDecoder.h"
 
23
#include "../../Compress/ImplodeDecoder.h"
 
24
#include "../../Compress/ShrinkDecoder.h"
 
25
 
 
26
#include "../../Crypto/WzAes.h"
 
27
#include "../../Crypto/ZipCrypto.h"
 
28
#include "../../Crypto/ZipStrong.h"
23
29
 
24
30
#include "../Common/ItemNameUtils.h"
25
31
#include "../Common/OutStreamWithCRC.h"
26
32
 
27
 
#include "../../Compress/Shrink/ShrinkDecoder.h"
28
 
#include "../../Compress/Implode/ImplodeDecoder.h"
29
 
 
30
 
 
31
 
#include "../../Crypto/Zip/ZipCipher.h"
32
 
#include "../../Crypto/WzAES/WzAES.h"
33
 
 
34
 
#ifdef ZIP_STRONG_SUPORT
35
 
#include "../../Crypto/ZipStrong/ZipStrong.h"
36
 
#endif
 
33
#include "ZipHandler.h"
37
34
 
38
35
using namespace NWindows;
39
 
using namespace NTime;
40
36
 
41
37
namespace NArchive {
42
38
namespace NZip {
45
41
static const CMethodId kMethodId_ZipBase = 0x040100;
46
42
static const CMethodId kMethodId_BZip2 = 0x040202;
47
43
 
48
 
const wchar_t *kHostOS[] = 
 
44
const wchar_t *kHostOS[] =
49
45
{
50
46
  L"FAT",
51
47
  L"AMIGA",
74
70
 
75
71
static const wchar_t *kUnknownOS = L"Unknown";
76
72
 
77
 
STATPROPSTG kProps[] = 
 
73
STATPROPSTG kProps[] =
78
74
{
79
75
  { NULL, kpidPath, VT_BSTR},
80
 
  { NULL, kpidIsFolder, VT_BOOL},
 
76
  { NULL, kpidIsDir, VT_BOOL},
81
77
  { NULL, kpidSize, VT_UI8},
82
 
  { NULL, kpidPackedSize, VT_UI8},
83
 
  { NULL, kpidLastWriteTime, VT_FILETIME},
84
 
  { NULL, kpidCreationTime, VT_FILETIME},
85
 
  { NULL, kpidLastAccessTime, VT_FILETIME},
 
78
  { NULL, kpidPackSize, VT_UI8},
 
79
  { NULL, kpidMTime, VT_FILETIME},
 
80
  { NULL, kpidCTime, VT_FILETIME},
 
81
  { NULL, kpidATime, VT_FILETIME},
86
82
  
87
 
  { NULL, kpidAttributes, VT_UI4},
 
83
  { NULL, kpidAttrib, VT_UI4},
88
84
 
89
85
  { NULL, kpidEncrypted, VT_BOOL},
90
86
  { NULL, kpidComment, VT_BSTR},
97
93
  // { NULL, kpidUnpackVer, VT_UI1},
98
94
};
99
95
 
100
 
const wchar_t *kMethods[] = 
 
96
const wchar_t *kMethods[] =
101
97
{
102
98
  L"Store",
103
99
  L"Shrink",
109
105
  L"Tokenizing",
110
106
  L"Deflate",
111
107
  L"Deflate64",
112
 
  L"PKImploding",
113
 
  L"Unknown",
114
 
  L"BZip2"
 
108
  L"PKImploding"
115
109
};
116
110
 
117
111
const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
118
 
// const wchar_t *kUnknownMethod = L"Unknown";
 
112
const wchar_t *kBZip2Method = L"BZip2";
 
113
const wchar_t *kLZMAMethod = L"LZMA";
 
114
const wchar_t *kJpegMethod = L"Jpeg";
 
115
const wchar_t *kWavPackMethod = L"WavPack";
119
116
const wchar_t *kPPMdMethod = L"PPMd";
120
117
const wchar_t *kAESMethod = L"AES";
121
118
const wchar_t *kZipCryptoMethod = L"ZipCrypto";
127
124
  const wchar_t *Name;
128
125
};
129
126
 
130
 
CStrongCryptoPair g_StrongCryptoPairs[] = 
 
127
CStrongCryptoPair g_StrongCryptoPairs[] =
131
128
{
132
129
  { NStrongCryptoFlags::kDES, L"DES" },
133
130
  { NStrongCryptoFlags::kRC2old, L"RC2a" },
142
139
  { NStrongCryptoFlags::kRC4, L"RC4" }
143
140
};
144
141
 
145
 
STATPROPSTG kArcProps[] = 
 
142
STATPROPSTG kArcProps[] =
146
143
{
 
144
  { NULL, kpidBit64, VT_BOOL},
147
145
  { NULL, kpidComment, VT_BSTR}
148
146
};
149
147
 
150
 
CHandler::CHandler():
151
 
  m_ArchiveIsOpen(false)
 
148
CHandler::CHandler()
152
149
{
153
150
  InitMethodProperties();
154
151
}
176
173
  NWindows::NCOM::CPropVariant prop;
177
174
  switch(propID)
178
175
  {
 
176
    case kpidBit64:  if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break;
179
177
    case kpidComment:
180
178
      prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP);
181
179
      break;
198
196
  const CItemEx &item = m_Items[index];
199
197
  switch(propID)
200
198
  {
201
 
    case kpidPath:
202
 
      prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name));
203
 
      break;
204
 
    case kpidIsFolder:
205
 
      prop = item.IsDirectory();
206
 
      break;
207
 
    case kpidSize:
208
 
      prop = item.UnPackSize;
209
 
      break;
210
 
    case kpidPackedSize:
211
 
      prop = item.PackSize;
212
 
      break;
 
199
    case kpidPath:  prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name)); break;
 
200
    case kpidIsDir:  prop = item.IsDir(); break;
 
201
    case kpidSize:  prop = item.UnPackSize; break;
 
202
    case kpidPackSize:  prop = item.PackSize; break;
213
203
    case kpidTimeType:
 
204
    {
214
205
      FILETIME utcFileTime;
215
206
      if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kTagTime, utcFileTime))
216
207
        prop = (UInt32)NFileTimeType::kWindows;
217
208
      break;
218
 
    case kpidCreationTime: 
 
209
    }
 
210
    case kpidCTime:
219
211
    {
220
212
      FILETIME ft;
221
213
      if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
222
214
        prop = ft;
223
215
      break;
224
216
    }
225
 
    case kpidLastAccessTime:
 
217
    case kpidATime:
226
218
    {
227
219
      FILETIME ft;
228
220
      if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
229
221
        prop = ft;
230
222
      break;
231
223
    }
232
 
    case kpidLastWriteTime:
 
224
    case kpidMTime:
233
225
    {
234
226
      FILETIME utcFileTime;
235
227
      if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utcFileTime))
236
228
      {
237
229
        FILETIME localFileTime;
238
 
        if (DosTimeToFileTime(item.Time, localFileTime))
 
230
        if (NTime::DosTimeToFileTime(item.Time, localFileTime))
239
231
        {
240
232
          if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
241
233
            utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
246
238
      prop = utcFileTime;
247
239
      break;
248
240
    }
249
 
    case kpidAttributes:
250
 
      prop = item.GetWinAttributes();
251
 
      break;
252
 
    case kpidEncrypted:
253
 
      prop = item.IsEncrypted();
254
 
      break;
255
 
    case kpidComment:
256
 
    {
257
 
      prop = item.GetUnicodeString(BytesToString(item.Comment));
258
 
      break;
259
 
    }
260
 
    case kpidCRC:
261
 
      if (item.IsThereCrc())
262
 
        prop = item.FileCRC;
263
 
      break;
 
241
    case kpidAttrib:  prop = item.GetWinAttributes(); break;
 
242
    case kpidEncrypted:  prop = item.IsEncrypted(); break;
 
243
    case kpidComment:  prop = item.GetUnicodeString(BytesToString(item.Comment)); break;
 
244
    case kpidCRC:  if (item.IsThereCrc()) prop = item.FileCRC; break;
264
245
    case kpidMethod:
265
246
    {
266
247
      UInt16 methodId = item.CompressionMethod;
310
291
      }
311
292
      if (methodId < kNumMethods)
312
293
        method += kMethods[methodId];
313
 
      else if (methodId == NFileHeader::NCompressionMethod::kWzPPMd)
314
 
        method += kPPMdMethod;
315
 
      else
 
294
      else switch (methodId)
316
295
      {
317
 
        wchar_t s[32];
318
 
        ConvertUInt64ToString(methodId, s);
319
 
        method += s;
 
296
        case NFileHeader::NCompressionMethod::kLZMA:
 
297
          method += kLZMAMethod;
 
298
          if (item.IsLzmaEOS())
 
299
            method += L":EOS";
 
300
          break;
 
301
        case NFileHeader::NCompressionMethod::kBZip2: method += kBZip2Method; break;
 
302
        case NFileHeader::NCompressionMethod::kJpeg: method += kJpegMethod; break;
 
303
        case NFileHeader::NCompressionMethod::kWavPack: method += kWavPackMethod; break;
 
304
        case NFileHeader::NCompressionMethod::kPPMd: method += kPPMdMethod; break;
 
305
        default:
 
306
        {
 
307
          wchar_t s[32];
 
308
          ConvertUInt64ToString(methodId, s);
 
309
          method += s;
 
310
        }
320
311
      }
321
312
      prop = method;
322
313
      break;
331
322
  COM_TRY_END
332
323
}
333
324
 
334
 
class CPropgressImp: public CProgressVirt
 
325
class CProgressImp: public CProgressVirt
335
326
{
336
 
  CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
 
327
  CMyComPtr<IArchiveOpenCallback> _callback;
337
328
public:
338
 
  STDMETHOD(SetCompleted)(const UInt64 *numFiles);
339
 
  void Init(IArchiveOpenCallback *openArchiveCallback)
340
 
    { m_OpenArchiveCallback = openArchiveCallback; }
 
329
  STDMETHOD(SetTotal)(UInt64 numFiles);
 
330
  STDMETHOD(SetCompleted)(UInt64 numFiles);
 
331
  CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}
341
332
};
342
333
 
343
 
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
344
 
{
345
 
  if (m_OpenArchiveCallback)
346
 
    return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
347
 
  return S_OK;
348
 
}
349
 
 
350
 
STDMETHODIMP CHandler::Open(IInStream *inStream, 
351
 
    const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback)
 
334
STDMETHODIMP CProgressImp::SetTotal(UInt64 numFiles)
 
335
{
 
336
  if (_callback)
 
337
    return _callback->SetTotal(&numFiles, NULL);
 
338
  return S_OK;
 
339
}
 
340
 
 
341
STDMETHODIMP CProgressImp::SetCompleted(UInt64 numFiles)
 
342
{
 
343
  if (_callback)
 
344
    return _callback->SetCompleted(&numFiles, NULL);
 
345
  return S_OK;
 
346
}
 
347
 
 
348
STDMETHODIMP CHandler::Open(IInStream *inStream,
 
349
    const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
352
350
{
353
351
  COM_TRY_BEGIN
354
 
  // try
355
 
  {
356
 
    if(!m_Archive.Open(inStream, maxCheckStartPosition))
357
 
      return S_FALSE;
358
 
    m_ArchiveIsOpen = true;
359
 
    m_Items.Clear();
360
 
    if (openArchiveCallback != NULL)
361
 
    {
362
 
      RINOK(openArchiveCallback->SetTotal(NULL, NULL));
363
 
    }
364
 
    CPropgressImp propgressImp;
365
 
    propgressImp.Init(openArchiveCallback);
366
 
    RINOK(m_Archive.ReadHeaders(m_Items, &propgressImp));
367
 
  }
368
 
  /*
369
 
  catch(...)
370
 
  {
371
 
    return S_FALSE;
372
 
  }
373
 
  */
 
352
  try
 
353
  {
 
354
    Close();
 
355
    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
 
356
    RINOK(m_Archive.Open(inStream, maxCheckStartPosition));
 
357
    CProgressImp progressImp(callback);
 
358
    return m_Archive.ReadHeaders(m_Items, &progressImp);
 
359
  }
 
360
  catch(const CInArchiveException &) { Close(); return S_FALSE; }
 
361
  catch(...) { Close(); throw; }
374
362
  COM_TRY_END
375
 
  return S_OK;
376
363
}
377
364
 
378
365
STDMETHODIMP CHandler::Close()
379
366
{
380
367
  m_Items.Clear();
381
368
  m_Archive.Close();
382
 
  m_ArchiveIsOpen = false;
383
369
  return S_OK;
384
370
}
385
371
 
386
372
//////////////////////////////////////
387
373
// CHandler::DecompressItems
388
374
 
 
375
class CLzmaDecoder:
 
376
  public ICompressCoder,
 
377
  public CMyUnknownImp
 
378
{
 
379
  NCompress::NLzma::CDecoder *DecoderSpec;
 
380
  CMyComPtr<ICompressCoder> Decoder;
 
381
public:
 
382
  CLzmaDecoder();
 
383
  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
 
384
      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
 
385
 
 
386
  MY_UNKNOWN_IMP
 
387
};
 
388
 
 
389
CLzmaDecoder::CLzmaDecoder()
 
390
{
 
391
  DecoderSpec = new NCompress::NLzma::CDecoder;
 
392
  Decoder = DecoderSpec;
 
393
}
 
394
 
 
395
HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
 
396
    const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
 
397
{
 
398
  Byte buf[9];
 
399
  RINOK(ReadStream_FALSE(inStream, buf, 9));
 
400
  if (buf[2] != 5 || buf[3] != 0)
 
401
    return E_NOTIMPL;
 
402
  RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, 5));
 
403
  return Decoder->Code(inStream, outStream, NULL, outSize, progress);
 
404
}
 
405
 
389
406
struct CMethodItem
390
407
{
391
408
  UInt16 ZipMethod;
395
412
class CZipDecoder
396
413
{
397
414
  NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec;
398
 
  NCrypto::NWzAES::CDecoder *_aesDecoderSpec;
 
415
  NCrypto::NZipStrong::CDecoder *_pkAesDecoderSpec;
 
416
  NCrypto::NWzAes::CDecoder *_wzAesDecoderSpec;
 
417
 
399
418
  CMyComPtr<ICompressFilter> _zipCryptoDecoder;
400
 
  CMyComPtr<ICompressFilter> _aesDecoder;
401
 
  #ifdef ZIP_STRONG_SUPORT
402
 
  NCrypto::NZipStrong::CDecoder *_zsDecoderSpec;
403
 
  CMyComPtr<ICompressFilter> _zsDecoder;
404
 
  #endif
 
419
  CMyComPtr<ICompressFilter> _pkAesDecoder;
 
420
  CMyComPtr<ICompressFilter> _wzAesDecoder;
 
421
 
405
422
  CFilterCoder *filterStreamSpec;
406
423
  CMyComPtr<ISequentialInStream> filterStream;
407
424
  CMyComPtr<ICryptoGetTextPassword> getTextPassword;
408
425
  CObjectVector<CMethodItem> methodItems;
409
426
 
410
427
public:
411
 
  CZipDecoder(): _zipCryptoDecoderSpec(0), _aesDecoderSpec(0), filterStreamSpec(0) {}
 
428
  CZipDecoder():
 
429
      _zipCryptoDecoderSpec(0),
 
430
      _pkAesDecoderSpec(0),
 
431
      _wzAesDecoderSpec(0),
 
432
      filterStreamSpec(0) {}
412
433
 
413
434
  HRESULT Decode(
414
435
    DECL_EXTERNAL_CODECS_LOC_VARS
415
 
    CInArchive &archive, const CItemEx &item, 
416
 
    ISequentialOutStream *realOutStream, 
417
 
    IArchiveExtractCallback *extractCallback, 
 
436
    CInArchive &archive, const CItemEx &item,
 
437
    ISequentialOutStream *realOutStream,
 
438
    IArchiveExtractCallback *extractCallback,
418
439
    ICompressProgressInfo *compressProgress,
419
440
    UInt32 numThreads, Int32 &res);
420
441
};
421
442
 
422
443
HRESULT CZipDecoder::Decode(
423
444
    DECL_EXTERNAL_CODECS_LOC_VARS
424
 
    CInArchive &archive, const CItemEx &item, 
425
 
    ISequentialOutStream *realOutStream, 
 
445
    CInArchive &archive, const CItemEx &item,
 
446
    ISequentialOutStream *realOutStream,
426
447
    IArchiveExtractCallback *extractCallback,
427
448
    ICompressProgressInfo *compressProgress,
428
449
    UInt32 numThreads, Int32 &res)
431
452
  CInStreamReleaser inStreamReleaser;
432
453
 
433
454
  bool needCRC = true;
434
 
  bool aesMode = false;
435
 
  #ifdef ZIP_STRONG_SUPORT
 
455
  bool wzAesMode = false;
436
456
  bool pkAesMode = false;
437
 
  #endif
438
457
  UInt16 methodId = item.CompressionMethod;
439
458
  if (item.IsEncrypted())
440
459
  {
441
460
    if (item.IsStrongEncrypted())
442
461
    {
443
 
      #ifdef ZIP_STRONG_SUPORT
444
462
      CStrongCryptoField f;
445
463
      if (item.CentralExtra.GetStrongCryptoField(f))
446
464
      {
447
465
        pkAesMode = true;
448
466
      }
449
467
      if (!pkAesMode)
450
 
      #endif
451
468
      {
452
469
        res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
453
470
        return S_OK;
458
475
      CWzAesExtraField aesField;
459
476
      if (item.CentralExtra.GetWzAesField(aesField))
460
477
      {
461
 
        aesMode = true;
 
478
        wzAesMode = true;
462
479
        needCRC = aesField.NeedCrc();
463
480
      }
464
481
    }
474
491
  CMyComPtr<ISequentialInStream> inStream;
475
492
  {
476
493
    UInt64 packSize = item.PackSize;
477
 
    if (aesMode)
 
494
    if (wzAesMode)
478
495
    {
479
 
      if (packSize < NCrypto::NWzAES::kMacSize)
 
496
      if (packSize < NCrypto::NWzAes::kMacSize)
480
497
        return S_OK;
481
 
      packSize -= NCrypto::NWzAES::kMacSize;
 
498
      packSize -= NCrypto::NWzAes::kMacSize;
482
499
    }
483
500
    UInt64 dataPos = item.GetDataPosition();
484
501
    inStream.Attach(archive.CreateLimitedStream(dataPos, packSize));
488
505
  CMyComPtr<ICompressFilter> cryptoFilter;
489
506
  if (item.IsEncrypted())
490
507
  {
491
 
    if (aesMode)
 
508
    if (wzAesMode)
492
509
    {
493
510
      CWzAesExtraField aesField;
494
511
      if (!item.CentralExtra.GetWzAesField(aesField))
495
512
        return S_OK;
496
513
      methodId = aesField.Method;
497
 
      if (!_aesDecoder)
 
514
      if (!_wzAesDecoder)
498
515
      {
499
 
        _aesDecoderSpec = new NCrypto::NWzAES::CDecoder;
500
 
        _aesDecoder = _aesDecoderSpec;
 
516
        _wzAesDecoderSpec = new NCrypto::NWzAes::CDecoder;
 
517
        _wzAesDecoder = _wzAesDecoderSpec;
501
518
      }
502
 
      cryptoFilter = _aesDecoder;
 
519
      cryptoFilter = _wzAesDecoder;
503
520
      Byte properties = aesField.Strength;
504
 
      RINOK(_aesDecoderSpec->SetDecoderProperties2(&properties, 1));
 
521
      RINOK(_wzAesDecoderSpec->SetDecoderProperties2(&properties, 1));
505
522
    }
506
 
    #ifdef ZIP_STRONG_SUPORT
507
523
    else if (pkAesMode)
508
524
    {
509
 
      if (!_zsDecoder)
 
525
      if (!_pkAesDecoder)
510
526
      {
511
 
        _zsDecoderSpec = new NCrypto::NZipStrong::CDecoder;
512
 
        _zsDecoder = _zsDecoderSpec;
 
527
        _pkAesDecoderSpec = new NCrypto::NZipStrong::CDecoder;
 
528
        _pkAesDecoder = _pkAesDecoderSpec;
513
529
      }
514
 
      cryptoFilter = _zsDecoder;
 
530
      cryptoFilter = _pkAesDecoder;
515
531
    }
516
 
    #endif
517
532
    else
518
533
    {
519
534
      if (!_zipCryptoDecoder)
534
549
      CMyComBSTR password;
535
550
      RINOK(getTextPassword->CryptoGetTextPassword(&password));
536
551
      AString charPassword;
537
 
      if (aesMode 
538
 
        #ifdef ZIP_STRONG_SUPORT
539
 
        || pkAesMode
540
 
        #endif
541
 
        )
 
552
      if (wzAesMode || pkAesMode)
542
553
      {
543
554
        charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP);
544
555
        /*
561
572
        // we use OEM. WinZip/Windows probably use ANSI for some files
562
573
        charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
563
574
      }
564
 
      HRESULT res = cryptoSetPassword->CryptoSetPassword(
 
575
      HRESULT result = cryptoSetPassword->CryptoSetPassword(
565
576
        (const Byte *)(const char *)charPassword, charPassword.Length());
566
 
      if (res != S_OK)
 
577
      if (result != S_OK)
567
578
        return S_OK;
568
579
    }
569
580
    else
587
598
      mi.Coder = new NCompress::NShrink::CDecoder;
588
599
    else if (methodId == NFileHeader::NCompressionMethod::kImploded)
589
600
      mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
 
601
    else if (methodId == NFileHeader::NCompressionMethod::kLZMA)
 
602
      mi.Coder = new CLzmaDecoder;
590
603
    else
591
604
    {
592
605
      CMethodId szMethodID;
636
649
  #endif
637
650
  
638
651
  {
639
 
    HRESULT result;
 
652
    HRESULT result = S_OK;
640
653
    CMyComPtr<ISequentialInStream> inStreamNew;
641
654
    if (item.IsEncrypted())
642
655
    {
646
659
        filterStream = filterStreamSpec;
647
660
      }
648
661
      filterStreamSpec->Filter = cryptoFilter;
649
 
      if (aesMode)
 
662
      if (wzAesMode)
650
663
      {
651
 
        RINOK(_aesDecoderSpec->ReadHeader(inStream));
 
664
        result = _wzAesDecoderSpec->ReadHeader(inStream);
652
665
      }
653
 
      #ifdef ZIP_STRONG_SUPORT
654
666
      else if (pkAesMode)
655
667
      {
656
 
        RINOK(_zsDecoderSpec->ReadHeader(inStream));
 
668
        result =_pkAesDecoderSpec->ReadHeader(inStream, item.FileCRC, item.UnPackSize);
 
669
        if (result == S_OK)
 
670
        {
 
671
          bool passwOK;
 
672
          result = _pkAesDecoderSpec->CheckPassword(passwOK);
 
673
          if (result == S_OK && !passwOK)
 
674
            result = S_FALSE;
 
675
        }
657
676
      }
658
 
      #endif
659
677
      else
660
678
      {
661
 
        RINOK(_zipCryptoDecoderSpec->ReadHeader(inStream));
 
679
        result = _zipCryptoDecoderSpec->ReadHeader(inStream);
662
680
      }
663
 
      RINOK(filterStreamSpec->SetInStream(inStream));
664
 
      inStreamReleaser.FilterCoder = filterStreamSpec;
665
 
      inStreamNew = filterStream; 
666
 
      
667
 
      if (aesMode)
 
681
 
 
682
      if (result == S_OK)
668
683
      {
669
 
        if (!_aesDecoderSpec->CheckPasswordVerifyCode())
670
 
          return S_OK;
 
684
        RINOK(filterStreamSpec->SetInStream(inStream));
 
685
        inStreamReleaser.FilterCoder = filterStreamSpec;
 
686
        inStreamNew = filterStream;
 
687
        if (wzAesMode)
 
688
        {
 
689
          if (!_wzAesDecoderSpec->CheckPasswordVerifyCode())
 
690
            result = S_FALSE;
 
691
        }
671
692
      }
672
693
    }
673
694
    else
674
 
      inStreamNew = inStream; 
675
 
    result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress);
 
695
      inStreamNew = inStream;
 
696
    if (result == S_OK)
 
697
      result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress);
676
698
    if (result == S_FALSE)
677
699
      return S_OK;
 
700
    if (result == E_NOTIMPL)
 
701
    {
 
702
      res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
 
703
      return S_OK;
 
704
    }
 
705
 
678
706
    RINOK(result);
679
707
  }
680
708
  bool crcOK = true;
681
709
  bool authOk = true;
682
710
  if (needCRC)
683
711
    crcOK = (outStreamSpec->GetCRC() == item.FileCRC);
684
 
  if (aesMode)
 
712
  if (wzAesMode)
685
713
  {
686
 
    inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAES::kMacSize));
687
 
    if (_aesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
 
714
    inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAes::kMacSize));
 
715
    if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
688
716
      authOk = false;
689
717
  }
690
718
  
691
 
  res = ((crcOK && authOk) ? 
 
719
  res = ((crcOK && authOk) ?
692
720
    NArchive::NExtract::NOperationResult::kOK :
693
721
    NArchive::NExtract::NOperationResult::kCRCError);
694
722
  return S_OK;
734
762
    RINOK(lps->SetCur());
735
763
 
736
764
    CMyComPtr<ISequentialOutStream> realOutStream;
737
 
    Int32 askMode = testMode ? 
 
765
    Int32 askMode = testMode ?
738
766
        NArchive::NExtract::NAskMode::kTest :
739
767
        NArchive::NExtract::NAskMode::kExtract;
740
768
    Int32 index = allFilesMode ? i : indices[i];
747
775
      HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item);
748
776
      if (res == S_FALSE)
749
777
      {
750
 
        if (item.IsDirectory() || realOutStream || testMode)
 
778
        if (item.IsDir() || realOutStream || testMode)
751
779
        {
752
780
          RINOK(extractCallback->PrepareOperation(askMode));
753
781
          realOutStream.Release();
758
786
      RINOK(res);
759
787
    }
760
788
 
761
 
    if (item.IsDirectory() || item.IgnoreItem())
 
789
    if (item.IsDir() || item.IgnoreItem())
762
790
    {
763
791
      // if (!testMode)
764
792
      {
772
800
    currentItemUnPacked = item.UnPackSize;
773
801
    currentItemPacked = item.PackSize;
774
802
 
775
 
    if (!testMode && (!realOutStream)) 
 
803
    if (!testMode && (!realOutStream))
776
804
      continue;
777
805
 
778
806
    RINOK(extractCallback->PrepareOperation(askMode));
780
808
    Int32 res;
781
809
    RINOK(myDecoder.Decode(
782
810
        EXTERNAL_CODECS_VARS
783
 
        m_Archive, item, realOutStream, extractCallback, 
 
811
        m_Archive, item, realOutStream, extractCallback,
784
812
        progress, _numThreads, res));
785
813
    realOutStream.Release();
786
814