mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-14 08:12:16 +00:00
104 lines
No EOL
2.4 KiB
C++
104 lines
No EOL
2.4 KiB
C++
#include "PKG.h"
|
|
#include "../../core/FsFile.h"
|
|
#include <direct.h>
|
|
#include <QString>
|
|
#include <QDir>
|
|
|
|
PKG::PKG()
|
|
{
|
|
}
|
|
|
|
|
|
PKG::~PKG()
|
|
{
|
|
}
|
|
|
|
bool PKG::open(const std::string& filepath) {
|
|
FsFile file;
|
|
if (!file.Open(filepath, fsRead))
|
|
{
|
|
return false;
|
|
}
|
|
pkgSize = file.getFileSize();
|
|
PKGHeader pkgheader;
|
|
file.ReadBE(pkgheader);
|
|
//we have already checked magic should be ok
|
|
|
|
//find title id it is part of pkg_content_id starting at offset 0x40
|
|
file.Seek(0x47, fsSeekSet);//skip first 7 characters of content_id
|
|
file.Read(&pkgTitleID, sizeof(pkgTitleID));
|
|
|
|
file.Close();
|
|
|
|
return true;
|
|
}
|
|
bool PKG::extract(const std::string& filepath, const std::string& extractPath, std::string& failreason)
|
|
{
|
|
this->extractPath = extractPath;
|
|
FsFile file;
|
|
if (!file.Open(filepath, fsRead))
|
|
{
|
|
return false;
|
|
}
|
|
pkgSize = file.getFileSize();
|
|
PKGHeader pkgheader;
|
|
file.ReadBE(pkgheader);
|
|
|
|
if (pkgheader.pkg_size > pkgSize)
|
|
{
|
|
failreason = "PKG file size is different";
|
|
return false;
|
|
}
|
|
if ((pkgheader.pkg_content_size + pkgheader.pkg_content_offset) > pkgheader.pkg_size)
|
|
{
|
|
failreason = "Content size is bigger than pkg size";
|
|
return false;
|
|
}
|
|
file.Seek(0, fsSeekSet);
|
|
pkg = (U08*)mmap(pkgSize, file.fileDescr());
|
|
if (pkg == nullptr)
|
|
{
|
|
failreason = "Can't allocate size for image";
|
|
return false;
|
|
}
|
|
|
|
file.Read(pkg, pkgSize);
|
|
|
|
U32 offset = pkgheader.pkg_table_entry_offset;
|
|
U32 n_files = pkgheader.pkg_table_entry_count;
|
|
|
|
|
|
for (int i = 0; i < n_files; i++) {
|
|
PKGEntry entry = (PKGEntry&)pkg[offset + i * 0x20];
|
|
ReadBE(entry);
|
|
//try to figure out the name
|
|
std::string name = getEntryNameByType(entry.id);
|
|
if (!name.empty())
|
|
{
|
|
QString filepath= QString::fromStdString(extractPath+ "/sce_sys/" + name);
|
|
QDir dir = QFileInfo(filepath).dir();
|
|
if (!dir.exists()) {
|
|
dir.mkpath(dir.path());
|
|
}
|
|
FsFile out;
|
|
out.Open(extractPath + "/sce_sys/" + name, fsWrite);
|
|
out.Write(pkg + entry.offset, entry.size);
|
|
out.Close();
|
|
}
|
|
else
|
|
{
|
|
//just print with id
|
|
FsFile out;
|
|
out.Open(extractPath + "/sce_sys/" + std::to_string(entry.id), fsWrite);
|
|
out.Write(pkg + entry.offset, entry.size);
|
|
out.Close();
|
|
}
|
|
}
|
|
//extract pfs_image.dat
|
|
FsFile out;
|
|
out.Open(extractPath + "pfs_image.dat", fsWrite);
|
|
out.Write(pkg + pkgheader.pfs_image_offset, pkgheader.pfs_image_size);
|
|
out.Close();
|
|
munmap(pkg);
|
|
return true;
|
|
} |