コード例 #1
0
bool CNANDContentLoader::Initialize(const std::string& _rName)
{
	if (_rName.empty())
		return false;
	m_Path = _rName;
	WiiWAD Wad(_rName);
	u8* pDataApp = nullptr;
	u8* pTMD = nullptr;
	u8 DecryptTitleKey[16];
	u8 IV[16];
	if (Wad.IsValid())
	{
		m_isWAD = true;
		m_TIKSize = Wad.GetTicketSize();
		m_TIK = new u8[m_TIKSize];
		memcpy(m_TIK, Wad.GetTicket(), m_TIKSize);
		GetKeyFromTicket(m_TIK, DecryptTitleKey);
		u32 pTMDSize = Wad.GetTMDSize();
		pTMD = new u8[pTMDSize];
		memcpy(pTMD, Wad.GetTMD(), pTMDSize);
		pDataApp = Wad.GetDataApp();
	}
	else
	{
		std::string TMDFileName(m_Path);

		if ('/' == *TMDFileName.rbegin())
			TMDFileName += "title.tmd";
		else
			m_Path = TMDFileName.substr(0, TMDFileName.find("title.tmd"));

		File::IOFile pTMDFile(TMDFileName, "rb");
		if (!pTMDFile)
		{
			WARN_LOG(DISCIO, "CreateFromDirectory: error opening %s",
					 TMDFileName.c_str());
			return false;
		}
		u32 pTMDSize = (u32)File::GetSize(TMDFileName);
		pTMD = new u8[pTMDSize];
		pTMDFile.ReadBytes(pTMD, (size_t)pTMDSize);
		pTMDFile.Close();
	}

	memcpy(m_TMDView, pTMD + 0x180, TMD_VIEW_SIZE);
	memcpy(m_TMDHeader, pTMD, TMD_HEADER_SIZE);


	m_TitleVersion = 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);
	m_Country = *(u8*)&m_TitleID;
	if (m_Country == 2) // SYSMENU
		m_Country = GetSysMenuRegion(m_TitleVersion);

	m_Content.resize(m_numEntries);


	for (u32 i=0; i<m_numEntries; i++)
	{
		SNANDContent& rContent = m_Content[i];

		rContent.m_ContentID = Common::swap32(pTMD + 0x01e4 + 0x24*i);
		rContent.m_Index = Common::swap16(pTMD + 0x01e8 + 0x24*i);
		rContent.m_Type = Common::swap16(pTMD + 0x01ea + 0x24*i);
		rContent.m_Size= (u32)Common::swap64(pTMD + 0x01ec + 0x24*i);
		memcpy(rContent.m_SHA1Hash, pTMD + 0x01f4 + 0x24*i, 20);
		memcpy(rContent.m_Header, pTMD + 0x01e4 + 0x24*i, 36);

		if (m_isWAD)
		{
			u32 RoundedSize = ROUND_UP(rContent.m_Size, 0x40);
			rContent.m_pData = new u8[RoundedSize];

			memset(IV, 0, sizeof IV);
			memcpy(IV, pTMD + 0x01e8 + 0x24*i, 2);
			AESDecode(DecryptTitleKey, IV, pDataApp, RoundedSize, rContent.m_pData);

			pDataApp += RoundedSize;
			continue;
		}

		rContent.m_pData = nullptr;

		if (rContent.m_Type & 0x8000)  // shared app
		{
			rContent.m_Filename = CSharedContent::AccessInstance().GetFilenameFromSHA1(rContent.m_SHA1Hash);
		}
		else
		{
			rContent.m_Filename = StringFromFormat("%s/%08x.app", m_Path.c_str(), rContent.m_ContentID);
		}

		// Be graceful about incorrect tmds.
		if (File::Exists(rContent.m_Filename))
		{
			rContent.m_Size = (u32) File::GetSize(rContent.m_Filename);
		}
	}

	delete [] pTMD;
	return true;
}
コード例 #2
0
#include "TestDefines.h"

TEST_CASE("Nominals")
{
	Wad wad = Nominals::rub();
	REQUIRE(wad == Wad({ RUB_10, RUB_50, RUB_100, RUB_500, RUB_1000, RUB_5000 }));
}