diff options
| author | Léo Lam <leo@innovatetechnologi.es> | 2017-05-07 16:43:27 +0200 |
|---|---|---|
| committer | Léo Lam <leo@innovatetechnologi.es> | 2017-05-13 00:34:58 +0200 |
| commit | bacf52384ffcd83c2a8856ac4eabe63c0474d244 (patch) | |
| tree | 1d76343f7684ab2e19aed6986e41745bf40a2ef5 /Source/Core | |
| parent | 12801fd722e4f4038722fc35de4edcb1f5d1b3ca (diff) | |
IOS/ES: Implement DeleteTitleContent properly
Just like DeleteTitle, Using CNANDContentManager is overkill,
inefficient and useless. And it results in a few failures in
situations where a delete should just always work.
But here it gets bonus points, because it manages to actually use
the TMD for deleting contents, when IOS does none of that and just
deletes files ending with .app in the title content directory. :)
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/IOS/ES/ES.h | 2 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/ES/TitleManagement.cpp | 29 | ||||
| -rw-r--r-- | Source/Core/DiscIO/NANDContentLoader.cpp | 29 | ||||
| -rw-r--r-- | Source/Core/DiscIO/NANDContentLoader.h | 2 | ||||
| -rw-r--r-- | Source/Core/DolphinQt2/GameList/GameFile.cpp | 7 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/FrameTools.cpp | 4 |
6 files changed, 28 insertions, 45 deletions
diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 498b9c7e71..b6d64c655f 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -55,6 +55,8 @@ public: ReturnCode Close(u32 fd) override; IPCCommandResult IOCtlV(const IOCtlVRequest& request) override; + ReturnCode DeleteTitleContent(u64 title_id) const; + private: enum { diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index 2de0ab7c40..254276994d 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -376,20 +376,29 @@ IPCCommandResult ES::DeleteTicket(const IOCtlVRequest& request) return GetDefaultReply(IPC_SUCCESS); } -IPCCommandResult ES::DeleteTitleContent(const IOCtlVRequest& request) +ReturnCode ES::DeleteTitleContent(u64 title_id) const { - if (!request.HasNumberOfValidVectors(1, 0)) - return GetDefaultReply(ES_EINVAL); + if (!CanDeleteTitle(title_id)) + return ES_EINVAL; - u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); - INFO_LOG(IOS_ES, "IOCTL_ES_DELETETITLECONTENT: title: %08x/%08x", (u32)(TitleID >> 32), - (u32)TitleID); + const std::string content_dir = Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT); + if (!File::IsDirectory(content_dir)) + return FS_ENOENT; - // Presumably return -1017 when title not installed TODO verify - if (!DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) - return GetDefaultReply(ES_EINVAL); + for (const auto& file : File::ScanDirectoryTree(content_dir, false).children) + { + if (file.virtualName.size() == 12 && file.virtualName.compare(8, 4, ".app") == 0) + File::Delete(file.physicalName); + } - return GetDefaultReply(IPC_SUCCESS); + return IPC_SUCCESS; +} + +IPCCommandResult ES::DeleteTitleContent(const IOCtlVRequest& request) +{ + if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u64)) + return GetDefaultReply(ES_EINVAL); + return GetDefaultReply(DeleteTitleContent(Memory::Read_U64(request.in_vectors[0].address))); } IPCCommandResult ES::ExportTitleInit(Context& context, const IOCtlVRequest& request) diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp index b87e52a246..4e7f6f12ba 100644 --- a/Source/Core/DiscIO/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/NANDContentLoader.cpp @@ -241,40 +241,11 @@ const CNANDContentLoader& CNANDContentManager::GetNANDLoader(u64 title_id, return GetNANDLoader(path); } -bool CNANDContentManager::RemoveTitle(u64 title_id, Common::FromWhichRoot from) -{ - auto& loader = GetNANDLoader(title_id, from); - if (!loader.IsValid()) - return false; - loader.RemoveTitle(); - return GetNANDLoader(title_id, from).IsValid(); -} - void CNANDContentManager::ClearCache() { m_map.clear(); } -void CNANDContentLoader::RemoveTitle() const -{ - const u64 title_id = m_tmd.GetTitleId(); - INFO_LOG(DISCIO, "RemoveTitle %016" PRIx64, title_id); - if (IsValid()) - { - // remove TMD? - for (const auto& content : m_Content) - { - if (!content.m_metadata.IsShared()) - { - std::string path = StringFromFormat("%s/%08x.app", m_Path.c_str(), content.m_metadata.id); - INFO_LOG(DISCIO, "Delete %s", path.c_str()); - File::Delete(path); - } - } - CNANDContentManager::Access().ClearCache(); // deletes 'this' - } -} - u64 CNANDContentManager::Install_WiiWAD(const std::string& filename) { if (filename.find(".wad") == std::string::npos) diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h index 6e6a5d77e8..3b16b82bda 100644 --- a/Source/Core/DiscIO/NANDContentLoader.h +++ b/Source/Core/DiscIO/NANDContentLoader.h @@ -79,7 +79,6 @@ public: ~CNANDContentLoader(); bool IsValid() const; - void RemoveTitle() const; const SNANDContent* GetContentByID(u32 id) const; const SNANDContent* GetContentByIndex(int index) const; const IOS::ES::TMDReader& GetTMD() const { return m_tmd; } @@ -111,7 +110,6 @@ public: const CNANDContentLoader& GetNANDLoader(const std::string& content_path); const CNANDContentLoader& GetNANDLoader(u64 title_id, Common::FromWhichRoot from); - bool RemoveTitle(u64 title_id, Common::FromWhichRoot from); void ClearCache(); private: diff --git a/Source/Core/DolphinQt2/GameList/GameFile.cpp b/Source/Core/DolphinQt2/GameList/GameFile.cpp index 1088e66e82..2f23107776 100644 --- a/Source/Core/DolphinQt2/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt2/GameList/GameFile.cpp @@ -13,6 +13,8 @@ #include "Common/NandPaths.h" #include "Core/ConfigManager.h" #include "Core/HW/WiiSaveCrypted.h" +#include "Core/IOS/ES/ES.h" +#include "Core/IOS/IOS.h" #include "DiscIO/Blob.h" #include "DiscIO/Enums.h" #include "DiscIO/NANDContentLoader.h" @@ -324,9 +326,8 @@ bool GameFile::Install() bool GameFile::Uninstall() { _assert_(m_platform == DiscIO::Platform::WII_WAD); - - return DiscIO::CNANDContentManager::Access().RemoveTitle(m_title_id, - Common::FROM_CONFIGURED_ROOT); + IOS::HLE::Kernel ios; + return ios.GetES()->DeleteTitleContent(m_title_id) == IOS::HLE::IPC_SUCCESS; } bool GameFile::ExportWiiSave() diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 09a6e625fa..232c5418ab 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -42,6 +42,7 @@ #include "Core/HW/Wiimote.h" #include "Core/Host.h" #include "Core/HotkeyManager.h" +#include "Core/IOS/ES/ES.h" #include "Core/IOS/IOS.h" #include "Core/IOS/STM/STM.h" #include "Core/IOS/USB/Bluetooth/BTEmu.h" @@ -1228,7 +1229,8 @@ void CFrame::OnUninstallWAD(wxCommandEvent&) } u64 title_id = file->GetTitleID(); - if (!DiscIO::CNANDContentManager::Access().RemoveTitle(title_id, Common::FROM_CONFIGURED_ROOT)) + IOS::HLE::Kernel ios; + if (ios.GetES()->DeleteTitleContent(title_id) < 0) { PanicAlertT("Failed to remove this title from the NAND."); return; |
