diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp index 6e03048b2e..eb8488b3ab 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -583,6 +583,37 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) Memory::Write_U32(0, _CommandAddress + 0x4); WARN_LOG(WII_IPC_ES, "IOCTL_ES_GETCONSUMPTION:%d", Memory::Read_U32(_CommandAddress+4)); return true; + + case IOCTL_ES_DELETETICKET: + { + u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETICKET: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); + if (File::Delete(Common::CreateTicketFileName(TitleID))) + { + Memory::Write_U32(0, _CommandAddress + 0x4); + } + else + { + // Presumably return -1017 when delete fails + Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); + } + } + break; + case IOCTL_ES_DELETETITLECONTENT: + { + u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); + INFO_LOG(WII_IPC_ES, "IOCTL_ES_DELETETITLECONTENT: title: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID); + if (DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID)) + { + Memory::Write_U32(0, _CommandAddress + 0x4); + } + else + { + // Presumably return -1017 when title not installed TODO verify + Memory::Write_U32(ES_PARAMTER_SIZE_OR_ALIGNMENT, _CommandAddress + 0x4); + } + + } case IOCTL_ES_GETSTOREDTMDSIZE: { _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_GETSTOREDTMDSIZE no in buffer"); diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index 6d1a8f7240..67a915fc17 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -108,6 +108,7 @@ public: virtual ~CNANDContentLoader(); bool IsValid() const { return m_Valid; } + void RemoveTitle(void) const; u64 GetTitleID() const { return m_TitleID; } u16 GetIosVersion() const { return m_IosVersion; } u32 GetBootIndex() const { return m_BootIndex; } @@ -390,6 +391,32 @@ const INANDContentLoader& CNANDContentManager::GetNANDLoader(u64 _titleId, bool std::string _rName = Common::CreateTitleContentPath(_titleId); return GetNANDLoader(_rName, forceReload); } +bool CNANDContentManager::RemoveTitle(u64 _titleID) +{ + if (!GetNANDLoader(_titleID).IsValid()) + return false; + GetNANDLoader(_titleID).RemoveTitle(); + return GetNANDLoader(_titleID, true).IsValid(); +} + +void CNANDContentLoader::RemoveTitle() const +{ + INFO_LOG(DISCIO, "RemoveTitle %08x/%08x", (u32)(m_TitleID >> 32), (u32)m_TitleID); + if(IsValid()) + { + // remove tmd? + for (u32 i = 0; i < m_numEntries; i++) + { + char szFilename[1024]; + if (!(m_Content[i].m_Type & 0x8000)) // skip shared apps + { + sprintf(szFilename, "%s/%08x.app", Common::CreateTitleContentPath(m_TitleID).c_str(), m_Content[i].m_ContentID); + INFO_LOG(DISCIO, "Delete %s", szFilename); + File::Delete(szFilename); + } + } + } +} cUIDsys::cUIDsys() { diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h index 3543061b22..8f607be2b5 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.h +++ b/Source/Core/DiscIO/Src/NANDContentLoader.h @@ -52,6 +52,7 @@ public: virtual ~INANDContentLoader() {} virtual bool IsValid() const = 0; + virtual void RemoveTitle() const = 0; virtual u64 GetTitleID() const = 0; virtual u16 GetIosVersion() const = 0; virtual u32 GetBootIndex() const = 0; @@ -83,6 +84,7 @@ public: const INANDContentLoader& GetNANDLoader(const std::string& _rName, bool forceReload = false); const INANDContentLoader& GetNANDLoader(u64 _titleId, bool forceReload = false); + bool RemoveTitle(u64 _titleID); private: CNANDContentManager() {};