From 2d75d7a8be4f5487db9735ff1de010d57312fcd2 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Thu, 22 Mar 2012 21:15:05 +1300 Subject: Fixes issue 5278. Thanks to megazig for finding the bug :) --- Source/Core/DiscIO/Src/VolumeDirectory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/DiscIO/Src') diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index 08188bac71..52e9f4389a 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -389,8 +389,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, -- cgit v1.2.3 From fab037446cb28610ce5084ecd04bac3d125105a9 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Thu, 22 Mar 2012 23:04:13 -0700 Subject: Forward "raw" reads of GC discs to the normal read function, since they are not encrypted in the first place. --- Source/Core/DiscIO/Src/VolumeGC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/DiscIO/Src') 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 -- cgit v1.2.3 From 404a6b9ba8c4276df22efb87487b138175c3aab3 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sat, 31 Mar 2012 16:07:11 +1300 Subject: Fixes issue 5330. --- Source/Core/DiscIO/Src/NANDContentLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/DiscIO/Src') 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"); } -- cgit v1.2.3 From 26521aa66af52594f97633f991a467bd37100362 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Mon, 23 Apr 2012 00:38:58 -0700 Subject: force VolumeDirectory to align files to 32KB (only streaming audio files really need to be aligned...) --- Source/Core/DiscIO/Src/VolumeDirectory.cpp | 26 +++++++++++--------------- Source/Core/DiscIO/Src/VolumeDirectory.h | 10 ++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-) (limited to 'Source/Core/DiscIO/Src') diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index 52e9f4389a..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 @@ -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 -- cgit v1.2.3 From 330f63df80f94488655d21b535cf75a2ce0e9fa2 Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 28 Apr 2012 11:21:55 +1000 Subject: Corrected the file offset within the FST of virtual disks (used by the DVD Root path function). --- Source/Core/DiscIO/Src/VolumeDirectory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/DiscIO/Src') diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index dc76e2e641..f22ed52ce6 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -447,7 +447,7 @@ void CVolumeDirectory::WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, m_FSTData[entryOffset++] = (nameOffset >> 8) & 0xff; m_FSTData[entryOffset++] = (nameOffset) & 0xff; - Write32((u32)(dataOffset >> m_addressShift), entryOffset, m_FSTData); + Write32((u32)(dataOffset), entryOffset, m_FSTData); entryOffset += 4; Write32((u32)length, entryOffset, m_FSTData); -- cgit v1.2.3 From 7885e63deb7310d59701639d02e6c400fa91ccb7 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 4 May 2012 00:09:01 +1000 Subject: Added wbfs support. Thanks to lordlyhobo for the patch. Fixes issue 859. --- Source/Core/DiscIO/Src/Blob.cpp | 4 + Source/Core/DiscIO/Src/WbfsBlob.cpp | 209 ++++++++++++++++++++++++++++++++++++ Source/Core/DiscIO/Src/WbfsBlob.h | 82 ++++++++++++++ 3 files changed, 295 insertions(+) create mode 100644 Source/Core/DiscIO/Src/WbfsBlob.cpp create mode 100644 Source/Core/DiscIO/Src/WbfsBlob.h (limited to 'Source/Core/DiscIO/Src') 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/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 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 -- cgit v1.2.3 From 77f47866dfb4fbf330292957031b1914b2ac3a3e Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Fri, 4 May 2012 12:49:10 +0200 Subject: Add Wii DVD integrity checking to Dolphin This allows users to easily check whether their Wii dump is corrupted or not using the Dolphin properties window. Right click on a game, Properties, Filesystem tab, then right click on the game partition and select "Check partition integrity". This may have some false negatives due to the unused clusters heuristic (see the comment in VolumeWiiCrypted.cpp). False positives are unlikely. --- Source/Core/DiscIO/Src/Volume.h | 4 +- Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp | 65 +++++++++++++++++++++++++++++ Source/Core/DiscIO/Src/VolumeWiiCrypted.h | 3 ++ 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'Source/Core/DiscIO/Src') 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& _rwNames) const {return false;}; + virtual bool GetWName(std::vector& _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/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; -- cgit v1.2.3 From 04bde406d3ae4db07706491bb5a2bd6e2357f113 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Fri, 11 May 2012 22:19:57 +0200 Subject: Fix DVD root path for Wii games. Now Wii games can be booted using extracted files instead of a disc image. --- Source/Core/DiscIO/Src/VolumeDirectory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/DiscIO/Src') diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index f22ed52ce6..dc76e2e641 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -447,7 +447,7 @@ void CVolumeDirectory::WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, m_FSTData[entryOffset++] = (nameOffset >> 8) & 0xff; m_FSTData[entryOffset++] = (nameOffset) & 0xff; - Write32((u32)(dataOffset), entryOffset, m_FSTData); + Write32((u32)(dataOffset >> m_addressShift), entryOffset, m_FSTData); entryOffset += 4; Write32((u32)length, entryOffset, m_FSTData); -- cgit v1.2.3