summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBhaaL <bhaal@0x1337.org>2016-03-16 20:08:37 +0100
committerBhaaL <bhaal@0x1337.org>2016-03-20 13:10:50 +0100
commit8a6d9e1e0b2fe407dd986b4982ca77e91f0604c3 (patch)
treeaa04cb497d2b60a12fe6a52cc69f9948474c5149 /Source
parent8fd2f057414d51e4145f71675c356359bcbd1902 (diff)
hide the distinction between WAD and File from ES
instead, leave all the management with the NANDContentLoader. for file data (directly on the NAND), this opens the file on-demand and returns the requested chunk when asked for it. for on-the-fly decrypted WAD data, we just keep the decoded buffer in memory, like we've done before - except that we don't give away any objects we don't want to.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/Boot/Boot_WiiWAD.cpp10
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp50
-rw-r--r--Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h2
-rw-r--r--Source/Core/DiscIO/NANDContentLoader.cpp55
-rw-r--r--Source/Core/DiscIO/NANDContentLoader.h31
5 files changed, 86 insertions, 62 deletions
diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp
index 00bca2eb97..2d27231426 100644
--- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp
+++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp
@@ -101,15 +101,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
WII_IPC_HLE_Interface::SetDefaultContentFile(_pFilename);
- std::unique_ptr<CDolLoader> pDolLoader;
- if (pContent->m_data.empty())
- {
- pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
- }
- else
- {
- pDolLoader = std::make_unique<CDolLoader>(pContent->m_data);
- }
+ std::unique_ptr<CDolLoader> pDolLoader = std::make_unique<CDolLoader>(pContent->m_Data->Get());
if (!pDolLoader->IsValid())
return false;
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
index 3f28100833..87a8c41351 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
@@ -185,10 +185,6 @@ IPCCommandResult CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode)
IPCCommandResult CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress, bool _bForce)
{
- for (auto& pair : m_ContentAccessMap)
- {
- delete pair.second.m_pFile;
- }
m_ContentAccessMap.clear();
m_TitleIDs.clear();
m_TitleID = -1;
@@ -223,20 +219,8 @@ u32 CWII_IPC_HLE_Device_es::OpenTitleContent(u32 CFD, u64 TitleID, u16 Index)
Access.m_Index = pContent->m_Index;
Access.m_Size = pContent->m_Size;
Access.m_TitleID = TitleID;
- Access.m_pFile = nullptr;
- if (pContent->m_data.empty())
- {
- std::string Filename = pContent->m_Filename;
- INFO_LOG(WII_IPC_ES, "ES: load %s", Filename.c_str());
- Access.m_pFile = new File::IOFile(Filename, "rb");
- if (!Access.m_pFile->IsGood())
- {
- WARN_LOG(WII_IPC_ES, "ES: couldn't load %s", Filename.c_str());
- return 0xffffffff;
- }
- }
m_ContentAccessMap[CFD] = Access;
return CFD;
@@ -401,25 +385,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{
if (pDest)
{
- // FIXME: this breaks WAD access (the else part), fixed in the next commit
- //if (rContent.m_pContent->m_data.empty())
+ const DiscIO::CNANDContentLoader& ContentLoader = AccessContentDevice(rContent.m_TitleID);
+ // ContentLoader should never be invalid; rContent has been created by it.
+ if (ContentLoader.IsValid())
{
- auto& pFile = rContent.m_pFile;
- if (!pFile->Seek(rContent.m_Position, SEEK_SET))
- {
- ERROR_LOG(WII_IPC_ES, "ES: couldn't seek!");
- }
- WARN_LOG(WII_IPC_ES, "2 %p", pFile->GetHandle());
- if (!pFile->ReadBytes(pDest, Size))
- {
- ERROR_LOG(WII_IPC_ES, "ES: short read; returning uninitialized data!");
- }
+ const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(rContent.m_Index);
+ if (!pContent->m_Data->GetRange(rContent.m_Position, Size, pDest))
+ ERROR_LOG(WII_IPC_ES, "ES: failed to read %u bytes from %u!", Size, rContent.m_Position);
}
- /*else
- {
- const u8* src = &rContent.m_pContent->m_data[rContent.m_Position];
- memcpy(pDest, src, Size);
- }*/
rContent.m_Position += Size;
}
@@ -452,7 +425,6 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
return GetDefaultReply();
}
- delete itr->second.m_pFile;
m_ContentAccessMap.erase(itr);
Memory::Write_U32(0, _CommandAddress + 0x4);
@@ -915,15 +887,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
if (pContent)
{
tContentFile = Common::GetTitleContentPath(TitleID, Common::FROM_SESSION_ROOT);
- std::unique_ptr<CDolLoader> pDolLoader;
- if (pContent->m_data.empty())
- {
- pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
- }
- else
- {
- pDolLoader = std::make_unique<CDolLoader>(pContent->m_data);
- }
+ std::unique_ptr<CDolLoader> pDolLoader = std::make_unique<CDolLoader>(pContent->m_Data->Get());
if (pDolLoader->IsValid())
{
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h
index 07b5fbede4..a0d0d72065 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.h
@@ -127,8 +127,6 @@ private:
u64 m_TitleID;
u16 m_Index;
u32 m_Size;
- // This is a (raw) pointer to work around a MSVC bug.
- File::IOFile* m_pFile;
};
typedef std::map<u32, SContentAccess> CContentAccessMap;
diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp
index 0ab9383802..6a9fc29bdf 100644
--- a/Source/Core/DiscIO/NANDContentLoader.cpp
+++ b/Source/Core/DiscIO/NANDContentLoader.cpp
@@ -92,6 +92,46 @@ std::string CSharedContent::AddSharedContent(const u8* hash)
}
+const std::vector<u8> CNANDContentDataFile::Get()
+{
+ std::vector<u8> result;
+ File::IOFile file(m_filename, "rb");
+ if (!file.IsGood())
+ return result;
+
+ u64 size = file.GetSize();
+ if (size == 0)
+ return result;
+
+ result.resize(size);
+ file.ReadBytes(result.data(), result.size());
+
+ return result;
+}
+
+bool CNANDContentDataFile::GetRange(u32 start, u32 size, u8* buffer)
+{
+ File::IOFile file(m_filename, "rb");
+ if (!file.IsGood())
+ return false;
+
+ if (!file.Seek(start, SEEK_SET))
+ return false;
+
+ return file.ReadBytes(buffer, static_cast<size_t>(size));
+}
+
+
+bool CNANDContentDataBuffer::GetRange(u32 start, u32 size, u8* buffer)
+{
+ if (start + size > m_buffer.size())
+ return false;
+
+ std::copy(&m_buffer[start], &m_buffer[start + size], buffer);
+ return true;
+}
+
+
CNANDContentLoader::CNANDContentLoader(const std::string& content_name)
: m_Valid(false)
, m_IsWAD(false)
@@ -207,20 +247,23 @@ void CNANDContentLoader::InitializeContentEntries(const std::vector<u8>& tmd, co
iv.fill(0);
std::copy(&tmd[entry_offset + 0x01E8], &tmd[entry_offset + 0x01E8 + 2], iv.begin());
- content.m_data = AESDecode(decrypted_title_key.data(), iv.data(), &data_app[data_app_offset], rounded_size);
+ content.m_Data = std::make_unique<CNANDContentDataBuffer>(AESDecode(decrypted_title_key.data(), iv.data(), &data_app[data_app_offset], rounded_size));
data_app_offset += rounded_size;
continue;
}
+ std::string filename;
if (content.m_Type & 0x8000) // shared app
- content.m_Filename = CSharedContent::AccessInstance().GetFilenameFromSHA1(content.m_SHA1Hash);
+ filename = CSharedContent::AccessInstance().GetFilenameFromSHA1(content.m_SHA1Hash);
else
- content.m_Filename = StringFromFormat("%s/%08x.app", m_Path.c_str(), content.m_ContentID);
+ filename = StringFromFormat("%s/%08x.app", m_Path.c_str(), content.m_ContentID);
+
+ content.m_Data = std::make_unique<CNANDContentDataFile>(filename);
// Be graceful about incorrect TMDs.
- if (File::Exists(content.m_Filename))
- content.m_Size = static_cast<u32>(File::GetSize(content.m_Filename));
+ if (File::Exists(filename))
+ content.m_Size = static_cast<u32>(File::GetSize(filename));
}
}
@@ -429,7 +472,7 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& filename)
return 0;
}
- app_file.WriteBytes(content.m_data.data(), content.m_Size);
+ app_file.WriteBytes(content.m_Data->Get().data(), content.m_Size);
}
else
{
diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h
index 911d6110e9..c82d46db1f 100644
--- a/Source/Core/DiscIO/NANDContentLoader.h
+++ b/Source/Core/DiscIO/NANDContentLoader.h
@@ -17,6 +17,34 @@ namespace DiscIO
{
bool AddTicket(u64 title_id, const std::vector<u8>& ticket);
+class CNANDContentData
+{
+public:
+ virtual const std::vector<u8> Get() = 0;
+ virtual bool GetRange(u32 start, u32 size, u8* buffer) = 0;
+};
+
+class CNANDContentDataFile final : public CNANDContentData
+{
+public:
+ CNANDContentDataFile(const std::string& filename) : m_filename(filename) { };
+
+ const std::vector<u8> Get() override;
+ bool GetRange(u32 start, u32 size, u8* buffer) override;
+private:
+ const std::string m_filename;
+};
+class CNANDContentDataBuffer final : public CNANDContentData
+{
+public:
+ CNANDContentDataBuffer(const std::vector<u8>& buffer) : m_buffer(buffer) { };
+
+ const std::vector<u8> Get() override { return m_buffer; };
+ bool GetRange(u32 start, u32 size, u8* buffer) override;
+private:
+ const std::vector<u8> m_buffer;
+};
+
struct SNANDContent
{
u32 m_ContentID;
@@ -26,8 +54,7 @@ struct SNANDContent
u8 m_SHA1Hash[20];
u8 m_Header[36]; //all of the above
- std::string m_Filename;
- std::vector<u8> m_data;
+ std::unique_ptr<CNANDContentData> m_Data;
};
// Instances of this class must be created by CNANDContentManager