DiscScrubber: fail gracefully on corrupt images

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3272 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-05-22 07:14:34 +00:00
parent 6a8da15f51
commit 32691cfad7
2 changed files with 74 additions and 52 deletions

View File

@ -169,8 +169,11 @@ 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");
if (!inf)

View File

@ -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,6 +341,13 @@ void ParsePartitionData(SPartition& _rPartition)
m_Disc = CreateVolumeFromFilename(m_Filename.c_str(), _rPartition.GroupNumber, _rPartition.Number);
IFileSystem *FileSystem = CreateFileSystem(m_Disc);
if (!FileSystem)
{
ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", _rPartition.GroupNumber, _rPartition.Number)
ParsedOK = false;
}
else
{
std::vector<const SFileInfo *> Files;
size_t numFiles = FileSystem->GetFileList(Files);
@ -376,12 +392,15 @@ void ParsePartitionData(SPartition& _rPartition)
+ _rPartition.Header.DataOffset
, (*Files.at(currentFile)).m_Offset, (*Files.at(currentFile)).m_FileSize);
}
}
delete FileSystem;
// Swap back
delete m_Disc;
m_Disc = OldVolume;
return ParsedOK;
}
u32 GetDOLSize(u64 _DOLOffset)