From e0383634d33194812ab7ee1440d0796dc12abea2 Mon Sep 17 00:00:00 2001 From: LPFaint99 Date: Tue, 7 Sep 2010 06:06:08 +0000 Subject: [PATCH] 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 --- Source/Core/Common/Src/NandPaths.cpp | 58 ++++++++++++++-- Source/Core/Common/Src/NandPaths.h | 8 ++- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 8 +++ Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h | 1 + .../Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp | 14 +++- .../Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 41 +++++++++++- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h | 2 +- Source/Core/DiscIO/Src/NANDContentLoader.cpp | 66 ++----------------- Source/Core/DiscIO/Src/NANDContentLoader.h | 4 +- 9 files changed, 126 insertions(+), 76 deletions(-) diff --git a/Source/Core/Common/Src/NandPaths.cpp b/Source/Core/Common/Src/NandPaths.cpp index 32a4253e9e..970b083e79 100644 --- a/Source/Core/Common/Src/NandPaths.cpp +++ b/Source/Core/Common/Src/NandPaths.cpp @@ -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; +} +}; \ No newline at end of file diff --git a/Source/Core/Common/Src/NandPaths.h b/Source/Core/Common/Src/NandPaths.h index d68bbba2e0..fd8e60120d 100644 --- a/Source/Core/Common/Src/NandPaths.h +++ b/Source/Core/Common/Src/NandPaths.h @@ -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 + diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 19eeaee796..d4dc63d107 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -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) { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h index 612f6f356d..5770d39bfd 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h @@ -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); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index a0e7714388..9fc60f45fa 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -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; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp index b2c157da56..556b203ced 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -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; +} + diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h index 07ba5aeec9..f3db3ee12e 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -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 diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp index a67af7646d..854d607ca6 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/Src/NANDContentLoader.cpp @@ -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& _TitleIDs) +void cUIDsys::GetTitleIDs(std::vector& _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 diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.h b/Source/Core/DiscIO/Src/NANDContentLoader.h index fce9810791..45bd07717a 100644 --- a/Source/Core/DiscIO/Src/NANDContentLoader.h +++ b/Source/Core/DiscIO/Src/NANDContentLoader.h @@ -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& _TitleIDs); + void GetTitleIDs(std::vector& _TitleIDs, bool _owned = false); private: