Emulate ES's GetStoredTmd and GetStoredTmdSize commands (patch from issue 1016)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3460 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ac572e9d03
commit
d6c40f65ff
|
@ -644,8 +644,69 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_ES_GETSTOREDTMD:
|
||||||
|
{
|
||||||
|
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no in buffer");
|
||||||
|
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no out buffer");
|
||||||
|
|
||||||
|
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);
|
||||||
|
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||||
|
|
||||||
|
|
||||||
|
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffersize: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||||
|
|
||||||
|
u32 Count = 0;
|
||||||
|
if (Loader.IsValid())
|
||||||
|
{
|
||||||
|
u32 Address = Buffer.PayloadBuffer[0].m_Address;
|
||||||
|
|
||||||
|
Memory::WriteBigEData(Loader.GetTmdHeader(), Address, DiscIO::INANDContentLoader::TMD_HEADER_SIZE);
|
||||||
|
Address += DiscIO::INANDContentLoader::TMD_HEADER_SIZE;
|
||||||
|
|
||||||
|
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
|
||||||
|
for (size_t i=0; i<Loader.GetContentSize(); i++)
|
||||||
|
{
|
||||||
|
Memory::Write_U32(rContent[i].m_ContentID, Address); Address += 4;
|
||||||
|
Memory::Write_U16(rContent[i].m_Index, Address); Address += 2;
|
||||||
|
Memory::Write_U16(rContent[i].m_Type, Address); Address += 2;
|
||||||
|
Memory::Write_U64(rContent[i].m_Size, Address); Address += 8;
|
||||||
|
Memory::WriteBigEData(rContent[i].m_SHA1Hash, Address, 20); Address += 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
_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_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case IOCTL_ES_GETSTOREDTMDSIZE:
|
case IOCTL_ES_GETSTOREDTMDSIZE:
|
||||||
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_GETSTOREDTMDSIZE: this looks really wrong...");
|
{
|
||||||
|
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMDSIZE no in buffer");
|
||||||
|
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer");
|
||||||
|
|
||||||
|
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||||
|
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
||||||
|
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||||
|
|
||||||
|
_dbg_assert_(WII_IPC_ES, Loader.IsValid());
|
||||||
|
u32 TMDCnt = 0;
|
||||||
|
if (Loader.IsValid())
|
||||||
|
{
|
||||||
|
TMDCnt += DiscIO::INANDContentLoader::TMD_HEADER_SIZE;
|
||||||
|
TMDCnt += (u32)Loader.GetContentSize() * (4 + 2 + 2 + 8 + 20); //id, index, type, size, hash
|
||||||
|
}
|
||||||
|
Memory::Write_U32(TMDCnt, Buffer.PayloadBuffer[0].m_Address);
|
||||||
|
|
||||||
|
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||||
|
|
||||||
|
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDCnt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes)
|
case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes)
|
||||||
|
@ -656,6 +717,10 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||||
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
|
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_ES_GETDEVICECERT: //
|
||||||
|
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_GETDEVICECERT: this looks really wrong...");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_dbg_assert_msg_(WII_IPC_ES, 0, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter);
|
_dbg_assert_msg_(WII_IPC_ES, 0, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter);
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,7 @@ public:
|
||||||
size_t GetContentSize() const { return m_Content.size(); }
|
size_t GetContentSize() const { return m_Content.size(); }
|
||||||
const SNANDContent* GetContentByIndex(int _Index) const;
|
const SNANDContent* GetContentByIndex(int _Index) const;
|
||||||
const u8* GetTicket() const { return m_TicketView; }
|
const u8* GetTicket() const { return m_TicketView; }
|
||||||
|
const u8* GetTmdHeader() const { return m_TmdHeader; }
|
||||||
|
|
||||||
const std::vector<SNANDContent>& GetContent() const { return m_Content; }
|
const std::vector<SNANDContent>& GetContent() const { return m_Content; }
|
||||||
|
|
||||||
|
@ -144,9 +145,11 @@ private:
|
||||||
u16 m_numEntries;
|
u16 m_numEntries;
|
||||||
u16 m_TileVersion;
|
u16 m_TileVersion;
|
||||||
u8 m_TicketView[TICKET_VIEW_SIZE];
|
u8 m_TicketView[TICKET_VIEW_SIZE];
|
||||||
|
u8 m_TmdHeader[TMD_HEADER_SIZE];
|
||||||
|
|
||||||
std::vector<SNANDContent> m_Content;
|
std::vector<SNANDContent> m_Content;
|
||||||
|
|
||||||
|
|
||||||
bool CreateFromDirectory(const std::string& _rPath);
|
bool CreateFromDirectory(const std::string& _rPath);
|
||||||
bool CreateFromWAD(const std::string& _rName);
|
bool CreateFromWAD(const std::string& _rName);
|
||||||
|
|
||||||
|
@ -231,6 +234,7 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
|
||||||
fclose(pTMDFile);
|
fclose(pTMDFile);
|
||||||
|
|
||||||
memcpy(m_TicketView, pTMD + 0x180, TICKET_VIEW_SIZE);
|
memcpy(m_TicketView, pTMD + 0x180, TICKET_VIEW_SIZE);
|
||||||
|
memcpy(m_TmdHeader, pTMD, TMD_HEADER_SIZE);
|
||||||
|
|
||||||
//////
|
//////
|
||||||
m_TileVersion = Common::swap16(pTMD + 0x01dc);
|
m_TileVersion = Common::swap16(pTMD + 0x01dc);
|
||||||
|
@ -326,17 +330,21 @@ bool CNANDContentLoader::ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u
|
||||||
u8 IV[16];
|
u8 IV[16];
|
||||||
|
|
||||||
GetKeyFromTicket(pTicket, DecryptTitleKey);
|
GetKeyFromTicket(pTicket, DecryptTitleKey);
|
||||||
|
|
||||||
|
memcpy(m_TicketView, pTMD + 0x180, TICKET_VIEW_SIZE);
|
||||||
|
memcpy(m_TmdHeader, pTMD, TMD_HEADER_SIZE);
|
||||||
|
|
||||||
u32 numEntries = Common::swap16(pTMD + 0x01de);
|
m_TileVersion = Common::swap16(pTMD + 0x01dc);
|
||||||
|
m_numEntries = Common::swap16(pTMD + 0x01de);
|
||||||
m_BootIndex = Common::swap16(pTMD + 0x01e0);
|
m_BootIndex = Common::swap16(pTMD + 0x01e0);
|
||||||
m_TitleID = Common::swap64(pTMD + 0x018c);
|
m_TitleID = Common::swap64(pTMD + 0x018c);
|
||||||
m_IosVersion = Common::swap16(pTMD + 0x018a);
|
m_IosVersion = Common::swap16(pTMD + 0x018a);
|
||||||
|
|
||||||
u8* p = pDataApp;
|
u8* p = pDataApp;
|
||||||
|
|
||||||
m_Content.resize(numEntries);
|
m_Content.resize(m_numEntries);
|
||||||
|
|
||||||
for (u32 i=0; i<numEntries; i++)
|
for (u32 i=0; i<m_numEntries; i++)
|
||||||
{
|
{
|
||||||
SNANDContent& rContent = m_Content[i];
|
SNANDContent& rContent = m_Content[i];
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ public:
|
||||||
virtual size_t GetContentSize() const = 0;
|
virtual size_t GetContentSize() const = 0;
|
||||||
virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
|
virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
|
||||||
virtual const u8* GetTicket() const = 0;
|
virtual const u8* GetTicket() const = 0;
|
||||||
|
virtual const u8* GetTmdHeader() const = 0;
|
||||||
virtual const std::vector<SNANDContent>& GetContent() const = 0;
|
virtual const std::vector<SNANDContent>& GetContent() const = 0;
|
||||||
virtual const u16 GetTitleVersion() const = 0;
|
virtual const u16 GetTitleVersion() const = 0;
|
||||||
virtual const u16 GetNumEntries() const = 0;
|
virtual const u16 GetNumEntries() const = 0;
|
||||||
|
@ -62,7 +63,8 @@ public:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TICKET_VIEW_SIZE = 0x58
|
TICKET_VIEW_SIZE = 0x58,
|
||||||
|
TMD_HEADER_SIZE = 0x1e4
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue