diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index af79f9b37a..b1e033d3a2 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -90,7 +90,7 @@ std::string CBoot::GenerateMapFilename() { case SCoreStartupParameter::BOOT_WII_NAND: { - DiscIO::CNANDContentLoader Loader( _StartupPara.m_strFilename); + const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_StartupPara.m_strFilename); if (Loader.IsValid()) { u64 TitleID = Loader.GetTitleID(); diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp index b2d95af346..d8317b48a2 100644 --- a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp @@ -86,12 +86,12 @@ void SetupWiiMem() bool CBoot::IsWiiWAD(const char *filename) { - return DiscIO::CNANDContentLoader::IsWiiWAD(filename); + return DiscIO::CNANDContentManager::IsWiiWAD(filename); } bool CBoot::Boot_WiiWAD(const char* _pFilename) { - DiscIO::CNANDContentLoader ContentLoader(_pFilename); + const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_pFilename); if (ContentLoader.IsValid() == false) return false; @@ -109,7 +109,7 @@ bool CBoot::Boot_WiiWAD(const char* _pFilename) Memory::Write_U64( ContentLoader.GetTitleID(), 0x0000318c); // NAND Load Title ID // DOL - DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()); + const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()); if (pContent == NULL) return false; diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index f0c4fa9eb9..643bfffcfa 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -140,7 +140,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios) m_BootType = BOOT_DOL; bNTSC = true; } - else if (DiscIO::CNANDContentLoader(m_strFilename).IsValid()) + else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid()) { bWii = true; Region = EUR_DIR; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 716921f8a4..c50723f0c8 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -203,6 +203,10 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName else if (_rDeviceName.find("/dev/usb/oh0") != std::string::npos) { pDevice = new CWII_IPC_HLE_Device_usb_oh0(_DeviceID, _rDeviceName); + } + else if (_rDeviceName.find("/dev/usb/kbd") != std::string::npos) + { + pDevice = new CWII_IPC_HLE_Device_usb_kbd(_DeviceID, _rDeviceName); } else if (_rDeviceName.find("/dev/sdio/slot0") != std::string::npos) { 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 58dc61a63d..34e6e6343b 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 @@ -60,7 +60,7 @@ CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& , m_TitleID(-1) , AccessIdentID(0x6000000) { - m_pContentLoader = new DiscIO::CNANDContentLoader(_rDefaultContentFile); + m_pContentLoader = &DiscIO::CNANDContentManager::Access().GetNANDLoader(_rDefaultContentFile); // check for cd ... if (m_pContentLoader->IsValid()) @@ -79,43 +79,20 @@ CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& // scan for the title ids listed in TMDs within /title/ m_TitleIDs.clear(); + m_TitleIDs.push_back(0x0000000100000002ULL); + // m_TitleIDs.push_back(0x0001000248414741ULL); + // m_TitleIDs.push_back(0x0001000248414341ULL); + // m_TitleIDs.push_back(0x0001000248414241ULL); + // m_TitleIDs.push_back(0x0001000248414141ULL); + + // FindValidTitleIDs(); -// std::string titleDir(FULL_WII_USER_DIR + std::string("title")); -// File::FSTEntry parentEntry; -// u32 numEntries = ScanDirectoryTree(titleDir.c_str(), parentEntry); -// -// for(std::vector::iterator level1 = parentEntry.children.begin(); level1 != parentEntry.children.end(); ++level1) -// { -// if (level1->isDirectory) -// { -// for(std::vector::iterator level2 = level1->children.begin(); level2 != level1->children.end(); ++level2) -// { -// if (level2->isDirectory) -// { -// // finally at /title/*/*/ -// // ...get titleID from content/title.tmd -// std::string currentTMD(level2->physicalName + DIR_SEP + "content" + DIR_SEP + "title.tmd"); -// if (File::Exists(currentTMD.c_str())) -// { -// FILE *tmd = fopen(currentTMD.c_str(), "rb"); -// u64 titleID = 0xDEADBEEFDEADBEEFULL; -// fseek(tmd, 0x18C, SEEK_SET); -// fread(&titleID, 8, 1, tmd); -// m_TitleIDs.push_back(Common::swap64(titleID)); -// fclose(tmd); -// } -// } -// } -// } -// } INFO_LOG(WII_IPC_ES, "Set default title to %08x/%08x", m_TitleID>>32, m_TitleID); } CWII_IPC_HLE_Device_es::~CWII_IPC_HLE_Device_es() { - delete m_pContentLoader; - CTitleToContentMap::const_iterator itr = m_NANDContent.begin(); while(itr != m_NANDContent.end()) { @@ -162,12 +139,22 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); - DiscIO::CNANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID); + const DiscIO::INANDContentLoader& rNANDCOntent = AccessContentDevice(TitleID); _dbg_assert_(WII_IPC_ES, rNANDCOntent.IsValid()); + + u32 NumberOfPrivateContent = 0; + const std::vector& rContent = rNANDCOntent.GetContent(); + for (size_t i=0; i>32), (u32)TitleID, rNANDCOntent.GetContentSize()); Memory::Write_U32(0, _CommandAddress + 0x4); @@ -183,25 +170,25 @@ bool 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); std::string TitleFilename = CreateTitleContentPath(TitleID); - DiscIO::CNANDContentLoader Loader(TitleFilename); + const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename); - ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: title: %08x/%08x buffersize: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); + ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: title: %08x/%08x MaxCount: %i (just content in private directory)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); - u32 Count = 0; + _dbg_assert_(WII_IPC_ES, Loader.GetContentSize() == MaxCount); if (Loader.IsValid()) { const std::vector& rContent = Loader.GetContent(); for (size_t i=0; i=MaxCount) - break; + if ((rContent[i].m_Type & 0x8000) == 0) + { + Memory::Write_U32(rContent[i].m_ContentID, Buffer.PayloadBuffer[0].m_Address+i*4); + ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Index 0x%x", rContent[i].m_ContentID); + } } } Memory::Write_U32(0, _CommandAddress + 0x4); - ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Count %i", Count); + ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: Count %i", Loader.GetContentSize()); return true; } break; @@ -494,23 +481,22 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address); std::string TitleFilename = CreateTitleContentPath(TitleID); - DiscIO::CNANDContentLoader Loader(TitleFilename); + const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename); _dbg_assert_(WII_IPC_ES, Loader.IsValid()); u32 TMDViewCnt = 0; if (Loader.IsValid()) { - TMDViewCnt += DiscIO::CNANDContentLoader::TICKET_VIEW_SIZE; + TMDViewCnt += DiscIO::INANDContentLoader::TICKET_VIEW_SIZE; TMDViewCnt += 2; // title version TMDViewCnt += 2; // num entries - TMDViewCnt += Loader.GetContentSize() * (4+2+2+8); // content id, index, type, size + TMDViewCnt += (u32)Loader.GetContentSize() * (4+2+2+8); // content id, index, type, size } Memory::Write_U32(TMDViewCnt, Buffer.PayloadBuffer[0].m_Address); Memory::Write_U32(0, _CommandAddress + 0x4); - INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x -> count %i", (u32)(TitleID >> 32), (u32)TitleID, TMDViewCnt); - + INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDViewCnt); return true; } break; @@ -523,7 +509,8 @@ bool 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); std::string TitleFilename = CreateTitleContentPath(TitleID); - DiscIO::CNANDContentLoader Loader(TitleFilename); + const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename); + INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x buffersize: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount); @@ -533,8 +520,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) { u32 Address = Buffer.PayloadBuffer[0].m_Address; - Memory::WriteBigEData(Loader.GetTicket(), Address, DiscIO::CNANDContentLoader::TICKET_VIEW_SIZE); - Address += DiscIO::CNANDContentLoader::TICKET_VIEW_SIZE; + Memory::WriteBigEData(Loader.GetTicket(), Address, DiscIO::INANDContentLoader::TICKET_VIEW_SIZE); + Address += DiscIO::INANDContentLoader::TICKET_VIEW_SIZE; Memory::Write_U16(Loader.GetTitleVersion(), Address); Address += 2; Memory::Write_U16(Loader.GetNumEntries(), Address); Address += 2; @@ -550,8 +537,9 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) _dbg_assert_(WII_IPC_ES, (Address-Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size); } - Memory::Write_U32(0, _CommandAddress + 0x4); - INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: Count %i", Count); + Memory::Write_U32(0, _CommandAddress + 0x4); + + INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)", TitleID >> 32, TitleID, MaxCount); return true; } break; @@ -616,7 +604,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) return true; } -DiscIO::CNANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 _TitleID) +const DiscIO::INANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 _TitleID) { if (m_pContentLoader->IsValid() && m_pContentLoader->GetTitleID() == _TitleID) return* m_pContentLoader; @@ -626,7 +614,7 @@ DiscIO::CNANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 _Tit return *itr->second; std::string TitleFilename = CreateTitleContentPath(_TitleID); - m_NANDContent[_TitleID] = new DiscIO::CNANDContentLoader(TitleFilename); + m_NANDContent[_TitleID] = &DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename); _dbg_assert_(WII_IPC_ES, m_NANDContent[_TitleID]->IsValid()); return *m_NANDContent[_TitleID]; @@ -656,3 +644,35 @@ std::string CWII_IPC_HLE_Device_es::CreateTitleContentPath(u64 _TitleID) const return TicketFilename; } +void CWII_IPC_HLE_Device_es::FindValidTitleIDs() +{ + m_TitleIDs.clear(); + + std::string TitlePath(FULL_WII_USER_DIR + std::string("title")); + File::FSTEntry ParentEntry; + u32 NumEntries = ScanDirectoryTree(TitlePath.c_str(), ParentEntry); + for(std::vector::iterator Level1 = ParentEntry.children.begin(); Level1 != ParentEntry.children.end(); ++Level1) + { + if (Level1->isDirectory) + { + for(std::vector::iterator Level2 = Level1->children.begin(); Level2 != Level1->children.end(); ++Level2) + { + if (Level2->isDirectory) + { + // finally at /title/*/*/ + // ...get titleID from content/title.tmd + std::string CurrentTMD(Level2->physicalName + DIR_SEP + "content" + DIR_SEP + "title.tmd"); + if (File::Exists(CurrentTMD.c_str())) + { + FILE* pTMDFile = fopen(CurrentTMD.c_str(), "rb"); + u64 TitleID = 0xDEADBEEFDEADBEEFULL; + fseek(pTMDFile, 0x18C, SEEK_SET); + fread(&TitleID, 8, 1, pTMDFile); + m_TitleIDs.push_back(Common::swap64(TitleID)); + fclose(pTMDFile); + } + } + } + } + } +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h index 61b83c64c9..0d830ed1c4 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -26,7 +26,7 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device { public: - CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName, const std::string& _rDefaultContentFile); + CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName, const std::string& _rDefaultContentFile); virtual ~CWII_IPC_HLE_Device_es(); @@ -97,19 +97,35 @@ private: IOCTL_ES_GETSHAREDCONTENTS = 0x37, }; + enum EErrorCodes + { + ES_INVALID_TMD = -106, // or access denied + ES_READ_LESS_DATA_THAN_EXPECTED = -1009, + ES_UNK_1 = -1010, + ES_PARAMTER_SIZE_OR_ALIGNMENT = -1017, + ES_HASH_DOESNT_MATCH = -1022, + ES_MEM_ALLOC_FAILED = -1024, + ES_INCORRECT_ACCESS_RIGHT = -1026, + ES_NO_TICKET_INSTALLED = -1028, + ES_INSTALLED_TICKET_INVALID = -1029, + ES_INVALID_PARAMETR = -2008, + ES_SIGNATURE_CHECK_FAILED = -2011, + ES_HASH_SIZE_WRONG = -2014, // HASH !=20 + }; + struct SContentAccess { u32 m_Position; - DiscIO::SNANDContent* m_pContent; + const DiscIO::SNANDContent* m_pContent; }; typedef std::map CContentAccessMap; CContentAccessMap m_ContentAccessMap; - typedef std::map CTitleToContentMap; + typedef std::map CTitleToContentMap; CTitleToContentMap m_NANDContent; - DiscIO::CNANDContentLoader* m_pContentLoader; + const DiscIO::INANDContentLoader* m_pContentLoader; std::vector m_TitleIDs; u64 m_TitleID; @@ -117,12 +133,13 @@ private: u64 GetCurrentTitleID() const; - DiscIO::CNANDContentLoader& AccessContentDevice(u64 _TitleID); + const DiscIO::INANDContentLoader& AccessContentDevice(u64 _TitleID); bool IsValid(u64 _TitleID) const; std::string CreateTicketFileName(u64 _TitleID) const; std::string CreateTitleContentPath(u64 _TitleID) const; + void FindValidTitleIDs(); }; #endif diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index 3e29a2f799..1de5423397 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -18,6 +18,8 @@ #include "stdafx.h" #include "NANDContentLoader.h" +#include +#include #include "AES/aes.h" #include "MathUtil.h" #include "FileUtil.h" @@ -110,6 +112,53 @@ private: }; +// this classes must be created by the CNANDContentManager +class CNANDContentLoader : public INANDContentLoader +{ +public: + + CNANDContentLoader(const std::string& _rName); + + virtual ~CNANDContentLoader(); + + bool IsValid() const { return m_Valid; } + u64 GetTitleID() const { return m_TitleID; } + u32 GetBootIndex() const { return m_BootIndex; } + size_t GetContentSize() const { return m_Content.size(); } + const SNANDContent* GetContentByIndex(int _Index) const; + const u8* GetTicket() const { return m_TicketView; } + + const std::vector& GetContent() const { return m_Content; } + + const u16 GetTitleVersion() const {return m_TileVersion;} + const u16 GetNumEntries() const {return m_numEntries;} + +private: + + bool m_Valid; + u64 m_TitleID; + u32 m_BootIndex; + u16 m_numEntries; + u16 m_TileVersion; + u8 m_TicketView[TICKET_VIEW_SIZE]; + + std::vector m_Content; + + bool CreateFromDirectory(const std::string& _rPath); + bool CreateFromWAD(const std::string& _rName); + + bool ParseWAD(DiscIO::IBlobReader& _rReader); + + void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest); + + u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset); + + void GetKeyFromTicket(u8* pTicket, u8* pTicketKey); + + bool ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u8* pTMD); +}; + + CNANDContentLoader::CNANDContentLoader(const std::string& _rName) @@ -140,7 +189,7 @@ CNANDContentLoader::~CNANDContentLoader() m_Content.clear(); } -SNANDContent* CNANDContentLoader::GetContentByIndex(int _Index) +const SNANDContent* CNANDContentLoader::GetContentByIndex(int _Index) const { for (size_t i=0; isecond; + itr++; + } + m_Map.clear(); +} + +const INANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string& _rName) +{ + std::string KeyString(_rName); + + std::transform(KeyString.begin(), KeyString.end(), KeyString.begin(), + (int(*)(int)) std::toupper); + + + CNANDContentMap::iterator itr = m_Map.find(KeyString); + if (itr != m_Map.end()) + return *itr->second; + + m_Map[KeyString] = new CNANDContentLoader(KeyString); + return *m_Map[KeyString]; +} + + +bool CNANDContentManager::IsWiiWAD(const std::string& _rName) +{ + DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rName.c_str()); + if (pReader == NULL) + return false; + + CBlobBigEndianReader Reader(*pReader); + bool Result = false; + + // check for wii wad + if (Reader.Read32(0x00) == 0x20) + { + u32 WADTYpe = Reader.Read32(0x04); + switch(WADTYpe) + { + case 0x49730000: + case 0x69620000: + Result = true; + } + } + + delete pReader; + + return Result; +} + + + + + } // namespace end diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h index 7757f7440c..c65efbe0ff 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.h +++ b/Source/Core/DiscIO/Src/NANDContentLoader.h @@ -20,6 +20,8 @@ #include #include +#include + #include "Common.h" #include "Blob.h" @@ -36,58 +38,54 @@ struct SNANDContent u8* m_pData; }; -class CNANDContentLoader +// pure virtual interface so just the NANDContentManager can create these files only +class INANDContentLoader { public: - CNANDContentLoader(const std::string& _rName); + INANDContentLoader() {} - virtual ~CNANDContentLoader(); + virtual ~INANDContentLoader() {} - bool IsValid() const { return m_Valid; } - u64 GetTitleID() const { return m_TitleID; } - u32 GetBootIndex() const { return m_BootIndex; } - size_t GetContentSize() const { return m_Content.size(); } - SNANDContent* GetContentByIndex(int _Index); - const u8* GetTicket() const { return m_TicketView; } - - const std::vector& GetContent() const { return m_Content; } - - static bool IsWiiWAD(const std::string& _rName); - - const u16 GetTitleVersion() const {return m_TileVersion;} - const u16 GetNumEntries() const {return m_numEntries;} - + virtual bool IsValid() const = NULL; + virtual u64 GetTitleID() const = NULL; + virtual u32 GetBootIndex() const = NULL; + virtual size_t GetContentSize() const = NULL; + virtual const SNANDContent* GetContentByIndex(int _Index) const = NULL;; + virtual const u8* GetTicket() const = NULL; + virtual const std::vector& GetContent() const = NULL; + virtual const u16 GetTitleVersion() const = NULL; + virtual const u16 GetNumEntries() const = NULL; enum { TICKET_VIEW_SIZE = 0x58 }; +}; + + +// we open the NAND Content files to often... lets cache them +class CNANDContentManager +{ +public: + + static CNANDContentManager& Access() { return m_Instance; } + + const INANDContentLoader& GetNANDLoader(const std::string& _rName); + + static bool IsWiiWAD(const std::string& _rName); private: - bool m_Valid; - u64 m_TitleID; - u32 m_BootIndex; - u16 m_numEntries; - u16 m_TileVersion; - u8 m_TicketView[TICKET_VIEW_SIZE]; + CNANDContentManager() {}; - std::vector m_Content; + ~CNANDContentManager(); - bool CreateFromDirectory(const std::string& _rPath); - bool CreateFromWAD(const std::string& _rName); + static CNANDContentManager m_Instance; - bool ParseWAD(DiscIO::IBlobReader& _rReader); + typedef std::map CNANDContentMap; + CNANDContentMap m_Map; - void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest); - - u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset); - - void GetKeyFromTicket(u8* pTicket, u8* pTicketKey); - - - bool ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u8* pTMD); }; } diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index c1ab6549b6..b4749b32cd 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -160,8 +160,8 @@ void CFrame::CreateMenu() toolsMenu->Append(IDM_MEMCARD, _T("&Memcard Manager")); toolsMenu->Append(IDM_CHEATS, _T("Action &Replay Manager")); // toolsMenu->Append(IDM_SDCARD, _T("Mount &SDCard")); // Disable for now - - if (DiscIO::CNANDContentLoader(FULL_WII_MENU_DIR).IsValid()) + + if (DiscIO::CNANDContentManager::Access().GetNANDLoader(FULL_WII_MENU_DIR).IsValid()) { toolsMenu->Append(IDM_LOAD_WII_MENU, _T("Load Wii Menu")); }