From c8bffb01531addda9f345c30d614500650ca82a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 14 May 2017 00:15:12 +0200 Subject: [PATCH] Reuse the IOS code for WAD installation * Less code and logic duplication. * Fixes a bug with the data dir not being created, steps being done in the wrong order. --- Source/Core/DiscIO/NANDContentLoader.cpp | 68 -------------------- Source/Core/DiscIO/NANDContentLoader.h | 1 - Source/Core/DolphinQt2/GameList/GameFile.cpp | 3 +- Source/Core/DolphinWX/FrameTools.cpp | 7 +- Source/Core/UICommon/CMakeLists.txt | 1 + Source/Core/UICommon/UICommon.vcxproj | 4 +- Source/Core/UICommon/WiiUtils.cpp | 64 ++++++++++++++++++ Source/Core/UICommon/WiiUtils.h | 14 ++++ 8 files changed, 87 insertions(+), 75 deletions(-) create mode 100644 Source/Core/UICommon/WiiUtils.cpp create mode 100644 Source/Core/UICommon/WiiUtils.h diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp index 4e7f6f12ba..e6aca0ce79 100644 --- a/Source/Core/DiscIO/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/NANDContentLoader.cpp @@ -246,74 +246,6 @@ void CNANDContentManager::ClearCache() m_map.clear(); } -u64 CNANDContentManager::Install_WiiWAD(const std::string& filename) -{ - if (filename.find(".wad") == std::string::npos) - return 0; - const CNANDContentLoader& content_loader = GetNANDLoader(filename); - if (content_loader.IsValid() == false) - return 0; - - const u64 title_id = content_loader.GetTMD().GetTitleId(); - - // copy WAD's TMD header and contents to content directory - - std::string content_path(Common::GetTitleContentPath(title_id, Common::FROM_CONFIGURED_ROOT)); - std::string tmd_filename(Common::GetTMDFileName(title_id, Common::FROM_CONFIGURED_ROOT)); - File::CreateFullPath(tmd_filename); - - File::IOFile tmd_file(tmd_filename, "wb"); - if (!tmd_file) - { - PanicAlertT("WAD installation failed: error creating %s", tmd_filename.c_str()); - return 0; - } - - const auto& raw_tmd = content_loader.GetTMD().GetRawTMD(); - tmd_file.WriteBytes(raw_tmd.data(), raw_tmd.size()); - - IOS::ES::SharedContentMap shared_content{Common::FromWhichRoot::FROM_CONFIGURED_ROOT}; - for (const auto& content : content_loader.GetContent()) - { - std::string app_filename; - if (content.m_metadata.IsShared()) - app_filename = shared_content.AddSharedContent(content.m_metadata.sha1); - else - app_filename = StringFromFormat("%s%08x.app", content_path.c_str(), content.m_metadata.id); - - if (!File::Exists(app_filename)) - { - File::CreateFullPath(app_filename); - File::IOFile app_file(app_filename, "wb"); - if (!app_file) - { - PanicAlertT("WAD installation failed: error creating %s", app_filename.c_str()); - return 0; - } - - app_file.WriteBytes(content.m_Data->Get().data(), content.m_metadata.size); - } - else - { - INFO_LOG(DISCIO, "Content %s already exists.", app_filename.c_str()); - } - } - - // Extract and copy WAD's ticket to ticket directory - if (!AddTicket(content_loader.GetTicket())) - { - PanicAlertT("WAD installation failed: error creating ticket"); - return 0; - } - - IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_CONFIGURED_ROOT}; - uid_sys.GetOrInsertUIDForTitle(title_id); - - ClearCache(); - - return title_id; -} - bool AddTicket(const IOS::ES::TicketReader& signed_ticket) { if (!signed_ticket.IsValid()) diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h index 3b16b82bda..af4ff4909c 100644 --- a/Source/Core/DiscIO/NANDContentLoader.h +++ b/Source/Core/DiscIO/NANDContentLoader.h @@ -106,7 +106,6 @@ public: static CNANDContentManager instance; return instance; } - u64 Install_WiiWAD(const std::string& fileName); const CNANDContentLoader& GetNANDLoader(const std::string& content_path); const CNANDContentLoader& GetNANDLoader(u64 title_id, Common::FromWhichRoot from); diff --git a/Source/Core/DolphinQt2/GameList/GameFile.cpp b/Source/Core/DolphinQt2/GameList/GameFile.cpp index b81d491aff..f3a644934d 100644 --- a/Source/Core/DolphinQt2/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt2/GameList/GameFile.cpp @@ -23,6 +23,7 @@ #include "DolphinQt2/GameList/GameFile.h" #include "DolphinQt2/Resources.h" #include "DolphinQt2/Settings.h" +#include "UICommon/WiiUtils.h" static const int CACHE_VERSION = 13; // Last changed in PR #3261 static const int DATASTREAM_VERSION = QDataStream::Qt_5_5; @@ -331,7 +332,7 @@ bool GameFile::Install() { _assert_(m_platform == DiscIO::Platform::WII_WAD); - return DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_path.toStdString()); + return WiiUtils::InstallWAD(m_path.toStdString()); } bool GameFile::Uninstall() diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index f8f99cdd81..1098852605 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -83,6 +83,8 @@ #include "InputCommon/ControllerInterface/ControllerInterface.h" +#include "UICommon/WiiUtils.h" + #include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" @@ -1209,11 +1211,8 @@ void CFrame::OnInstallWAD(wxCommandEvent& event) wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH); - u64 titleID = DiscIO::CNANDContentManager::Access().Install_WiiWAD(fileName); - if (titleID == TITLEID_SYSMENU) - { + if (WiiUtils::InstallWAD(fileName)) UpdateLoadWiiMenuItem(); - } } void CFrame::OnUninstallWAD(wxCommandEvent&) diff --git a/Source/Core/UICommon/CMakeLists.txt b/Source/Core/UICommon/CMakeLists.txt index 36648bbe7c..df1f3fd157 100644 --- a/Source/Core/UICommon/CMakeLists.txt +++ b/Source/Core/UICommon/CMakeLists.txt @@ -3,6 +3,7 @@ set(SRCS Disassembler.cpp UICommon.cpp USBUtils.cpp + WiiUtils.cpp ) if(USE_X11) diff --git a/Source/Core/UICommon/UICommon.vcxproj b/Source/Core/UICommon/UICommon.vcxproj index 18d1ee0966..d5982fc1b3 100644 --- a/Source/Core/UICommon/UICommon.vcxproj +++ b/Source/Core/UICommon/UICommon.vcxproj @@ -59,12 +59,14 @@ 4200;%(DisableSpecificWarnings) + + @@ -74,4 +76,4 @@ - \ No newline at end of file + diff --git a/Source/Core/UICommon/WiiUtils.cpp b/Source/Core/UICommon/WiiUtils.cpp new file mode 100644 index 0000000000..1575f272f7 --- /dev/null +++ b/Source/Core/UICommon/WiiUtils.cpp @@ -0,0 +1,64 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "UICommon/WiiUtils.h" +#include "Common/CommonTypes.h" +#include "Common/MsgHandler.h" +#include "Core/IOS/ES/ES.h" +#include "Core/IOS/ES/Formats.h" +#include "Core/IOS/IOS.h" +#include "DiscIO/NANDContentLoader.h" +#include "DiscIO/WiiWad.h" + +namespace WiiUtils +{ +bool InstallWAD(const std::string& wad_path) +{ + const DiscIO::WiiWAD wad{wad_path}; + if (!wad.IsValid()) + { + PanicAlertT("WAD installation failed: The selected file is not a valid WAD."); + return false; + } + + const auto tmd = wad.GetTMD(); + IOS::HLE::Kernel ios; + const auto es = ios.GetES(); + + IOS::HLE::Device::ES::Context context; + if (es->ImportTicket(wad.GetTicket().GetRawTicket()) < 0 || + es->ImportTitleInit(context, tmd.GetRawTMD()) < 0) + { + PanicAlertT("WAD installation failed: Could not initialise title import."); + return false; + } + + const bool contents_imported = [&]() { + const u64 title_id = tmd.GetTitleId(); + for (const IOS::ES::Content& content : tmd.GetContents()) + { + const std::vector data = wad.GetContent(content.index); + + if (es->ImportContentBegin(context, title_id, content.id) < 0 || + es->ImportContentData(context, 0, data.data(), static_cast(data.size())) < 0 || + es->ImportContentEnd(context, 0) < 0) + { + PanicAlertT("WAD installation failed: Could not import content %08x.", content.id); + return false; + } + } + return true; + }(); + + if ((contents_imported && es->ImportTitleDone(context) < 0) || + (!contents_imported && es->ImportTitleCancel(context) < 0)) + { + PanicAlertT("WAD installation failed: Could not finalise title import."); + return false; + } + + DiscIO::CNANDContentManager::Access().ClearCache(); + return true; +} +} diff --git a/Source/Core/UICommon/WiiUtils.h b/Source/Core/UICommon/WiiUtils.h new file mode 100644 index 0000000000..8419e01b9b --- /dev/null +++ b/Source/Core/UICommon/WiiUtils.h @@ -0,0 +1,14 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +// Small utility functions for common Wii related tasks. + +namespace WiiUtils +{ +bool InstallWAD(const std::string& wad_path); +}