From d210fbac2c1a934e3490f2da5068a201a1657106 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Thu, 21 May 2009 19:19:15 +0000 Subject: [PATCH] Wii images can now be scrubbed and compressed (my z:tp wii is now 1.08GB :D ) Currently scrubbing will display a warning that it removes the garbage data PERMENENTLY from the original file (mainly for speed of scrubbing). It could be removed in the future if people agree with me, since it is indeed just garbage. Any tips for making scrubbing faster would be welcomed :) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3267 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp | 6 +- Source/Core/Core/Src/VolumeHandler.cpp | 12 +- Source/Core/DiscIO/DiscIO.vcproj | 14 +- Source/Core/DiscIO/Src/BannerLoader.cpp | 2 +- Source/Core/DiscIO/Src/BannerLoader.h | 2 +- Source/Core/DiscIO/Src/BannerLoaderGC.cpp | 2 +- Source/Core/DiscIO/Src/BannerLoaderGC.h | 2 +- Source/Core/DiscIO/Src/BannerLoaderWii.cpp | 2 +- Source/Core/DiscIO/Src/BannerLoaderWii.h | 2 +- Source/Core/DiscIO/Src/Blob.cpp | 2 +- Source/Core/DiscIO/Src/Blob.h | 2 +- Source/Core/DiscIO/Src/CompressedBlob.cpp | 21 +- Source/Core/DiscIO/Src/CompressedBlob.h | 2 +- Source/Core/DiscIO/Src/DiscScrubber.cpp | 410 +++++++++++++++++++ Source/Core/DiscIO/Src/DiscScrubber.h | 48 +++ Source/Core/DiscIO/Src/DriveBlob.cpp | 2 +- Source/Core/DiscIO/Src/DriveBlob.h | 2 +- Source/Core/DiscIO/Src/FileBlob.cpp | 2 +- Source/Core/DiscIO/Src/FileBlob.h | 2 +- Source/Core/DiscIO/Src/FileHandlerARC.cpp | 2 +- Source/Core/DiscIO/Src/FileHandlerARC.h | 2 +- Source/Core/DiscIO/Src/FileSystemGCWii.cpp | 2 +- Source/Core/DiscIO/Src/FileSystemGCWii.h | 2 +- Source/Core/DiscIO/Src/Filesystem.cpp | 2 +- Source/Core/DiscIO/Src/Filesystem.h | 2 +- Source/Core/DiscIO/Src/NANDContentLoader.cpp | 2 +- Source/Core/DiscIO/Src/NANDContentLoader.h | 2 +- Source/Core/DiscIO/Src/Volume.h | 2 +- Source/Core/DiscIO/Src/VolumeCreator.cpp | 2 +- Source/Core/DiscIO/Src/VolumeCreator.h | 2 +- Source/Core/DiscIO/Src/VolumeDirectory.cpp | 2 +- Source/Core/DiscIO/Src/VolumeDirectory.h | 2 +- Source/Core/DiscIO/Src/VolumeGC.cpp | 18 +- Source/Core/DiscIO/Src/VolumeGC.h | 2 +- Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp | 32 +- Source/Core/DiscIO/Src/VolumeWiiCrypted.h | 2 +- Source/Core/DiscIO/Src/stdafx.cpp | 2 +- Source/Core/DiscIO/Src/stdafx.h | 2 +- 38 files changed, 539 insertions(+), 82 deletions(-) create mode 100644 Source/Core/DiscIO/Src/DiscScrubber.cpp create mode 100644 Source/Core/DiscIO/Src/DiscScrubber.h diff --git a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp index 78247a8a59..bae4c17e3f 100644 --- a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp @@ -256,11 +256,11 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode) // IOS Version from TMD VolumeHandler::RAWReadToPtr(Memory::GetPointer(0x00003141), TMDOffset + 0x18B, 1); Memory::Write_U16(0xffff, 0x00003142); // IOS revision - Memory::Write_U32(0x00062507, 0x00003144); // ??? + Memory::Write_U32(0x00062507, 0x00003144); // Date in USA format } else { - // Use fake IOS Version + // Fake IOS9 Version 2.4 Memory::Write_U64(0x0009020400062507ULL, 0x00003140); } @@ -271,7 +271,7 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode) Memory::Write_U8(0x00, 0x00000006); // DVDInit Memory::Write_U8(0x00, 0x00000007); // DVDInit Memory::Write_U16(0x0000, 0x000030e0); // PADInit - Memory::Write_U32(0x80000000, 0x00003184); // GameID Address + Memory::Write_U32(0x80000000, 0x00003184); // GameID Address // Fake the VI Init of the BIOS Memory::Write_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC ? 0 : 1, 0x000000CC); diff --git a/Source/Core/Core/Src/VolumeHandler.cpp b/Source/Core/Core/Src/VolumeHandler.cpp index 69052dc7bd..3c05f56dda 100644 --- a/Source/Core/Core/Src/VolumeHandler.cpp +++ b/Source/Core/Core/Src/VolumeHandler.cpp @@ -108,14 +108,14 @@ bool GetTMDOffset(u32 _Partition, u64& _Offset) if (IsWii()) { // Get the info table - u8 pInfoTableOffset[4]; - ret |= RAWReadToPtr(pInfoTableOffset, 0x40004, 4); - u64 InfoTableOffset = (u32)(pInfoTableOffset[3] | pInfoTableOffset[2] << 8 | pInfoTableOffset[1] << 16 | pInfoTableOffset[0] << 24) << 2; + u32 pInfoTableOffset = 0; + ret |= RAWReadToPtr((u8*)&pInfoTableOffset, 0x40004, 4); + u64 InfoTableOffset = (u64)Common::swap32(pInfoTableOffset) << 2; // Get the offset of the partition - u8 pInfoTableEntryOffset[4]; - ret |= RAWReadToPtr(pInfoTableEntryOffset, InfoTableOffset + (_Partition << 2) + 4, 4); - u64 PartitionOffset = (u32)(pInfoTableEntryOffset[3] | pInfoTableEntryOffset[2] << 8 | pInfoTableEntryOffset[1] << 16 | pInfoTableEntryOffset[0] << 24) << 2; + u32 pInfoTableEntryOffset = 0; + ret |= RAWReadToPtr((u8*)&pInfoTableEntryOffset, InfoTableOffset + (_Partition * 8), 4); + u64 PartitionOffset = (u64)Common::swap32(pInfoTableEntryOffset) << 2; _Offset = PartitionOffset + 0x2c0; } diff --git a/Source/Core/DiscIO/DiscIO.vcproj b/Source/Core/DiscIO/DiscIO.vcproj index b2ff70b22a..7b441abc14 100644 --- a/Source/Core/DiscIO/DiscIO.vcproj +++ b/Source/Core/DiscIO/DiscIO.vcproj @@ -1,7 +1,7 @@ + + + + + + diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp index c759a5265a..b5d2d21690 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.cpp +++ b/Source/Core/DiscIO/Src/BannerLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/BannerLoader.h b/Source/Core/DiscIO/Src/BannerLoader.h index 0da8ee3358..357571b371 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.h +++ b/Source/Core/DiscIO/Src/BannerLoader.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp index 5134bb3bb7..e94a1321a1 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.h b/Source/Core/DiscIO/Src/BannerLoaderGC.h index 1c164ff377..ff3370cc4c 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.h +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp index d325c58ef6..c03287aa28 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.h b/Source/Core/DiscIO/Src/BannerLoaderWii.h index 3b5b5110cc..f5101c5be7 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.h +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/Blob.cpp b/Source/Core/DiscIO/Src/Blob.cpp index 13c8d983ff..76f9bb2d79 100644 --- a/Source/Core/DiscIO/Src/Blob.cpp +++ b/Source/Core/DiscIO/Src/Blob.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/Blob.h b/Source/Core/DiscIO/Src/Blob.h index af754459d3..8724e589be 100644 --- a/Source/Core/DiscIO/Src/Blob.h +++ b/Source/Core/DiscIO/Src/Blob.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/CompressedBlob.cpp b/Source/Core/DiscIO/Src/CompressedBlob.cpp index f424b2c465..eb340ea216 100644 --- a/Source/Core/DiscIO/Src/CompressedBlob.cpp +++ b/Source/Core/DiscIO/Src/CompressedBlob.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 @@ -26,6 +26,7 @@ #include "Common.h" #include "CompressedBlob.h" +#include "DiscScrubber.h" #include "FileUtil.h" #include "Hash.h" @@ -159,17 +160,25 @@ void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr) bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type, int block_size, CompressCB callback, void* arg) { - if (File::GetSize(infile) > 2000000000ULL) { - PanicAlert("Sorry - compressing Wii games not yet supported."); - return false; - } - if (IsCompressedBlob(infile)) { PanicAlert("%s is already compressed! Cannot compress it further.", infile); return false; } + if (sub_type == 1) + { + if (PanicYesNo("WARNING - Scrubbing Wii disc %s will permanently remove garbage data.\n" + "This should be 100%% OK, but you have the option to opt out.\n\n\n" + "Would you like to scrub it?", infile)) + { + if (!DiscScrubber::Scrub(infile, callback, arg)) + return false; + } + else + return false; + } + FILE* inf = fopen(infile, "rb"); if (!inf) return false; diff --git a/Source/Core/DiscIO/Src/CompressedBlob.h b/Source/Core/DiscIO/Src/CompressedBlob.h index d4714834d0..3058bea0ae 100644 --- a/Source/Core/DiscIO/Src/CompressedBlob.h +++ b/Source/Core/DiscIO/Src/CompressedBlob.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/DiscScrubber.cpp b/Source/Core/DiscIO/Src/DiscScrubber.cpp new file mode 100644 index 0000000000..0a9c1be18a --- /dev/null +++ b/Source/Core/DiscIO/Src/DiscScrubber.cpp @@ -0,0 +1,410 @@ +// Copyright (C) 2003-2009 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 "stdafx.h" + +#include "Filesystem.h" +#include "VolumeCreator.h" +#include "FileUtil.h" +#include "DiscScrubber.h" + +namespace DiscIO +{ + +namespace DiscScrubber +{ + +#define SCRUBBER_VERSION 1 + +#define CLUSTER_SIZE 0x8000 + +u8* m_Sector1; +u8* m_FreeTable; +u64 m_FileSize; + +std::string m_Filename; +IVolume* m_Disc = NULL; + +struct SPartitionHeader +{ + u8* Ticket[0x2a4]; + u32 TMDSize; + u64 TMDOffset; + u32 CertChainSize; + u64 CertChainOffset; + // H3Size is always 0x18000 + u64 H3Offset; + u64 DataOffset; + u64 DataSize; + // TMD would be here + u64 DOLOffset; + u64 DOLSize; + u64 FSTOffset; + u64 FSTSize; + u32 ApploaderSize; + u32 ApploaderTrailerSize; +}; +struct SPartition +{ + u32 Number; + u64 Offset; + u32 Type; + SPartitionHeader Header; +}; +struct SPartitionGroup +{ + u32 numPartitions; + u64 PartitionsOffset; + std::vector PartitionsVec; +}; +SPartitionGroup PartitionGroup[4]; + + +void MarkAsUsed(u64 _Offset, u64 _Size); +void MarkAsUsedE(u64 _PartitionDataOffset, u64 _Offset, u64 _Size); +bool MarkAsScrubbed(const char* filename); +void ReadFromDisc(u64 _Offset, u64 _Length, u32& _Buffer); +void ReadFromDisc(u64 _Offset, u64 _Length, u64& _Buffer); +void ReadFromVolume(u64 _Offset, u64 _Length, u32& _Buffer); +void ReadFromVolume(u64 _Offset, u64 _Length, u64& _Buffer); +void ParseDisc(); +void ParsePartitionData(SPartition& _rPartition); +u32 GetDOLSize(u64 _DOLOffset); + + +// Check for simplistic flag stored in an unencrypted pad space (offset 0x80) +u32 IsScrubbed(const char* filename) +{ + FILE* f = fopen(filename, "rb"); + + if (!f) + return false; + + u32 ScrubbedFlag = SCRUBBER_VERSION; + fseek(f, 0x80, SEEK_SET); + fread(&ScrubbedFlag, sizeof(ScrubbedFlag), 1, f); + fclose(f); + return ScrubbedFlag; +} + +bool Scrub(const char* filename, CompressCB callback, void* arg) +{ + bool success = true; + m_Filename = std::string(filename); + + u32 version = IsScrubbed(filename); + if (version && version < SCRUBBER_VERSION) + { + if (!PanicYesNo("%s was scrubbed with an older version of DiscScrubber, would you like to re-scrub?", filename)) + return success; + } + else if (version) + { + callback("DiscScrubber: This disc is already scrubbed", 0, arg); + NOTICE_LOG(DISCIO, "%s is already scrubbed, skipping...", filename); + return success; + } + + m_Disc = CreateVolumeFromFilename(filename); + m_FileSize = m_Disc->GetSize(); + + u64 numClusters = m_FileSize / CLUSTER_SIZE; + + // Warn if not DVD5 or DVD9 size + if (numClusters != 0x23048 && numClusters != 0x46090) + WARN_LOG(DISCIO, "%s is not a standard sized wii m_Disc! (%x blocks)", filename, numClusters); + + // Table of free blocks + m_FreeTable = new u8[numClusters]; + std::fill(m_FreeTable, m_FreeTable + numClusters, 1); + // Fill the dummy all 1 block + m_Sector1 = new u8[CLUSTER_SIZE]; + std::fill(m_Sector1, m_Sector1 + CLUSTER_SIZE, 0xFF); + + // Fill out table of free blocks + callback("DiscScrubber: Parsing...", 0, arg); + ParseDisc(); + // Done with it; need it closed for the next part + delete m_Disc; + m_Disc = NULL; + + // Open file + FILE* pFile = fopen(filename, "r+b"); + if (!pFile) + { + ERROR_LOG(DISCIO, "DiscScrubber failed to open %s", filename); + success = false; + return success; + } + + // Modify file, obeying the table of free blocks + NOTICE_LOG(DISCIO, "Removing garbage data...go get some coffee :)"); + for (u64 i = 0; i < numClusters; i++) + { + u64 CurrentOffset = i * CLUSTER_SIZE; + + if (m_FreeTable[i]) + { + DEBUG_LOG(DISCIO, "Freeing 0x%016llx", CurrentOffset); + // Area is unused so fill with 1s + fseek(pFile, CurrentOffset, SEEK_SET); + success |= fwrite(m_Sector1, CLUSTER_SIZE, 1, pFile) == CLUSTER_SIZE; + + if (!success) + { + PanicAlert("DiscScrubber failure"); + break; + } + } + else + { + DEBUG_LOG(DISCIO, "Used 0x%016llx", CurrentOffset); + } + + // Update progress dialog + if (i % (numClusters / 1000) == 0) + { + char temp[512]; + sprintf(temp, "DiscScrubber: %u/%u (%s)", i, numClusters, m_FreeTable[i] ? "Free" : "Used"); + callback(temp, (float)i / (float)numClusters, arg); + } + } + NOTICE_LOG(DISCIO, "Done removing garbage data"); + + fclose(pFile); + + delete m_Sector1; + delete m_FreeTable; + + if (success) + if (!MarkAsScrubbed(filename)) + ERROR_LOG(DISCIO, "Really weird - failed to mark scrubbed disk as scrubbed :s"); + + return success; +} + +void MarkAsUsed(u64 _Offset, u64 _Size) +{ + u64 CurrentOffset = _Offset; + u64 EndOffset = CurrentOffset + _Size; + + DEBUG_LOG(DISCIO, "Marking 0x%016llx - 0x%016llx as used", _Offset, EndOffset); + + while ((CurrentOffset < EndOffset) && (CurrentOffset < m_FileSize)) + { + m_FreeTable[CurrentOffset / CLUSTER_SIZE] = 0; + CurrentOffset += CLUSTER_SIZE; + } +} +// Compensate for 0x400(SHA-1) per 0x8000(cluster) +void MarkAsUsedE(u64 _PartitionDataOffset, u64 _Offset, u64 _Size) +{ + u64 Offset; + u64 Size; + + Offset = _Offset / 0x7c00; + Offset = Offset * CLUSTER_SIZE; + Offset += _PartitionDataOffset; + + Size = _Size / 0x7c00; + Size = (Size + 1) * CLUSTER_SIZE; + + // Add on the offset in the first block for the case where data straddles blocks + Size += _Offset % 0x7c00; + + MarkAsUsed(Offset, Size); +} + +bool MarkAsScrubbed(const char* filename) +{ + FILE* f = fopen(filename, "r+b"); + + if (!f) + return false; + + bool success; + u8 ScrubbedFlag[1] = {SCRUBBER_VERSION}; + fseek(f, 0x80, SEEK_SET); + success |= fwrite(ScrubbedFlag, 1, 1, f) == 1; + fclose(f); + return success; +} + +// Helper functions for RAW reading the BE discs +void ReadFromDisc(u64 _Offset, u64 _Length, u32& _Buffer) +{ + m_Disc->RAWRead(_Offset, _Length, (u8*)&_Buffer); + _Buffer = Common::swap32(_Buffer); +} +void ReadFromDisc(u64 _Offset, u64 _Length, u64& _Buffer) +{ + m_Disc->RAWRead(_Offset, _Length, (u8*)&_Buffer); + _Buffer = Common::swap32((u32)_Buffer); + _Buffer <<= 2; +} +// Helper functions for reading the BE volume +void ReadFromVolume(u64 _Offset, u64 _Length, u32& _Buffer) +{ + m_Disc->Read(_Offset, _Length, (u8*)&_Buffer); + _Buffer = Common::swap32(_Buffer); +} +void ReadFromVolume(u64 _Offset, u64 _Length, u64& _Buffer) +{ + m_Disc->Read(_Offset, _Length, (u8*)&_Buffer); + _Buffer = Common::swap32((u32)_Buffer); + _Buffer <<= 2; +} + +void ParseDisc() +{ + // Mark the header as used - it's mostly 0s anyways + MarkAsUsed(0, 0x50000); + + for (int x = 0; x < 4; x++) + { + ReadFromDisc(0x40000 + (x * 8) + 0, 4, PartitionGroup[x].numPartitions); + ReadFromDisc(0x40000 + (x * 8) + 4, 4, PartitionGroup[x].PartitionsOffset); + + // Read all partitions + for (u32 i = 0; i < PartitionGroup[x].numPartitions; i++) + { + SPartition Partition; + + Partition.Number = i; + + ReadFromDisc(PartitionGroup[x].PartitionsOffset + (i * 8) + 0, 4, Partition.Offset); + ReadFromDisc(PartitionGroup[x].PartitionsOffset + (i * 8) + 4, 4, Partition.Type); + + ReadFromDisc(Partition.Offset + 0x2a4, 4, Partition.Header.TMDSize); + ReadFromDisc(Partition.Offset + 0x2a8, 4, Partition.Header.TMDOffset); + ReadFromDisc(Partition.Offset + 0x2ac, 4, Partition.Header.CertChainSize); + ReadFromDisc(Partition.Offset + 0x2b0, 4, Partition.Header.CertChainOffset); + ReadFromDisc(Partition.Offset + 0x2b4, 4, Partition.Header.H3Offset); + ReadFromDisc(Partition.Offset + 0x2b8, 4, Partition.Header.DataOffset); + ReadFromDisc(Partition.Offset + 0x2bc, 4, Partition.Header.DataSize); + + PartitionGroup[x].PartitionsVec.push_back(Partition); + } + + for (size_t i = 0; i < PartitionGroup[x].PartitionsVec.size(); i++) + { + SPartition& rPartition = PartitionGroup[x].PartitionsVec.at(i); + const SPartitionHeader& rHeader = PartitionGroup[x].PartitionsVec.at(i).Header; + + MarkAsUsed(rPartition.Offset, 0x2c0); + + MarkAsUsed(rPartition.Offset + rHeader.TMDOffset, rHeader.TMDSize); + MarkAsUsed(rPartition.Offset + rHeader.CertChainOffset, rHeader.CertChainSize); + MarkAsUsed(rPartition.Offset + rHeader.H3Offset, 0x18000); + // This would mark the whole (encrypted) data area + // we need to parse FST and other crap to find what's free within it! + //MarkAsUsed(rPartition.Offset + rHeader.DataOffset, rHeader.DataSize); + + // Parse Data! This is where the big gain is + ParsePartitionData(rPartition); + } + } +} + +// Operations dealing with encrypted space are done here - the volume is swapped to allow this +void ParsePartitionData(SPartition& _rPartition) +{ + // Switch out the main volume temporarily + IVolume *OldVolume = m_Disc; + + // Ready some stuff + m_Disc = CreateVolumeFromFilename(m_Filename.c_str(), _rPartition.Number); + IFileSystem *FileSystem = CreateFileSystem(m_Disc); + + std::vector Files; + size_t numFiles = FileSystem->GetFileList(Files); + + // Mark things as used which are not in the filesystem + // Header, Header Information, Apploader + ReadFromVolume(0x2440 + 0x14, 4, _rPartition.Header.ApploaderSize); + ReadFromVolume(0x2440 + 0x18, 4, _rPartition.Header.ApploaderTrailerSize); + MarkAsUsedE(_rPartition.Offset + + _rPartition.Header.DataOffset + , 0 + , 0x2440 + + _rPartition.Header.ApploaderSize + + _rPartition.Header.ApploaderTrailerSize); + + // DOL + ReadFromVolume(0x420, 4, _rPartition.Header.DOLOffset); + _rPartition.Header.DOLSize = GetDOLSize(_rPartition.Header.DOLOffset); + MarkAsUsedE(_rPartition.Offset + + _rPartition.Header.DataOffset + , _rPartition.Header.DOLOffset + , _rPartition.Header.DOLSize); + + // FST + ReadFromVolume(0x424, 4, _rPartition.Header.FSTOffset); + ReadFromVolume(0x428, 4, _rPartition.Header.FSTSize); + MarkAsUsedE(_rPartition.Offset + + _rPartition.Header.DataOffset + , _rPartition.Header.FSTOffset + , _rPartition.Header.FSTSize); + + // Go through the filesystem and mark entries as used + for (size_t currentFile = 0; currentFile < numFiles; currentFile++) + { + DEBUG_LOG(DISCIO, "%s", (*Files.at(currentFile)).m_FullPath); + // Just 1byte for directory? - it will end up reserving a cluster this way + if ((*Files.at(currentFile)).m_NameOffset & 0x1000000) + MarkAsUsedE(_rPartition.Offset + + _rPartition.Header.DataOffset + , (*Files.at(currentFile)).m_Offset, 1); + else + MarkAsUsedE(_rPartition.Offset + + _rPartition.Header.DataOffset + , (*Files.at(currentFile)).m_Offset, (*Files.at(currentFile)).m_FileSize); + } + + // Swap back + delete m_Disc; + m_Disc = OldVolume; +} + +u32 GetDOLSize(u64 _DOLOffset) +{ + u32 offset = 0, size = 0, max = 0; + + // Iterate through the 7 code segments + for (u8 i = 0; i < 7; i++) + { + ReadFromVolume(_DOLOffset + 0x00 + i * 4, 4, offset); + ReadFromVolume(_DOLOffset + 0x90 + i * 4, 4, size); + if (offset + size > max) + max = offset + size; + } + + // Iterate through the 11 data segments + for (u8 i = 0; i < 11; i++) + { + ReadFromVolume(_DOLOffset + 0x1c + i * 4, 4, offset); + ReadFromVolume(_DOLOffset + 0xac + i * 4, 4, size); + if (offset + size > max) + max = offset + size; + } + + return max; +} + +} // namespace DiscScrubber + +} // namespace DiscIO diff --git a/Source/Core/DiscIO/Src/DiscScrubber.h b/Source/Core/DiscIO/Src/DiscScrubber.h new file mode 100644 index 0000000000..9e57698055 --- /dev/null +++ b/Source/Core/DiscIO/Src/DiscScrubber.h @@ -0,0 +1,48 @@ +// Copyright (C) 2003-2009 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/ + + +// DiscScrubber removes the garbage data from discs (currently wii only) which +// is on the disc due to encryption + +// It could be adapted to gc discs, but the gain is most likely negligible, +// and having 1:1 backups of discs is always nice when they are reasonably sized + +// Note: the technique is inspired by Wiiscrubber, but much simpler - intentionally :) + +#ifndef DISC_SCRUBBER_H +#define DISC_SCRUBBER_H + +#include "Common.h" +#include "Blob.h" + + +namespace DiscIO +{ + +namespace DiscScrubber +{ + +u32 IsScrubbed(const char* filename); + +bool Scrub(const char* filename, CompressCB callback = 0, void* arg = 0); + +} // namespace DiscScrubber + +} // namespace DiscIO + +#endif // DISC_SCRUBBER_H diff --git a/Source/Core/DiscIO/Src/DriveBlob.cpp b/Source/Core/DiscIO/Src/DriveBlob.cpp index e8f5ab22ad..1a49890839 100644 --- a/Source/Core/DiscIO/Src/DriveBlob.cpp +++ b/Source/Core/DiscIO/Src/DriveBlob.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/DriveBlob.h b/Source/Core/DiscIO/Src/DriveBlob.h index d1da218e91..62fe08d5e4 100644 --- a/Source/Core/DiscIO/Src/DriveBlob.h +++ b/Source/Core/DiscIO/Src/DriveBlob.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/FileBlob.cpp b/Source/Core/DiscIO/Src/FileBlob.cpp index 787335e511..ffbc06645f 100644 --- a/Source/Core/DiscIO/Src/FileBlob.cpp +++ b/Source/Core/DiscIO/Src/FileBlob.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/FileBlob.h b/Source/Core/DiscIO/Src/FileBlob.h index e7888d31d1..a7ffec8cb1 100644 --- a/Source/Core/DiscIO/Src/FileBlob.h +++ b/Source/Core/DiscIO/Src/FileBlob.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/FileHandlerARC.cpp b/Source/Core/DiscIO/Src/FileHandlerARC.cpp index cc464050c7..d6b5374cc8 100644 --- a/Source/Core/DiscIO/Src/FileHandlerARC.cpp +++ b/Source/Core/DiscIO/Src/FileHandlerARC.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/FileHandlerARC.h b/Source/Core/DiscIO/Src/FileHandlerARC.h index c59002eca1..800f11fa91 100644 --- a/Source/Core/DiscIO/Src/FileHandlerARC.h +++ b/Source/Core/DiscIO/Src/FileHandlerARC.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp index 4afdad5a73..527bf99cf5 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.h b/Source/Core/DiscIO/Src/FileSystemGCWii.h index dded1c17e1..cf34dc0675 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.h +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/Filesystem.cpp b/Source/Core/DiscIO/Src/Filesystem.cpp index 2ec9c38ceb..6cad4731f7 100644 --- a/Source/Core/DiscIO/Src/Filesystem.cpp +++ b/Source/Core/DiscIO/Src/Filesystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/Filesystem.h b/Source/Core/DiscIO/Src/Filesystem.h index b8be5649a8..e5e8c00c5e 100644 --- a/Source/Core/DiscIO/Src/Filesystem.h +++ b/Source/Core/DiscIO/Src/Filesystem.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index 7b25b535c8..b80156973f 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h index 731ca722f5..9b5068fa9d 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.h +++ b/Source/Core/DiscIO/Src/NANDContentLoader.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/Volume.h b/Source/Core/DiscIO/Src/Volume.h index e5e2880d47..d065e26d55 100644 --- a/Source/Core/DiscIO/Src/Volume.h +++ b/Source/Core/DiscIO/Src/Volume.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/VolumeCreator.cpp b/Source/Core/DiscIO/Src/VolumeCreator.cpp index dca2279cf0..f379c6a94e 100644 --- a/Source/Core/DiscIO/Src/VolumeCreator.cpp +++ b/Source/Core/DiscIO/Src/VolumeCreator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/VolumeCreator.h b/Source/Core/DiscIO/Src/VolumeCreator.h index 650bb15b7e..8948873d17 100644 --- a/Source/Core/DiscIO/Src/VolumeCreator.h +++ b/Source/Core/DiscIO/Src/VolumeCreator.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index 426e42ead4..4da377b451 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h index 6f8d827d0d..828f2cb969 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.h +++ b/Source/Core/DiscIO/Src/VolumeDirectory.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp index aca22480c9..3082d74aa2 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.cpp +++ b/Source/Core/DiscIO/Src/VolumeGC.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 @@ -20,14 +20,6 @@ #include "VolumeGC.h" #include "StringUtil.h" -////////////////////////////////////////////////// -// Music mod -// ŻŻŻŻŻŻŻŻŻŻ -#include "Setup.h" // Define MUSICMOD here -#ifdef MUSICMOD -#include "../../../../Externals/MusicMod/Main/Src/Main.h" -#endif -/////////////////////// namespace DiscIO { @@ -45,13 +37,7 @@ bool CVolumeGC::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const { if (m_pReader == NULL) return false; - ////////////////////////////////////////////////// - // Music mod - // ŻŻŻŻŻŻŻŻŻŻ - #ifdef MUSICMOD - MusicMod::FindFilename(_Offset, _Length); - #endif - /////////////////////// + return m_pReader->Read(_Offset, _Length, _pBuffer); } diff --git a/Source/Core/DiscIO/Src/VolumeGC.h b/Source/Core/DiscIO/Src/VolumeGC.h index 941ceb64ee..aacc38de98 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.h +++ b/Source/Core/DiscIO/Src/VolumeGC.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp index ed9a9bcf8c..324ec878a8 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 @@ -22,7 +22,9 @@ namespace DiscIO { -CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, const unsigned char* _pVolumeKey) + +CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, + const unsigned char* _pVolumeKey) : m_pReader(_pReader), m_pBuffer(0), m_VolumeOffset(_VolumeOffset), @@ -53,8 +55,7 @@ bool CVolumeWiiCrypted::RAWRead( u64 _Offset, u64 _Length, u8* _pBuffer ) const return true; } -bool -CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const +bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const { if (m_pReader == NULL) { @@ -97,8 +98,7 @@ CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const return(true); } -std::string -CVolumeWiiCrypted::GetUniqueID() const +std::string CVolumeWiiCrypted::GetUniqueID() const { if (m_pReader == NULL) { @@ -118,8 +118,7 @@ CVolumeWiiCrypted::GetUniqueID() const } -IVolume::ECountry -CVolumeWiiCrypted::GetCountry() const +IVolume::ECountry CVolumeWiiCrypted::GetCountry() const { if (!m_pReader) { @@ -181,8 +180,7 @@ CVolumeWiiCrypted::GetCountry() const return(country); } -std::string -CVolumeWiiCrypted::GetMakerID() const +std::string CVolumeWiiCrypted::GetMakerID() const { if (m_pReader == NULL) { @@ -201,8 +199,7 @@ CVolumeWiiCrypted::GetMakerID() const return(makerID); } -std::string -CVolumeWiiCrypted::GetName() const +std::string CVolumeWiiCrypted::GetName() const { if (m_pReader == NULL) { @@ -219,8 +216,7 @@ CVolumeWiiCrypted::GetName() const return(name); } -u32 -CVolumeWiiCrypted::GetFSTSize() const +u32 CVolumeWiiCrypted::GetFSTSize() const { if (m_pReader == NULL) { @@ -237,8 +233,7 @@ CVolumeWiiCrypted::GetFSTSize() const return(size); } -std::string -CVolumeWiiCrypted::GetApploaderDate() const +std::string CVolumeWiiCrypted::GetApploaderDate() const { if (m_pReader == NULL) { @@ -257,9 +252,7 @@ CVolumeWiiCrypted::GetApploaderDate() const return(date); } - -u64 -CVolumeWiiCrypted::GetSize() const +u64 CVolumeWiiCrypted::GetSize() const { if (m_pReader) { @@ -271,5 +264,4 @@ CVolumeWiiCrypted::GetSize() const } } - } // namespace diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h index 64435ba2cc..a8973f135d 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/stdafx.cpp b/Source/Core/DiscIO/Src/stdafx.cpp index 903e31a1fc..7bd4a0b18e 100644 --- a/Source/Core/DiscIO/Src/stdafx.cpp +++ b/Source/Core/DiscIO/Src/stdafx.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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 diff --git a/Source/Core/DiscIO/Src/stdafx.h b/Source/Core/DiscIO/Src/stdafx.h index 9069e384d1..90bb93821e 100644 --- a/Source/Core/DiscIO/Src/stdafx.h +++ b/Source/Core/DiscIO/Src/stdafx.h @@ -1,4 +1,4 @@ -// Copyright (C) 2003-2008 Dolphin Project. +// Copyright (C) 2003-2009 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