From c22d1d68ab8675edc9969e0c819eccf021cfca28 Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 21 Jun 2015 13:19:52 -0400 Subject: [PATCH] Mark which Wii root to use in the NAND path code. It's used by both the GUI to do things like install WADs and check up on the system menu, in which case the global root should be used, and by /dev/es, in which case the local one should. The latter isn't *terribly* useful today, since no contents will ever be installed in temporary roots (although it's still relevant for data directories), but converting the whole thing makes sense because then it will Just Work once the entire NAND is synced. Because it would have been a bit of work to split it up (but I can if desired), this commit also contains some basic cleanup of NANDContentLoader: (1) The useless interface class INANDContentLoader is removed and the methods are changed to just return CNANDContentLoader (the only implementation); (2) CNANDContentManager is changed to use unique_ptr and cleaned up a bit. --- Source/Core/Common/NandPaths.cpp | 30 +++-- Source/Core/Common/NandPaths.h | 18 ++- Source/Core/Core/Boot/Boot.cpp | 2 +- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 2 +- Source/Core/Core/Boot/Boot_WiiWAD.cpp | 6 +- Source/Core/Core/ConfigManager.cpp | 2 +- Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp | 2 +- Source/Core/Core/HW/WiiSaveCrypted.cpp | 3 +- .../IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 2 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 76 +++++------ .../Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h | 8 +- .../Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp | 2 +- Source/Core/Core/Movie.cpp | 2 +- Source/Core/DiscIO/NANDContentLoader.cpp | 120 +++++------------- Source/Core/DiscIO/NANDContentLoader.h | 83 +++++++----- .../Core/DolphinWX/Config/PathConfigPane.cpp | 1 + Source/Core/DolphinWX/FrameTools.cpp | 6 +- 17 files changed, 174 insertions(+), 191 deletions(-) diff --git a/Source/Core/Common/NandPaths.cpp b/Source/Core/Common/NandPaths.cpp index d4c9f8a15158..4048979c3c25 100644 --- a/Source/Core/Common/NandPaths.cpp +++ b/Source/Core/Common/NandPaths.cpp @@ -56,34 +56,40 @@ void ShutdownWiiRoot() } } -std::string GetTicketFileName(u64 _titleID) +static std::string RootUserPath(FromWhichRoot from) +{ + int idx = from == FROM_CONFIGURED_ROOT ? D_WIIROOT_IDX : D_SESSION_WIIROOT_IDX; + return File::GetUserPath(idx); +} + +std::string GetTicketFileName(u64 _titleID, FromWhichRoot from) { return StringFromFormat("%s/ticket/%08x/%08x.tik", - File::GetUserPath(D_SESSION_WIIROOT_IDX).c_str(), + RootUserPath(from).c_str(), (u32)(_titleID >> 32), (u32)_titleID); } -std::string GetTitleDataPath(u64 _titleID) +std::string GetTitleDataPath(u64 _titleID, FromWhichRoot from) { return StringFromFormat("%s/title/%08x/%08x/data/", - File::GetUserPath(D_SESSION_WIIROOT_IDX).c_str(), + RootUserPath(from).c_str(), (u32)(_titleID >> 32), (u32)_titleID); } -std::string GetTMDFileName(u64 _titleID) +std::string GetTMDFileName(u64 _titleID, FromWhichRoot from) { - return GetTitleContentPath(_titleID) + "title.tmd"; + return GetTitleContentPath(_titleID, from) + "title.tmd"; } -std::string GetTitleContentPath(u64 _titleID) +std::string GetTitleContentPath(u64 _titleID, FromWhichRoot from) { return StringFromFormat("%s/title/%08x/%08x/content/", - File::GetUserPath(D_SESSION_WIIROOT_IDX).c_str(), + RootUserPath(from).c_str(), (u32)(_titleID >> 32), (u32)_titleID); } -bool CheckTitleTMD(u64 _titleID) +bool CheckTitleTMD(u64 _titleID, FromWhichRoot from) { - const std::string TitlePath = GetTMDFileName(_titleID); + const std::string TitlePath = GetTMDFileName(_titleID, from); if (File::Exists(TitlePath)) { File::IOFile pTMDFile(TitlePath, "rb"); @@ -96,9 +102,9 @@ bool CheckTitleTMD(u64 _titleID) return false; } -bool CheckTitleTIK(u64 _titleID) +bool CheckTitleTIK(u64 _titleID, FromWhichRoot from) { - const std::string ticketFileName = Common::GetTicketFileName(_titleID); + const std::string ticketFileName = Common::GetTicketFileName(_titleID, from); if (File::Exists(ticketFileName)) { File::IOFile pTIKFile(ticketFileName, "rb"); diff --git a/Source/Core/Common/NandPaths.h b/Source/Core/Common/NandPaths.h index 6a79abf3bfd8..7d33477d76b7 100644 --- a/Source/Core/Common/NandPaths.h +++ b/Source/Core/Common/NandPaths.h @@ -21,11 +21,17 @@ namespace Common void InitializeWiiRoot(bool use_temporary); void ShutdownWiiRoot(); - std::string GetTicketFileName(u64 _titleID); - std::string GetTMDFileName(u64 _titleID); - std::string GetTitleDataPath(u64 _titleID); - std::string GetTitleContentPath(u64 _titleID); - bool CheckTitleTMD(u64 _titleID); - bool CheckTitleTIK(u64 _titleID); + enum FromWhichRoot + { + FROM_CONFIGURED_ROOT, // not related to currently running game - use D_WIIROOT_IDX + FROM_SESSION_ROOT, // request from currently running game - use D_SESSION_WIIROOT_IDX + }; + + std::string GetTicketFileName(u64 _titleID, FromWhichRoot from); + std::string GetTMDFileName(u64 _titleID, FromWhichRoot from); + std::string GetTitleDataPath(u64 _titleID, FromWhichRoot from); + std::string GetTitleContentPath(u64 _titleID, FromWhichRoot from); + bool CheckTitleTMD(u64 _titleID, FromWhichRoot from); + bool CheckTitleTIK(u64 _titleID, FromWhichRoot from); void ReadReplacements(replace_v& replacements); } diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 44d1cbd39dc7..30fce0bc68f6 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -79,7 +79,7 @@ bool CBoot::FindMapFile(std::string* existing_map_file, { case SConfig::BOOT_WII_NAND: { - const DiscIO::INANDContentLoader& Loader = + const DiscIO::CNANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_StartupPara.m_strFilename); if (Loader.IsValid()) { diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index af720a955a3c..3ab6ed6c583d 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -187,7 +187,7 @@ bool CBoot::SetupWiiMemory(DiscIO::IVolume::ECountry country) SettingsHandler gen; std::string serno; - std::string settings_Filename(Common::GetTitleDataPath(TITLEID_SYSMENU) + WII_SETTING); + std::string settings_Filename(Common::GetTitleDataPath(TITLEID_SYSMENU, Common::FROM_SESSION_ROOT) + WII_SETTING); if (File::Exists(settings_Filename)) { File::IOFile settingsFileHandle(settings_Filename, "rb"); diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index a267227f499a..5ae4c0f0f577 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -49,7 +49,7 @@ struct StateFlags bool CBoot::Boot_WiiWAD(const std::string& _pFilename) { - std::string state_filename(Common::GetTitleDataPath(TITLEID_SYSMENU) + WII_STATE); + std::string state_filename(Common::GetTitleDataPath(TITLEID_SYSMENU, Common::FROM_SESSION_ROOT) + WII_STATE); if (File::Exists(state_filename)) { @@ -75,13 +75,13 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename) state_file.WriteBytes(&state, sizeof(StateFlags)); } - const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_pFilename); + const DiscIO::CNANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_pFilename); if (!ContentLoader.IsValid()) return false; u64 titleID = ContentLoader.GetTitleID(); // create data directory - File::CreateFullPath(Common::GetTitleDataPath(titleID)); + File::CreateFullPath(Common::GetTitleDataPath(titleID, Common::FROM_SESSION_ROOT)); if (titleID == TITLEID_SYSMENU) HLE_IPC_CreateVirtualFATFilesystem(); diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 87041a3b2ded..16a88c5e7e7f 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -757,7 +757,7 @@ bool SConfig::AutoSetup(EBootBS2 _BootBS2) else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid()) { std::unique_ptr pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename)); - const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename); + const DiscIO::CNANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename); if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr) { diff --git a/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp index 0a154f3a4304..024b45ebac13 100644 --- a/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp @@ -145,7 +145,7 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) u32 CurrentGameId = 0; if (strUniqueID == TITLEID_SYSMENU_STRING) { - const DiscIO::INANDContentLoader & SysMenu_Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU, false); + const DiscIO::CNANDContentLoader & SysMenu_Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU, Common::FROM_SESSION_ROOT); if (SysMenu_Loader.IsValid()) { country_code = DiscIO::CountrySwitch(SysMenu_Loader.GetCountryChar()); diff --git a/Source/Core/Core/HW/WiiSaveCrypted.cpp b/Source/Core/Core/HW/WiiSaveCrypted.cpp index 4a7ee2840cab..84837e4a2250 100644 --- a/Source/Core/Core/HW/WiiSaveCrypted.cpp +++ b/Source/Core/Core/HW/WiiSaveCrypted.cpp @@ -569,7 +569,8 @@ bool CWiiSaveCrypted::getPaths(bool for_export) { if (m_title_id) { - m_wii_title_path = Common::GetTitleDataPath(m_title_id); + // CONFIGURED because this whole class is only used from the GUI, not directly by games. + m_wii_title_path = Common::GetTitleDataPath(m_title_id, Common::FROM_CONFIGURED_ROOT); } if (for_export) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 23f8f6ce20a5..d92950b7f7d0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -41,7 +41,7 @@ std::string HLE_IPC_BuildFilename(std::string path_wii) void HLE_IPC_CreateVirtualFATFilesystem() { const int cdbSize = 0x01400000; - const std::string cdbPath = Common::GetTitleDataPath(TITLEID_SYSMENU) + "cdb.vff"; + const std::string cdbPath = Common::GetTitleDataPath(TITLEID_SYSMENU, Common::FROM_SESSION_ROOT) + "cdb.vff"; if ((int)File::GetSize(cdbPath) < cdbSize) { // cdb.vff is a virtual Fat filesystem created on first launch of sysmenu diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp index bdc630178be4..73d08cc2e386 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -185,7 +185,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode) IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce) { - // Leave deletion of the INANDContentLoader objects to CNANDContentManager, don't do it here! + // Leave deletion of the CNANDContentLoader objects to CNANDContentManager, don't do it here! m_NANDContent.clear(); for (auto& pair : m_ContentAccessMap) { @@ -206,7 +206,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index) { - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); if (!Loader.IsValid()) { @@ -292,7 +292,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - const DiscIO::INANDContentLoader& rNANDContent = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& rNANDContent = AccessContentDevice(TitleID); u16 NumberOfPrivateContent = 0; if (rNANDContent.IsValid()) // Not sure if dolphin will ever fail this check { @@ -322,7 +322,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - const DiscIO::INANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID); if (rNANDCOntent.IsValid()) // Not sure if dolphin will ever fail this check { for (u16 i = 0; i < rNANDCOntent.GetNumEntries(); i++) @@ -579,18 +579,18 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u32 retVal = 0; - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); - u32 ViewCount = Loader.GetTIKSize() / DiscIO::INANDContentLoader::TICKET_SIZE; + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); + u32 ViewCount = Loader.GetTIKSize() / DiscIO::CNANDContentLoader::TICKET_SIZE; if (!ViewCount) { - std::string TicketFilename = Common::GetTicketFileName(TitleID); + std::string TicketFilename = Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT); if (File::Exists(TicketFilename)) { u32 FileSize = (u32)File::GetSize(TicketFilename); - _dbg_assert_msg_(WII_IPC_ES, (FileSize % DiscIO::INANDContentLoader::TICKET_SIZE) == 0, "IOCTL_ES_GETVIEWCNT ticket file size seems to be wrong"); + _dbg_assert_msg_(WII_IPC_ES, (FileSize % DiscIO::CNANDContentLoader::TICKET_SIZE) == 0, "IOCTL_ES_GETVIEWCNT ticket file size seems to be wrong"); - ViewCount = FileSize / DiscIO::INANDContentLoader::TICKET_SIZE; + ViewCount = FileSize / DiscIO::CNANDContentLoader::TICKET_SIZE; _dbg_assert_msg_(WII_IPC_ES, (ViewCount>0) && (ViewCount<=4), "IOCTL_ES_GETVIEWCNT ticket count seems to be wrong"); } else if (TitleID >> 32 == 0x00000001) @@ -626,29 +626,29 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u32 maxViews = Memory::Read_U32(Buffer.InBuffer[1].m_Address); u32 retVal = 0; - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); const u8 *Ticket = Loader.GetTIK(); if (Ticket) { - u32 viewCnt = Loader.GetTIKSize() / DiscIO::INANDContentLoader::TICKET_SIZE; + u32 viewCnt = Loader.GetTIKSize() / DiscIO::CNANDContentLoader::TICKET_SIZE; for (unsigned int View = 0; View != maxViews && View < viewCnt; ++View) { Memory::Write_U32(View, Buffer.PayloadBuffer[0].m_Address + View * 0xD8); Memory::CopyToEmu(Buffer.PayloadBuffer[0].m_Address + 4 + View * 0xD8, - Ticket + 0x1D0 + (View * DiscIO::INANDContentLoader::TICKET_SIZE), 212); + Ticket + 0x1D0 + (View * DiscIO::CNANDContentLoader::TICKET_SIZE), 212); } } else { - std::string TicketFilename = Common::GetTicketFileName(TitleID); + std::string TicketFilename = Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT); if (File::Exists(TicketFilename)) { File::IOFile pFile(TicketFilename, "rb"); if (pFile) { - u8 FileTicket[DiscIO::INANDContentLoader::TICKET_SIZE]; - for (unsigned int View = 0; View != maxViews && pFile.ReadBytes(FileTicket, DiscIO::INANDContentLoader::TICKET_SIZE); ++View) + u8 FileTicket[DiscIO::CNANDContentLoader::TICKET_SIZE]; + for (unsigned int View = 0; View != maxViews && pFile.ReadBytes(FileTicket, DiscIO::CNANDContentLoader::TICKET_SIZE); ++View) { Memory::Write_U32(View, Buffer.PayloadBuffer[0].m_Address + View * 0xD8); Memory::CopyToEmu(Buffer.PayloadBuffer[0].m_Address + 4 + View * 0xD8, FileTicket+0x1D0, 212); @@ -688,12 +688,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); u32 TMDViewCnt = 0; if (Loader.IsValid()) { - TMDViewCnt += DiscIO::INANDContentLoader::TMD_VIEW_SIZE; + TMDViewCnt += DiscIO::CNANDContentLoader::TMD_VIEW_SIZE; TMDViewCnt += 2; // title version TMDViewCnt += 2; // num entries TMDViewCnt += (u32)Loader.GetContentSize() * (4+2+2+8); // content id, index, type, size @@ -715,7 +715,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x buffer size: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); @@ -723,8 +723,8 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) { u32 Address = Buffer.PayloadBuffer[0].m_Address; - Memory::CopyToEmu(Address, Loader.GetTMDView(), DiscIO::INANDContentLoader::TMD_VIEW_SIZE); - Address += DiscIO::INANDContentLoader::TMD_VIEW_SIZE; + Memory::CopyToEmu(Address, Loader.GetTMDView(), DiscIO::CNANDContentLoader::TMD_VIEW_SIZE); + Address += DiscIO::CNANDContentLoader::TMD_VIEW_SIZE; Memory::Write_U16(Loader.GetTitleVersion(), Address); Address += 2; Memory::Write_U16(Loader.GetNumEntries(), Address); Address += 2; @@ -757,7 +757,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) { 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::GetTicketFileName(TitleID))) + if (File::Delete(Common::GetTicketFileName(TitleID, Common::FROM_SESSION_ROOT))) { Memory::Write_U32(0, _CommandAddress + 0x4); } @@ -772,7 +772,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) { 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)) + if (DiscIO::CNANDContentManager::Access().RemoveTitle(TitleID, Common::FROM_SESSION_ROOT)) { Memory::Write_U32(0, _CommandAddress + 0x4); } @@ -790,14 +790,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer"); u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); _dbg_assert_(WII_IPC_ES, Loader.IsValid()); u32 TMDCnt = 0; if (Loader.IsValid()) { - TMDCnt += DiscIO::INANDContentLoader::TMD_HEADER_SIZE; - TMDCnt += (u32)Loader.GetContentSize() * DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE; + TMDCnt += DiscIO::CNANDContentLoader::TMD_HEADER_SIZE; + TMDCnt += (u32)Loader.GetContentSize() * DiscIO::CNANDContentLoader::CONTENT_HEADER_SIZE; } if (Buffer.NumberPayloadBuffer) Memory::Write_U32(TMDCnt, Buffer.PayloadBuffer[0].m_Address); @@ -822,7 +822,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // TODO: actually use this param in when writing to the outbuffer :/ MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address); } - const DiscIO::INANDContentLoader& Loader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffer size: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); @@ -831,14 +831,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) { u32 Address = Buffer.PayloadBuffer[0].m_Address; - Memory::CopyToEmu(Address, Loader.GetTMDHeader(), DiscIO::INANDContentLoader::TMD_HEADER_SIZE); - Address += DiscIO::INANDContentLoader::TMD_HEADER_SIZE; + Memory::CopyToEmu(Address, Loader.GetTMDHeader(), DiscIO::CNANDContentLoader::TMD_HEADER_SIZE); + Address += DiscIO::CNANDContentLoader::TMD_HEADER_SIZE; const std::vector& rContent = Loader.GetContent(); for (size_t i=0; i>32) != 0x00000001 || TitleID == TITLEID_SYSMENU) { - const DiscIO::INANDContentLoader& ContentLoader = AccessContentDevice(TitleID); + const DiscIO::CNANDContentLoader& ContentLoader = AccessContentDevice(TitleID); if (ContentLoader.IsValid()) { u32 bootInd = ContentLoader.GetBootIndex(); const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(bootInd); if (pContent) { - tContentFile = Common::GetTitleContentPath(TitleID); + tContentFile = Common::GetTitleContentPath(TitleID, Common::FROM_SESSION_ROOT); std::unique_ptr pDolLoader; if (pContent->m_pData) { @@ -1071,7 +1071,8 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) return GetDefaultReply(); } -const DiscIO::INANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 _TitleID) +// TODO: This cache is redundant with the one in CNANDContentManager.h +const DiscIO::CNANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 _TitleID) { if (m_pContentLoader->IsValid() && m_pContentLoader->GetTitleID() == _TitleID) return *m_pContentLoader; @@ -1080,7 +1081,7 @@ const DiscIO::INANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u6 if (itr != m_NANDContent.end()) return *itr->second; - m_NANDContent[_TitleID] = &DiscIO::CNANDContentManager::Access().GetNANDLoader(_TitleID); + m_NANDContent[_TitleID] = &DiscIO::CNANDContentManager::Access().GetNANDLoader(_TitleID, Common::FROM_SESSION_ROOT); _dbg_assert_msg_(WII_IPC_ES, ((u32)(_TitleID >> 32) == 0x00010000) || m_NANDContent[_TitleID]->IsValid(), "NandContent not valid for TitleID %08x/%08x", (u32)(_TitleID >> 32), (u32)_TitleID); return *m_NANDContent[_TitleID]; @@ -1104,13 +1105,13 @@ u32 CWII_IPC_HLE_Device_es::ES_DIVerify(u8* _pTMD, u32 _sz) { return -1; } - std::string tmdPath = Common::GetTMDFileName(tmdTitleID); + std::string tmdPath = Common::GetTMDFileName(tmdTitleID, Common::FROM_SESSION_ROOT); File::CreateFullPath(tmdPath); - File::CreateFullPath(Common::GetTitleDataPath(tmdTitleID)); + File::CreateFullPath(Common::GetTitleDataPath(tmdTitleID, Common::FROM_SESSION_ROOT)); Movie::g_titleID = tmdTitleID; - std::string savePath = Common::GetTitleDataPath(tmdTitleID); + std::string savePath = Common::GetTitleDataPath(tmdTitleID, Common::FROM_SESSION_ROOT); if (Movie::IsRecordingInput()) { // TODO: Check for the actual save data @@ -1161,5 +1162,6 @@ u32 CWII_IPC_HLE_Device_es::ES_DIVerify(u8* _pTMD, u32 _sz) ERROR_LOG(WII_IPC_ES, "DIVerify failed to write disc TMD to NAND."); } DiscIO::cUIDsys::AccessInstance().AddTitle(tmdTitleID); + DiscIO::CNANDContentManager::Access().ClearCache(); return 0; } diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h index 776c1ca7844e..9720e766c1bf 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -14,7 +14,7 @@ class PointerWrap; namespace DiscIO { - class INANDContentLoader; + class CNANDContentLoader; struct SNANDContent; } @@ -133,10 +133,10 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device typedef std::map CContentAccessMap; CContentAccessMap m_ContentAccessMap; - typedef std::map CTitleToContentMap; + typedef std::map CTitleToContentMap; CTitleToContentMap m_NANDContent; - const DiscIO::INANDContentLoader* m_pContentLoader; + const DiscIO::CNANDContentLoader* m_pContentLoader; std::vector m_TitleIDs; u64 m_TitleID; @@ -144,7 +144,7 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device static u8 *keyTable[11]; - const DiscIO::INANDContentLoader& AccessContentDevice(u64 _TitleID); + const DiscIO::CNANDContentLoader& AccessContentDevice(u64 _TitleID); u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index); bool IsValid(u64 _TitleID) const; diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp index d7aad53ad5c6..c7cc1b518dbd 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -134,7 +134,7 @@ IPCCommandResult CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) INFO_LOG(WII_IPC_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID"); if (config.CreationStage() == nwc24_config_t::NWC24_IDCS_INITIAL) { - std::string settings_Filename(Common::GetTitleDataPath(TITLEID_SYSMENU) + WII_SETTING); + std::string settings_Filename(Common::GetTitleDataPath(TITLEID_SYSMENU, Common::FROM_SESSION_ROOT) + WII_SETTING); SettingsHandler gen; std::string area, model; bool _GotSettings = false; diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index f31073e7d557..5a515ca4ea91 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -491,7 +491,7 @@ bool BeginRecordingInput(int controllers) // TODO: find a way to GetTitleDataPath() from Movie::Init() if (SConfig::GetInstance().bWii) { - if (File::Exists(Common::GetTitleDataPath(g_titleID) + "banner.bin")) + if (File::Exists(Common::GetTitleDataPath(g_titleID, Common::FROM_SESSION_ROOT) + "banner.bin")) Movie::g_bClearSave = false; else Movie::g_bClearSave = true; diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp index 0e26fa051e38..5c169537944e 100644 --- a/Source/Core/DiscIO/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/NANDContentLoader.cpp @@ -89,58 +89,6 @@ std::string CSharedContent::AddSharedContent(const u8* _pHash) } -// this classes must be created by the CNANDContentManager -class CNANDContentLoader : public INANDContentLoader -{ -public: - CNANDContentLoader(const std::string& _rName); - virtual ~CNANDContentLoader(); - - bool IsValid() const override { return m_Valid; } - void RemoveTitle() const override; - u64 GetTitleID() const override { return m_TitleID; } - u16 GetIosVersion() const override { return m_IosVersion; } - u32 GetBootIndex() const override { return m_BootIndex; } - size_t GetContentSize() const override { return m_Content.size(); } - const SNANDContent* GetContentByIndex(int _Index) const override; - const u8* GetTMDView() const override { return m_TMDView; } - const u8* GetTMDHeader() const override { return m_TMDHeader; } - u32 GetTIKSize() const override { return m_TIKSize; } - const u8* GetTIK() const override { return m_TIK; } - - const std::vector& GetContent() const override { return m_Content; } - - u16 GetTitleVersion() const override {return m_TitleVersion;} - u16 GetNumEntries() const override {return m_numEntries;} - DiscIO::IVolume::ECountry GetCountry() const override; - u8 GetCountryChar() const override {return m_Country; } - -private: - bool m_Valid; - bool m_isWAD; - std::string m_Path; - u64 m_TitleID; - u16 m_IosVersion; - u32 m_BootIndex; - u16 m_numEntries; - u16 m_TitleVersion; - u8 m_TMDView[TMD_VIEW_SIZE]; - u8 m_TMDHeader[TMD_HEADER_SIZE]; - u32 m_TIKSize; - u8* m_TIK; - u8 m_Country; - - std::vector m_Content; - - - bool Initialize(const std::string& _rName); - - void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest); - - void GetKeyFromTicket(u8* pTicket, u8* pTicketKey); -}; - - CNANDContentLoader::CNANDContentLoader(const std::string& _rName) : m_Valid(false) , m_isWAD(false) @@ -306,43 +254,34 @@ DiscIO::IVolume::ECountry CNANDContentLoader::GetCountry() const CNANDContentManager::~CNANDContentManager() { - for (auto& entry : m_Map) - { - delete entry.second; - } - m_Map.clear(); } -const INANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string& _rName, bool forceReload) +const CNANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string& content_path) { - CNANDContentMap::iterator lb = m_Map.lower_bound(_rName); - - if (lb == m_Map.end() || (m_Map.key_comp()(_rName, lb->first))) - { - m_Map.insert(lb, CNANDContentMap::value_type(_rName, new CNANDContentLoader(_rName))); - } - else - { - if (!lb->second->IsValid() || forceReload) - { - delete lb->second; - lb->second = new CNANDContentLoader(_rName); - } - } - return *m_Map[_rName]; + auto it = m_map.find(content_path); + if (it != m_map.end()) + return *it->second; + return *m_map.emplace_hint(it, std::make_pair(content_path, std::make_unique(content_path)))->second; } -const INANDContentLoader& CNANDContentManager::GetNANDLoader(u64 _titleId, bool forceReload) +const CNANDContentLoader& CNANDContentManager::GetNANDLoader(u64 title_id, Common::FromWhichRoot from) { - std::string _rName = Common::GetTitleContentPath(_titleId); - return GetNANDLoader(_rName, forceReload); + std::string path = Common::GetTitleContentPath(title_id, from); + return GetNANDLoader(path); } -bool CNANDContentManager::RemoveTitle(u64 _titleID) + +bool CNANDContentManager::RemoveTitle(u64 title_id, Common::FromWhichRoot from) { - if (!GetNANDLoader(_titleID).IsValid()) + auto& loader = GetNANDLoader(title_id, from); + if (!loader.IsValid()) return false; - GetNANDLoader(_titleID).RemoveTitle(); - return GetNANDLoader(_titleID, true).IsValid(); + loader.RemoveTitle(); + return GetNANDLoader(title_id, from).IsValid(); +} + +void CNANDContentManager::ClearCache() +{ + m_map.clear(); } void CNANDContentLoader::RemoveTitle() const @@ -355,11 +294,12 @@ void CNANDContentLoader::RemoveTitle() const { if (!(m_Content[i].m_Type & 0x8000)) // skip shared apps { - std::string filename = StringFromFormat("%s%08x.app", Common::GetTitleContentPath(m_TitleID).c_str(), m_Content[i].m_ContentID); + std::string filename = StringFromFormat("%s/%08x.app", m_Path.c_str(), m_Content[i].m_ContentID); INFO_LOG(DISCIO, "Delete %s", filename.c_str()); File::Delete(filename); } } + CNANDContentManager::Access().ClearCache(); // deletes 'this' } } @@ -434,8 +374,8 @@ void cUIDsys::GetTitleIDs(std::vector& _TitleIDs, bool _owned) { for (auto& Element : m_Elements) { - if ((_owned && Common::CheckTitleTIK(Common::swap64(Element.titleID))) || - (!_owned && Common::CheckTitleTMD(Common::swap64(Element.titleID)))) + if ((_owned && Common::CheckTitleTIK(Common::swap64(Element.titleID), Common::FROM_SESSION_ROOT)) || + (!_owned && Common::CheckTitleTMD(Common::swap64(Element.titleID), Common::FROM_SESSION_ROOT))) _TitleIDs.push_back(Common::swap64(Element.titleID)); } } @@ -444,7 +384,7 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& fileName) { if (fileName.find(".wad") == std::string::npos) return 0; - const INANDContentLoader& ContentLoader = GetNANDLoader(fileName); + const CNANDContentLoader& ContentLoader = GetNANDLoader(fileName); if (ContentLoader.IsValid() == false) return 0; @@ -452,8 +392,8 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& fileName) //copy WAD's TMD header and contents to content directory - std::string ContentPath(Common::GetTitleContentPath(TitleID)); - std::string TMDFileName(Common::GetTMDFileName(TitleID)); + std::string ContentPath(Common::GetTitleContentPath(TitleID, Common::FROM_CONFIGURED_ROOT)); + std::string TMDFileName(Common::GetTMDFileName(TitleID, Common::FROM_CONFIGURED_ROOT)); File::CreateFullPath(TMDFileName); File::IOFile pTMDFile(TMDFileName, "wb"); @@ -463,13 +403,13 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& fileName) return 0; } - pTMDFile.WriteBytes(ContentLoader.GetTMDHeader(), INANDContentLoader::TMD_HEADER_SIZE); + pTMDFile.WriteBytes(ContentLoader.GetTMDHeader(), CNANDContentLoader::TMD_HEADER_SIZE); for (u32 i = 0; i < ContentLoader.GetContentSize(); i++) { const SNANDContent& Content = ContentLoader.GetContent()[i]; - pTMDFile.WriteBytes(Content.m_Header, INANDContentLoader::CONTENT_HEADER_SIZE); + pTMDFile.WriteBytes(Content.m_Header, CNANDContentLoader::CONTENT_HEADER_SIZE); std::string APPFileName; if (Content.m_Type & 0x8000) //shared @@ -504,12 +444,14 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& fileName) cUIDsys::AccessInstance().AddTitle(TitleID); + ClearCache(); + return TitleID; } bool Add_Ticket(u64 TitleID, const u8* p_tik, u32 tikSize) { - std::string TicketFileName = Common::GetTicketFileName(TitleID); + std::string TicketFileName = Common::GetTicketFileName(TitleID, Common::FROM_CONFIGURED_ROOT); File::CreateFullPath(TicketFileName); File::IOFile pTicketFile(TicketFileName, "wb"); if (!pTicketFile || !p_tik) diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h index 8b309b13f556..c14fbb05c877 100644 --- a/Source/Core/DiscIO/NANDContentLoader.h +++ b/Source/Core/DiscIO/NANDContentLoader.h @@ -5,11 +5,12 @@ #pragma once #include -#include #include +#include #include #include "Common/CommonTypes.h" +#include "Common/NandPaths.h" #include "DiscIO/Volume.h" namespace DiscIO @@ -28,31 +29,31 @@ struct SNANDContent u8* m_pData; }; -// pure virtual interface so just the NANDContentManager can create these files only -class INANDContentLoader +// Instances of this class must be created by CNANDContentManager +class CNANDContentLoader final { public: - - INANDContentLoader() {} - - 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; - virtual size_t GetContentSize() const = 0; - virtual const SNANDContent* GetContentByIndex(int _Index) const = 0; - virtual const u8* GetTMDView() const = 0; - virtual const u8* GetTMDHeader() const = 0; - virtual u32 GetTIKSize() const = 0; - virtual const u8* GetTIK() const = 0; - virtual const std::vector& GetContent() const = 0; - virtual u16 GetTitleVersion() const = 0; - virtual u16 GetNumEntries() const = 0; - virtual DiscIO::IVolume::ECountry GetCountry() const = 0; - virtual u8 GetCountryChar() const = 0; + CNANDContentLoader(const std::string& _rName); + virtual ~CNANDContentLoader(); + + bool IsValid() const { return m_Valid; } + void RemoveTitle() const; + u64 GetTitleID() const { return m_TitleID; } + u16 GetIosVersion() const { return m_IosVersion; } + u32 GetBootIndex() const { return m_BootIndex; } + size_t GetContentSize() const { return m_Content.size(); } + const SNANDContent* GetContentByIndex(int _Index) const; + const u8* GetTMDView() const { return m_TMDView; } + const u8* GetTMDHeader() const { return m_TMDHeader; } + u32 GetTIKSize() const { return m_TIKSize; } + const u8* GetTIK() const { return m_TIK; } + + const std::vector& GetContent() const { return m_Content; } + + u16 GetTitleVersion() const {return m_TitleVersion;} + u16 GetNumEntries() const {return m_numEntries;} + DiscIO::IVolume::ECountry GetCountry() const; + u8 GetCountryChar() const {return m_Country; } enum { @@ -61,6 +62,30 @@ class INANDContentLoader CONTENT_HEADER_SIZE = 0x24, TICKET_SIZE = 0x2A4 }; + +private: + bool m_Valid; + bool m_isWAD; + std::string m_Path; + u64 m_TitleID; + u16 m_IosVersion; + u32 m_BootIndex; + u16 m_numEntries; + u16 m_TitleVersion; + u8 m_TMDView[TMD_VIEW_SIZE]; + u8 m_TMDHeader[TMD_HEADER_SIZE]; + u32 m_TIKSize; + u8* m_TIK; + u8 m_Country; + + std::vector m_Content; + + + bool Initialize(const std::string& _rName); + + void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest); + + void GetKeyFromTicket(u8* pTicket, u8* pTicketKey); }; @@ -71,9 +96,10 @@ class CNANDContentManager static CNANDContentManager& Access() { static CNANDContentManager instance; return instance; } u64 Install_WiiWAD(const std::string& fileName); - const INANDContentLoader& GetNANDLoader(const std::string& _rName, bool forceReload = false); - const INANDContentLoader& GetNANDLoader(u64 _titleId, bool forceReload = false); - bool RemoveTitle(u64 _titleID); + const CNANDContentLoader& GetNANDLoader(const std::string& content_path); + const CNANDContentLoader& GetNANDLoader(u64 title_id, Common::FromWhichRoot from); + bool RemoveTitle(u64 titl_id, Common::FromWhichRoot from); + void ClearCache(); private: CNANDContentManager() {} @@ -82,8 +108,7 @@ class CNANDContentManager CNANDContentManager(CNANDContentManager const&) = delete; void operator=(CNANDContentManager const&) = delete; - typedef std::map CNANDContentMap; - CNANDContentMap m_Map; + std::unordered_map> m_map; }; class CSharedContent diff --git a/Source/Core/DolphinWX/Config/PathConfigPane.cpp b/Source/Core/DolphinWX/Config/PathConfigPane.cpp index c71693eb920e..4c4ad7909de5 100644 --- a/Source/Core/DolphinWX/Config/PathConfigPane.cpp +++ b/Source/Core/DolphinWX/Config/PathConfigPane.cpp @@ -182,6 +182,7 @@ void PathConfigPane::OnNANDRootChanged(wxCommandEvent& event) m_nand_root_dirpicker->SetPath(StrToWxStr(nand_path)); SConfig::GetInstance().m_SYSCONF->UpdateLocation(); + DiscIO::CNANDContentManager::Access().ClearCache(); main_frame->UpdateWiiMenuChoice(); } diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 294819928665..621a6ef39434 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1471,7 +1471,7 @@ void CFrame::OnShowCheatsWindow(wxCommandEvent& WXUNUSED (event)) void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED(event)) { - BootGame(Common::GetTitleContentPath(TITLEID_SYSMENU)); + BootGame(Common::GetTitleContentPath(TITLEID_SYSMENU, Common::FROM_CONFIGURED_ROOT)); } void CFrame::OnInstallWAD(wxCommandEvent& event) @@ -1527,7 +1527,7 @@ void CFrame::UpdateWiiMenuChoice(wxMenuItem *WiiMenuItem) WiiMenuItem = GetMenuBar()->FindItem(IDM_LOAD_WII_MENU); } - const DiscIO::INANDContentLoader & SysMenu_Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU, true); + const DiscIO::CNANDContentLoader & SysMenu_Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU, Common::FROM_CONFIGURED_ROOT); if (SysMenu_Loader.IsValid()) { int sysmenuVersion = SysMenu_Loader.GetTitleVersion(); @@ -1758,7 +1758,7 @@ void CFrame::UpdateGUI() GetMenuBar()->FindItem(IDM_SAVE_STATE)->Enable(Initialized); // Misc GetMenuBar()->FindItem(IDM_CHANGE_DISC)->Enable(Initialized); - if (DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU).IsValid()) + if (DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU, Common::FROM_CONFIGURED_ROOT).IsValid()) GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->Enable(!Initialized); // Tools