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); }
bool CFileSystemGCWii::ExportDOL(const std::string& _rExportFolder) const { u32 DolOffset = m_rVolume->Read32(0x420, m_Wii) << GetOffsetShift(); u32 DolSize = GetBootDOLSize(); std::vector<u8> buffer(DolSize); if (m_rVolume->Read(DolOffset, DolSize, &buffer[0], m_Wii)) { std::string exportName(_rExportFolder + "/boot.dol"); File::IOFile DolFile(exportName, "wb"); if (DolFile) { DolFile.WriteBytes(&buffer[0], DolSize); return true; } } return false; }
bool CFileSystemGCWii::GetBootDOL(u8* &buffer, u32 DolSize) const { char filePathNew[512]; strcpy((char*)&filePathNew, "ISO/&&systemdata/Start.dol"); if (access((char*)&filePathNew, 0) != -1) { FILE* newFile = fopen((char*)&filePathNew, "rb"); u64 fileRelOffset = 0; WARN_LOG(VIDEO, "Loading custom DOL file from ISO/&&systemData/Start.dol"); if (newFile) { // Get file size fseek(newFile, 0, SEEK_END); int fileSize = ftell(newFile); fseek(newFile, 0, SEEK_SET); fseek(newFile, (long)fileRelOffset, SEEK_SET); if ((int)DolSize > fileSize) { fread(buffer, fileSize, 1, newFile); } else { fread(buffer, DolSize, 1, newFile); } } fclose(newFile); return true; } u32 DolOffset = m_rVolume->Read32(0x420, m_Wii) << GetOffsetShift(); return m_rVolume->Read(DolOffset, DolSize, buffer, m_Wii); }
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); }
u32 CFileSystemGCWii::GetBootDOLSize() const { return GetBootDOLSize((u64)m_rVolume->Read32(0x420, m_Wii) << GetOffsetShift()); }
u64 CFileSystemGCWii::GetBootDOLOffset() const { u32 offset = 0; m_rVolume->ReadSwapped(0x420, &offset, m_Wii); return static_cast<u64>(offset) << GetOffsetShift(); }