diff --git a/Source/Core/Common/NandPaths.cpp b/Source/Core/Common/NandPaths.cpp index d4c9f8a151..4048979c3c 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 6a79abf3bf..7d33477d76 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 44d1cbd39d..30fce0bc68 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 af720a955a..3ab6ed6c58 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 a267227f49..5ae4c0f0f5 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 87041a3b2d..16a88c5e7e 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 0a154f3a43..024b45ebac 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 4a7ee2840c..84837e4a22 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 23f8f6ce20..d92950b7f7 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 bdc630178b..73d08cc2e3 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 776c1ca784..9720e766c1 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 @@ private: 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 @@ private: 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 d7aad53ad5..c7cc1b518d 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 f31073e7d5..5a515ca4ea 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 0e26fa051e..5c16953794 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 8b309b13f5..c14fbb05c8 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: + CNANDContentLoader(const std::string& _rName); + virtual ~CNANDContentLoader(); - INANDContentLoader() {} + 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; } - virtual ~INANDContentLoader() {} + const std::vector& GetContent() const { return m_Content; } - 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; + 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 @@ public: 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 @@ public: 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 @@ private: 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 c71693eb92..4c4ad7909d 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 2948199286..621a6ef394 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