// Changed this stuff from C++ string to C strings for speed in debug mode. Doesn't matter in release, but
// std::string is SLOW in debug mode.
size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, u64 _NameTableOffset)
{
	size_t CurrentIndex = _FirstIndex;

	while (CurrentIndex < _LastIndex)
	{
		SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex];
		u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF);
		std::string filename = GetStringFromOffset(uOffset);

		// check next index
		if (rFileInfo->IsDirectory())
		{
			// this is a directory, build up the new szDirectory
			if (_szDirectory != NULL)
				CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename.c_str());
			else
				CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename.c_str());

			CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset);
		}
		else
		{
			// this is a filename
			if (_szDirectory != NULL)
				CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename.c_str());
			else
				CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename.c_str());

			CurrentIndex++;
		}
	}

	return CurrentIndex;
}
size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const std::string& _szDirectory, u64 _NameTableOffset)
{
	size_t CurrentIndex = _FirstIndex;

	while (CurrentIndex < _LastIndex)
	{
		SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex];
		u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF);
		std::string filename = GetStringFromOffset(uOffset);

		// check next index
		if (rFileInfo->IsDirectory())
		{
			if (_szDirectory.empty())
				rFileInfo->m_FullPath += StringFromFormat("%s/", filename.c_str());
			else
				rFileInfo->m_FullPath += StringFromFormat("%s%s/", _szDirectory.c_str(), filename.c_str());

			CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset);
		}
		else // This is a filename
		{
			if (_szDirectory.empty())
				rFileInfo->m_FullPath += filename;
			else
				rFileInfo->m_FullPath += StringFromFormat("%s%s", _szDirectory.c_str(), filename.c_str());

			CurrentIndex++;
		}
	}

	return CurrentIndex;
}
Exemple #3
0
void CFileSystemGCWii::InitFileSystem()
{
  m_Initialized = true;
  u32 const shift = GetOffsetShift();

  // read the whole FST
  u32 fst_offset_unshifted;
  if (!m_rVolume->ReadSwapped(0x424, &fst_offset_unshifted, m_Wii))
    return;
  u64 FSTOffset = static_cast<u64>(fst_offset_unshifted) << shift;

  // read all fileinfos
  u32 name_offset, offset, size;
  if (!m_rVolume->ReadSwapped(FSTOffset + 0x0, &name_offset, m_Wii) ||
      !m_rVolume->ReadSwapped(FSTOffset + 0x4, &offset, m_Wii) ||
      !m_rVolume->ReadSwapped(FSTOffset + 0x8, &size, m_Wii))
    return;
  SFileInfo root = {name_offset, static_cast<u64>(offset) << shift, size};

  if (!root.IsDirectory())
    return;

  // 12 bytes (the size of a file entry) times 10 * 1024 * 1024 is 120 MiB,
  // more than total RAM in a Wii. No file system should use anywhere near that much.
  static const u32 ARBITRARY_FILE_SYSTEM_SIZE_LIMIT = 10 * 1024 * 1024;
  if (root.m_FileSize > ARBITRARY_FILE_SYSTEM_SIZE_LIMIT)
  {
    // Without this check, Dolphin can crash by trying to allocate too much
    // memory when loading the file systems of certain malformed disc images.

    ERROR_LOG(DISCIO, "File system is abnormally large! Aborting loading");
    return;
  }

  if (m_FileInfoVector.size())
    PanicAlert("Wtf?");
  u64 NameTableOffset = FSTOffset;

  m_FileInfoVector.reserve((size_t)root.m_FileSize);
  for (u32 i = 0; i < root.m_FileSize; i++)
  {
    const u64 read_offset = FSTOffset + (i * 0xC);
    name_offset = 0;
    m_rVolume->ReadSwapped(read_offset + 0x0, &name_offset, m_Wii);
    offset = 0;
    m_rVolume->ReadSwapped(read_offset + 0x4, &offset, m_Wii);
    size = 0;
    m_rVolume->ReadSwapped(read_offset + 0x8, &size, m_Wii);
    m_FileInfoVector.emplace_back(name_offset, static_cast<u64>(offset) << shift, size);
    NameTableOffset += 0xC;
  }

  BuildFilenames(1, m_FileInfoVector.size(), "", NameTableOffset);
}
Exemple #4
0
bool
CARCFile::ParseBuffer()
{
	// check ID
	u32 ID = Common::swap32(*(u32*)(m_pBuffer));

	if (ID != ARC_ID)
		return false;

	// read header
	u32 FSTOffset  = Common::swap32(*(u32*)(m_pBuffer + 0x4));
	//u32 FSTSize    = Common::swap32(*(u32*)(m_pBuffer + 0x8));
	//u32 FileOffset = Common::swap32(*(u32*)(m_pBuffer + 0xC));

	// read all file infos
	SFileInfo Root;
	Root.m_NameOffset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x0));
	Root.m_Offset     = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x4));
	Root.m_FileSize   = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x8));

	if (Root.IsDirectory())
	{
		m_FileInfoVector.resize((unsigned int)Root.m_FileSize);
		const char* szNameTable = (char*)(m_pBuffer + FSTOffset);

		for (size_t i = 0; i < m_FileInfoVector.size(); i++)
		{
			u8* Offset = m_pBuffer + FSTOffset + (i * 0xC);
			m_FileInfoVector[i].m_NameOffset = Common::swap32(*(u32*)(Offset + 0x0));
			m_FileInfoVector[i].m_Offset   = Common::swap32(*(u32*)(Offset + 0x4));
			m_FileInfoVector[i].m_FileSize = Common::swap32(*(u32*)(Offset + 0x8));

			szNameTable += 0xC;
		}

		BuildFilenames(1, m_FileInfoVector.size(), NULL, szNameTable);
	}

	return(true);
}
void CFileSystemGCWii::InitFileSystem()
{
	m_Initialized = true;
	u32 const shift = GetOffsetShift();

	// read the whole FST
	u64 FSTOffset = static_cast<u64>(m_rVolume->Read32(0x424, m_Wii)) << shift;
	// u32 FSTSize     = Read32(0x428);
	// u32 FSTMaxSize  = Read32(0x42C);


	// read all fileinfos
	SFileInfo Root
	{
		m_rVolume->Read32(FSTOffset + 0x0, m_Wii),
		static_cast<u64>(FSTOffset + 0x4) << shift,
		m_rVolume->Read32(FSTOffset + 0x8, m_Wii)
	};

	if (!Root.IsDirectory())
		return;

	if (m_FileInfoVector.size())
		PanicAlert("Wtf?");
	u64 NameTableOffset = FSTOffset;

	m_FileInfoVector.reserve((size_t)Root.m_FileSize);
	for (u32 i = 0; i < Root.m_FileSize; i++)
	{
		u64 const read_offset = FSTOffset + (i * 0xC);
		u64 const name_offset = m_rVolume->Read32(read_offset + 0x0, m_Wii);
		u64 const offset = static_cast<u64>(m_rVolume->Read32(read_offset + 0x4, m_Wii)) << shift;
		u64 const size = m_rVolume->Read32(read_offset + 0x8, m_Wii);
		m_FileInfoVector.emplace_back(name_offset, offset, size);
		NameTableOffset += 0xC;
	}

	BuildFilenames(1, m_FileInfoVector.size(), "", NameTableOffset);
}
void CFileSystemGCWii::InitFileSystem()
{
	m_Initialized = true;

	// read the whole FST
	u64 FSTOffset = (u64)Read32(0x424) << m_OffsetShift;
	// u32 FSTSize     = Read32(0x428);
	// u32 FSTMaxSize  = Read32(0x42C);


	// read all fileinfos
	SFileInfo Root;
	Root.m_NameOffset = Read32(FSTOffset + 0x0);
	Root.m_Offset     = (u64)Read32(FSTOffset + 0x4) << m_OffsetShift;
	Root.m_FileSize   = Read32(FSTOffset + 0x8);

	if (Root.IsDirectory())
	{
		if (m_FileInfoVector.size())
			PanicAlert("Wtf?");
		u64 NameTableOffset = FSTOffset;

		m_FileInfoVector.reserve((unsigned int)Root.m_FileSize);
		for (u32 i = 0; i < Root.m_FileSize; i++)
		{
			SFileInfo sfi;
			u64 Offset = FSTOffset + (i * 0xC);
			sfi.m_NameOffset = Read32(Offset + 0x0);
			sfi.m_Offset     = (u64)Read32(Offset + 0x4) << m_OffsetShift;
			sfi.m_FileSize   = Read32(Offset + 0x8);

			m_FileInfoVector.push_back(sfi);
			NameTableOffset += 0xC;
		}

		BuildFilenames(1, m_FileInfoVector.size(), "", NameTableOffset);
	}
}
Exemple #7
0
	bool CFileReceiver::getSingleFileInfo(const std::string &fileName,SFileInfo& fileInfo) const
	{
		// run through the attached proxies to find a match for the file...
		for (TProxies::const_iterator pit= _Proxies.begin(); pit!=_Proxies.end();++pit)
		{
			// if there's a match for this proxy then it'll do
			TFileInfoMap::const_iterator fit= pit->second.FileInfo.find(fileName);
			if (fit!=pit->second.FileInfo.end())
			{
				fileInfo= fit->second;
				return true;
			}
		}

		// failed to find a match so clear out the file info record and return false
		fileInfo.clear();
		return false;
	}