forked from dolphin-emu/dolphin
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:
@@ -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;
|
||||
}
|
||||
};
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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"
|
||||
@@ -122,10 +123,17 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
|
||||
|
||||
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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user