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:
itsnotmailmail 2009-06-15 22:27:46 +00:00
parent ac572e9d03
commit d6c40f65ff
3 changed files with 80 additions and 5 deletions

View File

@ -644,8 +644,69 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
}
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:
_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;
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...");
break;
case IOCTL_ES_GETDEVICECERT: //
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_GETDEVICECERT: this looks really wrong...");
break;
default:
_dbg_assert_msg_(WII_IPC_ES, 0, "CWII_IPC_HLE_Device_es: 0x%x", Buffer.Parameter);

View File

@ -128,6 +128,7 @@ public:
size_t GetContentSize() const { return m_Content.size(); }
const SNANDContent* GetContentByIndex(int _Index) const;
const u8* GetTicket() const { return m_TicketView; }
const u8* GetTmdHeader() const { return m_TmdHeader; }
const std::vector<SNANDContent>& GetContent() const { return m_Content; }
@ -144,9 +145,11 @@ private:
u16 m_numEntries;
u16 m_TileVersion;
u8 m_TicketView[TICKET_VIEW_SIZE];
u8 m_TmdHeader[TMD_HEADER_SIZE];
std::vector<SNANDContent> m_Content;
bool CreateFromDirectory(const std::string& _rPath);
bool CreateFromWAD(const std::string& _rName);
@ -231,6 +234,7 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
fclose(pTMDFile);
memcpy(m_TicketView, pTMD + 0x180, TICKET_VIEW_SIZE);
memcpy(m_TmdHeader, pTMD, TMD_HEADER_SIZE);
//////
m_TileVersion = Common::swap16(pTMD + 0x01dc);
@ -326,17 +330,21 @@ bool CNANDContentLoader::ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u
u8 IV[16];
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_TitleID = Common::swap64(pTMD + 0x018c);
m_IosVersion = Common::swap16(pTMD + 0x018a);
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];

View File

@ -55,6 +55,7 @@ public:
virtual size_t GetContentSize() const = 0;
virtual const SNANDContent* GetContentByIndex(int _Index) const = 0;
virtual const u8* GetTicket() const = 0;
virtual const u8* GetTmdHeader() const = 0;
virtual const std::vector<SNANDContent>& GetContent() const = 0;
virtual const u16 GetTitleVersion() const = 0;
virtual const u16 GetNumEntries() const = 0;
@ -62,7 +63,8 @@ public:
enum
{
TICKET_VIEW_SIZE = 0x58
TICKET_VIEW_SIZE = 0x58,
TMD_HEADER_SIZE = 0x1e4
};
};