Fix extracting Wii disc partitions numbered 10 or higher

Instead of trying to get the partition number from the
(localized!) item name, the partitions are now stored as item data.
This commit is contained in:
JosJuice 2015-04-15 09:29:24 +02:00
parent a6970b3744
commit 86ceb54c38
2 changed files with 61 additions and 87 deletions

View File

@ -115,39 +115,6 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
// Load ISO data // Load ISO data
OpenISO = DiscIO::CreateVolumeFromFilename(fileName); OpenISO = DiscIO::CreateVolumeFromFilename(fileName);
bool IsWad = OpenISO->IsWadFile(); bool IsWad = OpenISO->IsWadFile();
if (OpenISO->IsWiiDisc())
{
for (int group = 0; group < 4; group++)
{
for (u32 i = 0; i < 0xFFFFFFFF; i++) // yes, technically there can be OVER NINE THOUSAND partitions...
{
WiiPartition temp;
if ((temp.Partition = DiscIO::CreateVolumeFromFilename(fileName, group, i)) != nullptr)
{
if ((temp.FileSystem = DiscIO::CreateFileSystem(temp.Partition)) != nullptr)
{
temp.FileSystem->GetFileList(temp.Files);
WiiDisc.push_back(temp);
}
}
else
{
break;
}
}
}
}
else
{
// TODO : Should we add a way to browse the wad file ?
if (!IsWad)
{
GCFiles.clear();
pFileSystem = DiscIO::CreateFileSystem(OpenISO);
if (pFileSystem)
pFileSystem->GetFileList(GCFiles);
}
}
// TODO: Is it really necessary to use GetTitleID in case GetUniqueID fails? // TODO: Is it really necessary to use GetTitleID in case GetUniqueID fails?
game_id = OpenISO->GetUniqueID(); game_id = OpenISO->GetUniqueID();
@ -274,19 +241,41 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW
{ {
if (OpenISO->IsWiiDisc()) if (OpenISO->IsWiiDisc())
{ {
for (u32 i = 0; i < WiiDisc.size(); i++) int partition_count = 0;
for (int group = 0; group < 4; group++)
{ {
WiiPartition partition = WiiDisc.at(i); for (u32 i = 0; i < 0xFFFFFFFF; i++) // yes, technically there can be OVER NINE THOUSAND partitions...
wxTreeItemId PartitionRoot = {
m_Treectrl->AppendItem(RootId, wxString::Format(_("Partition %i"), i), 0, 0); WiiPartition partition;
CreateDirectoryTree(PartitionRoot, partition.Files, 1, partition.Files.at(0)->m_FileSize); if ((partition.Partition = DiscIO::CreateVolumeFromFilename(fileName, group, i)) != nullptr)
if (i == 1) {
m_Treectrl->Expand(PartitionRoot); if ((partition.FileSystem = DiscIO::CreateFileSystem(partition.Partition)) != nullptr)
{
partition.FileSystem->GetFileList(partition.Files);
wxTreeItemId PartitionRoot =
m_Treectrl->AppendItem(RootId, wxString::Format(_("Partition %i"), partition_count), 0, 0);
m_Treectrl->SetItemData(PartitionRoot, new WiiPartition(partition));
CreateDirectoryTree(PartitionRoot, partition.Files, 1, partition.Files.at(0)->m_FileSize);
if (partition_count == 1)
m_Treectrl->Expand(PartitionRoot);
partition_count++;
}
}
else
{
break;
}
}
} }
} }
else if (!GCFiles.empty()) else
{ {
CreateDirectoryTree(RootId, GCFiles, 1, GCFiles.at(0)->m_FileSize); GCFiles.clear();
pFileSystem = DiscIO::CreateFileSystem(OpenISO);
if (pFileSystem)
pFileSystem->GetFileList(GCFiles);
if (!GCFiles.empty())
CreateDirectoryTree(RootId, GCFiles, 1, GCFiles.at(0)->m_FileSize);
} }
m_Treectrl->Expand(RootId); m_Treectrl->Expand(RootId);
@ -297,8 +286,7 @@ CISOProperties::~CISOProperties()
{ {
if (!OpenISO->IsWiiDisc() && !OpenISO->IsWadFile() && pFileSystem) if (!OpenISO->IsWiiDisc() && !OpenISO->IsWadFile() && pFileSystem)
delete pFileSystem; delete pFileSystem;
// two vector's items are no longer valid after deleting filesystem // vector's items are no longer valid after deleting filesystem
WiiDisc.clear();
GCFiles.clear(); GCFiles.clear();
delete OpenGameListItem; delete OpenGameListItem;
delete OpenISO; delete OpenISO;
@ -767,11 +755,8 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event))
if (OpenISO->IsWiiDisc()) if (OpenISO->IsWiiDisc())
{ {
size_t slash_index = File.find('/'); WiiPartition* partition = reinterpret_cast<WiiPartition*>(m_Treectrl->GetItemData(m_Treectrl->GetSelection()));
int partitionNum = wxAtoi(File.Mid(slash_index - 1, 1)); partition->FileSystem->ExportFile(WxStrToStr(File), WxStrToStr(Path));
File.erase(0, slash_index + 1); // Remove "Partition x/"
WiiDisc.at(partitionNum).FileSystem->ExportFile(WxStrToStr(File), WxStrToStr(Path));
} }
else else
{ {
@ -779,9 +764,9 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event))
} }
} }
void CISOProperties::ExportDir(const std::string& _rFullPath, const std::string& _rExportFolder, const int partitionNum) void CISOProperties::ExportDir(const std::string& _rFullPath, const std::string& _rExportFolder, const WiiPartition* partition)
{ {
DiscIO::IFileSystem* const fs = OpenISO->IsWiiDisc() ? WiiDisc[partitionNum].FileSystem : pFileSystem; DiscIO::IFileSystem* const fs = OpenISO->IsWiiDisc() ? partition->FileSystem : pFileSystem;
std::vector<const DiscIO::SFileInfo*> fst; std::vector<const DiscIO::SFileInfo*> fst;
fs->GetFileList(fst); fs->GetFileList(fst);
@ -882,10 +867,20 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event)
if (event.GetId() == IDM_EXTRACTALL) if (event.GetId() == IDM_EXTRACTALL)
{ {
if (OpenISO->IsWiiDisc()) if (OpenISO->IsWiiDisc())
for (u32 i = 0; i < WiiDisc.size(); i++) {
ExportDir("", WxStrToStr(Path), i); wxTreeItemIdValue cookie;
wxTreeItemId root = m_Treectrl->GetRootItem();
wxTreeItemId item = m_Treectrl->GetFirstChild(root, cookie);
while (item.IsOk())
{
ExportDir("", WxStrToStr(Path), reinterpret_cast<WiiPartition*>(m_Treectrl->GetItemData(item)));
item = m_Treectrl->GetNextChild(root, cookie);
}
}
else else
{
ExportDir("", WxStrToStr(Path)); ExportDir("", WxStrToStr(Path));
}
return; return;
} }
@ -902,11 +897,9 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event)
if (OpenISO->IsWiiDisc()) if (OpenISO->IsWiiDisc())
{ {
size_t slash_index = Directory.find('/'); WiiPartition* partition = reinterpret_cast<WiiPartition*>(m_Treectrl->GetItemData(m_Treectrl->GetSelection()));
int partitionNum = wxAtoi(Directory.Mid(slash_index - 1, 1)); Directory.erase(0, m_Treectrl->GetItemText(m_Treectrl->GetSelection()).length() + 1); // Remove "Partition x/"
ExportDir(WxStrToStr(Directory), WxStrToStr(Path), partition);
Directory.erase(0, slash_index + 1); // Remove "Partition x/"
ExportDir(WxStrToStr(Directory), WxStrToStr(Path), partitionNum);
} }
else else
{ {
@ -924,19 +917,8 @@ void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event)
if (OpenISO->IsWiiDisc()) if (OpenISO->IsWiiDisc())
{ {
wxString Directory = m_Treectrl->GetItemText(m_Treectrl->GetSelection()); WiiPartition* partition = reinterpret_cast<WiiPartition*>(m_Treectrl->GetItemData(m_Treectrl->GetSelection()));
unsigned int partitionNum = wxAtoi(Directory.Mid(Directory.find_first_of("0123456789"), 2)); FS = partition->FileSystem;
if (WiiDisc.size() > partitionNum)
{
// Get the filesystem of the LAST partition
FS = WiiDisc.at(partitionNum).FileSystem;
}
else
{
WxUtils::ShowErrorDialog(wxString::Format(_("Partition doesn't exist: %d"), partitionNum));
return;
}
} }
else else
{ {
@ -982,19 +964,12 @@ void CISOProperties::CheckPartitionIntegrity(wxCommandEvent& event)
if (!OpenISO->IsWiiDisc()) if (!OpenISO->IsWiiDisc())
return; return;
wxString PartitionName = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
if (!PartitionName)
return;
// Get the partition number from the item text ("Partition N")
int PartitionNum = wxAtoi(PartitionName.Mid(PartitionName.find_first_of("0123456789"), 1));
const WiiPartition& Partition = WiiDisc[PartitionNum];
wxProgressDialog dialog(_("Checking integrity..."), _("Working..."), 1000, this, wxProgressDialog dialog(_("Checking integrity..."), _("Working..."), 1000, this,
wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH
); );
IntegrityCheckThread thread(Partition); WiiPartition* partition = reinterpret_cast<WiiPartition*>(m_Treectrl->GetItemData(m_Treectrl->GetSelection()));
IntegrityCheckThread thread(*partition);
thread.Run(); thread.Run();
while (thread.IsAlive()) while (thread.IsAlive())
@ -1008,9 +983,9 @@ void CISOProperties::CheckPartitionIntegrity(wxCommandEvent& event)
if (!thread.Wait()) if (!thread.Wait())
{ {
wxMessageBox( wxMessageBox(
wxString::Format(_("Integrity check for partition %d failed. " wxString::Format(_("Integrity check for %s failed. The disc image is most "
"Your dump is most likely corrupted or has been " "likely corrupted or has been patched incorrectly."),
"patched incorrectly."), PartitionNum), m_Treectrl->GetItemText(m_Treectrl->GetSelection())),
_("Integrity Check Error"), wxOK | wxICON_ERROR, this _("Integrity Check Error"), wxOK | wxICON_ERROR, this
); );
} }

View File

@ -40,8 +40,9 @@ class wxWindow;
namespace DiscIO { struct SFileInfo; } namespace DiscIO { struct SFileInfo; }
namespace Gecko { class CodeConfigPanel; } namespace Gecko { class CodeConfigPanel; }
struct WiiPartition class WiiPartition final : public wxTreeItemData
{ {
public:
DiscIO::IVolume *Partition; DiscIO::IVolume *Partition;
DiscIO::IFileSystem *FileSystem; DiscIO::IFileSystem *FileSystem;
std::vector<const DiscIO::SFileInfo *> Files; std::vector<const DiscIO::SFileInfo *> Files;
@ -75,8 +76,6 @@ public:
private: private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
std::vector<WiiPartition> WiiDisc;
DiscIO::IVolume *OpenISO; DiscIO::IVolume *OpenISO;
DiscIO::IFileSystem *pFileSystem; DiscIO::IFileSystem *pFileSystem;
@ -227,7 +226,7 @@ private:
const size_t _FirstIndex, const size_t _FirstIndex,
const size_t _LastIndex); const size_t _LastIndex);
void ExportDir(const std::string& _rFullPath, const std::string& _rExportFilename, void ExportDir(const std::string& _rFullPath, const std::string& _rExportFilename,
const int partitionNum = 0); const WiiPartition* partition = nullptr);
IniFile GameIniDefault; IniFile GameIniDefault;
IniFile GameIniLocal; IniFile GameIniLocal;