diff options
Diffstat (limited to 'Source/Core/DiscIO')
| -rw-r--r-- | Source/Core/DiscIO/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Source/Core/DiscIO/DiscIO.vcxproj | 3 | ||||
| -rw-r--r-- | Source/Core/DiscIO/DiscIO.vcxproj.filters | 7 | ||||
| -rw-r--r-- | Source/Core/DiscIO/SConscript | 29 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/Blob.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/NANDContentLoader.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/Volume.h | 4 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeDirectory.cpp | 30 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeDirectory.h | 10 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeGC.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp | 65 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/VolumeWiiCrypted.h | 3 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/WbfsBlob.cpp | 209 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/WbfsBlob.h | 82 |
14 files changed, 401 insertions, 52 deletions
diff --git a/Source/Core/DiscIO/CMakeLists.txt b/Source/Core/DiscIO/CMakeLists.txt index 7f6ff7e4cc..01e15a374f 100644 --- a/Source/Core/DiscIO/CMakeLists.txt +++ b/Source/Core/DiscIO/CMakeLists.txt @@ -3,6 +3,7 @@ set(SRCS Src/BannerLoader.cpp Src/BannerLoaderWii.cpp Src/Blob.cpp Src/CISOBlob.cpp + Src/WbfsBlob.cpp Src/CompressedBlob.cpp Src/DiscScrubber.cpp Src/DriveBlob.cpp diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj index d94ac13212..6dd24ddd44 100644 --- a/Source/Core/DiscIO/DiscIO.vcxproj +++ b/Source/Core/DiscIO/DiscIO.vcxproj @@ -175,6 +175,7 @@ <ClInclude Include="Src\BannerLoaderWii.h" /> <ClInclude Include="Src\Blob.h" /> <ClInclude Include="Src\CISOBlob.h" /> + <ClInclude Include="Src\WbfsBlob.h" /> <ClInclude Include="Src\CompressedBlob.h" /> <ClInclude Include="Src\DiscScrubber.h" /> <ClInclude Include="Src\DriveBlob.h" /> @@ -199,6 +200,7 @@ <ClCompile Include="Src\BannerLoaderWii.cpp" /> <ClCompile Include="Src\Blob.cpp" /> <ClCompile Include="Src\CISOBlob.cpp" /> + <ClCompile Include="Src\WbfsBlob.cpp" /> <ClCompile Include="Src\CompressedBlob.cpp" /> <ClCompile Include="Src\DiscScrubber.cpp" /> <ClCompile Include="Src\DriveBlob.cpp" /> @@ -226,7 +228,6 @@ </ItemGroup> <ItemGroup> <None Include="CMakeLists.txt" /> - <None Include="Src\SConscript" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/Source/Core/DiscIO/DiscIO.vcxproj.filters b/Source/Core/DiscIO/DiscIO.vcxproj.filters index 80ddbe57c6..105d3ffc47 100644 --- a/Source/Core/DiscIO/DiscIO.vcxproj.filters +++ b/Source/Core/DiscIO/DiscIO.vcxproj.filters @@ -8,6 +8,9 @@ <ClCompile Include="Src\CISOBlob.cpp"> <Filter>Volume\Blob</Filter> </ClCompile> + <ClCompile Include="Src\WbfsBlob.cpp"> + <Filter>Volume\Blob</Filter> + </ClCompile> <ClCompile Include="Src\CompressedBlob.cpp"> <Filter>Volume\Blob</Filter> </ClCompile> @@ -71,6 +74,9 @@ <ClInclude Include="Src\CISOBlob.h"> <Filter>Volume\Blob</Filter> </ClInclude> + <ClInclude Include="Src\WbfsBlob.h"> + <Filter>Volume\Blob</Filter> + </ClInclude> <ClInclude Include="Src\Blob.h"> <Filter>Volume\Blob</Filter> </ClInclude> @@ -133,7 +139,6 @@ </ClInclude> </ItemGroup> <ItemGroup> - <None Include="Src\SConscript" /> <None Include="CMakeLists.txt" /> </ItemGroup> <ItemGroup> diff --git a/Source/Core/DiscIO/SConscript b/Source/Core/DiscIO/SConscript deleted file mode 100644 index 3c563cf5e3..0000000000 --- a/Source/Core/DiscIO/SConscript +++ /dev/null @@ -1,29 +0,0 @@ -# -*- python -*- - -Import('env') - -files = [ - 'Src/BannerLoader.cpp', - 'Src/BannerLoaderGC.cpp', - 'Src/BannerLoaderWii.cpp', - 'Src/Blob.cpp', - 'Src/CISOBlob.cpp', - 'Src/CompressedBlob.cpp', - 'Src/DiscScrubber.cpp', - 'Src/DriveBlob.cpp', - 'Src/FileBlob.cpp', - 'Src/FileHandlerARC.cpp', - 'Src/FileMonitor.cpp', - 'Src/FileSystemGCWii.cpp', - 'Src/Filesystem.cpp', - 'Src/NANDContentLoader.cpp', - 'Src/VolumeCommon.cpp', - 'Src/VolumeCreator.cpp', - 'Src/VolumeDirectory.cpp', - 'Src/VolumeGC.cpp', - 'Src/VolumeWad.cpp', - 'Src/VolumeWiiCrypted.cpp', - 'Src/WiiWad.cpp', - ] - -env['LIBS'] += env.StaticLibrary('discio', files) diff --git a/Source/Core/DiscIO/Src/Blob.cpp b/Source/Core/DiscIO/Src/Blob.cpp index a728780f23..115145e290 100644 --- a/Source/Core/DiscIO/Src/Blob.cpp +++ b/Source/Core/DiscIO/Src/Blob.cpp @@ -23,6 +23,7 @@ #include "FileBlob.h" #include "CISOBlob.h" #include "DriveBlob.h" +#include "WbfsBlob.h" namespace DiscIO { @@ -128,6 +129,9 @@ IBlobReader* CreateBlobReader(const char* filename) if (!File::Exists(filename)) return 0; + if (IsWbfsBlob(filename)) + return WbfsFileReader::Create(filename); + if (IsCompressedBlob(filename)) return CompressedBlobReader::Create(filename); diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index f010b7ed98..dc1f44739b 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -462,7 +462,7 @@ void cUIDsys::AddTitle(u64 _TitleID) File::CreateFullPath(uidSys); File::IOFile pFile(uidSys, "ab"); - if (pFile.WriteArray(&Element, 1)) + if (!pFile.WriteArray(&Element, 1)) ERROR_LOG(DISCIO, "fwrite failed"); } diff --git a/Source/Core/DiscIO/Src/Volume.h b/Source/Core/DiscIO/Src/Volume.h index ec20e47b6c..f8a6f13ecb 100644 --- a/Source/Core/DiscIO/Src/Volume.h +++ b/Source/Core/DiscIO/Src/Volume.h @@ -38,9 +38,11 @@ public: virtual std::string GetUniqueID() const = 0; virtual std::string GetMakerID() const = 0; virtual std::string GetName() const = 0; - virtual bool GetWName(std::vector<std::wstring>& _rwNames) const {return false;}; + virtual bool GetWName(std::vector<std::wstring>& _rwNames) const { return false; } virtual u32 GetFSTSize() const = 0; virtual std::string GetApploaderDate() const = 0; + virtual bool SupportsIntegrityCheck() const { return false; } + virtual bool CheckIntegrity() const { return false; } enum ECountry { diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index 08188bac71..dc76e2e641 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "Common.h" +#include "MathUtil.h" #include "CommonPaths.h" #include "VolumeDirectory.h" #include "FileBlob.h" @@ -23,17 +24,6 @@ namespace DiscIO { -static const u8 ENTRY_SIZE = 0x0c; -static const u8 FILE_ENTRY = 0; -static const u8 DIRECTORY_ENTRY = 1; -static const u64 DISKHEADER_ADDRESS = 0; -static const u64 DISKHEADERINFO_ADDRESS = 0x440; -static const u64 APPLOADER_ADDRESS = 0x2440; -static const u32 MAX_NAME_LENGTH = 0x3df; -// relocatable -static u64 FST_ADDRESS = 0x440; -static u64 DOL_ADDRESS = 0; - CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader, const std::string& _rDOL) : m_totalNameSize(0) @@ -44,6 +34,8 @@ CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii, , m_apploader(NULL) , m_DOLSize(0) , m_DOL(NULL) + , FST_ADDRESS(0) + , DOL_ADDRESS(0) { m_rootDirectory = ExtractDirectoryName(_rDirectory); @@ -321,7 +313,7 @@ bool CVolumeDirectory::SetApploader(const std::string& _rApploader) copy(data.begin(), data.end(), m_apploader); // 32byte aligned (plus 0x20 padding) - DOL_ADDRESS = (APPLOADER_ADDRESS + m_apploaderSize + 0x20 + 31) & ~31ULL; + DOL_ADDRESS = ROUND_UP(APPLOADER_ADDRESS + m_apploaderSize + 0x20, 0x20ull); return true; } else @@ -347,7 +339,7 @@ void CVolumeDirectory::SetDOL(const std::string& _rDOL) Write32((u32)(DOL_ADDRESS >> m_addressShift), 0x0420, m_diskHeader); // 32byte aligned (plus 0x20 padding) - FST_ADDRESS = (DOL_ADDRESS + m_DOLSize + 0x20 + 31) & ~31ULL; + FST_ADDRESS = ROUND_UP(DOL_ADDRESS + m_DOLSize + 0x20, 0x20ull); } } @@ -367,8 +359,12 @@ void CVolumeDirectory::BuildFST() m_fstSize = m_fstNameOffset + m_totalNameSize; m_FSTData = new u8[(u32)m_fstSize]; + // if FST hasn't been assigned (ie no apploader/dol setup), set to default + if (FST_ADDRESS == 0) + FST_ADDRESS = APPLOADER_ADDRESS + 0x2000; + // 4 byte aligned start of data on disk - m_dataStartAddress = (FST_ADDRESS + m_fstSize + 3) & ~3; + m_dataStartAddress = ROUND_UP(FST_ADDRESS + m_fstSize, 0x8000ull); u64 curDataAddress = m_dataStartAddress; u32 fstOffset = 0; // offset within FST data @@ -389,8 +385,8 @@ void CVolumeDirectory::BuildFST() // write FST size and location _dbg_assert_(DVDINTERFACE, m_diskHeader); Write32((u32)(FST_ADDRESS >> m_addressShift), 0x0424, m_diskHeader); - Write32((u32)m_fstSize, 0x0428, m_diskHeader); - Write32((u32)m_fstSize, 0x042c, m_diskHeader); + Write32((u32)(m_fstSize >> m_addressShift), 0x0428, m_diskHeader); + Write32((u32)(m_fstSize >> m_addressShift), 0x042c, m_diskHeader); } void CVolumeDirectory::WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src, @@ -490,7 +486,7 @@ void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u m_virtualDisk.insert(make_pair(dataOffset, entry.physicalName)); // 4 byte aligned - dataOffset = (dataOffset + entry.size + 3) & ~3ULL; + dataOffset = ROUND_UP(dataOffset + entry.size, 0x8000ull); } } diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h index 727974a417..0547be3b8a 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.h +++ b/Source/Core/DiscIO/Src/VolumeDirectory.h @@ -141,6 +141,16 @@ private: u64 m_DOLSize; u8* m_DOL; + + static const u8 ENTRY_SIZE = 0x0c; + static const u8 FILE_ENTRY = 0; + static const u8 DIRECTORY_ENTRY = 1; + static const u64 DISKHEADER_ADDRESS = 0; + static const u64 DISKHEADERINFO_ADDRESS = 0x440; + static const u64 APPLOADER_ADDRESS = 0x2440; + static const u32 MAX_NAME_LENGTH = 0x3df; + u64 FST_ADDRESS; + u64 DOL_ADDRESS; }; } // namespace diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp index 0b0fabf7e9..51fac285fc 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.cpp +++ b/Source/Core/DiscIO/Src/VolumeGC.cpp @@ -43,9 +43,9 @@ bool CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const return m_pReader->Read(_Offset, _Length, _pBuffer); } -bool CVolumeGC::RAWRead( u64 _Offset, u64 _Length, u8* _pBuffer ) const +bool CVolumeGC::RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const { - return false; + return Read(_Offset, _Length, _pBuffer); } std::string CVolumeGC::GetUniqueID() const diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp index 9e7865d9c6..ca010b5ae4 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp @@ -17,6 +17,7 @@ #include "VolumeWiiCrypted.h" #include "StringUtil.h" +#include "Crypto/sha1.h" namespace DiscIO { @@ -232,4 +233,68 @@ u64 CVolumeWiiCrypted::GetSize() const } } +bool CVolumeWiiCrypted::CheckIntegrity() const +{ + // Get partition data size + u32 partSizeDiv4; + RAWRead(m_VolumeOffset + 0x2BC, 4, (u8*)&partSizeDiv4); + u64 partDataSize = (u64)Common::swap32(partSizeDiv4) * 4; + + u32 nClusters = (u32)(partDataSize / 0x8000); + for (u32 clusterID = 0; clusterID < nClusters; ++clusterID) + { + u64 clusterOff = m_VolumeOffset + dataOffset + (u64)clusterID * 0x8000; + + // Read and decrypt the cluster metadata + u8 clusterMDCrypted[0x400]; + u8 clusterMD[0x400]; + u8 IV[16] = { 0 }; + if (!m_pReader->Read(clusterOff, 0x400, clusterMDCrypted)) + { + NOTICE_LOG(DISCIO, "Integrity Check: fail at cluster %d: could not read metadata", clusterID); + return false; + } + AES_cbc_encrypt(clusterMDCrypted, clusterMD, 0x400, &m_AES_KEY, IV, AES_DECRYPT); + + // Some clusters have invalid data and metadata because they aren't + // meant to be read by the game (for example, holes between files). To + // try to avoid reporting errors because of these clusters, we check + // the 0x00 paddings in the metadata. + // + // This may cause some false negatives though: some bad clusters may be + // skipped because they are *too* bad and are not even recognized as + // valid clusters. To be improved. + bool meaningless = false; + for (u32 idx = 0x26C; idx < 0x280; ++idx) + if (clusterMD[idx] != 0) + meaningless = true; + + if (meaningless) + continue; + + u8 clusterData[0x7C00]; + if (!Read((u64)clusterID * 0x7C00, 0x7C00, clusterData)) + { + NOTICE_LOG(DISCIO, "Integrity Check: fail at cluster %d: could not read data", clusterID); + return false; + } + + for (u32 hashID = 0; hashID < 31; ++hashID) + { + u8 hash[20]; + + sha1(clusterData + hashID * 0x400, 0x400, hash); + + // Note that we do not use strncmp here + if (memcmp(hash, clusterMD + hashID * 20, 20)) + { + NOTICE_LOG(DISCIO, "Integrity Check: fail at cluster %d: hash %d is invalid", clusterID, hashID); + return false; + } + } + } + + return true; +} + } // namespace diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h index f69bcfb490..5010e46bbd 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h @@ -43,6 +43,9 @@ public: ECountry GetCountry() const; u64 GetSize() const; + bool SupportsIntegrityCheck() const { return true; } + bool CheckIntegrity() const; + private: IBlobReader* m_pReader; diff --git a/Source/Core/DiscIO/Src/WbfsBlob.cpp b/Source/Core/DiscIO/Src/WbfsBlob.cpp new file mode 100644 index 0000000000..1b7696cc58 --- /dev/null +++ b/Source/Core/DiscIO/Src/WbfsBlob.cpp @@ -0,0 +1,209 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "WbfsBlob.h" +#include "FileUtil.h" + +namespace DiscIO +{ +const u64 wii_sector_size = 0x8000; +const u64 wii_sector_count = 143432 * 2; +const u64 wii_sector_log2 = 15; +const u64 wii_disc_header_size = 256; + +static inline u64 align(u64 value, u64 bounds) +{ + return (value + (bounds - 1)) & (~(bounds - 1)); +} + +WbfsFileReader::WbfsFileReader(const char* filename) + : m_total_files(0), m_size(0), m_wlba_table(0), m_good(true) +{ + if(!filename || (strlen(filename) < 4) || !OpenFiles(filename) || !ReadHeader()) + { + m_good = false; + return; + } + + // Grab disc info (assume slot 0, checked in ReadHeader()) + m_wlba_table = new u16[m_blocks_per_disc]; + m_files[0]->file.Seek(hd_sector_size + wii_disc_header_size /*+ i * m_disc_info_size*/, SEEK_SET); + m_files[0]->file.ReadBytes(m_wlba_table, m_blocks_per_disc * sizeof(u16)); +} + +WbfsFileReader::~WbfsFileReader() +{ + for(u32 i = 0; i != m_files.size(); ++ i) + { + delete m_files[i]; + } + + delete[] m_wlba_table; +} + +bool WbfsFileReader::OpenFiles(const char* filename) +{ + m_total_files = 0; + + while(true) + { + file_entry* new_entry = new file_entry; + + // Replace last character with index (e.g. wbfs = wbf1) + std::string path = filename; + if(0 != m_total_files) + { + path[path.length() - 1] = '0' + m_total_files; + } + + if(!new_entry->file.Open(path, "rb")) + { + delete new_entry; + return 0 != m_total_files; + } + + new_entry->base_address = m_size; + new_entry->size = new_entry->file.GetSize(); + m_size += new_entry->size; + + m_total_files ++; + m_files.push_back(new_entry); + } +} + +bool WbfsFileReader::ReadHeader() +{ + m_files[0]->file.Seek(4, SEEK_SET); + + // Read hd size info + m_files[0]->file.ReadBytes(&hd_sector_count, 4); + hd_sector_count = Common::swap32(hd_sector_count); + + m_files[0]->file.ReadBytes(&hd_sector_shift, 1); + hd_sector_size = 1 << hd_sector_shift; + + if(m_size != hd_sector_count * hd_sector_size) + { + //printf("File size doesn't match expected size\n"); + return false; + } + + // Read wbfs cluster info + m_files[0]->file.ReadBytes(&wbfs_sector_shift, 1); + wbfs_sector_size = 1 << wbfs_sector_shift; + wbfs_sector_count = m_size / wbfs_sector_size; + + if(wbfs_sector_size < wii_sector_size) + { + //Setting this too low would case a very large memory allocation + return false; + } + + m_blocks_per_disc = (wii_sector_count * wii_sector_size) / wbfs_sector_size; + m_disc_info_size = align(wii_disc_header_size + m_blocks_per_disc * 2, hd_sector_size); + + // Read disc table + m_files[0]->file.Seek(2, SEEK_CUR); + m_files[0]->file.ReadBytes(disc_table, 500); + + if(0 == disc_table[0]) + { + //printf("Game must be in 'slot 0'\n"); + return false; + } + + return true; +} + +bool WbfsFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr) +{ + while(nbytes) + { + u64 read_size; + File::IOFile& data_file = SeekToCluster(offset, &read_size); + read_size = (read_size > nbytes) ? nbytes : read_size; + + data_file.ReadBytes(out_ptr, read_size); + + out_ptr += read_size; + nbytes -= read_size; + offset += read_size; + } + + return true; +} + +File::IOFile& WbfsFileReader::SeekToCluster(u64 offset, u64* available) +{ + u64 base_cluster = offset >> wbfs_sector_shift; + if(base_cluster < m_blocks_per_disc) + { + u64 cluster_address = wbfs_sector_size * Common::swap16(m_wlba_table[base_cluster]); + u64 cluster_offset = offset & (wbfs_sector_size - 1); + u64 final_address = cluster_address + cluster_offset; + + for(u32 i = 0; i != m_total_files; i ++) + { + if(final_address < (m_files[i]->base_address + m_files[i]->size)) + { + m_files[i]->file.Seek(final_address - m_files[i]->base_address, SEEK_SET); + if(available) + { + u64 till_end_of_file = m_files[i]->size - (final_address - m_files[i]->base_address); + u64 till_end_of_sector = wbfs_sector_size - cluster_offset; + *available = std::min(till_end_of_file, till_end_of_sector); + } + + return m_files[i]->file; + } + } + } + + PanicAlert("Read beyond end of disc"); + m_files[0]->file.Seek(0, SEEK_SET); + return m_files[0]->file; +} + +WbfsFileReader* WbfsFileReader::Create(const char* filename) +{ + WbfsFileReader* reader = new WbfsFileReader(filename); + + if(reader->IsGood()) + { + return reader; + } + else + { + delete reader; + return NULL; + } +} + +bool IsWbfsBlob(const char* filename) +{ + File::IOFile f(filename, "rb"); + + u8 magic[4] = {0, 0, 0, 0}; + f.ReadBytes(&magic, 4); + + return (magic[0] == 'W') && + (magic[1] == 'B') && + (magic[2] == 'F') && + (magic[3] == 'S'); +} + +} // namespace diff --git a/Source/Core/DiscIO/Src/WbfsBlob.h b/Source/Core/DiscIO/Src/WbfsBlob.h new file mode 100644 index 0000000000..78b3ae8b78 --- /dev/null +++ b/Source/Core/DiscIO/Src/WbfsBlob.h @@ -0,0 +1,82 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _WBFS_BLOB_H +#define _WBFS_BLOB_H + +#include "Blob.h" +#include "FileUtil.h" + +namespace DiscIO +{ + +struct wbfs_head_t; + +class WbfsFileReader : public IBlobReader +{ + WbfsFileReader(const char* filename); + ~WbfsFileReader(); + + bool OpenFiles(const char* filename); + bool ReadHeader(); + + File::IOFile& SeekToCluster(u64 offset, u64* available); + bool IsGood() {return m_good;} + + + struct file_entry + { + File::IOFile file; + u64 base_address; + u64 size; + }; + + std::vector<file_entry*> m_files; + + u32 m_total_files; + u64 m_size; + + u64 hd_sector_size; + u8 hd_sector_shift; + u32 hd_sector_count; + + u64 wbfs_sector_size; + u64 wbfs_sector_shift; + u64 wbfs_sector_count; + u64 m_disc_info_size; + + u8 disc_table[500]; + + u16* m_wlba_table; + u64 m_blocks_per_disc; + + bool m_good; + +public: + static WbfsFileReader* Create(const char* filename); + + u64 GetDataSize() const { return m_size; } + u64 GetRawSize() const { return m_size; } + bool Read(u64 offset, u64 nbytes, u8* out_ptr); +}; + +bool IsWbfsBlob(const char* filename); + + +} // namespace + +#endif // _FILE_BLOB_H |
