Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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"));
	}
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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);
  }
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
int64_t BinaryReader::ReadInt64()
{
    return (int64_t)ReadUInt64();
}
Ejemplo n.º 11
0
double BinaryReader::ReadDouble()
{
    uint64_t value = ReadUInt64();

    return *(double*)&value;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
 ID Packet::ReadID ()
 {
   return ID (ReadUInt64 ());
 }
Ejemplo n.º 17
0
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;
}