fixed some ES problems and added cached for NANDContentLoader (we open this content files ways to often at the moment)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2651 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
b3a6208fcc
commit
0b76db1c04
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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<File::FSTEntry>::iterator level1 = parentEntry.children.begin(); level1 != parentEntry.children.end(); ++level1)
|
||||
// {
|
||||
// if (level1->isDirectory)
|
||||
// {
|
||||
// for(std::vector<File::FSTEntry>::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());
|
||||
|
||||
Memory::Write_U32((u32)rNANDCOntent.GetContentSize(), Buffer.PayloadBuffer[0].m_Address);
|
||||
u32 NumberOfPrivateContent = 0;
|
||||
const std::vector<DiscIO::SNANDContent>& rContent = rNANDCOntent.GetContent();
|
||||
for (size_t i=0; i<rContent.size();i++)
|
||||
{
|
||||
if ((rContent[i].m_Type & 0x8000) == 0)
|
||||
{
|
||||
NumberOfPrivateContent++;
|
||||
}
|
||||
}
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i",
|
||||
Memory::Write_U32(NumberOfPrivateContent, Buffer.PayloadBuffer[0].m_Address);
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLECONTENTSCNT: TitleID: %08x/%08x content count %i (just content in private directory)",
|
||||
(u32)(TitleID>>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<DiscIO::SNANDContent>& rContent = Loader.GetContent();
|
||||
for (size_t i=0; i<Loader.GetContentSize(); i++)
|
||||
{
|
||||
Memory::Write_U32(rContent[i].m_Index, Buffer.PayloadBuffer[0].m_Address+i*4);
|
||||
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);
|
||||
Count++;
|
||||
if (Count>=MaxCount)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
@ -551,7 +538,8 @@ 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);
|
||||
|
||||
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<File::FSTEntry>::iterator Level1 = ParentEntry.children.begin(); Level1 != ParentEntry.children.end(); ++Level1)
|
||||
{
|
||||
if (Level1->isDirectory)
|
||||
{
|
||||
for(std::vector<File::FSTEntry>::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<u32, SContentAccess> CContentAccessMap;
|
||||
CContentAccessMap m_ContentAccessMap;
|
||||
|
||||
typedef std::map<u64, DiscIO::CNANDContentLoader*> CTitleToContentMap;
|
||||
typedef std::map<u64, const DiscIO::INANDContentLoader*> CTitleToContentMap;
|
||||
CTitleToContentMap m_NANDContent;
|
||||
|
||||
DiscIO::CNANDContentLoader* m_pContentLoader;
|
||||
const DiscIO::INANDContentLoader* m_pContentLoader;
|
||||
|
||||
std::vector<u64> 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
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "stdafx.h"
|
||||
#include "NANDContentLoader.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#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<SNANDContent>& 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<SNANDContent> 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; i<m_Content.size(); i++)
|
||||
{
|
||||
|
@ -232,35 +281,6 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CNANDContentLoader::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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CNANDContentLoader::AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest)
|
||||
{
|
||||
AES_KEY AESKey;
|
||||
|
@ -371,6 +391,70 @@ bool CNANDContentLoader::ParseWAD(DiscIO::IBlobReader& _rReader)
|
|||
return Result;
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
|
||||
CNANDContentManager CNANDContentManager::m_Instance;
|
||||
|
||||
|
||||
CNANDContentManager::~CNANDContentManager()
|
||||
{
|
||||
CNANDContentMap::iterator itr = m_Map.begin();
|
||||
while (itr != m_Map.end())
|
||||
{
|
||||
delete itr->second;
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#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();
|
||||
|
||||
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<SNANDContent>& 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 ~INANDContentLoader() {}
|
||||
|
||||
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<SNANDContent>& 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<SNANDContent> 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<std::string, INANDContentLoader*> 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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ void CFrame::CreateMenu()
|
|||
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"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue