Example #1
0
HRESULT CHandler::Open2(IInStream *stream)
{
  UInt64 archiveStartPos;
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &archiveStartPos));

  const UInt32 kHeaderSize = 0x1C;
  Byte buf[kHeaderSize];
  RINOK(ReadStream_FALSE(stream, buf, kHeaderSize));

  UInt32 size = Get16(buf + 4);
  // UInt32 ver = Get16(buf + 6); // == 0
  if (Get32(buf) != 0x78617221 || size != kHeaderSize)
    return S_FALSE;

  UInt64 packSize = Get64(buf + 8);
  UInt64 unpackSize = Get64(buf + 0x10);
  // UInt32 checkSumAlogo = Get32(buf + 0x18);

  if (unpackSize >= kXmlSizeMax)
    return S_FALSE;

  _dataStartPos = archiveStartPos + kHeaderSize + packSize;

  char *ss = _xml.GetBuffer((int)unpackSize + 1);

  NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder();
  CMyComPtr<ICompressCoder> zlibCoder = zlibCoderSpec;

  CLimitedSequentialInStream *inStreamLimSpec = new CLimitedSequentialInStream;
  CMyComPtr<ISequentialInStream> inStreamLim(inStreamLimSpec);
  inStreamLimSpec->SetStream(stream);
  inStreamLimSpec->Init(packSize);

  CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream;
  CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec);
  outStreamLimSpec->Init((Byte *)ss, (size_t)unpackSize);

  RINOK(zlibCoder->Code(inStreamLim, outStreamLim, NULL, NULL, NULL));

  if (outStreamLimSpec->GetPos() != (size_t)unpackSize)
    return S_FALSE;

  ss[(size_t)unpackSize] = 0;
  _xml.ReleaseBuffer();

  CXml xml;
  if (!xml.Parse(_xml))
    return S_FALSE;

  if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1)
    return S_FALSE;
  const CXmlItem &toc = xml.Root.SubItems[0];
  if (!toc.IsTagged("toc"))
    return S_FALSE;
  if (!AddItem(toc, _files, -1))
    return S_FALSE;
  return S_OK;
}
Example #2
0
HRESULT CInArchive::ReadAndDecodePackedStreams(
    DECL_EXTERNAL_CODECS_LOC_VARS
    UInt64 baseOffset,
    UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
    #ifndef _NO_CRYPTO
    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    #endif
    )
{
  CRecordVector<UInt64> packSizes;
  CBoolVector packCRCsDefined;
  CRecordVector<UInt32> packCRCs;
  CObjectVector<CFolder> folders;
  
  CRecordVector<CNum> numUnpackStreamsInFolders;
  CRecordVector<UInt64> unpackSizes;
  CBoolVector digestsDefined;
  CRecordVector<UInt32> digests;
  
  ReadStreamsInfo(NULL,
    dataOffset,
    packSizes,
    packCRCsDefined,
    packCRCs,
    folders,
    numUnpackStreamsInFolders,
    unpackSizes,
    digestsDefined,
    digests);
  
  // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
  
  CNum packIndex = 0;
  CDecoder decoder(
    #ifdef _ST_MODE
    false
    #else
    true
    #endif
    );
  UInt64 dataStartPos = baseOffset + dataOffset;
  for (int i = 0; i < folders.Size(); i++)
  {
    const CFolder &folder = folders[i];
    dataVector.Add(CByteBuffer());
    CByteBuffer &data = dataVector.Back();
    UInt64 unpackSize64 = folder.GetUnpackSize();
    size_t unpackSize = (size_t)unpackSize64;
    if (unpackSize != unpackSize64)
      ThrowUnsupported();
    data.SetCapacity(unpackSize);
    
    CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
    CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
    outStreamSpec->Init(data, unpackSize);
    
    HRESULT result = decoder.Decode(
      EXTERNAL_CODECS_LOC_VARS
      _stream, dataStartPos,
      &packSizes[packIndex], folder, outStream, NULL
      #ifndef _NO_CRYPTO
      , getTextPassword, passwordIsDefined
      #endif
      #if !defined(_7ZIP_ST) && !defined(_SFX)
      , false, 1
      #endif
      );
    RINOK(result);
    
    if (folder.UnpackCRCDefined)
      if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
        ThrowIncorrect();
    for (int j = 0; j < folder.PackStreams.Size(); j++)
    {
      UInt64 packSize = packSizes[packIndex++];
      dataStartPos += packSize;
      HeadersSize += packSize;
    }
  }
  return S_OK;
}
Example #3
0
HRESULT CHandler::Open2(IInStream *stream)
{
  const UInt32 kHeaderSize = 0x1C;
  Byte buf[kHeaderSize];
  RINOK(ReadStream_FALSE(stream, buf, kHeaderSize));

  UInt32 size = Get16(buf + 4);
  // UInt32 ver = Get16(buf + 6); // == 1
  if (Get32(buf) != 0x78617221 || size != kHeaderSize)
    return S_FALSE;

  UInt64 packSize = Get64(buf + 8);
  UInt64 unpackSize = Get64(buf + 0x10);

  // _checkSumAlgo = Get32(buf + 0x18);

  if (packSize >= kXmlPackSizeMax ||
      unpackSize >= kXmlSizeMax)
    return S_FALSE;

  _dataStartPos = kHeaderSize + packSize;
  _phySize = _dataStartPos;

  _xml.Alloc((size_t)unpackSize + 1);
  _xmlLen = (size_t)unpackSize;
  
  NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder();
  CMyComPtr<ICompressCoder> zlibCoder = zlibCoderSpec;

  CLimitedSequentialInStream *inStreamLimSpec = new CLimitedSequentialInStream;
  CMyComPtr<ISequentialInStream> inStreamLim(inStreamLimSpec);
  inStreamLimSpec->SetStream(stream);
  inStreamLimSpec->Init(packSize);

  CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream;
  CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec);
  outStreamLimSpec->Init(_xml, (size_t)unpackSize);

  RINOK(zlibCoder->Code(inStreamLim, outStreamLim, NULL, NULL, NULL));

  if (outStreamLimSpec->GetPos() != (size_t)unpackSize)
    return S_FALSE;

  _xml[(size_t)unpackSize] = 0;
  if (strlen((const char *)(const Byte *)_xml) != unpackSize) return S_FALSE;

  CXml xml;
  if (!xml.Parse((const char *)(const Byte *)_xml))
    return S_FALSE;
  
  if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1)
    return S_FALSE;
  const CXmlItem &toc = xml.Root.SubItems[0];
  if (!toc.IsTagged("toc"))
    return S_FALSE;
  if (!AddItem(toc, _files, -1))
    return S_FALSE;

  UInt64 totalPackSize = 0;
  unsigned numMainFiles = 0;
  
  FOR_VECTOR (i, _files)
  {
    const CFile &file = _files[i];
    file.UpdateTotalPackSize(totalPackSize);
    if (file.Name == "Payload" || file.Name == "Content")
    {
      _mainSubfile = i;
      numMainFiles++;
    }
    else if (file.Name == "PackageInfo")
      _is_pkg = true;
  }

  if (numMainFiles > 1)
    _mainSubfile = -1;
  
  _phySize = _dataStartPos + totalPackSize;

  return S_OK;
}