mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
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:
|
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())
|
if (Loader.IsValid())
|
||||||
{
|
{
|
||||||
u64 TitleID = Loader.GetTitleID();
|
u64 TitleID = Loader.GetTitleID();
|
||||||
|
@ -86,12 +86,12 @@ void SetupWiiMem()
|
|||||||
|
|
||||||
bool CBoot::IsWiiWAD(const char *filename)
|
bool CBoot::IsWiiWAD(const char *filename)
|
||||||
{
|
{
|
||||||
return DiscIO::CNANDContentLoader::IsWiiWAD(filename);
|
return DiscIO::CNANDContentManager::IsWiiWAD(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBoot::Boot_WiiWAD(const char* _pFilename)
|
bool CBoot::Boot_WiiWAD(const char* _pFilename)
|
||||||
{
|
{
|
||||||
DiscIO::CNANDContentLoader ContentLoader(_pFilename);
|
const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_pFilename);
|
||||||
if (ContentLoader.IsValid() == false)
|
if (ContentLoader.IsValid() == false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ bool CBoot::Boot_WiiWAD(const char* _pFilename)
|
|||||||
Memory::Write_U64( ContentLoader.GetTitleID(), 0x0000318c); // NAND Load Title ID
|
Memory::Write_U64( ContentLoader.GetTitleID(), 0x0000318c); // NAND Load Title ID
|
||||||
|
|
||||||
// DOL
|
// DOL
|
||||||
DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex());
|
const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex());
|
||||||
if (pContent == NULL)
|
if (pContent == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
|
|||||||
m_BootType = BOOT_DOL;
|
m_BootType = BOOT_DOL;
|
||||||
bNTSC = true;
|
bNTSC = true;
|
||||||
}
|
}
|
||||||
else if (DiscIO::CNANDContentLoader(m_strFilename).IsValid())
|
else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid())
|
||||||
{
|
{
|
||||||
bWii = true;
|
bWii = true;
|
||||||
Region = EUR_DIR;
|
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)
|
else if (_rDeviceName.find("/dev/usb/oh0") != std::string::npos)
|
||||||
{
|
{
|
||||||
pDevice = new CWII_IPC_HLE_Device_usb_oh0(_DeviceID, _rDeviceName);
|
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)
|
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)
|
, m_TitleID(-1)
|
||||||
, AccessIdentID(0x6000000)
|
, AccessIdentID(0x6000000)
|
||||||
{
|
{
|
||||||
m_pContentLoader = new DiscIO::CNANDContentLoader(_rDefaultContentFile);
|
m_pContentLoader = &DiscIO::CNANDContentManager::Access().GetNANDLoader(_rDefaultContentFile);
|
||||||
|
|
||||||
// check for cd ...
|
// check for cd ...
|
||||||
if (m_pContentLoader->IsValid())
|
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/
|
// scan for the title ids listed in TMDs within /title/
|
||||||
m_TitleIDs.clear();
|
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);
|
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()
|
CWII_IPC_HLE_Device_es::~CWII_IPC_HLE_Device_es()
|
||||||
{
|
{
|
||||||
delete m_pContentLoader;
|
|
||||||
|
|
||||||
CTitleToContentMap::const_iterator itr = m_NANDContent.begin();
|
CTitleToContentMap::const_iterator itr = m_NANDContent.begin();
|
||||||
while(itr != m_NANDContent.end())
|
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);
|
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());
|
_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());
|
(u32)(TitleID>>32), (u32)TitleID, rNANDCOntent.GetContentSize());
|
||||||
|
|
||||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
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);
|
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||||
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
||||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
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())
|
if (Loader.IsValid())
|
||||||
{
|
{
|
||||||
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
|
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
|
||||||
for (size_t i=0; i<Loader.GetContentSize(); i++)
|
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);
|
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);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -494,23 +481,22 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||||||
|
|
||||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
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());
|
_dbg_assert_(WII_IPC_ES, Loader.IsValid());
|
||||||
u32 TMDViewCnt = 0;
|
u32 TMDViewCnt = 0;
|
||||||
if (Loader.IsValid())
|
if (Loader.IsValid())
|
||||||
{
|
{
|
||||||
TMDViewCnt += DiscIO::CNANDContentLoader::TICKET_VIEW_SIZE;
|
TMDViewCnt += DiscIO::INANDContentLoader::TICKET_VIEW_SIZE;
|
||||||
TMDViewCnt += 2; // title version
|
TMDViewCnt += 2; // title version
|
||||||
TMDViewCnt += 2; // num entries
|
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(TMDViewCnt, Buffer.PayloadBuffer[0].m_Address);
|
||||||
|
|
||||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -523,7 +509,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||||
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
||||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
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);
|
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;
|
u32 Address = Buffer.PayloadBuffer[0].m_Address;
|
||||||
|
|
||||||
Memory::WriteBigEData(Loader.GetTicket(), Address, DiscIO::CNANDContentLoader::TICKET_VIEW_SIZE);
|
Memory::WriteBigEData(Loader.GetTicket(), Address, DiscIO::INANDContentLoader::TICKET_VIEW_SIZE);
|
||||||
Address += DiscIO::CNANDContentLoader::TICKET_VIEW_SIZE;
|
Address += DiscIO::INANDContentLoader::TICKET_VIEW_SIZE;
|
||||||
|
|
||||||
Memory::Write_U16(Loader.GetTitleVersion(), Address); Address += 2;
|
Memory::Write_U16(Loader.GetTitleVersion(), Address); Address += 2;
|
||||||
Memory::Write_U16(Loader.GetNumEntries(), 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);
|
_dbg_assert_(WII_IPC_ES, (Address-Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size);
|
||||||
}
|
}
|
||||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -616,7 +604,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||||||
return true;
|
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)
|
if (m_pContentLoader->IsValid() && m_pContentLoader->GetTitleID() == _TitleID)
|
||||||
return* m_pContentLoader;
|
return* m_pContentLoader;
|
||||||
@ -626,7 +614,7 @@ DiscIO::CNANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u64 _Tit
|
|||||||
return *itr->second;
|
return *itr->second;
|
||||||
|
|
||||||
std::string TitleFilename = CreateTitleContentPath(_TitleID);
|
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());
|
_dbg_assert_(WII_IPC_ES, m_NANDContent[_TitleID]->IsValid());
|
||||||
return *m_NANDContent[_TitleID];
|
return *m_NANDContent[_TitleID];
|
||||||
@ -656,3 +644,35 @@ std::string CWII_IPC_HLE_Device_es::CreateTitleContentPath(u64 _TitleID) const
|
|||||||
return TicketFilename;
|
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,
|
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
|
struct SContentAccess
|
||||||
{
|
{
|
||||||
u32 m_Position;
|
u32 m_Position;
|
||||||
DiscIO::SNANDContent* m_pContent;
|
const DiscIO::SNANDContent* m_pContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<u32, SContentAccess> CContentAccessMap;
|
typedef std::map<u32, SContentAccess> CContentAccessMap;
|
||||||
CContentAccessMap m_ContentAccessMap;
|
CContentAccessMap m_ContentAccessMap;
|
||||||
|
|
||||||
typedef std::map<u64, DiscIO::CNANDContentLoader*> CTitleToContentMap;
|
typedef std::map<u64, const DiscIO::INANDContentLoader*> CTitleToContentMap;
|
||||||
CTitleToContentMap m_NANDContent;
|
CTitleToContentMap m_NANDContent;
|
||||||
|
|
||||||
DiscIO::CNANDContentLoader* m_pContentLoader;
|
const DiscIO::INANDContentLoader* m_pContentLoader;
|
||||||
|
|
||||||
std::vector<u64> m_TitleIDs;
|
std::vector<u64> m_TitleIDs;
|
||||||
u64 m_TitleID;
|
u64 m_TitleID;
|
||||||
@ -117,12 +133,13 @@ private:
|
|||||||
|
|
||||||
u64 GetCurrentTitleID() const;
|
u64 GetCurrentTitleID() const;
|
||||||
|
|
||||||
DiscIO::CNANDContentLoader& AccessContentDevice(u64 _TitleID);
|
const DiscIO::INANDContentLoader& AccessContentDevice(u64 _TitleID);
|
||||||
|
|
||||||
bool IsValid(u64 _TitleID) const;
|
bool IsValid(u64 _TitleID) const;
|
||||||
|
|
||||||
std::string CreateTicketFileName(u64 _TitleID) const;
|
std::string CreateTicketFileName(u64 _TitleID) const;
|
||||||
std::string CreateTitleContentPath(u64 _TitleID) const;
|
std::string CreateTitleContentPath(u64 _TitleID) const;
|
||||||
|
void FindValidTitleIDs();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "NANDContentLoader.h"
|
#include "NANDContentLoader.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
#include "AES/aes.h"
|
#include "AES/aes.h"
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
#include "FileUtil.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)
|
CNANDContentLoader::CNANDContentLoader(const std::string& _rName)
|
||||||
@ -140,7 +189,7 @@ CNANDContentLoader::~CNANDContentLoader()
|
|||||||
m_Content.clear();
|
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++)
|
for (size_t i=0; i<m_Content.size(); i++)
|
||||||
{
|
{
|
||||||
@ -232,35 +281,6 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
|
|||||||
return true;
|
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)
|
void CNANDContentLoader::AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest)
|
||||||
{
|
{
|
||||||
AES_KEY AESKey;
|
AES_KEY AESKey;
|
||||||
@ -371,6 +391,70 @@ bool CNANDContentLoader::ParseWAD(DiscIO::IBlobReader& _rReader)
|
|||||||
return Result;
|
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
|
} // namespace end
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Blob.h"
|
#include "Blob.h"
|
||||||
|
|
||||||
@ -36,58 +38,54 @@ struct SNANDContent
|
|||||||
u8* m_pData;
|
u8* m_pData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CNANDContentLoader
|
// pure virtual interface so just the NANDContentManager can create these files only
|
||||||
|
class INANDContentLoader
|
||||||
{
|
{
|
||||||
public:
|
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<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 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
|
enum
|
||||||
{
|
{
|
||||||
TICKET_VIEW_SIZE = 0x58
|
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:
|
private:
|
||||||
|
|
||||||
bool m_Valid;
|
CNANDContentManager() {};
|
||||||
u64 m_TitleID;
|
|
||||||
u32 m_BootIndex;
|
|
||||||
u16 m_numEntries;
|
|
||||||
u16 m_TileVersion;
|
|
||||||
u8 m_TicketView[TICKET_VIEW_SIZE];
|
|
||||||
|
|
||||||
std::vector<SNANDContent> m_Content;
|
~CNANDContentManager();
|
||||||
|
|
||||||
bool CreateFromDirectory(const std::string& _rPath);
|
static CNANDContentManager m_Instance;
|
||||||
bool CreateFromWAD(const std::string& _rName);
|
|
||||||
|
|
||||||
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_CHEATS, _T("Action &Replay Manager"));
|
||||||
// toolsMenu->Append(IDM_SDCARD, _T("Mount &SDCard")); // Disable for now
|
// 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"));
|
toolsMenu->Append(IDM_LOAD_WII_MENU, _T("Load Wii Menu"));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user