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:
parent
dee24e5695
commit
e0383634d3
|
@ -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"
|
||||
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue