Rename package_reader member variables

This commit is contained in:
Megamouse 2020-11-11 18:28:01 +01:00
parent 68d411918d
commit ccec6e53c0
2 changed files with 158 additions and 154 deletions

View File

@ -20,7 +20,7 @@ package_reader::package_reader(const std::string& path)
return;
}
filelist.emplace_back(fs::file{ path });
m_filelist.emplace_back(fs::file{path});
m_is_valid = read_header();
@ -50,34 +50,34 @@ package_reader::~package_reader()
bool package_reader::read_header()
{
if (m_path.empty() || filelist.empty())
if (m_path.empty() || m_filelist.empty())
{
pkg_log.error("Reading PKG header: no file to read!");
return false;
}
if (archive_read(&header, sizeof(header)) != sizeof(header))
if (archive_read(&m_header, sizeof(m_header)) != sizeof(m_header))
{
pkg_log.error("Reading PKG header: file is too short!");
return false;
}
pkg_log.notice("Header: pkg_magic = 0x%x = \"%s\"", +header.pkg_magic, std::string(reinterpret_cast<const char*>(&header.pkg_magic), 4));
pkg_log.notice("Header: pkg_type = 0x%x = %d", header.pkg_type, header.pkg_type);
pkg_log.notice("Header: pkg_platform = 0x%x = %d", header.pkg_platform, header.pkg_platform);
pkg_log.notice("Header: meta_offset = 0x%x = %d", header.meta_offset, header.meta_offset);
pkg_log.notice("Header: meta_count = 0x%x = %d", header.meta_count, header.meta_count);
pkg_log.notice("Header: meta_size = 0x%x = %d", header.meta_size, header.meta_size);
pkg_log.notice("Header: file_count = 0x%x = %d", header.file_count, header.file_count);
pkg_log.notice("Header: pkg_size = 0x%x = %d", header.pkg_size, header.pkg_size);
pkg_log.notice("Header: data_offset = 0x%x = %d", header.data_offset, header.data_offset);
pkg_log.notice("Header: data_size = 0x%x = %d", header.data_size, header.data_size);
pkg_log.notice("Header: title_id = %s", header.title_id);
pkg_log.notice("Header: qa_digest = 0x%x 0x%x", header.qa_digest[0], header.qa_digest[1]);
pkg_log.notice("Header: pkg_magic = 0x%x = \"%s\"", +m_header.pkg_magic, std::string(reinterpret_cast<const char*>(&m_header.pkg_magic), 4));
pkg_log.notice("Header: pkg_type = 0x%x = %d", m_header.pkg_type, m_header.pkg_type);
pkg_log.notice("Header: pkg_platform = 0x%x = %d", m_header.pkg_platform, m_header.pkg_platform);
pkg_log.notice("Header: meta_offset = 0x%x = %d", m_header.meta_offset, m_header.meta_offset);
pkg_log.notice("Header: meta_count = 0x%x = %d", m_header.meta_count, m_header.meta_count);
pkg_log.notice("Header: meta_size = 0x%x = %d", m_header.meta_size, m_header.meta_size);
pkg_log.notice("Header: file_count = 0x%x = %d", m_header.file_count, m_header.file_count);
pkg_log.notice("Header: pkg_size = 0x%x = %d", m_header.pkg_size, m_header.pkg_size);
pkg_log.notice("Header: data_offset = 0x%x = %d", m_header.data_offset, m_header.data_offset);
pkg_log.notice("Header: data_size = 0x%x = %d", m_header.data_size, m_header.data_size);
pkg_log.notice("Header: title_id = %s", m_header.title_id);
pkg_log.notice("Header: qa_digest = 0x%x 0x%x", m_header.qa_digest[0], m_header.qa_digest[1]);
//pkg_log.notice("Header: klicensee = 0x%x = %d", header.klicensee, header.klicensee);
// Get extended PKG information for PSP or PSVita
if (header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA)
if (m_header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA)
{
PKGExtHeader ext_header;
@ -102,13 +102,13 @@ bool package_reader::read_header()
//pkg_log.notice("Extended header: padding2 = 0x%x = %d", ext_header.padding2, ext_header.padding2);
}
if (header.pkg_magic != std::bit_cast<le_t<u32>>("\x7FPKG"_u32))
if (m_header.pkg_magic != std::bit_cast<le_t<u32>>("\x7FPKG"_u32))
{
pkg_log.error("Not a PKG file!");
return false;
}
switch (const u16 type = header.pkg_type)
switch (const u16 type = m_header.pkg_type)
{
case PKG_RELEASE_TYPE_DEBUG: break;
case PKG_RELEASE_TYPE_RELEASE: break;
@ -119,7 +119,7 @@ bool package_reader::read_header()
}
}
switch (const u16 platform = header.pkg_platform)
switch (const u16 platform = m_header.pkg_platform)
{
case PKG_PLATFORM_TYPE_PS3: break;
case PKG_PLATFORM_TYPE_PSP_PSVITA: break;
@ -130,20 +130,20 @@ bool package_reader::read_header()
}
}
if (header.pkg_size > filelist[0].size())
if (m_header.pkg_size > m_filelist[0].size())
{
// Check if multi-files pkg
if (!m_path.ends_with("_00.pkg"))
{
pkg_log.error("PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
pkg_log.error("PKG file size mismatch (pkg_size=0x%llx)", m_header.pkg_size);
return false;
}
const std::string name_wo_number = m_path.substr(0, m_path.size() - 7);
u64 cursize = filelist[0].size();
while (cursize < header.pkg_size)
u64 cursize = m_filelist[0].size();
while (cursize < m_header.pkg_size)
{
const std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
const std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, m_filelist.size());
fs::file archive_file(archive_filename);
if (!archive_file)
@ -153,13 +153,13 @@ bool package_reader::read_header()
}
cursize += archive_file.size();
filelist.emplace_back(std::move(archive_file));
m_filelist.emplace_back(std::move(archive_file));
}
}
if (header.data_size + header.data_offset > header.pkg_size)
if (m_header.data_size + m_header.data_offset > m_header.pkg_size)
{
pkg_log.error("PKG data size mismatch (data_size=0x%llx, data_offset=0x%llx, file_size=0x%llx)", header.data_size, header.data_offset, header.pkg_size);
pkg_log.error("PKG data size mismatch (data_size=0x%llx, data_offset=0x%llx, file_size=0x%llx)", m_header.data_size, m_header.data_offset, m_header.pkg_size);
return false;
}
@ -168,21 +168,25 @@ bool package_reader::read_header()
bool package_reader::read_metadata()
{
if (!m_is_valid)
if (!decrypt_data())
{
return false;
}
//if (!m_is_valid)
//{
// return false;
//}
// Read title ID and use it as an installation directory
install_dir.resize(9);
m_install_dir.resize(9);
archive_seek(55);
archive_read(&install_dir.front(), install_dir.size());
archive_read(&m_install_dir.front(), m_install_dir.size());
// Read package metadata
archive_seek(header.meta_offset);
archive_seek(m_header.meta_offset);
for (u32 i = 0; i < header.meta_count; i++)
for (u32 i = 0; i < m_header.meta_count; i++)
{
struct packet_T
{
@ -197,10 +201,10 @@ bool package_reader::read_metadata()
{
case 0x1:
{
if (packet.size == sizeof(metadata.drm_type))
if (packet.size == sizeof(m_metadata.drm_type))
{
archive_read(&metadata.drm_type, sizeof(metadata.drm_type));
pkg_log.notice("Metadata: DRM Type = 0x%x = %d", metadata.drm_type, metadata.drm_type);
archive_read(&m_metadata.drm_type, sizeof(m_metadata.drm_type));
pkg_log.notice("Metadata: DRM Type = 0x%x = %d", m_metadata.drm_type, m_metadata.drm_type);
continue;
}
else
@ -212,10 +216,10 @@ bool package_reader::read_metadata()
}
case 0x2:
{
if (packet.size == sizeof(metadata.content_type))
if (packet.size == sizeof(m_metadata.content_type))
{
archive_read(&metadata.content_type, sizeof(metadata.content_type));
pkg_log.notice("Metadata: Content Type = 0x%x = %d", metadata.content_type, metadata.content_type);
archive_read(&m_metadata.content_type, sizeof(m_metadata.content_type));
pkg_log.notice("Metadata: Content Type = 0x%x = %d", m_metadata.content_type, m_metadata.content_type);
continue;
}
else
@ -227,10 +231,10 @@ bool package_reader::read_metadata()
}
case 0x3:
{
if (packet.size == sizeof(metadata.package_type))
if (packet.size == sizeof(m_metadata.package_type))
{
archive_read(&metadata.package_type, sizeof(metadata.package_type));
pkg_log.notice("Metadata: Package Type = 0x%x = %d", metadata.package_type, metadata.package_type);
archive_read(&m_metadata.package_type, sizeof(m_metadata.package_type));
pkg_log.notice("Metadata: Package Type = 0x%x = %d", m_metadata.package_type, m_metadata.package_type);
continue;
}
else
@ -241,10 +245,10 @@ bool package_reader::read_metadata()
}
case 0x4:
{
if (packet.size == sizeof(metadata.package_size))
if (packet.size == sizeof(m_metadata.package_size))
{
archive_read(&metadata.package_size, sizeof(metadata.package_size));
pkg_log.notice("Metadata: Package Size = 0x%x = %d", metadata.package_size, metadata.package_size);
archive_read(&m_metadata.package_size, sizeof(m_metadata.package_size));
pkg_log.notice("Metadata: Package Size = 0x%x = %d", m_metadata.package_size, m_metadata.package_size);
continue;
}
else
@ -255,11 +259,11 @@ bool package_reader::read_metadata()
}
case 0x5:
{
if (packet.size == sizeof(metadata.package_revision.data))
if (packet.size == sizeof(m_metadata.package_revision.data))
{
archive_read(&metadata.package_revision.data, sizeof(metadata.package_revision.data));
metadata.package_revision.interpret_data();
pkg_log.notice("Metadata: Package Revision = %s", metadata.package_revision.to_string());
archive_read(&m_metadata.package_revision.data, sizeof(m_metadata.package_revision.data));
m_metadata.package_revision.interpret_data();
pkg_log.notice("Metadata: Package Revision = %s", m_metadata.package_revision.to_string());
continue;
}
else
@ -270,13 +274,13 @@ bool package_reader::read_metadata()
}
case 0x6:
{
metadata.title_id.resize(12);
m_metadata.title_id.resize(12);
if (packet.size == metadata.title_id.size())
if (packet.size == m_metadata.title_id.size())
{
archive_read(&metadata.title_id, metadata.title_id.size());
metadata.title_id = fmt::trim(metadata.title_id);
pkg_log.notice("Metadata: Title ID = %s", metadata.title_id);
archive_read(&m_metadata.title_id, m_metadata.title_id.size());
m_metadata.title_id = fmt::trim(m_metadata.title_id);
pkg_log.notice("Metadata: Title ID = %s", m_metadata.title_id);
continue;
}
else
@ -287,10 +291,10 @@ bool package_reader::read_metadata()
}
case 0x7:
{
if (packet.size == sizeof(metadata.qa_digest))
if (packet.size == sizeof(m_metadata.qa_digest))
{
archive_read(&metadata.qa_digest, sizeof(metadata.qa_digest));
pkg_log.notice("Metadata: QA Digest = 0x%x", metadata.qa_digest);
archive_read(&m_metadata.qa_digest, sizeof(m_metadata.qa_digest));
pkg_log.notice("Metadata: QA Digest = 0x%x", m_metadata.qa_digest);
continue;
}
else
@ -301,11 +305,11 @@ bool package_reader::read_metadata()
}
case 0x8:
{
if (packet.size == sizeof(metadata.software_revision.data))
if (packet.size == sizeof(m_metadata.software_revision.data))
{
archive_read(&metadata.software_revision.data, sizeof(metadata.software_revision.data));
metadata.software_revision.interpret_data();
pkg_log.notice("Metadata: Software Revision = %s", metadata.software_revision.to_string());
archive_read(&m_metadata.software_revision.data, sizeof(m_metadata.software_revision.data));
m_metadata.software_revision.interpret_data();
pkg_log.notice("Metadata: Software Revision = %s", m_metadata.software_revision.to_string());
continue;
}
else
@ -316,10 +320,10 @@ bool package_reader::read_metadata()
}
case 0x9:
{
if (packet.size == sizeof(metadata.unk_0x9))
if (packet.size == sizeof(m_metadata.unk_0x9))
{
archive_read(&metadata.unk_0x9, sizeof(metadata.unk_0x9));
pkg_log.notice("Metadata: unk_0x9 = 0x%x = %d", metadata.unk_0x9, metadata.unk_0x9);
archive_read(&m_metadata.unk_0x9, sizeof(m_metadata.unk_0x9));
pkg_log.notice("Metadata: unk_0x9 = 0x%x = %d", m_metadata.unk_0x9, m_metadata.unk_0x9);
continue;
}
else
@ -333,11 +337,11 @@ bool package_reader::read_metadata()
if (packet.size > 8)
{
// Read an actual installation directory (DLC)
install_dir.resize(packet.size);
archive_read(&install_dir.front(), packet.size);
install_dir = install_dir.c_str() + 8;
metadata.install_dir = install_dir;
pkg_log.notice("Metadata: Install Dir = %s", metadata.install_dir);
m_install_dir.resize(packet.size);
archive_read(&m_install_dir.front(), packet.size);
m_install_dir = m_install_dir.c_str() + 8;
m_metadata.install_dir = m_install_dir;
pkg_log.notice("Metadata: Install Dir = %s", m_metadata.install_dir);
continue;
}
else
@ -349,10 +353,10 @@ bool package_reader::read_metadata()
}
case 0xB:
{
if (packet.size == sizeof(metadata.unk_0xB))
if (packet.size == sizeof(m_metadata.unk_0xB))
{
archive_read(&metadata.unk_0xB, sizeof(metadata.unk_0xB));
pkg_log.notice("Metadata: unk_0xB = 0x%x = %d", metadata.unk_0xB, metadata.unk_0xB);
archive_read(&m_metadata.unk_0xB, sizeof(m_metadata.unk_0xB));
pkg_log.notice("Metadata: unk_0xB = 0x%x = %d", m_metadata.unk_0xB, m_metadata.unk_0xB);
continue;
}
else
@ -368,10 +372,10 @@ bool package_reader::read_metadata()
}
case 0xD: // PSVita stuff
{
if (packet.size == sizeof(metadata.item_info))
if (packet.size == sizeof(m_metadata.item_info))
{
archive_read(&metadata.item_info, sizeof(metadata.item_info));
pkg_log.notice("Metadata: PSVita item info = %s", metadata.item_info.to_string());
archive_read(&m_metadata.item_info, sizeof(m_metadata.item_info));
pkg_log.notice("Metadata: PSVita item info = %s", m_metadata.item_info.to_string());
continue;
}
else
@ -382,10 +386,10 @@ bool package_reader::read_metadata()
}
case 0xE: // PSVita stuff
{
if (packet.size == sizeof(metadata.sfo_info))
if (packet.size == sizeof(m_metadata.sfo_info))
{
archive_read(&metadata.sfo_info, sizeof(metadata.sfo_info));
pkg_log.notice("Metadata: PSVita sfo info = %s", metadata.sfo_info.to_string());
archive_read(&m_metadata.sfo_info, sizeof(m_metadata.sfo_info));
pkg_log.notice("Metadata: PSVita sfo info = %s", m_metadata.sfo_info.to_string());
continue;
}
else
@ -396,10 +400,10 @@ bool package_reader::read_metadata()
}
case 0xF: // PSVita stuff
{
if (packet.size == sizeof(metadata.unknown_data_info))
if (packet.size == sizeof(m_metadata.unknown_data_info))
{
archive_read(&metadata.unknown_data_info, sizeof(metadata.unknown_data_info));
pkg_log.notice("Metadata: PSVita unknown data info = %s", metadata.unknown_data_info.to_string());
archive_read(&m_metadata.unknown_data_info, sizeof(m_metadata.unknown_data_info));
pkg_log.notice("Metadata: PSVita unknown data info = %s", m_metadata.unknown_data_info.to_string());
continue;
}
else
@ -410,10 +414,10 @@ bool package_reader::read_metadata()
}
case 0x10: // PSVita stuff
{
if (packet.size == sizeof(metadata.entirety_info))
if (packet.size == sizeof(m_metadata.entirety_info))
{
archive_read(&metadata.entirety_info, sizeof(metadata.entirety_info));
pkg_log.notice("Metadata: PSVita entirety info = %s", metadata.entirety_info.to_string());
archive_read(&m_metadata.entirety_info, sizeof(m_metadata.entirety_info));
pkg_log.notice("Metadata: PSVita entirety info = %s", m_metadata.entirety_info.to_string());
continue;
}
else
@ -424,10 +428,10 @@ bool package_reader::read_metadata()
}
case 0x11: // PSVita stuff
{
if (packet.size == sizeof(metadata.version_info))
if (packet.size == sizeof(m_metadata.version_info))
{
archive_read(&metadata.version_info, sizeof(metadata.version_info));
pkg_log.notice("Metadata: PSVita version info = %s", metadata.version_info.to_string());
archive_read(&m_metadata.version_info, sizeof(m_metadata.version_info));
pkg_log.notice("Metadata: PSVita version info = %s", m_metadata.version_info.to_string());
continue;
}
else
@ -437,10 +441,10 @@ bool package_reader::read_metadata()
}
case 0x12: // PSVita stuff
{
if (packet.size == sizeof(metadata.self_info))
if (packet.size == sizeof(m_metadata.self_info))
{
archive_read(&metadata.self_info, sizeof(metadata.self_info));
pkg_log.notice("Metadata: PSVita self info = %s", metadata.self_info.to_string());
archive_read(&m_metadata.self_info, sizeof(m_metadata.self_info));
pkg_log.notice("Metadata: PSVita self info = %s", m_metadata.self_info.to_string());
continue;
}
else
@ -469,20 +473,20 @@ bool package_reader::decrypt_data()
return false;
}
if (header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA && metadata.content_type >= 0x15 && metadata.content_type <= 0x17)
if (m_header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA && m_metadata.content_type >= 0x15 && m_metadata.content_type <= 0x17)
{
// PSVita
// TODO: Not all the keys seem to match the content types. I was only able to install a dlc (0x16) with PKG_AES_KEY_VITA_1
aes_context ctx;
aes_setkey_enc(&ctx, metadata.content_type == 0x15u ? PKG_AES_KEY_VITA_1 : metadata.content_type == 0x16u ? PKG_AES_KEY_VITA_2 : PKG_AES_KEY_VITA_3, 128);
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const uchar*>(&header.klicensee), dec_key.data());
decrypt(0, header.file_count * sizeof(PKGEntry), dec_key.data());
aes_setkey_enc(&ctx, m_metadata.content_type == 0x15u ? PKG_AES_KEY_VITA_1 : m_metadata.content_type == 0x16u ? PKG_AES_KEY_VITA_2 : PKG_AES_KEY_VITA_3, 128);
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const uchar*>(&m_header.klicensee), m_dec_key.data());
decrypt(0, m_header.file_count * sizeof(PKGEntry), m_dec_key.data());
}
else
{
std::memcpy(dec_key.data(), PKG_AES_KEY, dec_key.size());
decrypt(0, header.file_count * sizeof(PKGEntry), header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA ? PKG_AES_KEY2 : dec_key.data());
std::memcpy(m_dec_key.data(), PKG_AES_KEY, m_dec_key.size());
decrypt(0, m_header.file_count * sizeof(PKGEntry), m_header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA ? PKG_AES_KEY2 : m_dec_key.data());
}
return true;
@ -495,9 +499,9 @@ bool package_reader::read_param_sfo()
return false;
}
std::vector<PKGEntry> entries(header.file_count);
std::vector<PKGEntry> entries(m_header.file_count);
std::memcpy(entries.data(), buf.get(), entries.size() * sizeof(PKGEntry));
std::memcpy(entries.data(), m_buf.get(), entries.size() * sizeof(PKGEntry));
for (const auto& entry : entries)
{
@ -509,9 +513,9 @@ bool package_reader::read_param_sfo()
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : dec_key.data());
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
const std::string name{reinterpret_cast<char*>(buf.get()), entry.name_size};
const std::string name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
// We're looking for the PARAM.SFO file, if there is any
if (name != "PARAM.SFO")
@ -526,13 +530,13 @@ bool package_reader::read_param_sfo()
{
const u64 block_size = std::min<u64>(BUF_SIZE, entry.file_size - pos);
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : dec_key.data()) != block_size)
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()) != block_size)
{
pkg_log.error("Failed to decrypt PARAM.SFO file");
return false;
}
if (tmp.write(buf.get(), block_size) != block_size)
if (tmp.write(m_buf.get(), block_size) != block_size)
{
pkg_log.error("Failed to write to temporary PARAM.SFO file");
return false;
@ -679,7 +683,7 @@ bool package_reader::extract_data(atomic_t<double>& sync)
std::string dir = Emulator::GetHddDir();
// Based on https://www.psdevwiki.com/ps3/PKG_files#ContentType
switch (metadata.content_type)
switch (m_metadata.content_type)
{
case PKG_CONTENT_TYPE_THEME:
dir += "theme/";
@ -705,7 +709,7 @@ bool package_reader::extract_data(atomic_t<double>& sync)
break;
}
dir += install_dir + '/';
dir += m_install_dir + '/';
// If false, an existing directory is being overwritten: cannot cancel the operation
const bool was_null = !fs::is_dir(dir);
@ -723,9 +727,9 @@ bool package_reader::extract_data(atomic_t<double>& sync)
usz num_failures = 0;
std::vector<PKGEntry> entries(header.file_count);
std::vector<PKGEntry> entries(m_header.file_count);
std::memcpy(entries.data(), buf.get(), entries.size() * sizeof(PKGEntry));
std::memcpy(entries.data(), m_buf.get(), entries.size() * sizeof(PKGEntry));
for (const auto& entry : entries)
{
@ -738,9 +742,9 @@ bool package_reader::extract_data(atomic_t<double>& sync)
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : dec_key.data());
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
const std::string name{ reinterpret_cast<char*>(buf.get()), entry.name_size };
const std::string name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
const std::string path = dir + vfs::escape(name);
pkg_log.notice("Entry 0x%08x: %s", entry.type, name);
@ -778,21 +782,21 @@ bool package_reader::extract_data(atomic_t<double>& sync)
{
const u64 block_size = std::min<u64>(BUF_SIZE, entry.file_size - pos);
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : dec_key.data()) != block_size)
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()) != block_size)
{
extract_success = false;
pkg_log.error("Failed to extract file %s", path);
break;
}
if (out.write(buf.get(), block_size) != block_size)
if (out.write(m_buf.get(), block_size) != block_size)
{
extract_success = false;
pkg_log.error("Failed to write file %s", path);
break;
}
if (sync.fetch_add((block_size + 0.0) / header.data_size) < 0.)
if (sync.fetch_add((block_size + 0.0) / m_header.data_size) < 0.)
{
if (was_null)
{
@ -876,55 +880,55 @@ bool package_reader::extract_data(atomic_t<double>& sync)
void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damode)
{
if (damode == fs::seek_set)
cur_offset = new_offset;
m_cur_offset = new_offset;
else if (damode == fs::seek_cur)
cur_offset += new_offset;
m_cur_offset += new_offset;
u64 _offset = 0;
for (usz i = 0; i < filelist.size(); i++)
for (usz i = 0; i < m_filelist.size(); i++)
{
if (cur_offset < (_offset + filelist[i].size()))
if (m_cur_offset < (_offset + m_filelist[i].size()))
{
cur_file = i;
cur_file_offset = cur_offset - _offset;
filelist[i].seek(cur_file_offset);
m_cur_file = i;
m_cur_file_offset = m_cur_offset - _offset;
m_filelist[i].seek(m_cur_file_offset);
break;
}
_offset += filelist[i].size();
_offset += m_filelist[i].size();
}
};
u64 package_reader::archive_read(void* data_ptr, const u64 num_bytes)
{
ensure(filelist.size() > cur_file && filelist[cur_file]);
ensure(m_filelist.size() > m_cur_file && m_filelist[m_cur_file]);
const u64 num_bytes_left = filelist[cur_file].size() - cur_file_offset;
const u64 num_bytes_left = m_filelist[m_cur_file].size() - m_cur_file_offset;
// check if it continues in another file
if (num_bytes > num_bytes_left)
{
filelist[cur_file].read(data_ptr, num_bytes_left);
m_filelist[m_cur_file].read(data_ptr, num_bytes_left);
if ((cur_file + 1) < filelist.size())
if ((m_cur_file + 1) < m_filelist.size())
{
++cur_file;
++m_cur_file;
}
else
{
cur_offset += num_bytes_left;
cur_file_offset = filelist[cur_file].size();
m_cur_offset += num_bytes_left;
m_cur_file_offset = m_filelist[m_cur_file].size();
return num_bytes_left;
}
const u64 num_read = filelist[cur_file].read(static_cast<u8*>(data_ptr) + num_bytes_left, num_bytes - num_bytes_left);
cur_offset += (num_read + num_bytes_left);
cur_file_offset = num_read;
const u64 num_read = m_filelist[m_cur_file].read(static_cast<u8*>(data_ptr) + num_bytes_left, num_bytes - num_bytes_left);
m_cur_offset += (num_read + num_bytes_left);
m_cur_file_offset = num_read;
return (num_read + num_bytes_left);
}
const u64 num_read = filelist[cur_file].read(data_ptr, num_bytes);
const u64 num_read = m_filelist[m_cur_file].read(data_ptr, num_bytes);
cur_offset += num_read;
cur_file_offset += num_read;
m_cur_offset += num_read;
m_cur_file_offset += num_read;
return num_read;
};
@ -936,29 +940,29 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
return 0;
}
if (!buf)
if (!m_buf)
{
// Allocate buffer with BUF_SIZE size or more if required
buf.reset(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * header.file_count) / sizeof(u128)]);
m_buf.reset(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * m_header.file_count) / sizeof(u128)]);
}
archive_seek(header.data_offset + offset);
archive_seek(m_header.data_offset + offset);
// Read the data and set available size
const u64 read = archive_read(buf.get(), size);
const u64 read = archive_read(m_buf.get(), size);
// Get block count
const u64 blocks = (read + 15) / 16;
if (header.pkg_type == PKG_RELEASE_TYPE_DEBUG)
if (m_header.pkg_type == PKG_RELEASE_TYPE_DEBUG)
{
// Debug key
be_t<u64> input[8] =
{
header.qa_digest[0],
header.qa_digest[0],
header.qa_digest[1],
header.qa_digest[1],
m_header.qa_digest[0],
m_header.qa_digest[0],
m_header.qa_digest[1],
m_header.qa_digest[1],
};
for (u64 i = 0; i < blocks; i++)
@ -974,10 +978,10 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
sha1(reinterpret_cast<const u8*>(input), sizeof(input), hash.data);
buf[i] ^= hash._v128;
m_buf[i] ^= hash._v128;
}
}
else if (header.pkg_type == PKG_RELEASE_TYPE_RELEASE)
else if (m_header.pkg_type == PKG_RELEASE_TYPE_RELEASE)
{
aes_context ctx;
@ -985,7 +989,7 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
aes_setkey_enc(&ctx, key, 128);
// Initialize stream cipher for start position
be_t<u128> input = header.klicensee.value() + offset / 16;
be_t<u128> input = m_header.klicensee.value() + offset / 16;
// Increment stream position for every block
for (u64 i = 0; i < blocks; i++, input++)
@ -994,12 +998,12 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const u8*>(&input), reinterpret_cast<u8*>(&key));
buf[i] ^= key;
m_buf[i] ^= key;
}
}
else
{
pkg_log.error("Unknown release type (0x%x)", header.pkg_type);
pkg_log.error("Unknown release type (0x%x)", m_header.pkg_type);
}
// Return the amount of data written in buf

View File

@ -320,15 +320,15 @@ private:
bool m_is_valid = false;
std::string m_path;
std::string install_dir;
std::vector<fs::file> filelist;
usz cur_file = 0;
u64 cur_offset = 0;
u64 cur_file_offset = 0;
std::unique_ptr<u128[]> buf;
std::array<uchar, 16> dec_key{};
std::string m_install_dir;
std::vector<fs::file> m_filelist;
usz m_cur_file = 0;
u64 m_cur_offset = 0;
u64 m_cur_file_offset = 0;
std::unique_ptr<u128[]> m_buf;
std::array<uchar, 16> m_dec_key{};
PKGHeader header{};
PKGMetaData metadata{};
PKGHeader m_header{};
PKGMetaData m_metadata{};
psf::registry m_psf;
};