summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/DiscIO/Src/CompressedBlob.cpp3
-rw-r--r--Source/Core/DiscIO/Src/DiscScrubber.cpp123
2 files changed, 74 insertions, 52 deletions
diff --git a/Source/Core/DiscIO/Src/CompressedBlob.cpp b/Source/Core/DiscIO/Src/CompressedBlob.cpp
index 387a0bee47..0b94073c5e 100644
--- a/Source/Core/DiscIO/Src/CompressedBlob.cpp
+++ b/Source/Core/DiscIO/Src/CompressedBlob.cpp
@@ -169,7 +169,10 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
if (sub_type == 1)
{
if (!DiscScrubber::Scrub(infile, callback, arg))
+ {
+ PanicAlert("%s failed to be scrubbed. Probably the image is corrupt.", infile);
return false;
+ }
}
FILE* inf = fopen(infile, "rb");
diff --git a/Source/Core/DiscIO/Src/DiscScrubber.cpp b/Source/Core/DiscIO/Src/DiscScrubber.cpp
index 5814bbab16..9b45a760e4 100644
--- a/Source/Core/DiscIO/Src/DiscScrubber.cpp
+++ b/Source/Core/DiscIO/Src/DiscScrubber.cpp
@@ -82,8 +82,8 @@ 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);
+bool ParseDisc();
+bool ParsePartitionData(SPartition& _rPartition);
u32 GetDOLSize(u64 _DOLOffset);
@@ -138,7 +138,8 @@ bool Scrub(const char* filename, CompressCB callback, void* arg)
// Fill out table of free blocks
callback("DiscScrubber: Parsing...", 0, arg);
- ParseDisc();
+ if (!ParseDisc())
+ success = false;
// Done with it; need it closed for the next part
delete m_Disc;
m_Disc = NULL;
@@ -149,9 +150,12 @@ bool Scrub(const char* filename, CompressCB callback, void* arg)
{
ERROR_LOG(DISCIO, "DiscScrubber failed to open %s", filename);
success = false;
- return success;
}
+ // Let's not touch the file if we've failed up to here :p
+ if (!success)
+ goto cleanup;
+
// 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++)
@@ -186,15 +190,15 @@ bool Scrub(const char* filename, CompressCB callback, void* 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");
+cleanup:
+ fclose(pFile);
+ delete m_Sector1;
+ delete m_FreeTable;
+
return success;
}
@@ -270,7 +274,7 @@ void ReadFromVolume(u64 _Offset, u64 _Length, u64& _Buffer)
_Buffer <<= 2;
}
-void ParseDisc()
+bool ParseDisc()
{
// Mark the header as used - it's mostly 0s anyways
MarkAsUsed(0, 0x50000);
@@ -317,14 +321,19 @@ void ParseDisc()
//MarkAsUsed(rPartition.Offset + rHeader.DataOffset, rHeader.DataSize);
// Parse Data! This is where the big gain is
- ParsePartitionData(rPartition);
+ if (!ParsePartitionData(rPartition))
+ return false;
}
}
+
+ return true;
}
// Operations dealing with encrypted space are done here - the volume is swapped to allow this
-void ParsePartitionData(SPartition& _rPartition)
+bool ParsePartitionData(SPartition& _rPartition)
{
+ bool ParsedOK = true;
+
// Switch out the main volume temporarily
IVolume *OldVolume = m_Disc;
@@ -332,49 +341,57 @@ void ParsePartitionData(SPartition& _rPartition)
m_Disc = CreateVolumeFromFilename(m_Filename.c_str(), _rPartition.GroupNumber, _rPartition.Number);
IFileSystem *FileSystem = CreateFileSystem(m_Disc);
- std::vector<const SFileInfo *> 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++)
+ if (!FileSystem)
+ {
+ ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", _rPartition.GroupNumber, _rPartition.Number)
+ ParsedOK = false;
+ }
+ else
{
- 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
+ std::vector<const SFileInfo *> 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
- , (*Files.at(currentFile)).m_Offset, 1);
- else
- MarkAsUsedE(_rPartition.Offset
+ , 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
- , (*Files.at(currentFile)).m_Offset, (*Files.at(currentFile)).m_FileSize);
+ , _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);
+ }
}
delete FileSystem;
@@ -382,6 +399,8 @@ void ParsePartitionData(SPartition& _rPartition)
// Swap back
delete m_Disc;
m_Disc = OldVolume;
+
+ return ParsedOK;
}
u32 GetDOLSize(u64 _DOLOffset)