Exemplo n.º 1
0
HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
  m_CryptoMode = false;
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition));
  m_Position = m_StreamStartPosition;

  UInt64 arcStartPos;
  RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
      searchHeaderSizeLimit, arcStartPos));
  m_Position = arcStartPos + NHeader::kMarkerSize;
  RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL));
  Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1];

  RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize));
  AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize);


  UInt32 blockSize = Get16(buf + 5);

  _header.EncryptVersion = 0;
  _header.Flags = Get16(buf + 3);

  UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize;
  if (_header.IsThereEncryptVer())
  {
    if (blockSize <= headerSize)
      return S_FALSE;
    RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1));
    AddToSeekValue(1);
    _header.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize];
    headerSize += 1;
  }
  if (blockSize < headerSize ||
      buf[2] != NHeader::NBlockType::kArchiveHeader ||
      (UInt32)Get16(buf) != (CrcCalc(buf + 2, headerSize - 2) & 0xFFFF))
    return S_FALSE;

  size_t commentSize = blockSize - headerSize; 
  _comment.SetCapacity(commentSize);
  RINOK(ReadStream_FALSE(stream, _comment, commentSize));
  AddToSeekValue(commentSize);
  m_Stream = stream;
  _header.StartPosition = arcStartPos;
  return S_OK;
}
Exemplo n.º 2
0
Arquivo: CabIn.cpp Projeto: bks/qz7
HRESULT CInArchive::Open2(IInStream *stream,
    const UInt64 *searchHeaderSizeLimit,
    CDatabase &database)
{
  database.Clear();
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));

  RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
      searchHeaderSizeLimit, database.StartPosition));

  RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
  if (!inBuffer.Create(1 << 17))
    return E_OUTOFMEMORY;
  inBuffer.SetStream(stream);
  inBuffer.Init();

  CInArchiveInfo &archiveInfo = database.ArchiveInfo;

  archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes
  if (ReadUInt32() != 0)
    return S_FALSE;
  archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry
  if (ReadUInt32() != 0)
    return S_FALSE;

  archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
  archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
  archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
  archiveInfo.NumFiles  = ReadUInt16(); // number of CFFILE entries in this cabinet
  archiveInfo.Flags = ReadUInt16();
  if (archiveInfo.Flags > 7)
    return S_FALSE;
  archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
  archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set

  if (archiveInfo.ReserveBlockPresent())
  {
    archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
    archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
    archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area

    Skeep(archiveInfo.PerCabinetAreaSize);
  }

  {
    if (archiveInfo.IsTherePrev())
      ReadOtherArchive(archiveInfo.PreviousArchive);
    if (archiveInfo.IsThereNext())
      ReadOtherArchive(archiveInfo.NextArchive);
  }
  
  int i;
  for(i = 0; i < archiveInfo.NumFolders; i++)
  {
    CFolder folder;

    folder.DataStart = ReadUInt32();
    folder.NumDataBlocks = ReadUInt16();
    folder.CompressionTypeMajor = ReadByte();
    folder.CompressionTypeMinor = ReadByte();

    Skeep(archiveInfo.PerFolderAreaSize);
    database.Folders.Add(folder);
  }
  
  RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));

  inBuffer.SetStream(stream);
  inBuffer.Init();
  for(i = 0; i < archiveInfo.NumFiles; i++)
  {
    CItem item;
    item.Size = ReadUInt32();
    item.Offset = ReadUInt32();
    item.FolderIndex = ReadUInt16();
    UInt16 pureDate = ReadUInt16();
    UInt16 pureTime = ReadUInt16();
    item.Time = ((UInt32(pureDate) << 16)) | pureTime;
    item.Attributes = ReadUInt16();
    item.Name = SafeReadName();
    int folderIndex = item.GetFolderIndex(database.Folders.Size());
    if (folderIndex >= database.Folders.Size())
      return S_FALSE;
    database.Items.Add(item);
  }
  return S_OK;
}
Exemplo n.º 3
0
HRESULT CInArchive::Open2(IInStream *stream,
    const UInt64 *searchHeaderSizeLimit,
    CDatabase &database)
{
  database.Clear();
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));

  RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
      searchHeaderSizeLimit, database.StartPosition));

  RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
  if (!inBuffer.Create(1 << 17))
    return E_OUTOFMEMORY;
  inBuffer.SetStream(stream);
  inBuffer.Init();

  CInArchiveInfo &ai = database.ArchiveInfo;

  ai.Size = ReadUInt32();
  if (ReadUInt32() != 0)
    return S_FALSE;
  ai.FileHeadersOffset = ReadUInt32();
  if (ReadUInt32() != 0)
    return S_FALSE;

  ai.VersionMinor = ReadByte();
  ai.VersionMajor = ReadByte();
  ai.NumFolders = ReadUInt16();
  ai.NumFiles = ReadUInt16();
  ai.Flags = ReadUInt16();
  if (ai.Flags > 7)
    return S_FALSE;
  ai.SetID = ReadUInt16();
  ai.CabinetNumber = ReadUInt16();

  if (ai.ReserveBlockPresent())
  {
    ai.PerCabinetAreaSize = ReadUInt16();
    ai.PerFolderAreaSize = ReadByte();
    ai.PerDataBlockAreaSize = ReadByte();

    Skip(ai.PerCabinetAreaSize);
  }

  {
    if (ai.IsTherePrev())
      ReadOtherArchive(ai.PreviousArchive);
    if (ai.IsThereNext())
      ReadOtherArchive(ai.NextArchive);
  }
  
  int i;
  for (i = 0; i < ai.NumFolders; i++)
  {
    CFolder folder;

    folder.DataStart = ReadUInt32();
    folder.NumDataBlocks = ReadUInt16();
    folder.CompressionTypeMajor = ReadByte();
    folder.CompressionTypeMinor = ReadByte();

    Skip(ai.PerFolderAreaSize);
    database.Folders.Add(folder);
  }
  
  RINOK(stream->Seek(database.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));

  inBuffer.SetStream(stream);
  inBuffer.Init();
  for (i = 0; i < ai.NumFiles; i++)
  {
    CItem item;
    item.Size = ReadUInt32();
    item.Offset = ReadUInt32();
    item.FolderIndex = ReadUInt16();
    UInt16 pureDate = ReadUInt16();
    UInt16 pureTime = ReadUInt16();
    item.Time = ((UInt32(pureDate) << 16)) | pureTime;
    item.Attributes = ReadUInt16();
    item.Name = SafeReadName();
    int folderIndex = item.GetFolderIndex(database.Folders.Size());
    if (folderIndex >= database.Folders.Size())
      return S_FALSE;
    database.Items.Add(item);
  }
  return S_OK;
}