⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ziphandler.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  /*  catch(...)  {    return S_FALSE;  }  */  COM_TRY_END  return S_OK;}STDMETHODIMP CHandler::Close(){  m_Items.Clear();  m_Archive.Close();  m_ArchiveIsOpen = false;  return S_OK;}//////////////////////////////////////// CHandler::DecompressItemsstruct CMethodItem{  Byte ZipMethod;  CMyComPtr<ICompressCoder> Coder;};STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,    Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback){  COM_TRY_BEGIN  CMyComPtr<ICryptoGetTextPassword> getTextPassword;  bool testMode = (_aTestMode != 0);  CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;  UInt64 totalUnPacked = 0, totalPacked = 0;  bool allFilesMode = (numItems == UInt32(-1));  if (allFilesMode)    numItems = m_Items.Size();  if(numItems == 0)    return S_OK;  UInt32 i;  for(i = 0; i < numItems; i++)  {    const CItemEx &item = m_Items[allFilesMode ? i : indices[i]];    totalUnPacked += item.UnPackSize;    totalPacked += item.PackSize;  }  extractCallback->SetTotal(totalUnPacked);  UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;  UInt64 currentItemUnPacked, currentItemPacked;     #ifndef EXCLUDE_COM  N7z::LoadMethodMap();  CCoderLibraries libraries;  #endif  CObjectVector<CMethodItem> methodItems;  /*  CCoderLibraries _libraries;  #ifndef COMPRESS_IMPLODE  CCoderLibrary implodeLib;  #endif    CMyComPtr<ICompressCoder> implodeDecoder;  CMyComPtr<ICompressCoder> deflateDecoder;  CMyComPtr<ICompressCoder> deflate64Decoder;  CMyComPtr<ICompressCoder> bzip2Decoder;  #ifndef CRYPTO_ZIP  CCoderLibrary cryptoLib;  #endif  */  NCrypto::NZip::CDecoder *cryptoDecoderSpec;  CMyComPtr<ICompressFilter> cryptoDecoder;  CFilterCoder *filterStreamSpec;  CMyComPtr<ISequentialInStream> filterStream;  // UInt16 mixerCoderMethod;  for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,      currentTotalPacked += currentItemPacked)  {    currentItemUnPacked = 0;    currentItemPacked = 0;    RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));    CMyComPtr<ISequentialOutStream> realOutStream;    Int32 askMode;    askMode = testMode ? NArchive::NExtract::NAskMode::kTest :        NArchive::NExtract::NAskMode::kExtract;    Int32 index = allFilesMode ? i : indices[i];    const CItemEx &item = m_Items[index];    RINOK(extractCallback->GetStream(index, &realOutStream, askMode));    if(item.IsDirectory() || item.IgnoreItem())    {      // if (!testMode)      {        RINOK(extractCallback->PrepareOperation(askMode));        RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));      }      continue;    }    if (!testMode && (!realOutStream))       continue;    RINOK(extractCallback->PrepareOperation(askMode));    currentItemUnPacked = item.UnPackSize;    currentItemPacked = item.PackSize;    CInStreamReleaser inStreamReleaser;    {      COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;      CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);      outStreamSpec->Init(realOutStream);      realOutStream.Release();            CMyComPtr<ISequentialInStream> inStream;      inStream.Attach(m_Archive.CreateLimitedStream(item.GetDataPosition(),          item.PackSize));      CLocalProgress *localProgressSpec = new CLocalProgress;      CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;      localProgressSpec->Init(extractCallback, false);      CLocalCompressProgressInfo *localCompressProgressSpec =           new CLocalCompressProgressInfo;      CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;      localCompressProgressSpec->Init(progress,           &currentTotalPacked,          &currentTotalUnPacked);      if (item.IsEncrypted())      {        if (!cryptoDecoder)        {          cryptoDecoderSpec = new NCrypto::NZip::CDecoder;          cryptoDecoder = cryptoDecoderSpec;        }        CMyComPtr<ICryptoSetPassword> cryptoSetPassword;        RINOK(cryptoDecoder.QueryInterface(            IID_ICryptoSetPassword, &cryptoSetPassword));        if (!getTextPassword)          extractCallback.QueryInterface(              IID_ICryptoGetTextPassword, &getTextPassword);        if (getTextPassword)        {          CMyComBSTR password;          RINOK(getTextPassword->CryptoGetTextPassword(&password));          AString anOemPassword = UnicodeStringToMultiByte(              (const wchar_t *)password, CP_OEMCP);          RINOK(cryptoSetPassword->CryptoSetPassword(              (const Byte *)(const char *)anOemPassword, anOemPassword.Length()));        }        else        {          RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));        }      }      int m;      for (m = 0; m < methodItems.Size(); m++)        if (methodItems[m].ZipMethod == item.CompressionMethod)          break;      if (m == methodItems.Size())      {        CMethodItem mi;        mi.ZipMethod = (Byte)item.CompressionMethod;        if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored)          mi.Coder = new NCompress::CCopyCoder;        else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kShrunk)          mi.Coder = new NCompress::NShrink::CDecoder;        else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kImploded)          mi.Coder = new NCompress::NImplode::NDecoder::CCoder;        else        {        #ifdef EXCLUDE_COM        switch(item.CompressionMethod)        {          case NFileHeader::NCompressionMethod::kDeflated:            mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder;            break;          case NFileHeader::NCompressionMethod::kDeflated64:            mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder64;            break;          case NFileHeader::NCompressionMethod::kBZip2:            mi.Coder = new NCompress::NBZip2::CDecoder;            break;          default:            RINOK(extractCallback->SetOperationResult(              NArchive::NExtract::NOperationResult::kUnSupportedMethod));            continue;        }        #else        N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 };        methodID.ID[2] = mi.ZipMethod;        if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored)        {          methodID.ID[0] = 0;          methodID.IDSize = 1;        }        else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kBZip2)        {          methodID.ID[1] = 0x02;          methodID.ID[2] = 0x02;        }                 N7z::CMethodInfo methodInfo;        if (!N7z::GetMethodInfo(methodID, methodInfo))        {          RINOK(extractCallback->SetOperationResult(              NArchive::NExtract::NOperationResult::kUnSupportedMethod));          continue;        }        RINOK(libraries.CreateCoder(methodInfo.FilePath,               methodInfo.Decoder, &mi.Coder));        #endif        }        m = methodItems.Add(mi);      }      ICompressCoder *coder = methodItems[m].Coder;      {        CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;        coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);        if (setDecoderProperties)        {          Byte properties = (Byte)item.Flags;          RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));        }      }      #ifdef COMPRESS_MT      {        CMyComPtr<ICompressSetCoderMt> setCoderMt;        coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);        if (setCoderMt)        {          RINOK(setCoderMt->SetNumberOfThreads(_numThreads));        }      }      #endif      // case NFileHeader::NCompressionMethod::kImploded:      // switch(item.CompressionMethod)      try      {        HRESULT result;        CMyComPtr<ISequentialInStream> inStreamNew;        if (item.IsEncrypted())        {          if (!filterStream)          {            filterStreamSpec = new CFilterCoder;            filterStream = filterStreamSpec;            filterStreamSpec->Filter = cryptoDecoder;          }          RINOK(cryptoDecoderSpec->ReadHeader(inStream));          RINOK(filterStreamSpec->SetInStream(inStream));          inStreamReleaser.FilterCoder = filterStreamSpec;          /*          switch(item.CompressionMethod)          {            case NFileHeader::NCompressionMethod::kStored:              mixerCoderSpec->SetCoderInfo(0, &currentItemPacked,                 &currentItemUnPacked);              mixerCoderSpec->SetCoderInfo(1, NULL, NULL);              break;            default:              mixerCoderSpec->SetCoderInfo(0, &currentItemPacked, NULL);              mixerCoderSpec->SetCoderInfo(1, NULL, &currentItemUnPacked);              break;          }          */          inStreamNew = filterStream;         }        else        {          inStreamNew = inStream;         }        result = coder->Code(inStreamNew, outStream,          NULL, &currentItemUnPacked, compressProgress);        if (result == S_FALSE)          throw "data error";        if (result != S_OK)          return result;      }      catch(...)      {        outStream.Release();        RINOK(extractCallback->SetOperationResult(          NArchive::NExtract::NOperationResult::kDataError));        continue;      }      bool crcOK = outStreamSpec->GetCRC() == item.FileCRC;      outStream.Release();      RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK :          NArchive::NExtract::NOperationResult::kCRCError))    }  }  return S_OK;  COM_TRY_END}}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -