mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
Rename package_reader member variables
This commit is contained in:
parent
68d411918d
commit
ccec6e53c0
2 changed files with 158 additions and 154 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue