diff --git a/Source/Core/DiscIO/Src/VolumeCreator.cpp b/Source/Core/DiscIO/Src/VolumeCreator.cpp index 546cd10d13..dca2279cf0 100644 --- a/Source/Core/DiscIO/Src/VolumeCreator.cpp +++ b/Source/Core/DiscIO/Src/VolumeCreator.cpp @@ -65,10 +65,10 @@ private: const unsigned char g_MasterKey[16] = {0xeb,0xe4,0x2a,0x22,0x5e,0x85,0x93,0xe4,0x48,0xd9,0xc5,0x45,0x73,0x81,0xaa,0xf7}; const unsigned char g_MasterKeyK[16] = {0x63,0xb8,0x2b,0xb4,0xf4,0x61,0x4e,0x2e,0x13,0xf2,0xfe,0xfb,0xba,0x4c,0x9b,0x7e}; -IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType, bool Korean); +IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType, u32 _VolumeNum, bool Korean); EDiscType GetDiscType(IBlobReader& _rReader); -IVolume* CreateVolumeFromFilename(const std::string& _rFilename) +IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _VolumeNum) { IBlobReader* pReader = CreateBlobReader(_rFilename.c_str()); if (pReader == NULL) @@ -85,7 +85,7 @@ IVolume* CreateVolumeFromFilename(const std::string& _rFilename) u8 region; pReader->Read(0x3,1,®ion); - IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, 0, region == 'K'); + IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, 0, _VolumeNum, region == 'K'); if (pVolume == NULL) { @@ -122,11 +122,14 @@ bool IsVolumeWiiDisc(const IVolume *_rVolume) return (Common::swap32(MagicWord) == 0x5D1C9EA3); } -IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType, bool Korean) +IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType, u32 _VolumeNum, bool Korean) { CBlobBigEndianReader Reader(_rReader); u32 numPartitions = Reader.Read32(0x40000); + // Check if we're looking for a valid partition + if (_VolumeNum != -1 && _VolumeNum > numPartitions) + return NULL; u64 PartitionsOffset = (u64)Reader.Read32(0x40004) << 2; #ifdef _WIN32 struct SPartition @@ -146,12 +149,14 @@ IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType, PartitionsVec.push_back(Partition); } - // find the partition with the game... type == 1 is prolly the firmware update partition + // return the partition type specified or number + // types: 0 = game, 1 = firmware update, 2 = channel installer + // some partitions on ssbb use the ascii title id of the demo VC game they hold... for (size_t i = 0; i < PartitionsVec.size(); i++) { const SPartition& rPartition = PartitionsVec[i]; - if (rPartition.Type == _VolumeType) + if (rPartition.Type == _VolumeType || i == _VolumeNum) { u8 SubKey[16]; _rReader.Read(rPartition.Offset + 0x1bf, 16, SubKey); @@ -166,7 +171,9 @@ IVolume* CreateVolumeFromCryptedWiiImage(IBlobReader& _rReader, u32 _VolumeType, u8 VolumeKey[16]; AES_cbc_encrypt(SubKey, VolumeKey, 16, &AES_KEY, IV, AES_DECRYPT); - return new CVolumeWiiCrypted(&_rReader, rPartition.Offset + 0x20000, VolumeKey); + // -1 means the caller just wanted the partition with matching type + if (_VolumeNum == -1 || i == _VolumeNum) + return new CVolumeWiiCrypted(&_rReader, rPartition.Offset + 0x20000, VolumeKey); } } diff --git a/Source/Core/DiscIO/Src/VolumeCreator.h b/Source/Core/DiscIO/Src/VolumeCreator.h index 6366bb1811..650bb15b7e 100644 --- a/Source/Core/DiscIO/Src/VolumeCreator.h +++ b/Source/Core/DiscIO/Src/VolumeCreator.h @@ -22,7 +22,7 @@ namespace DiscIO { -IVolume* CreateVolumeFromFilename(const std::string& _rFilename); +IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _VolumeNum = -1); IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii); bool IsVolumeWiiDisc(const IVolume *_rVolume); } // namespace diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 0ac00945aa..68f61a1326 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -24,6 +24,13 @@ #include "ARCodeAddEdit.h" #include "ConfigManager.h" +struct WiiPartition +{ + DiscIO::IVolume *Partition; + DiscIO::IFileSystem *FileSystem; + std::vector Files; +}; +std::vector WiiDisc; DiscIO::IVolume *OpenISO = NULL; DiscIO::IFileSystem *pFileSystem = NULL; @@ -56,10 +63,27 @@ END_EVENT_TABLE() CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) : wxDialog(parent, id, title, position, size, style) { - OpenISO = DiscIO::CreateVolumeFromFilename(fileName); - pFileSystem = DiscIO::CreateFileSystem(OpenISO); - - pFileSystem->GetFileList(Our_Files); + OpenISO = DiscIO::CreateVolumeFromFilename(fileName); + if (DiscIO::IsVolumeWiiDisc(OpenISO)) + { + for (u32 i = 0; i < 0xF; i++) + { + WiiPartition temp; + if ((temp.Partition = DiscIO::CreateVolumeFromFilename(fileName, i)) != NULL) + { + temp.FileSystem = DiscIO::CreateFileSystem(temp.Partition); + temp.FileSystem->GetFileList(temp.Files); + WiiDisc.push_back(temp); + } + else + break; + } + } + else + { + pFileSystem = DiscIO::CreateFileSystem(OpenISO); + pFileSystem->GetFileList(GCFiles); + } OpenGameListItem = new GameListItem(fileName); @@ -118,8 +142,22 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW wxMouseEventHandler(CISOProperties::RightClickOnBanner), (wxObject*)NULL, this); // Filesystem browser/dumper - fileIter beginning = Our_Files.begin(), end = Our_Files.end(), pos = Our_Files.begin(); - CreateDirectoryTree(RootId, beginning, end, pos, (char *)"/"); + if (DiscIO::IsVolumeWiiDisc(OpenISO)) + { + for (u32 i = 0; i < WiiDisc.size(); i++) + { + fileIter beginning = WiiDisc.at(i).Files.begin(), end = WiiDisc.at(i).Files.end(), pos = WiiDisc.at(i).Files.begin(); + wxTreeItemId PartitionRoot = m_Treectrl->AppendItem(RootId, wxString::Format("Partition %i", i), -1, -1, 0); + CreateDirectoryTree(PartitionRoot, beginning, end, pos, (char *)"/"); + if (i == 0) + m_Treectrl->Expand(PartitionRoot); + } + } + else + { + fileIter beginning = GCFiles.begin(), end = GCFiles.end(), pos = GCFiles.begin(); + CreateDirectoryTree(RootId, beginning, end, pos, (char *)"/"); + } m_Treectrl->Expand(RootId); std::string filename, extension; @@ -136,6 +174,7 @@ CISOProperties::~CISOProperties() { delete pFileSystem; delete OpenISO; + WiiDisc.clear(); } void CISOProperties::CreateDirectoryTree(wxTreeItemId& parent, @@ -386,9 +425,8 @@ void CISOProperties::CreateGUIControls() // Filesystem tree sbTreectrl = new wxStaticBoxSizer(wxVERTICAL, m_Filesystem, _("Filesystem")); m_Treectrl = new wxTreeCtrl(m_Filesystem, ID_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE, wxDefaultValidator); + RootId = m_Treectrl->AddRoot(wxT("Disc"), -1, -1, 0); - RootId = m_Treectrl->AddRoot(_("Root"), -1, -1, 0); - wxBoxSizer* sTreePage; sTreePage = new wxBoxSizer(wxVERTICAL); sbTreectrl->Add(m_Treectrl, 1, wxEXPAND); @@ -460,11 +498,11 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event)) File = m_Treectrl->GetItemText(m_Treectrl->GetSelection()); Path = wxFileSelector( - _T("Export File"), + wxT("Export File"), wxEmptyString, File, wxEmptyString, wxString::Format ( - _T("All files (%s)|%s"), + wxT("All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr ), @@ -478,12 +516,19 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event)) { wxString temp; temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection())); - File = temp + _T(DIR_SEP_CHR) + File; + File = temp + wxT(DIR_SEP_CHR) + File; m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection())); } - pFileSystem->ExportFile(File.mb_str(), Path.mb_str()); + if (DiscIO::IsVolumeWiiDisc(OpenISO)) + { + int partitionNum = wxAtoi(File.SubString(10, 11)); + File.Remove(0, 12); // Remove "Partition x/" + WiiDisc.at(partitionNum).FileSystem->ExportFile(File.mb_str(), Path.mb_str()); + } + else + pFileSystem->ExportFile(File.mb_str(), Path.mb_str()); } void CISOProperties::OnExtractDir(wxCommandEvent& WXUNUSED (event)) diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index 56eb74bfcd..5b64c29730 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -216,8 +216,8 @@ class CISOProperties : public wxDialog void OnChangeBannerLang(wxCommandEvent& event); GameListItem *OpenGameListItem; - - std::vector Our_Files; + + std::vector GCFiles; typedef std::vector::iterator fileIter; void CreateDirectoryTree(wxTreeItemId& parent,fileIter& begin,