summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
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/Core/DiscIO
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/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/NANDContentLoader.cpp55
-rw-r--r--Source/Core/DiscIO/NANDContentLoader.h31
2 files changed, 78 insertions, 8 deletions
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