summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/Src/NANDContentLoader.cpp
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2013-12-07 15:14:29 -0500
committerJasper St. Pierre <jstpierre@mecheye.net>2013-12-31 14:03:19 -0500
commit34692ab826abc8f8faa61bdb2280b742424528f1 (patch)
treeb0eedc645badbea316ff59c125eaf808b28777ec /Source/Core/DiscIO/Src/NANDContentLoader.cpp
parent43e618682e8093602fc83dfa902ee7ae3fd3a4f6 (diff)
Remove unnecessary Src/ folders
Diffstat (limited to 'Source/Core/DiscIO/Src/NANDContentLoader.cpp')
-rw-r--r--Source/Core/DiscIO/Src/NANDContentLoader.cpp547
1 files changed, 0 insertions, 547 deletions
diff --git a/Source/Core/DiscIO/Src/NANDContentLoader.cpp b/Source/Core/DiscIO/Src/NANDContentLoader.cpp
deleted file mode 100644
index e5b36c54d5..0000000000
--- a/Source/Core/DiscIO/Src/NANDContentLoader.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#include "NANDContentLoader.h"
-
-#include <algorithm>
-#include <cctype>
-#include <polarssl/aes.h>
-#include "MathUtil.h"
-#include "FileUtil.h"
-#include "Log.h"
-#include "WiiWad.h"
-#include "StringUtil.h"
-
-namespace DiscIO
-{
-CSharedContent CSharedContent::m_Instance;
-cUIDsys cUIDsys::m_Instance;
-
-
-CSharedContent::CSharedContent()
-{
- UpdateLocation();
-}
-
-void CSharedContent::UpdateLocation()
-{
- m_Elements.clear();
- lastID = 0;
- sprintf(contentMap, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX).c_str());
-
- File::IOFile pFile(contentMap, "rb");
- SElement Element;
- while (pFile.ReadArray(&Element, 1))
- {
- m_Elements.push_back(Element);
- lastID++;
- }
-}
-
-CSharedContent::~CSharedContent()
-{}
-
-std::string CSharedContent::GetFilenameFromSHA1(const u8* _pHash)
-{
- for (auto& Element : m_Elements)
- {
- if (memcmp(_pHash, Element.SHA1Hash, 20) == 0)
- {
- char szFilename[1024];
- sprintf(szFilename, "%sshared1/%c%c%c%c%c%c%c%c.app", File::GetUserPath(D_WIIUSER_IDX).c_str(),
- Element.FileName[0], Element.FileName[1], Element.FileName[2], Element.FileName[3],
- Element.FileName[4], Element.FileName[5], Element.FileName[6], Element.FileName[7]);
- return szFilename;
- }
- }
- return "unk";
-}
-
-std::string CSharedContent::AddSharedContent(const u8* _pHash)
-{
- std::string szFilename = GetFilenameFromSHA1(_pHash);
- if (strcasecmp(szFilename.c_str(), "unk") == 0)
- {
- char tempFilename[1024], c_ID[9];
- SElement Element;
- sprintf(c_ID, "%08x", lastID);
- memcpy(Element.FileName, c_ID, 8);
- memcpy(Element.SHA1Hash, _pHash, 20);
- m_Elements.push_back(Element);
-
- File::CreateFullPath(contentMap);
-
- File::IOFile pFile(contentMap, "ab");
- pFile.WriteArray(&Element, 1);
-
- sprintf(tempFilename, "%sshared1/%s.app", File::GetUserPath(D_WIIUSER_IDX).c_str(), c_ID);
- szFilename = tempFilename;
- lastID++;
- }
- return szFilename;
-}
-
-
-// this classes must be created by the CNANDContentManager
-class CNANDContentLoader : public INANDContentLoader
-{
-public:
-
- CNANDContentLoader(const std::string& _rName);
-
- virtual ~CNANDContentLoader();
-
- bool IsValid() const override { return m_Valid; }
- void RemoveTitle(void) const override;
- u64 GetTitleID() const override { return m_TitleID; }
- u16 GetIosVersion() const override { return m_IosVersion; }
- u32 GetBootIndex() const override { return m_BootIndex; }
- size_t GetContentSize() const override { return m_Content.size(); }
- const SNANDContent* GetContentByIndex(int _Index) const override;
- const u8* GetTMDView() const override { return m_TMDView; }
- const u8* GetTMDHeader() const override { return m_TMDHeader; }
- u32 GetTIKSize() const override { return m_TIKSize; }
- const u8* GetTIK() const override { return m_TIK; }
-
- const std::vector<SNANDContent>& GetContent() const override { return m_Content; }
-
- u16 GetTitleVersion() const override {return m_TitleVersion;}
- u16 GetNumEntries() const override {return m_numEntries;}
- DiscIO::IVolume::ECountry GetCountry() const override;
- u8 GetCountryChar() const override {return m_Country; }
-
-private:
-
- bool m_Valid;
- bool m_isWAD;
- std::string m_Path;
- u64 m_TitleID;
- u16 m_IosVersion;
- u32 m_BootIndex;
- u16 m_numEntries;
- u16 m_TitleVersion;
- u8 m_TMDView[TMD_VIEW_SIZE];
- u8 m_TMDHeader[TMD_HEADER_SIZE];
- u32 m_TIKSize;
- u8 *m_TIK;
- u8 m_Country;
-
- std::vector<SNANDContent> m_Content;
-
-
- bool Initialize(const std::string& _rName);
-
- void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest);
-
- void GetKeyFromTicket(u8* pTicket, u8* pTicketKey);
-};
-
-
-
-
-CNANDContentLoader::CNANDContentLoader(const std::string& _rName)
- : m_Valid(false)
- , m_isWAD(false)
- , m_TitleID(-1)
- , m_IosVersion(0x09)
- , m_BootIndex(-1)
- , m_TIKSize(0)
- , m_TIK(NULL)
-{
- m_Valid = Initialize(_rName);
-}
-
-CNANDContentLoader::~CNANDContentLoader()
-{
- for (auto& content : m_Content)
- {
- delete [] content.m_pData;
- }
- m_Content.clear();
- if (m_TIK)
- {
- delete []m_TIK;
- m_TIK = NULL;
- }
-}
-
-const SNANDContent* CNANDContentLoader::GetContentByIndex(int _Index) const
-{
- for (auto& Content : m_Content)
- {
- if (Content.m_Index == _Index)
- {
- return &Content;
- }
- }
- return NULL;
-}
-
-bool CNANDContentLoader::Initialize(const std::string& _rName)
-{
- if (_rName.empty())
- return false;
- m_Path = _rName;
- WiiWAD Wad(_rName);
- u8* pDataApp = NULL;
- u8* pTMD = NULL;
- 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 = NULL;
-
- 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;
-}
-void CNANDContentLoader::AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest)
-{
- aes_context AES_ctx;
-
- aes_setkey_dec(&AES_ctx, _pKey, 128);
- aes_crypt_cbc(&AES_ctx, AES_DECRYPT, _Size, _IV, _pSrc, _pDest);
-}
-
-void CNANDContentLoader::GetKeyFromTicket(u8* pTicket, u8* pTicketKey)
-{
- u8 CommonKey[16] = {0xeb,0xe4,0x2a,0x22,0x5e,0x85,0x93,0xe4,0x48,0xd9,0xc5,0x45,0x73,0x81,0xaa,0xf7};
- u8 IV[16];
- memset(IV, 0, sizeof IV);
- memcpy(IV, pTicket + 0x01dc, 8);
- AESDecode(CommonKey, IV, pTicket + 0x01bf, 16, pTicketKey);
-}
-
-
-DiscIO::IVolume::ECountry CNANDContentLoader::GetCountry() const
-{
- if (!IsValid())
- return DiscIO::IVolume::COUNTRY_UNKNOWN;
-
- return CountrySwitch(m_Country);
-}
-
-
-CNANDContentManager CNANDContentManager::m_Instance;
-
-
-CNANDContentManager::~CNANDContentManager()
-{
- CNANDContentMap::iterator itr = m_Map.begin();
- while (itr != m_Map.end())
- {
- delete itr->second;
- ++itr;
- }
- m_Map.clear();
-}
-
-const INANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string& _rName, bool forceReload)
-{
- CNANDContentMap::iterator lb = m_Map.lower_bound(_rName);
-
- if(lb == m_Map.end() || (m_Map.key_comp()(_rName, lb->first)))
- {
- m_Map.insert(lb, CNANDContentMap::value_type(_rName, new CNANDContentLoader(_rName)));
- }
- else
- {
- if (!lb->second->IsValid() || forceReload)
- {
- delete lb->second;
- lb->second = new CNANDContentLoader(_rName);
- }
- }
- return *m_Map[_rName];
-}
-
-const INANDContentLoader& CNANDContentManager::GetNANDLoader(u64 _titleId, bool forceReload)
-{
- std::string _rName = Common::GetTitleContentPath(_titleId);
- return GetNANDLoader(_rName, forceReload);
-}
-bool CNANDContentManager::RemoveTitle(u64 _titleID)
-{
- if (!GetNANDLoader(_titleID).IsValid())
- return false;
- GetNANDLoader(_titleID).RemoveTitle();
- return GetNANDLoader(_titleID, true).IsValid();
-}
-
-void CNANDContentLoader::RemoveTitle() const
-{
- INFO_LOG(DISCIO, "RemoveTitle %08x/%08x", (u32)(m_TitleID >> 32), (u32)m_TitleID);
- if(IsValid())
- {
- // remove tmd?
- for (u32 i = 0; i < m_numEntries; i++)
- {
- char szFilename[1024];
- if (!(m_Content[i].m_Type & 0x8000)) // skip shared apps
- {
- sprintf(szFilename, "%s%08x.app", Common::GetTitleContentPath(m_TitleID).c_str(), m_Content[i].m_ContentID);
- INFO_LOG(DISCIO, "Delete %s", szFilename);
- File::Delete(szFilename);
- }
- }
- }
-}
-
-cUIDsys::cUIDsys()
-{
- UpdateLocation();
-}
-
-void cUIDsys::UpdateLocation()
-{
- m_Elements.clear();
- lastUID = 0x00001000;
- sprintf(uidSys, "%ssys/uid.sys", File::GetUserPath(D_WIIUSER_IDX).c_str());
-
- File::IOFile pFile(uidSys, "rb");
- SElement Element;
- while (pFile.ReadArray(&Element, 1))
- {
- *(u32*)&(Element.UID) = Common::swap32(lastUID++);
- m_Elements.push_back(Element);
- }
- pFile.Close();
-
- if (m_Elements.empty())
- {
- *(u64*)&(Element.titleID) = Common::swap64(TITLEID_SYSMENU);
- *(u32*)&(Element.UID) = Common::swap32(lastUID++);
-
- File::CreateFullPath(uidSys);
- pFile.Open(uidSys, "wb");
- if (!pFile.WriteArray(&Element, 1))
- ERROR_LOG(DISCIO, "Failed to write to %s", uidSys);
- }
-}
-
-cUIDsys::~cUIDsys()
-{}
-
-u32 cUIDsys::GetUIDFromTitle(u64 _Title)
-{
- for (auto& Element : m_Elements)
- {
- if (Common::swap64(_Title) == *(u64*)&(Element.titleID))
- {
- return Common::swap32(Element.UID);
- }
- }
- return 0;
-}
-
-void cUIDsys::AddTitle(u64 _TitleID)
-{
- if (GetUIDFromTitle(_TitleID))
- {
- INFO_LOG(DISCIO, "Title %08x%08x, already exists in uid.sys", (u32)(_TitleID >> 32), (u32)_TitleID);
- return;
- }
-
- SElement Element;
- *(u64*)&(Element.titleID) = Common::swap64(_TitleID);
- *(u32*)&(Element.UID) = Common::swap32(lastUID++);
- m_Elements.push_back(Element);
-
- File::CreateFullPath(uidSys);
- File::IOFile pFile(uidSys, "ab");
-
- if (!pFile.WriteArray(&Element, 1))
- ERROR_LOG(DISCIO, "fwrite failed");
-}
-
-void cUIDsys::GetTitleIDs(std::vector<u64>& _TitleIDs, bool _owned)
-{
- for (auto& Element : m_Elements)
- {
- if ((_owned && Common::CheckTitleTIK(Common::swap64(Element.titleID))) ||
- (!_owned && Common::CheckTitleTMD(Common::swap64(Element.titleID))))
- _TitleIDs.push_back(Common::swap64(Element.titleID));
- }
-}
-
-u64 CNANDContentManager::Install_WiiWAD(std::string &fileName)
-{
- if (fileName.find(".wad") == std::string::npos)
- return 0;
- const INANDContentLoader& ContentLoader = GetNANDLoader(fileName);
- if (ContentLoader.IsValid() == false)
- return 0;
-
- u64 TitleID = ContentLoader.GetTitleID();
-
- //copy WAD's tmd header and contents to content directory
-
- std::string ContentPath(Common::GetTitleContentPath(TitleID));
- std::string TMDFileName(Common::GetTMDFileName(TitleID));
- File::CreateFullPath(TMDFileName);
-
- File::IOFile pTMDFile(TMDFileName, "wb");
- if (!pTMDFile)
- {
- PanicAlertT("WAD installation failed: error creating %s", TMDFileName.c_str());
- return 0;
- }
-
- pTMDFile.WriteBytes(ContentLoader.GetTMDHeader(), INANDContentLoader::TMD_HEADER_SIZE);
-
- for (u32 i = 0; i < ContentLoader.GetContentSize(); i++)
- {
- const SNANDContent& Content = ContentLoader.GetContent()[i];
-
- pTMDFile.WriteBytes(Content.m_Header, INANDContentLoader::CONTENT_HEADER_SIZE);
-
- char APPFileName[1024];
- if (Content.m_Type & 0x8000) //shared
- {
- sprintf(APPFileName, "%s",
- CSharedContent::AccessInstance().AddSharedContent(Content.m_SHA1Hash).c_str());
- }
- else
- {
- sprintf(APPFileName, "%s%08x.app", ContentPath.c_str(), Content.m_ContentID);
- }
-
- if (!File::Exists(APPFileName))
- {
- File::CreateFullPath(APPFileName);
- File::IOFile pAPPFile(APPFileName, "wb");
- if (!pAPPFile)
- {
- PanicAlertT("WAD installation failed: error creating %s", APPFileName);
- return 0;
- }
-
- pAPPFile.WriteBytes(Content.m_pData, Content.m_Size);
- }
- else
- {
- INFO_LOG(DISCIO, "Content %s already exists.", APPFileName);
- }
- }
-
- pTMDFile.Close();
-
-
-
-
- //Extract and copy WAD's ticket to ticket directory
- if (!Add_Ticket(TitleID, ContentLoader.GetTIK(), ContentLoader.GetTIKSize()))
- {
- PanicAlertT("WAD installation failed: error creating ticket");
- return 0;
- }
-
- cUIDsys::AccessInstance().AddTitle(TitleID);
-
-
- return TitleID;
-}
-
-bool Add_Ticket(u64 TitleID, const u8 *p_tik, u32 tikSize)
-{
- std::string TicketFileName = Common::GetTicketFileName(TitleID);
- File::CreateFullPath(TicketFileName);
- File::IOFile pTicketFile(TicketFileName, "wb");
- if (!pTicketFile || !p_tik)
- {
- //PanicAlertT("WAD installation failed: error creating %s", TicketFileName.c_str());
- return false;
- }
- return pTicketFile.WriteBytes(p_tik, tikSize);
-}
-
-} // namespace end
-