mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 16:31:28 +12: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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
filelist.emplace_back(fs::file{ path });
|
m_filelist.emplace_back(fs::file{path});
|
||||||
|
|
||||||
m_is_valid = read_header();
|
m_is_valid = read_header();
|
||||||
|
|
||||||
|
@ -50,34 +50,34 @@ package_reader::~package_reader()
|
||||||
|
|
||||||
bool package_reader::read_header()
|
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!");
|
pkg_log.error("Reading PKG header: no file to read!");
|
||||||
return false;
|
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!");
|
pkg_log.error("Reading PKG header: file is too short!");
|
||||||
return false;
|
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_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", header.pkg_type, header.pkg_type);
|
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", header.pkg_platform, header.pkg_platform);
|
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", header.meta_offset, header.meta_offset);
|
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", header.meta_count, header.meta_count);
|
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", header.meta_size, header.meta_size);
|
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", header.file_count, header.file_count);
|
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", header.pkg_size, header.pkg_size);
|
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", header.data_offset, header.data_offset);
|
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", header.data_size, header.data_size);
|
pkg_log.notice("Header: data_size = 0x%x = %d", m_header.data_size, m_header.data_size);
|
||||||
pkg_log.notice("Header: title_id = %s", header.title_id);
|
pkg_log.notice("Header: title_id = %s", m_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: 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);
|
//pkg_log.notice("Header: klicensee = 0x%x = %d", header.klicensee, header.klicensee);
|
||||||
|
|
||||||
// Get extended PKG information for PSP or PSVita
|
// 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;
|
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);
|
//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!");
|
pkg_log.error("Not a PKG file!");
|
||||||
return false;
|
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_DEBUG: break;
|
||||||
case PKG_RELEASE_TYPE_RELEASE: 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_PS3: break;
|
||||||
case PKG_PLATFORM_TYPE_PSP_PSVITA: 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
|
// Check if multi-files pkg
|
||||||
if (!m_path.ends_with("_00.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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string name_wo_number = m_path.substr(0, m_path.size() - 7);
|
const std::string name_wo_number = m_path.substr(0, m_path.size() - 7);
|
||||||
u64 cursize = filelist[0].size();
|
u64 cursize = m_filelist[0].size();
|
||||||
while (cursize < header.pkg_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);
|
fs::file archive_file(archive_filename);
|
||||||
if (!archive_file)
|
if (!archive_file)
|
||||||
|
@ -153,13 +153,13 @@ bool package_reader::read_header()
|
||||||
}
|
}
|
||||||
|
|
||||||
cursize += archive_file.size();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,21 +168,25 @@ bool package_reader::read_header()
|
||||||
|
|
||||||
bool package_reader::read_metadata()
|
bool package_reader::read_metadata()
|
||||||
{
|
{
|
||||||
if (!m_is_valid)
|
if (!decrypt_data())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
//if (!m_is_valid)
|
||||||
|
//{
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
// Read title ID and use it as an installation directory
|
// Read title ID and use it as an installation directory
|
||||||
install_dir.resize(9);
|
m_install_dir.resize(9);
|
||||||
archive_seek(55);
|
archive_seek(55);
|
||||||
archive_read(&install_dir.front(), install_dir.size());
|
archive_read(&m_install_dir.front(), m_install_dir.size());
|
||||||
|
|
||||||
// Read package metadata
|
// 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
|
struct packet_T
|
||||||
{
|
{
|
||||||
|
@ -197,10 +201,10 @@ bool package_reader::read_metadata()
|
||||||
{
|
{
|
||||||
case 0x1:
|
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));
|
archive_read(&m_metadata.drm_type, sizeof(m_metadata.drm_type));
|
||||||
pkg_log.notice("Metadata: DRM Type = 0x%x = %d", metadata.drm_type, metadata.drm_type);
|
pkg_log.notice("Metadata: DRM Type = 0x%x = %d", m_metadata.drm_type, m_metadata.drm_type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -212,10 +216,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x2:
|
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));
|
archive_read(&m_metadata.content_type, sizeof(m_metadata.content_type));
|
||||||
pkg_log.notice("Metadata: Content Type = 0x%x = %d", metadata.content_type, metadata.content_type);
|
pkg_log.notice("Metadata: Content Type = 0x%x = %d", m_metadata.content_type, m_metadata.content_type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -227,10 +231,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x3:
|
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));
|
archive_read(&m_metadata.package_type, sizeof(m_metadata.package_type));
|
||||||
pkg_log.notice("Metadata: Package Type = 0x%x = %d", metadata.package_type, metadata.package_type);
|
pkg_log.notice("Metadata: Package Type = 0x%x = %d", m_metadata.package_type, m_metadata.package_type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -241,10 +245,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x4:
|
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));
|
archive_read(&m_metadata.package_size, sizeof(m_metadata.package_size));
|
||||||
pkg_log.notice("Metadata: Package Size = 0x%x = %d", metadata.package_size, metadata.package_size);
|
pkg_log.notice("Metadata: Package Size = 0x%x = %d", m_metadata.package_size, m_metadata.package_size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -255,11 +259,11 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x5:
|
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));
|
archive_read(&m_metadata.package_revision.data, sizeof(m_metadata.package_revision.data));
|
||||||
metadata.package_revision.interpret_data();
|
m_metadata.package_revision.interpret_data();
|
||||||
pkg_log.notice("Metadata: Package Revision = %s", metadata.package_revision.to_string());
|
pkg_log.notice("Metadata: Package Revision = %s", m_metadata.package_revision.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -270,13 +274,13 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x6:
|
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());
|
archive_read(&m_metadata.title_id, m_metadata.title_id.size());
|
||||||
metadata.title_id = fmt::trim(metadata.title_id);
|
m_metadata.title_id = fmt::trim(m_metadata.title_id);
|
||||||
pkg_log.notice("Metadata: Title ID = %s", metadata.title_id);
|
pkg_log.notice("Metadata: Title ID = %s", m_metadata.title_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -287,10 +291,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x7:
|
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));
|
archive_read(&m_metadata.qa_digest, sizeof(m_metadata.qa_digest));
|
||||||
pkg_log.notice("Metadata: QA Digest = 0x%x", metadata.qa_digest);
|
pkg_log.notice("Metadata: QA Digest = 0x%x", m_metadata.qa_digest);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -301,11 +305,11 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x8:
|
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));
|
archive_read(&m_metadata.software_revision.data, sizeof(m_metadata.software_revision.data));
|
||||||
metadata.software_revision.interpret_data();
|
m_metadata.software_revision.interpret_data();
|
||||||
pkg_log.notice("Metadata: Software Revision = %s", metadata.software_revision.to_string());
|
pkg_log.notice("Metadata: Software Revision = %s", m_metadata.software_revision.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -316,10 +320,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x9:
|
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));
|
archive_read(&m_metadata.unk_0x9, sizeof(m_metadata.unk_0x9));
|
||||||
pkg_log.notice("Metadata: unk_0x9 = 0x%x = %d", metadata.unk_0x9, metadata.unk_0x9);
|
pkg_log.notice("Metadata: unk_0x9 = 0x%x = %d", m_metadata.unk_0x9, m_metadata.unk_0x9);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -333,11 +337,11 @@ bool package_reader::read_metadata()
|
||||||
if (packet.size > 8)
|
if (packet.size > 8)
|
||||||
{
|
{
|
||||||
// Read an actual installation directory (DLC)
|
// Read an actual installation directory (DLC)
|
||||||
install_dir.resize(packet.size);
|
m_install_dir.resize(packet.size);
|
||||||
archive_read(&install_dir.front(), packet.size);
|
archive_read(&m_install_dir.front(), packet.size);
|
||||||
install_dir = install_dir.c_str() + 8;
|
m_install_dir = m_install_dir.c_str() + 8;
|
||||||
metadata.install_dir = install_dir;
|
m_metadata.install_dir = m_install_dir;
|
||||||
pkg_log.notice("Metadata: Install Dir = %s", metadata.install_dir);
|
pkg_log.notice("Metadata: Install Dir = %s", m_metadata.install_dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -349,10 +353,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0xB:
|
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));
|
archive_read(&m_metadata.unk_0xB, sizeof(m_metadata.unk_0xB));
|
||||||
pkg_log.notice("Metadata: unk_0xB = 0x%x = %d", metadata.unk_0xB, metadata.unk_0xB);
|
pkg_log.notice("Metadata: unk_0xB = 0x%x = %d", m_metadata.unk_0xB, m_metadata.unk_0xB);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -368,10 +372,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0xD: // PSVita stuff
|
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));
|
archive_read(&m_metadata.item_info, sizeof(m_metadata.item_info));
|
||||||
pkg_log.notice("Metadata: PSVita item info = %s", metadata.item_info.to_string());
|
pkg_log.notice("Metadata: PSVita item info = %s", m_metadata.item_info.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -382,10 +386,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0xE: // PSVita stuff
|
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));
|
archive_read(&m_metadata.sfo_info, sizeof(m_metadata.sfo_info));
|
||||||
pkg_log.notice("Metadata: PSVita sfo info = %s", metadata.sfo_info.to_string());
|
pkg_log.notice("Metadata: PSVita sfo info = %s", m_metadata.sfo_info.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -396,10 +400,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0xF: // PSVita stuff
|
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));
|
archive_read(&m_metadata.unknown_data_info, sizeof(m_metadata.unknown_data_info));
|
||||||
pkg_log.notice("Metadata: PSVita unknown data info = %s", metadata.unknown_data_info.to_string());
|
pkg_log.notice("Metadata: PSVita unknown data info = %s", m_metadata.unknown_data_info.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -410,10 +414,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x10: // PSVita stuff
|
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));
|
archive_read(&m_metadata.entirety_info, sizeof(m_metadata.entirety_info));
|
||||||
pkg_log.notice("Metadata: PSVita entirety info = %s", metadata.entirety_info.to_string());
|
pkg_log.notice("Metadata: PSVita entirety info = %s", m_metadata.entirety_info.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -424,10 +428,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x11: // PSVita stuff
|
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));
|
archive_read(&m_metadata.version_info, sizeof(m_metadata.version_info));
|
||||||
pkg_log.notice("Metadata: PSVita version info = %s", metadata.version_info.to_string());
|
pkg_log.notice("Metadata: PSVita version info = %s", m_metadata.version_info.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -437,10 +441,10 @@ bool package_reader::read_metadata()
|
||||||
}
|
}
|
||||||
case 0x12: // PSVita stuff
|
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));
|
archive_read(&m_metadata.self_info, sizeof(m_metadata.self_info));
|
||||||
pkg_log.notice("Metadata: PSVita self info = %s", metadata.self_info.to_string());
|
pkg_log.notice("Metadata: PSVita self info = %s", m_metadata.self_info.to_string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -469,20 +473,20 @@ bool package_reader::decrypt_data()
|
||||||
return false;
|
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
|
// 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
|
// 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_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_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*>(&header.klicensee), dec_key.data());
|
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const uchar*>(&m_header.klicensee), m_dec_key.data());
|
||||||
decrypt(0, header.file_count * sizeof(PKGEntry), dec_key.data());
|
decrypt(0, m_header.file_count * sizeof(PKGEntry), m_dec_key.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::memcpy(dec_key.data(), PKG_AES_KEY, dec_key.size());
|
std::memcpy(m_dec_key.data(), PKG_AES_KEY, m_dec_key.size());
|
||||||
decrypt(0, header.file_count * sizeof(PKGEntry), header.pkg_platform == PKG_PLATFORM_TYPE_PSP_PSVITA ? PKG_AES_KEY2 : dec_key.data());
|
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;
|
return true;
|
||||||
|
@ -495,9 +499,9 @@ bool package_reader::read_param_sfo()
|
||||||
return false;
|
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)
|
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;
|
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
|
// We're looking for the PARAM.SFO file, if there is any
|
||||||
if (name != "PARAM.SFO")
|
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);
|
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");
|
pkg_log.error("Failed to decrypt PARAM.SFO file");
|
||||||
return false;
|
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");
|
pkg_log.error("Failed to write to temporary PARAM.SFO file");
|
||||||
return false;
|
return false;
|
||||||
|
@ -679,7 +683,7 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||||
std::string dir = Emulator::GetHddDir();
|
std::string dir = Emulator::GetHddDir();
|
||||||
|
|
||||||
// Based on https://www.psdevwiki.com/ps3/PKG_files#ContentType
|
// Based on https://www.psdevwiki.com/ps3/PKG_files#ContentType
|
||||||
switch (metadata.content_type)
|
switch (m_metadata.content_type)
|
||||||
{
|
{
|
||||||
case PKG_CONTENT_TYPE_THEME:
|
case PKG_CONTENT_TYPE_THEME:
|
||||||
dir += "theme/";
|
dir += "theme/";
|
||||||
|
@ -705,7 +709,7 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir += install_dir + '/';
|
dir += m_install_dir + '/';
|
||||||
|
|
||||||
// If false, an existing directory is being overwritten: cannot cancel the operation
|
// If false, an existing directory is being overwritten: cannot cancel the operation
|
||||||
const bool was_null = !fs::is_dir(dir);
|
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;
|
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)
|
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;
|
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);
|
const std::string path = dir + vfs::escape(name);
|
||||||
|
|
||||||
pkg_log.notice("Entry 0x%08x: %s", entry.type, 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);
|
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;
|
extract_success = false;
|
||||||
pkg_log.error("Failed to extract file %s", path);
|
pkg_log.error("Failed to extract file %s", path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out.write(buf.get(), block_size) != block_size)
|
if (out.write(m_buf.get(), block_size) != block_size)
|
||||||
{
|
{
|
||||||
extract_success = false;
|
extract_success = false;
|
||||||
pkg_log.error("Failed to write file %s", path);
|
pkg_log.error("Failed to write file %s", path);
|
||||||
break;
|
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)
|
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)
|
void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damode)
|
||||||
{
|
{
|
||||||
if (damode == fs::seek_set)
|
if (damode == fs::seek_set)
|
||||||
cur_offset = new_offset;
|
m_cur_offset = new_offset;
|
||||||
else if (damode == fs::seek_cur)
|
else if (damode == fs::seek_cur)
|
||||||
cur_offset += new_offset;
|
m_cur_offset += new_offset;
|
||||||
|
|
||||||
u64 _offset = 0;
|
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;
|
m_cur_file = i;
|
||||||
cur_file_offset = cur_offset - _offset;
|
m_cur_file_offset = m_cur_offset - _offset;
|
||||||
filelist[i].seek(cur_file_offset);
|
m_filelist[i].seek(m_cur_file_offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_offset += filelist[i].size();
|
_offset += m_filelist[i].size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
u64 package_reader::archive_read(void* data_ptr, const u64 num_bytes)
|
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
|
// check if it continues in another file
|
||||||
if (num_bytes > num_bytes_left)
|
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
|
else
|
||||||
{
|
{
|
||||||
cur_offset += num_bytes_left;
|
m_cur_offset += num_bytes_left;
|
||||||
cur_file_offset = filelist[cur_file].size();
|
m_cur_file_offset = m_filelist[m_cur_file].size();
|
||||||
return num_bytes_left;
|
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);
|
const u64 num_read = m_filelist[m_cur_file].read(static_cast<u8*>(data_ptr) + num_bytes_left, num_bytes - num_bytes_left);
|
||||||
cur_offset += (num_read + num_bytes_left);
|
m_cur_offset += (num_read + num_bytes_left);
|
||||||
cur_file_offset = num_read;
|
m_cur_file_offset = num_read;
|
||||||
return (num_read + num_bytes_left);
|
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;
|
m_cur_offset += num_read;
|
||||||
cur_file_offset += num_read;
|
m_cur_file_offset += num_read;
|
||||||
|
|
||||||
return num_read;
|
return num_read;
|
||||||
};
|
};
|
||||||
|
@ -936,29 +940,29 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buf)
|
if (!m_buf)
|
||||||
{
|
{
|
||||||
// Allocate buffer with BUF_SIZE size or more if required
|
// 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
|
// 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
|
// Get block count
|
||||||
const u64 blocks = (read + 15) / 16;
|
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
|
// Debug key
|
||||||
be_t<u64> input[8] =
|
be_t<u64> input[8] =
|
||||||
{
|
{
|
||||||
header.qa_digest[0],
|
m_header.qa_digest[0],
|
||||||
header.qa_digest[0],
|
m_header.qa_digest[0],
|
||||||
header.qa_digest[1],
|
m_header.qa_digest[1],
|
||||||
header.qa_digest[1],
|
m_header.qa_digest[1],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (u64 i = 0; i < blocks; i++)
|
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);
|
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;
|
aes_context ctx;
|
||||||
|
|
||||||
|
@ -985,7 +989,7 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
|
||||||
aes_setkey_enc(&ctx, key, 128);
|
aes_setkey_enc(&ctx, key, 128);
|
||||||
|
|
||||||
// Initialize stream cipher for start position
|
// 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
|
// Increment stream position for every block
|
||||||
for (u64 i = 0; i < blocks; i++, input++)
|
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));
|
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const u8*>(&input), reinterpret_cast<u8*>(&key));
|
||||||
|
|
||||||
buf[i] ^= key;
|
m_buf[i] ^= key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
// Return the amount of data written in buf
|
||||||
|
|
|
@ -320,15 +320,15 @@ private:
|
||||||
bool m_is_valid = false;
|
bool m_is_valid = false;
|
||||||
|
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
std::string install_dir;
|
std::string m_install_dir;
|
||||||
std::vector<fs::file> filelist;
|
std::vector<fs::file> m_filelist;
|
||||||
usz cur_file = 0;
|
usz m_cur_file = 0;
|
||||||
u64 cur_offset = 0;
|
u64 m_cur_offset = 0;
|
||||||
u64 cur_file_offset = 0;
|
u64 m_cur_file_offset = 0;
|
||||||
std::unique_ptr<u128[]> buf;
|
std::unique_ptr<u128[]> m_buf;
|
||||||
std::array<uchar, 16> dec_key{};
|
std::array<uchar, 16> m_dec_key{};
|
||||||
|
|
||||||
PKGHeader header{};
|
PKGHeader m_header{};
|
||||||
PKGMetaData metadata{};
|
PKGMetaData m_metadata{};
|
||||||
psf::registry m_psf;
|
psf::registry m_psf;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue