Implement parts of DIVerify that can be useful. (copy tmd to emulated nand for disc titles)

correct some parts of uid.sys as disc title ids are included
title in uid + tmd on nand is how the sysmenu knows which save files to look for.
IE games that are displayed in the disc channel at least once and have a save file will be
viewable in the sysmenu save manager

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6189 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99 2010-09-07 06:06:08 +00:00
parent dee24e5695
commit e0383634d3
9 changed files with 126 additions and 76 deletions

View File

@ -21,20 +21,68 @@
namespace Common
{
std::string CreateTicketFileName(u64 _TitleID)
std::string CreateTicketFileName(u64 _titleID)
{
char TicketFilename[1024];
sprintf(TicketFilename, "%sticket/%08x/%08x.tik", File::GetUserPath(D_WIIUSER_IDX), (u32)(_TitleID >> 32), (u32)_TitleID);
sprintf(TicketFilename, "%sticket/%08x/%08x.tik", File::GetUserPath(D_WIIUSER_IDX), (u32)(_titleID >> 32), (u32)_titleID);
return TicketFilename;
}
std::string CreateTitleContentPath(u64 _TitleID)
std::string CreateTitleDataPath(u64 _titleID)
{
char path[1024];
sprintf(path, "%stitle/%08x/%08x/data", File::GetUserPath(D_WIIUSER_IDX), (u32)(_titleID >> 32), (u32)_titleID);
return path;
}
std::string CreateTitleContentPath(u64 _titleID)
{
char ContentPath[1024];
sprintf(ContentPath, "%stitle/%08x/%08x/content", File::GetUserPath(D_WIIUSER_IDX), (u32)(_TitleID >> 32), (u32)_TitleID);
sprintf(ContentPath, "%stitle/%08x/%08x/content", File::GetUserPath(D_WIIUSER_IDX), (u32)(_titleID >> 32), (u32)_titleID);
return ContentPath;
}
};
bool CheckTitleTMD(u64 _titleID)
{
std::string TitlePath;
TitlePath = CreateTitleContentPath(_titleID) + "/title.tmd";
if (File::Exists(TitlePath.c_str()))
{
FILE* pTMDFile = fopen(TitlePath.c_str(), "rb");
if(pTMDFile)
{
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
fseek(pTMDFile, 0x18C, SEEK_SET);
fread(&TitleID, 8, 1, pTMDFile);
fclose(pTMDFile);
if (_titleID == Common::swap64(TitleID))
return true;
}
}
INFO_LOG(DISCIO, "Invalid or no tmd for title %08x %08x", (u32)(_titleID >> 32), (u32)(_titleID & 0xFFFFFFFF));
return false;
}
bool CheckTitleTIK(u64 _titleID)
{
std::string TikPath = Common::CreateTicketFileName(_titleID);
if (File::Exists(TikPath.c_str()))
{
FILE* pTIKFile = fopen(TikPath.c_str(), "rb");
if(pTIKFile)
{
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
fseek(pTIKFile, 0x1dC, SEEK_SET);
fread(&TitleID, 8, 1, pTIKFile);
fclose(pTIKFile);
if (_titleID == Common::swap64(TitleID))
return true;
}
}
INFO_LOG(DISCIO, "Invalid or no tik for title %08x %08x", (u32)(_titleID >> 32), (u32)(_titleID & 0xFFFFFFFF));
return false;
}
};

View File

@ -25,7 +25,11 @@
namespace Common
{
std::string CreateTicketFileName(u64 _TitleID);
std::string CreateTitleContentPath(u64 _TitleID);
std::string CreateTicketFileName(u64 _titleID);
std::string CreateTitleDataPath(u64 _titleID);
std::string CreateTitleContentPath(u64 _titleID);
bool CheckTitleTMD(u64 _titleID);
bool CheckTitleTIK(u64 _titleID);
}
#endif

View File

@ -137,6 +137,14 @@ void SetDefaultContentFile(const std::string& _rFilename)
if (pDevice)
pDevice->LoadWAD(_rFilename);
}
void ES_DIVerify(u8 *_pTMD, u32 _sz)
{
CWII_IPC_HLE_Device_es* pDevice = (CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
if (pDevice)
pDevice->ES_DIVerify(_pTMD, _sz);
else
ERROR_LOG(WII_IPC_ES, "DIVerify called but /dev/es is not available");
}
int GetDeviceIDByName(const std::string& _rDeviceName)
{

View File

@ -42,6 +42,7 @@ void DoState(PointerWrap &p);
// Set default content file
void SetDefaultContentFile(const std::string& _rFilename);
void ES_DIVerify(u8 *_pTMD, u32 _sz);
int GetDeviceIDByName(const std::string& _rDeviceName);

View File

@ -18,6 +18,7 @@
#include "Common.h"
#include "WII_IPC_HLE_Device_DI.h"
#include "WII_IPC_HLE.h"
#include "../HW/DVDInterface.h"
#include "../HW/CPU.h"
@ -119,13 +120,20 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
// Get TMD offset for requested partition...
u64 TMDOffset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2 ) + 0x2c0;
INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: TMDOffset 0x%016llx", TMDOffset);
u32 TMDsz = CommandBuffer.PayloadBuffer[0].m_Size;
u8 *pTMD = new u8[TMDsz];
if (pTMD)
{
// Read TMD to the buffer
readOK |= VolumeHandler::RAWReadToPtr(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address),
TMDOffset, CommandBuffer.PayloadBuffer[0].m_Size);
VolumeHandler::RAWReadToPtr(pTMD, TMDOffset, TMDsz);
memcpy(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), pTMD, TMDsz);
readOK |= true;
WII_IPC_HLE_Interface::ES_DIVerify(pTMD, TMDsz);
}
ReturnValue = readOK ? 1 : 0;
}
break;

View File

@ -55,7 +55,7 @@
#include "../Boot/Boot_DOL.h"
#include "NandPaths.h"
#include "CommonPaths.h"
CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pContentLoader(NULL)
@ -82,9 +82,12 @@ bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode)
m_TitleID = m_pContentLoader->GetTitleID();
// System menu versions about 0xE0 will indicate that system files are corrupted if there is more than one title
// TODO: fix System menu versions above this and remove this check
if (m_pContentLoader->GetTitleVersion() <= 0xE0)
{
DiscIO::cUIDsys::AccessInstance().GetTitleIDs(m_TitleIDs);
// uncomment if ES_GetOwnedTitlesCount / ES_GetOwnedTitles is implemented
// DiscIO::cUIDsys::AccessInstance().GetTitleIDs(m_TitleIDsOwned, true);
}
else
{
@ -156,7 +159,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, // Unknown
};
switch (Buffer.Parameter)
switch (Buffer.Parameter)
{
case IOCTL_ES_GETDEVICEID:
{
@ -387,7 +390,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "IOCTL_ES_SETUID no in buffer");
_dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 0);
// TODO: fs permissions based on this
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
INFO_LOG(WII_IPC_ES, "IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(TitleID>>32), (u32)TitleID);
}
@ -788,3 +791,35 @@ bool CWII_IPC_HLE_Device_es::IsValid(u64 _TitleID) const
}
u32 CWII_IPC_HLE_Device_es::ES_DIVerify(u8* _pTMD, u32 _sz)
{
u64 titleID = 0xDEADBEEFDEADBEEFull;
u64 tmdTitleID = Common::swap64(*(u64*)(_pTMD+0x18c));
VolumeHandler::GetVolume()->GetTitleID((u8*)&titleID);
if (Common::swap64(titleID) != tmdTitleID)
{
return -1;
}
std::string contentPath,
dataPath,
tmdPath;
contentPath = Common::CreateTitleContentPath(tmdTitleID) + DIR_SEP;
dataPath = Common::CreateTitleDataPath(tmdTitleID) + DIR_SEP;
tmdPath = contentPath + "/title.tmd";
File::CreateFullPath(contentPath.c_str());
File::CreateFullPath(dataPath.c_str());
if(!File::Exists(tmdPath.c_str()))
{
FILE* _pTMDFile = fopen(tmdPath.c_str(), "wb");
if (_pTMDFile)
{
if (fwrite(_pTMD, _sz, 1, _pTMDFile) != 1)
ERROR_LOG(WII_IPC_ES, "DIVerify failed to write disc tmd to nand");
fclose(_pTMDFile);
}
}
DiscIO::cUIDsys::AccessInstance().AddTitle(tmdTitleID);
return 0;
}

View File

@ -37,7 +37,7 @@ public:
virtual bool Close(u32 _CommandAddress, bool _bForce);
virtual bool IOCtlV(u32 _CommandAddress);
u32 ES_DIVerify(u8 *_pTMD, u32 _sz);
private:
enum

View File

@ -264,6 +264,7 @@ bool CNANDContentLoader::CreateFromDirectory(const std::string& _rPath)
else
{
ERROR_LOG(DISCIO, "NANDContentLoader: error opening %s", szFilename);
delete [] pTMD;
return false;
}
}
@ -374,7 +375,6 @@ const INANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string&
const INANDContentLoader& CNANDContentManager::GetNANDLoader(u64 _titleId)
{
std::string _rName = Common::CreateTitleContentPath(_titleId);
return GetNANDLoader(_rName);
}
@ -383,8 +383,6 @@ cUIDsys::cUIDsys()
{
sprintf(uidSys, "%ssys/uid.sys", File::GetUserPath(D_WIIUSER_IDX));
lastUID = 0x00001000;
bool validTMD;
bool validTIK;
if (File::Exists(uidSys))
{
FILE* pFile = fopen(uidSys, "rb");
@ -393,19 +391,13 @@ cUIDsys::cUIDsys()
SElement Element;
if (fread(&Element, sizeof(SElement), 1, pFile) == 1)
{
validTMD = CheckTitleTMD(Common::swap64(Element.titleID));
validTIK = CheckTitleTIK(Common::swap64(Element.titleID));
if (validTMD && validTIK)
{
*(u32*)&(Element.UID) = Common::swap32(lastUID++);
m_Elements.push_back(Element);
}
}
}
fclose(pFile);
}
else
if(!m_Elements.size())
{
SElement Element;
*(u64*)&(Element.titleID) = Common::swap64(TITLEID_SYSMENU);
@ -428,7 +420,7 @@ u32 cUIDsys::GetUIDFromTitle(u64 _Title)
{
for (size_t i=0; i<m_Elements.size(); i++)
{
if (Common::swap64(_Title) == (u64)m_Elements[i].titleID)
if (Common::swap64(_Title) == *(u64*)&(m_Elements[i].titleID))
{
return Common::swap32(m_Elements[i].UID);
}
@ -458,59 +450,15 @@ bool cUIDsys::AddTitle(u64 _TitleID)
}
}
void cUIDsys::GetTitleIDs(std::vector<u64>& _TitleIDs)
void cUIDsys::GetTitleIDs(std::vector<u64>& _TitleIDs, bool _owned)
{
for (size_t i = 0; i < m_Elements.size(); i++)
{
_TitleIDs.push_back(Common::swap64(m_Elements[i].titleID));
if ((_owned && Common::CheckTitleTIK(Common::swap64(m_Elements[i].titleID))) ||
(!_owned && Common::CheckTitleTMD(Common::swap64(m_Elements[i].titleID))))
_TitleIDs.push_back(Common::swap64(m_Elements[i].titleID));
}
}
bool cUIDsys::CheckTitleTMD(u64 _TitleID)
{
char TitlePath[1024];
sprintf(TitlePath, "%stitle/%08x/%08x/content/title.tmd", File::GetUserPath(D_WIIUSER_IDX),
(u32)(_TitleID >> 32), (u32)(_TitleID & 0xFFFFFFFF));
if (File::Exists(TitlePath))
{
FILE* pTMDFile = fopen(TitlePath, "rb");
if(pTMDFile)
{
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
fseek(pTMDFile, 0x18C, SEEK_SET);
fread(&TitleID, 8, 1, pTMDFile);
fclose(pTMDFile);
if (_TitleID == Common::swap64(TitleID))
return true;
}
}
INFO_LOG(DISCIO, "Invalid or no tmd for title %08x %08x", (u32)(_TitleID >> 32), (u32)(_TitleID & 0xFFFFFFFF));
return false;
}
bool cUIDsys::CheckTitleTIK(u64 _TitleID)
{
char TitlePath[1024];
sprintf(TitlePath, "%sticket/%08x/%08x.tik", File::GetUserPath(D_WIIUSER_IDX),
(u32)(_TitleID >> 32), (u32)(_TitleID & 0xFFFFFFFF));
if (File::Exists(TitlePath))
{
FILE* pTIKFile = fopen(TitlePath, "rb");
if(pTIKFile)
{
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
fseek(pTIKFile, 0x1dC, SEEK_SET);
fread(&TitleID, 8, 1, pTIKFile);
fclose(pTIKFile);
if (_TitleID == Common::swap64(TitleID))
return true;
}
}
INFO_LOG(DISCIO, "Invalid or no tik for title %08x %08x", (u32)(_TitleID >> 32), (u32)(_TitleID & 0xFFFFFFFF));
return false;
}
} // namespace end

View File

@ -133,9 +133,7 @@ public:
u32 GetUIDFromTitle(u64 _Title);
bool AddTitle(u64 _Title);
bool CheckTitleTMD(u64 _TitleID);
bool CheckTitleTIK(u64 _TitleID);
void GetTitleIDs(std::vector<u64>& _TitleIDs);
void GetTitleIDs(std::vector<u64>& _TitleIDs, bool _owned = false);
private: