bool AtomMDHD::ReadDataVersion1() { if (!ReadUInt64(_creationTime)) { FATAL("Unable to read creation time"); return false; } if (!ReadUInt64(_modificationTime)) { FATAL("Unable to read modification time"); return false; } if (!ReadUInt32(_timeScale)) { FATAL("Unable to read time scale"); return false; } if (!ReadUInt64(_duration)) { FATAL("Unable to read duration"); return false; } if (!ReadUInt16(_language)) { FATAL("Unable to read language"); return false; } if (!ReadUInt16(_quality)) { FATAL("Unable to read quality"); return false; } return true; }
uint64 CFileDataIO::GetIntTagValue() const { uint8 type = ReadUInt8(); ReadString(false); switch (type) { case TAGTYPE_UINT64: return ReadUInt64(); break; case TAGTYPE_UINT32: return ReadUInt32(); break; case TAGTYPE_UINT16: return ReadUInt16(); break; case TAGTYPE_UINT8: return ReadUInt8(); break; default: throw wxString(wxT("Wrong tag type reading int tag")); } }
bool AtomELST::ReadData() { uint32_t count = 0; if (!ReadUInt32(count)) { FATAL("Unable to read elst entries count"); return false; } //FINEST("-------"); ELSTEntry entry; for (uint32_t i = 0; i < count; i++) { if (_version == 1) { if (!ReadUInt64(entry.value._64.segmentDuration)) { FATAL("Unable to read elst atom"); return false; } if (!ReadUInt64(entry.value._64.mediaTime)) { FATAL("Unable to read elst atom"); return false; } } else { if (!ReadUInt32(entry.value._32.segmentDuration)) { FATAL("Unable to read elst atom"); return false; } if (!ReadUInt32(entry.value._32.mediaTime)) { FATAL("Unable to read elst atom"); return false; } } if (!ReadUInt16(entry.mediaRateInteger)) { FATAL("Unable to read elst atom"); return false; } if (!ReadUInt16(entry.mediaRateFraction)) { FATAL("Unable to read elst atom"); return false; } // FINEST("version: %"PRIu8"; segmentDuration: %"PRIu32"; mediaTime: %"PRIu32"; mediaRateInteger: %"PRIu16"; mediaRateFraction: %"PRIu16, // _version, // entry.value._32.segmentDuration, // entry.value._32.mediaTime, // entry.mediaRateInteger, // entry.mediaRateFraction); _entries.push_back(entry); } return SkipRead(false); }
bool AtomAFRT::ReadData() { //FINEST("AFRT"); if (!ReadUInt32(_timeScale)) { FATAL("Unable to read _timeScale"); return false; } //FINEST("_timeScale: %"PRIu32, _timeScale); if (!ReadUInt8(_qualityEntryCount)) { FATAL("Unable to read _qualityEntryCount"); return false; } //FINEST("_qualityEntryCount: %"PRIu8, _qualityEntryCount); for (uint8_t i = 0; i < _qualityEntryCount; i++) { string temp; if (!ReadNullTerminatedString(temp)) { FATAL("Unable to read QualitySegmentUrlModifiers"); return false; } //FINEST("%"PRIu8": QualitySegmentUrlModifiers: %s", i, STR(temp)); ADD_VECTOR_END(_qualitySegmentUrlModifiers, temp); } if (!ReadUInt32(_fragmentRunEntryCount)) { FATAL("Unable to read _fragmentRunEntryCount"); return false; } //FINEST("_fragmentRunEntryCount: %"PRIu32, _fragmentRunEntryCount); for (uint32_t i = 0; i < _fragmentRunEntryCount; i++) { FRAGMENTRUNENTRY temp = {0, 0, 0, 0}; if (!ReadUInt32(temp.firstFragment)) { FATAL("Unable to read FRAGMENTRUNENTRY.FirstFragment"); return false; } if (!ReadUInt64(temp.firstFragmentTimestamp)) { FATAL("Unable to read FRAGMENTRUNENTRY.FirstFragmentTimestamp"); return false; } if (!ReadUInt32(temp.fragmentDuration)) { FATAL("Unable to read FRAGMENTRUNENTRY.FragmentDuration"); return false; } if (temp.fragmentDuration == 0) { if (!ReadUInt8(temp.discontinuityIndicator)) { FATAL("Unable to read FRAGMENTRUNENTRY.DiscontinuityIndicator"); return false; } } //FINEST("%"PRIu32": FRAGMENTRUNENTRY.FirstFragment: %"PRIu32"; FRAGMENTRUNENTRY.FirstFragmentTimestamp: %"PRIu64"; FRAGMENTRUNENTRY.FragmentDuration: %"PRIu32"; FRAGMENTRUNENTRY.DiscontinuityIndicator: %"PRIu8, // i, temp.firstFragment, temp.firstFragmentTimestamp, temp.fragmentDuration, temp.discontinuityIndicator); ADD_VECTOR_END(_fragmentRunEntryTable, temp); } return true; }
void NgramVector::Deserialize(FILE *inFile) { _length = ReadUInt64(inFile); ReadVector(inFile, _words); ReadVector(inFile, _hists); _Reindex(nextPowerOf2(_length + _length / 4)); // Build truncated view into words and hists. _wordsView.attach(_words); _histsView.attach(_hists); }
void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, CUInt64DefVector &v, int numFiles) { ReadBoolVector2(numFiles, v.Defined); CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); v.Values.Reserve(numFiles); for (int i = 0; i < numFiles; i++) { UInt64 t = 0; if (v.Defined[i]) t = ReadUInt64(); v.Values.Add(t); } }
bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) { extraBlock.Clear(); UInt32 remain = extraSize; while (remain >= 4) { CExtraSubBlock subBlock; subBlock.ID = ReadUInt16(); unsigned dataSize = ReadUInt16(); remain -= 4; if (dataSize > remain) // it's bug { HeadersWarning = true; Skip(remain); return false; } if (subBlock.ID == NFileHeader::NExtraID::kZip64) { if (unpackSize == 0xFFFFFFFF) { if (dataSize < 8) { HeadersWarning = true; Skip(remain); return false; } unpackSize = ReadUInt64(); remain -= 8; dataSize -= 8; } if (packSize == 0xFFFFFFFF) { if (dataSize < 8) break; packSize = ReadUInt64(); remain -= 8; dataSize -= 8; } if (localHeaderOffset == 0xFFFFFFFF) { if (dataSize < 8) break; localHeaderOffset = ReadUInt64(); remain -= 8; dataSize -= 8; } if (diskStartNumber == 0xFFFF) { if (dataSize < 4) break; diskStartNumber = ReadUInt32(); remain -= 4; dataSize -= 4; } Skip(dataSize); } else { ReadBuffer(subBlock.Data, dataSize); extraBlock.SubBlocks.Add(subBlock); } remain -= dataSize; } if (remain != 0) { ExtraMinorError = true; // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers. // so we don't return false, but just set warning flag // return false; } Skip(remain); return true; }
CTag *CFileDataIO::ReadTag(bool bOptACP) const { CTag *retVal = NULL; wxString name; byte type = 0; try { type = ReadUInt8(); name = ReadString(false); switch (type) { // NOTE: This tag data type is accepted and stored only to give us the possibility to upgrade // the net in some months. // // And still.. it doesnt't work this way without breaking backward compatibility. To properly // do this without messing up the network the following would have to be done: // - those tag types have to be ignored by any client, otherwise those tags would also be sent (and // that's really the problem) // // - ignoring means, each client has to read and right throw away those tags, so those tags get // get never stored in any tag list which might be sent by that client to some other client. // // - all calling functions have to be changed to deal with the 'nr. of tags' attribute (which was // already parsed) correctly.. just ignoring those tags here is not enough, any taglists have to // be built with the knowledge that the 'nr. of tags' attribute may get decreased during the tag // reading.. // // If those new tags would just be stored and sent to remote clients, any malicious or just bugged // client could let send a lot of nodes "corrupted" packets... // case TAGTYPE_HASH16: { retVal = new CTagHash(name, ReadHash()); break; } case TAGTYPE_STRING: retVal = new CTagString(name, ReadString(bOptACP)); break; case TAGTYPE_UINT64: retVal = new CTagInt64(name, ReadUInt64()); break; case TAGTYPE_UINT32: retVal = new CTagInt32(name, ReadUInt32()); break; case TAGTYPE_UINT16: retVal = new CTagInt16(name, ReadUInt16()); break; case TAGTYPE_UINT8: retVal = new CTagInt8(name, ReadUInt8()); break; case TAGTYPE_FLOAT32: retVal = new CTagFloat(name, ReadFloat()); break; // NOTE: This tag data type is accepted and stored only to give us the possibility to upgrade // the net in some months. // // And still.. it doesnt't work this way without breaking backward compatibility case TAGTYPE_BSOB: { uint8 size = 0; CScopedArray<unsigned char> value(ReadBsob(&size)); retVal = new CTagBsob(name, value.get(), size); break; } default: throw wxString(CFormat(wxT("Invalid Kad tag type; type=0x%02x name=%s\n")) % type % name); } } catch(const CMuleException& e) { AddLogLineN(e.what()); delete retVal; throw; } catch(const wxString& e) { AddLogLineN(e); throw; } return retVal; }
bool CXBTFReader::Open(const std::string& path) { if (path.empty()) return false; m_path = path; #ifdef TARGET_WINDOWS std::wstring strPathW; g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(m_path), strPathW, false); m_file = _wfopen(strPathW.c_str(), L"rb"); #else m_file = fopen(m_path.c_str(), "rb"); #endif if (m_file == nullptr) return false; // read the magic word char magic[4]; if (!ReadString(m_file, magic, sizeof(magic))) return false; if (strncmp(XBTF_MAGIC.c_str(), magic, sizeof(magic)) != 0) return false; // read the version char version[1]; if (!ReadString(m_file, version, sizeof(version))) return false; if (strncmp(XBTF_VERSION.c_str(), version, sizeof(version)) != 0) return false; unsigned int nofFiles; if (!ReadUInt32(m_file, nofFiles)) return false; for (uint32_t i = 0; i < nofFiles; i++) { CXBTFFile xbtfFile; uint32_t u32; uint64_t u64; char path[CXBTFFile::MaximumPathLength]; memset(path, 0, sizeof(path)); if (!ReadString(m_file, path, sizeof(path))) return false; xbtfFile.SetPath(path); if (!ReadUInt32(m_file, u32)) return false; xbtfFile.SetLoop(u32); unsigned int nofFrames; if (!ReadUInt32(m_file, nofFrames)) return false; for (uint32_t j = 0; j < nofFrames; j++) { CXBTFFrame frame; if (!ReadUInt32(m_file, u32)) return false; frame.SetWidth(u32); if (!ReadUInt32(m_file, u32)) return false; frame.SetHeight(u32); if (!ReadUInt32(m_file, u32)) return false; frame.SetFormat(u32); if (!ReadUInt64(m_file, u64)) return false; frame.SetPackedSize(u64); if (!ReadUInt64(m_file, u64)) return false; frame.SetUnpackedSize(u64); if (!ReadUInt32(m_file, u32)) return false; frame.SetDuration(u32); if (!ReadUInt64(m_file, u64)) return false; frame.SetOffset(u64); xbtfFile.GetFrames().push_back(frame); } AddFile(xbtfFile); } // Sanity check uint64_t pos = static_cast<uint64_t>(ftell(m_file)); if (pos != GetHeaderSize()) return false; return true; }
int64_t BinaryReader::ReadInt64() { return (int64_t)ReadUInt64(); }
double BinaryReader::ReadDouble() { uint64_t value = ReadUInt64(); return *(double*)&value; }
HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) { if (ReadUInt32() != 1) // version return S_FALSE; if (ReadUInt32() != 0x28) // Location of header section table return S_FALSE; UInt32 numHeaderSections = ReadUInt32(); const unsigned kNumHeaderSectionsMax = 5; if (numHeaderSections != kNumHeaderSectionsMax) return S_FALSE; IsArc = true; ReadUInt32(); // Len of post-header table Byte g[16]; ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} // header section table UInt64 sectionOffsets[kNumHeaderSectionsMax]; UInt64 sectionSizes[kNumHeaderSectionsMax]; UInt32 i; for (i = 0; i < numHeaderSections; i++) { sectionOffsets[i] = ReadUInt64(); sectionSizes[i] = ReadUInt64(); UInt64 end = sectionOffsets[i] + sectionSizes[i]; database.UpdatePhySize(end); } // Post-Header ReadUInt32(); // 2 ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header) // ----- Directory information ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1 ReadUInt64(); // Chunk number of first AOLL chunk in directory ReadUInt64(); // Chunk number of last AOLL chunk in directory ReadUInt64(); // 0 (unknown) ReadUInt32(); // $2000 (Directory chunk size of directory) ReadUInt32(); // Quickref density for main directory, usually 2 ReadUInt32(); // 0 (unknown) ReadUInt32(); // Depth of main directory index tree // 1 there is no index, 2 if there is one level of AOLI chunks. ReadUInt64(); // 0 (unknown) UInt64 numDirEntries = ReadUInt64(); // Number of directory entries // ----- Directory Index Information ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index) ReadUInt64(); // Chunk number of first AOLL chunk in directory index ReadUInt64(); // Chunk number of last AOLL chunk in directory index ReadUInt64(); // 0 (unknown) ReadUInt32(); // $200 (Directory chunk size of directory index) ReadUInt32(); // Quickref density for directory index, usually 2 ReadUInt32(); // 0 (unknown) ReadUInt32(); // Depth of directory index index tree. ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0. ReadUInt64(); // Number of directory index entries (same as number of AOLL // chunks in main directory) // (The obvious guess for the following two fields, which recur in a number // of places, is they are maximum sizes for the directory and directory index. // However, I have seen no direct evidence that this is the case.) ReadUInt32(); // $100000 (Same as field following chunk size in directory) ReadUInt32(); // $20000 (Same as field following chunk size in directory index) ReadUInt64(); // 0 (unknown) if (ReadUInt32() != kSignature_CAOL) return S_FALSE; if (ReadUInt32() != 2) // (Most likely a version number) return S_FALSE; UInt32 caolLength = ReadUInt32(); // $50 (Len of the CAOL section, which includes the ITSF section) if (caolLength >= 0x2C) { /* UInt32 c7 = */ ReadUInt16(); // Unknown. Remains the same when identical files are built. // Does not appear to be a checksum. Many files have // 'HH' (HTML Help?) here, indicating this may be a compiler ID // field. But at least one ITOL/ITLS compiler does not set this // field to a constant value. ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field) ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0. ReadUInt32(); // $2000 (Directory chunk size of directory) ReadUInt32(); // $200 (Directory chunk size of directory index) ReadUInt32(); // $100000 (Same as field following chunk size in directory) ReadUInt32(); // $20000 (Same as field following chunk size in directory index) ReadUInt32(); // 0 (unknown) ReadUInt32(); // 0 (Unknown) if (caolLength == 0x2C) { // fprintf(stdout, "\n !!!NewFormat\n"); // fflush(stdout); database.ContentOffset = 0; // maybe we must add database.StartPosition here? database.NewFormat = true; } else if (caolLength == 0x50) { ReadUInt32(); // 0 (Unknown) if (ReadUInt32() != kSignature_ITSF) return S_FALSE; if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3) return S_FALSE; if (ReadUInt32() != 0x20) // $20 (length of ITSF) return S_FALSE; UInt32 unknown = ReadUInt32(); if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; return S_FALSE; database.ContentOffset = database.StartPosition + ReadUInt64(); /* UInt32 timeStamp = */ ReadUInt32(); // A timestamp of some sort. // Considered as a big-endian DWORD, it appears to contain // seconds (MSB) and fractional seconds (second byte). // The third and fourth bytes may contain even more fractional // bits. The 4 least significant bits in the last byte are constant. /* UInt32 lang = */ ReadUInt32(); // BE? } else return S_FALSE; } // Section 0 ReadChunk(inStream, database.StartPosition + sectionOffsets[0], sectionSizes[0]); if (sectionSizes[0] < 0x18) return S_FALSE; if (ReadUInt32() != 0x01FE) return S_FALSE; ReadUInt32(); // unknown: 0 UInt64 fileSize = ReadUInt64(); database.UpdatePhySize(fileSize); ReadUInt32(); // unknown: 0 ReadUInt32(); // unknown: 0 // Section 1: The Directory Listing ReadChunk(inStream, database.StartPosition + sectionOffsets[1], sectionSizes[1]); if (ReadUInt32() != kSignature_IFCM) return S_FALSE; if (ReadUInt32() != 1) // (probably a version number) return S_FALSE; UInt32 dirChunkSize = ReadUInt32(); // $2000 if (dirChunkSize < 64) return S_FALSE; ReadUInt32(); // $100000 (unknown) ReadUInt32(); // -1 (unknown) ReadUInt32(); // -1 (unknown) UInt32 numDirChunks = ReadUInt32(); ReadUInt32(); // 0 (unknown, probably high word of above) for (UInt32 ci = 0; ci < numDirChunks; ci++) { UInt64 chunkPos = _inBuffer.GetProcessedSize(); if (ReadUInt32() == kSignature_AOLL) { UInt32 quickrefLength = ReadUInt32(); // Len of quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; ReadUInt64(); // Directory chunk number // This must match physical position in file, that is // the chunk size times the chunk number must be the // offset from the end of the directory header. ReadUInt64(); // Chunk number of previous listing chunk when reading // directory in sequence (-1 if first listing chunk) ReadUInt64(); // Chunk number of next listing chunk when reading // directory in sequence (-1 if last listing chunk) ReadUInt64(); // Number of first listing entry in this chunk ReadUInt32(); // 1 (unknown -- other values have also been seen here) ReadUInt32(); // 0 (unknown) unsigned numItems = 0; for (;;) { UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; UInt32 offsetLimit = dirChunkSize - quickrefLength; if (offset > offsetLimit) return S_FALSE; if (offset == offsetLimit) break; if (database.NewFormat) { UInt16 nameLen = ReadUInt16(); if (nameLen == 0) return S_FALSE; UString name; ReadUString((unsigned)nameLen, name); AString s; ConvertUnicodeToUTF8(name, s); Byte b = ReadByte(); s.Add_Space(); PrintByte(b, s); s.Add_Space(); UInt64 len = ReadEncInt(); // then number of items ? // then length ? // then some data (binary encoding?) while (len-- != 0) { b = ReadByte(); PrintByte(b, s); } database.NewFormatString += s; database.NewFormatString += "\r\n"; } else { RINOK(ReadDirEntry(database)); } numItems++; } Skip(quickrefLength - 2); if (ReadUInt16() != numItems) return S_FALSE; if (numItems > numDirEntries) return S_FALSE; numDirEntries -= numItems; } else Skip(dirChunkSize - 4); } return numDirEntries == 0 ? S_OK : S_FALSE; }
HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) { UInt32 headerSize = ReadUInt32(); if (headerSize != 0x60) return S_FALSE; database.PhySize = headerSize; UInt32 unknown1 = ReadUInt32(); if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file return S_FALSE; IsArc = true; /* UInt32 timeStamp = */ ReadUInt32(); // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and // fractional seconds (second byte). // The third and fourth bytes may contain even more fractional bits. // The 4 least significant bits in the last byte are constant. /* UInt32 lang = */ ReadUInt32(); Byte g[16]; ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} const unsigned kNumSections = 2; UInt64 sectionOffsets[kNumSections]; UInt64 sectionSizes[kNumSections]; unsigned i; for (i = 0; i < kNumSections; i++) { sectionOffsets[i] = ReadUInt64(); sectionSizes[i] = ReadUInt64(); UInt64 end = sectionOffsets[i] + sectionSizes[i]; database.UpdatePhySize(end); } // if (chmVersion == 3) database.ContentOffset = ReadUInt64(); /* else database.ContentOffset = database.StartPosition + 0x58 */ // Section 0 ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]); if (sectionSizes[0] < 0x18) return S_FALSE; if (ReadUInt32() != 0x01FE) return S_FALSE; ReadUInt32(); // unknown: 0 UInt64 fileSize = ReadUInt64(); database.UpdatePhySize(fileSize); ReadUInt32(); // unknown: 0 ReadUInt32(); // unknown: 0 // Section 1: The Directory Listing ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]); if (ReadUInt32() != kSignature_ITSP) return S_FALSE; if (ReadUInt32() != 1) // version return S_FALSE; /* UInt32 dirHeaderSize = */ ReadUInt32(); ReadUInt32(); // 0x0A (unknown) UInt32 dirChunkSize = ReadUInt32(); // $1000 if (dirChunkSize < 32) return S_FALSE; /* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2. /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, // 2 if there is one level of PMGI chunks. /* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none // (though at least one file has 0 despite there being no // index chunk, probably a bug.) /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk /* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk ReadUInt32(); // -1 (unknown) UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total) /* UInt32 windowsLangId = */ ReadUInt32(); ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC} ReadUInt32(); // 0x54 (This is the length again) ReadUInt32(); // -1 (unknown) ReadUInt32(); // -1 (unknown) ReadUInt32(); // -1 (unknown) for (UInt32 ci = 0; ci < numDirChunks; ci++) { UInt64 chunkPos = _inBuffer.GetProcessedSize(); if (ReadUInt32() == kSignature_PMGL) { // The quickref area is written backwards from the end of the chunk. // One quickref entry exists for every n entries in the file, where n // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk if (quickrefLength > dirChunkSize || quickrefLength < 2) return S_FALSE; ReadUInt32(); // Always 0 ReadUInt32(); // Chunk number of previous listing chunk when reading // directory in sequence (-1 if this is the first listing chunk) ReadUInt32(); // Chunk number of next listing chunk when reading // directory in sequence (-1 if this is the last listing chunk) unsigned numItems = 0; for (;;) { UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; UInt32 offsetLimit = dirChunkSize - quickrefLength; if (offset > offsetLimit) return S_FALSE; if (offset == offsetLimit) break; RINOK(ReadDirEntry(database)); numItems++; } Skip(quickrefLength - 2); unsigned rrr = ReadUInt16(); if (rrr != numItems) { // Lazarus 9-26-2 chm contains 0 here. if (rrr != 0) return S_FALSE; } } else Skip(dirChunkSize - 4); } return S_OK; }
bool AtomAFRA::ReadData() { //FINEST("AFRA"); if (!ReadUInt8(_flags)) { FATAL("Unable to read flags"); return false; } //FINEST("flags: %" PRIu8, _flags); if (!ReadUInt32(_timeScale)) { FATAL("Unable to read timeScale"); return false; } //FINEST("_timeScale: %" PRIu32, _timeScale); if (!ReadUInt32(_entryCount)) { FATAL("Unable to read entryCount"); return false; } //FINEST("_entryCount: %" PRIu32, _entryCount); bool longOffsets = (_flags >> 6)&0x01; bool longIds = (_flags >> 7)&0x01; bool globalEntries = (_flags >> 5)&0x01; for (uint32_t i = 0; i < _entryCount; i++) { AFRAENTRY temp = {0, 0}; if (!ReadUInt64(temp.time)) { FATAL("Unable to read AFRAENTRY.Time"); return false; } if (longOffsets) { if (!ReadUInt64(temp.offset)) { FATAL("Unable to read AFRAENTRY.Offset"); return false; } } else { uint32_t ui32; if (!ReadUInt32(ui32)) { FATAL("Unable to read AFRAENTRY.Offset"); return false; } temp.offset = ui32; } //FINEST("%" PRIu32 ": AFRAENTRY.Time: %" PRIu64 "; AFRAENTRY.Offset: %" PRIu64, i, temp.time, temp.offset); ADD_VECTOR_END(_localAccessEntries, temp); } if (globalEntries) { if (!ReadUInt32(_globalEntryCount)) { FATAL("Unable to read globalEntryCount"); return false; } for (uint32_t i = 0; i < _entryCount; i++) { GLOBALAFRAENTRY temp = {0, 0, 0, 0, 0}; if (!ReadUInt64(temp.time)) { FATAL("Unable to read AFRAENTRY.Time"); return false; } //Segment,fragment if (longIds) { if (!ReadUInt32(temp.segment)) { FATAL("Unable to read GLOBALAFRAENTRY.Segment"); return false; } if (!ReadUInt32(temp.fragment)) { FATAL("Unable to read GLOBALAFRAENTRY.Fragment"); return false; } } else { uint16_t ui16; if (!ReadUInt16(ui16)) { FATAL("Unable to read GLOBALAFRAENTRY.Segment"); return false; } temp.segment = ui16; if (!ReadUInt16(ui16)) { FATAL("Unable to read GLOBALAFRAENTRY.Fragment"); return false; } temp.fragment = ui16; } //AfraOffset, OffsetFromAfra if (longOffsets) { if (!ReadUInt64(temp.afraOffset)) { FATAL("Unable to read GLOBALAFRAENTRY.AfraOffset"); return false; } if (!ReadUInt64(temp.offsetFromAfra)) { FATAL("Unable to read GLOBALAFRAENTRY.OffsetFromAfra"); return false; } } else { uint32_t ui32; if (!ReadUInt32(ui32)) { FATAL("Unable to read GLOBALAFRAENTRY.AfraOffset"); return false; } temp.afraOffset = ui32; if (!ReadUInt32(ui32)) { FATAL("Unable to read GLOBALAFRAENTRY.OffsetFromAfra"); return false; } temp.offsetFromAfra = ui32; } // FINEST("%" PRIu32 ": GLOBALAFRAENTRY.Time: %" PRIu64 "; GLOBALAFRAENTRY.Segment: %" PRIu32 "; GLOBALAFRAENTRY.Fragment: %" PRIu32 "; GLOBALAFRAENTRY.AfraOffset: %" PRIu64 "; GLOBALAFRAENTRY.OffsetFromAfra: %" PRIu64, // i, temp.time, temp.segment, temp.fragment, temp.afraOffset, temp.offsetFromAfra); ADD_VECTOR_END(_globalAccessEntries, temp); } } //FINEST("%02" PRIx8 "; timeScale: %" PRIu32 "; entryCount: %" PRIu32 "; globalEntryCount: %" PRIu32, // _flags, _timeScale, _entryCount, _globalEntryCount); return true; }
HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *progress) { items.Clear(); // m_Signature must be kLocalFileHeader or kEcd // m_Position points to next byte after signature RINOK(Stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); if (!_inBuffer.Create(1 << 15)) return E_OUTOFMEMORY; _inBuffer.SetStream(Stream); bool needReadCd = true; bool localsWereRead = false; if (m_Signature == NSignature::kEcd) { // It must be empty archive or backware archive // we don't support backware archive still const unsigned kBufSize = kEcdSize - 4; Byte buf[kBufSize]; SafeReadBytes(buf, kBufSize); CEcd ecd; ecd.Parse(buf); // if (ecd.cdSize != 0) // Do we need also to support the case where empty zip archive with PK00 uses cdOffset = 4 ?? if (!ecd.IsEmptyArc()) return S_FALSE; ArcInfo.Base = ArcInfo.MarkerPos; needReadCd = false; IsArc = true; // check it: we need more tests? RINOK(Stream->Seek(ArcInfo.MarkerPos2 + 4, STREAM_SEEK_SET, &m_Position)); } UInt64 cdSize = 0, cdRelatOffset = 0, cdAbsOffset = 0; HRESULT res = S_OK; if (needReadCd) { CItemEx firstItem; // try { try { if (!ReadLocalItem(firstItem)) return S_FALSE; } catch(CUnexpectEnd &) { return S_FALSE; } IsArc = true; res = ReadCd(items, cdRelatOffset, cdSize, progress); if (res == S_OK) m_Signature = ReadUInt32(); } // catch() { res = S_FALSE; } if (res != S_FALSE && res != S_OK) return res; if (res == S_OK && items.Size() == 0) res = S_FALSE; if (res == S_OK) { // we can't read local items here to keep _inBufMode state firstItem.LocalHeaderPos = ArcInfo.MarkerPos2 - ArcInfo.Base; int index = FindItem(items, firstItem.LocalHeaderPos); if (index == -1) res = S_FALSE; else if (!AreItemsEqual(firstItem, items[index])) res = S_FALSE; ArcInfo.CdWasRead = true; ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos; } } CObjectVector<CItemEx> cdItems; bool needSetBase = false; unsigned numCdItems = items.Size(); if (res == S_FALSE) { // CD doesn't match firstItem so we clear items and read Locals. items.Clear(); localsWereRead = true; _inBufMode = false; ArcInfo.Base = ArcInfo.MarkerPos; RINOK(Stream->Seek(ArcInfo.MarkerPos2, STREAM_SEEK_SET, &m_Position)); m_Signature = ReadUInt32(); RINOK(ReadLocals(items, progress)); if (m_Signature != NSignature::kCentralFileHeader) { m_Position -= 4; NoCentralDir = true; HeadersError = true; return S_OK; } _inBufMode = true; _inBuffer.Init(); cdAbsOffset = m_Position - 4; for (;;) { CItemEx cdItem; RINOK(ReadCdItem(cdItem)); cdItems.Add(cdItem); if (progress && cdItems.Size() % 1 == 0) RINOK(progress->SetCompletedCD(items.Size())); m_Signature = ReadUInt32(); if (m_Signature != NSignature::kCentralFileHeader) break; } cdSize = (m_Position - 4) - cdAbsOffset; needSetBase = true; numCdItems = cdItems.Size(); if (!cdItems.IsEmpty()) { ArcInfo.CdWasRead = true; ArcInfo.FirstItemRelatOffset = cdItems[0].LocalHeaderPos; } } CEcd64 ecd64; bool isZip64 = false; UInt64 ecd64AbsOffset = m_Position - 4; if (m_Signature == NSignature::kEcd64) { IsZip64 = isZip64 = true; UInt64 recordSize = ReadUInt64(); const unsigned kBufSize = kEcd64_MainSize; Byte buf[kBufSize]; SafeReadBytes(buf, kBufSize); ecd64.Parse(buf); Skip64(recordSize - kEcd64_MainSize); m_Signature = ReadUInt32(); if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) return E_NOTIMPL; if (needSetBase) { ArcInfo.Base = cdAbsOffset - ecd64.cdStartOffset; cdRelatOffset = ecd64.cdStartOffset; needSetBase = false; } if (ecd64.numEntriesInCDOnThisDisk != numCdItems || ecd64.numEntriesInCD != numCdItems || ecd64.cdSize != cdSize || (ecd64.cdStartOffset != cdRelatOffset && (!items.IsEmpty()))) return S_FALSE; } if (m_Signature == NSignature::kEcd64Locator) { if (!isZip64) return S_FALSE; /* UInt32 startEndCDDiskNumber = */ ReadUInt32(); UInt64 ecd64RelatOffset = ReadUInt64(); /* UInt32 numberOfDisks = */ ReadUInt32(); if (ecd64AbsOffset != ArcInfo.Base + ecd64RelatOffset) return S_FALSE; m_Signature = ReadUInt32(); } if (m_Signature != NSignature::kEcd) return S_FALSE; const unsigned kBufSize = kEcdSize - 4; Byte buf[kBufSize]; SafeReadBytes(buf, kBufSize); CEcd ecd; ecd.Parse(buf); COPY_ECD_ITEM_16(thisDiskNumber); COPY_ECD_ITEM_16(startCDDiskNumber); COPY_ECD_ITEM_16(numEntriesInCDOnThisDisk); COPY_ECD_ITEM_16(numEntriesInCD); COPY_ECD_ITEM_32(cdSize); COPY_ECD_ITEM_32(cdStartOffset); if (needSetBase) { ArcInfo.Base = cdAbsOffset - ecd64.cdStartOffset; cdRelatOffset = ecd64.cdStartOffset; needSetBase = false; } if (localsWereRead && (UInt64)ArcInfo.Base != ArcInfo.MarkerPos) { UInt64 delta = ArcInfo.MarkerPos - ArcInfo.Base; for (unsigned i = 0; i < items.Size(); i++) items[i].LocalHeaderPos += delta; } // ---------- merge Central Directory Items ---------- if (!cdItems.IsEmpty()) { for (unsigned i = 0; i < cdItems.Size(); i++) { const CItemEx &cdItem = cdItems[i]; int index = FindItem(items, cdItem.LocalHeaderPos); if (index == -1) { items.Add(cdItem); continue; } CItemEx &item = items[index]; if (item.Name != cdItem.Name // || item.Name.Len() != cdItem.Name.Len() || item.PackSize != cdItem.PackSize || item.Size != cdItem.Size // item.ExtractVersion != cdItem.ExtractVersion || !FlagsAreSame(item, cdItem) || item.Crc != cdItem.Crc) continue; // item.LocalHeaderPos = cdItem.LocalHeaderPos; // item.Name = cdItem.Name; item.MadeByVersion = cdItem.MadeByVersion; item.CentralExtra = cdItem.CentralExtra; item.InternalAttrib = cdItem.InternalAttrib; item.ExternalAttrib = cdItem.ExternalAttrib; item.Comment = cdItem.Comment; item.FromCentral = cdItem.FromCentral; } } if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0) return E_NOTIMPL; if (isZip64) { if (ecd64.numEntriesInCDOnThisDisk != items.Size()) HeadersError = true; } else { // old 7-zip could store 32-bit number of CD items to 16-bit field. if ((UInt16)ecd64.numEntriesInCDOnThisDisk != (UInt16)numCdItems || (UInt16)ecd64.numEntriesInCDOnThisDisk != (UInt16)items.Size()) HeadersError = true; } ReadBuffer(ArcInfo.Comment, ecd.commentSize); _inBufMode = false; _inBuffer.Free(); if ( (UInt16)ecd64.numEntriesInCD != ((UInt16)numCdItems) || (UInt32)ecd64.cdSize != (UInt32)cdSize || ((UInt32)(ecd64.cdStartOffset) != (UInt32)cdRelatOffset && (!items.IsEmpty()))) return S_FALSE; // printf("\nOpen OK"); return S_OK; }
ID Packet::ReadID () { return ID (ReadUInt64 ()); }
bool AtomMVHD::ReadData() { if (_version == 1) { if (!ReadUInt64(_creationTime)) { FATAL("Unable to read creation time"); return false; } if (!ReadUInt64(_modificationTime)) { FATAL("Unable to read modification time"); return false; } } else { uint32_t temp; if (!ReadUInt32(temp)) { FATAL("Unable to read creation time"); return false; } _creationTime = temp; if (!ReadUInt32(temp)) { FATAL("Unable to read modification time"); return false; } _modificationTime = temp; } if (!ReadUInt32(_timeScale)) { FATAL("Unable to read time scale"); return false; } if (_version == 1) { if (!ReadUInt64(_duration)) { FATAL("Unable to read duration"); return false; } } else { uint32_t temp; if (!ReadUInt32(temp)) { FATAL("Unable to read duration"); return false; } _duration = temp; } if (!ReadUInt32(_preferredRate)) { FATAL("Unable to read preferred rate"); return false; } if (!ReadUInt16(_preferredVolume)) { FATAL("Unable to read preferred volume"); return false; } if (!ReadArray(_reserved, 10)) { FATAL("Unable to read reserved"); return false; } if (!ReadArray((uint8_t *) _matrixStructure, 36)) { FATAL("Unable to read matrix structure"); return false; } if (!ReadUInt32(_previewTime)) { FATAL("Unable to read preview time"); return false; } if (!ReadUInt32(_previewDuration)) { FATAL("Unable to read preview duration"); return false; } if (!ReadUInt32(_posterTime)) { FATAL("Unable to read poster time"); return false; } if (!ReadUInt32(_selectionTime)) { FATAL("Unable to read selection time"); return false; } if (!ReadUInt32(_selectionDuration)) { FATAL("Unable to read selection duration"); return false; } if (!ReadUInt32(_currentTime)) { FATAL("Unable to read current time"); return false; } if (!ReadUInt32(_nextTrakId)) { FATAL("Unable to read next track ID"); return false; } return true; }