HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { _inBufMode = false; Close(); RINOK(stream->Seek(0, STREAM_SEEK_CUR, &m_Position)); RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileEndPos)); RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); // printf("\nOpen offset = %d", (int)m_Position); RINOK(FindAndReadMarker(stream, searchHeaderSizeLimit)); RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); Stream = stream; return S_OK; }
bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) { if (!FindAndReadMarker(searchHeaderSizeLimit)) return false; Byte buf[NHeader::NArchive::kArchiveHeaderSize]; UInt32 processedSize; ReadBytes(buf, sizeof(buf), &processedSize); if (processedSize != sizeof(buf)) return false; m_CurData = buf; m_CurPos = 0; m_PosLimit = sizeof(buf); m_ArchiveHeader.CRC = ReadUInt16(); m_ArchiveHeader.Type = ReadByte(); m_ArchiveHeader.Flags = ReadUInt16(); m_ArchiveHeader.Size = ReadUInt16(); m_ArchiveHeader.Reserved1 = ReadUInt16(); m_ArchiveHeader.Reserved2 = ReadUInt32(); m_ArchiveHeader.EncryptVersion = 0; UInt32 crc = CRC_INIT_VAL; crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.Type); crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Flags); crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Size); crc = CrcUpdateUInt16(crc, m_ArchiveHeader.Reserved1); crc = CrcUpdateUInt32(crc, m_ArchiveHeader.Reserved2); if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) { ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); if (processedSize != 1) return false; crc = CRC_UPDATE_BYTE(crc, m_ArchiveHeader.EncryptVersion); } if(m_ArchiveHeader.CRC != (CRC_GET_DIGEST(crc) & 0xFFFF)) ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) return false; m_ArchiveCommentPosition = m_Position; m_SeekOnArchiveComment = true; return true; }