mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Add a reader for PKG game update packages
PSP game updates were distributed as NPDRM .pkg files holding a patched EBOOT (PBOOT.PBP) plus the data files the patch replaces. PkgUnpack reads one: header, item table, both PARAM.SFOs, and the AES-128-CTR that covers everything past the header - including the per-item key split, where an item's pspType byte picks between the PSP and PS3 keys. Nothing new is needed to decrypt these. All packages checked use PRX tag 0x2E5E10F0 for their PBOOT, which PrxDecrypter already has a key for. Also adds "PPSSPPHeadless --install-pkg=DIR", a sibling of --unpack-updater, which installs without any UI. All packages install through it byte -identically to a reference implementation. Format notes are in docs/pkg_notes.md. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
ddc673916d
commit
5089caf2a0
12 files changed
+662
No files matched your search
@@ -58,6 +58,7 @@
|
||||
#include "Core/MIPS/MIPSTables.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Util/PSARUnpack.h"
|
||||
#include "Core/Util/PkgUnpack.h"
|
||||
#include "Core/WebServer.h"
|
||||
#include "Core/HLE/sceUtility.h"
|
||||
#include "Core/SaveState.h"
|
||||
@@ -671,6 +672,38 @@ int main(int argc, const char* argv[]) {
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
// Same deal for installing a game update package.
|
||||
if (cmdLineOptions.installPkg.has_value()) {
|
||||
if (cmdLineOptions.bootFilenames.size() != 1) {
|
||||
fprintf(stderr, "--install-pkg takes exactly one .pkg file\n");
|
||||
return 1;
|
||||
}
|
||||
std::unique_ptr<FileLoader> loader(ConstructFileLoader(Path(cmdLineOptions.bootFilenames[0])));
|
||||
PkgReader reader;
|
||||
std::string pkgError;
|
||||
if (!loader || !reader.Open(loader.get(), &pkgError)) {
|
||||
fprintf(stderr, "Not a usable PKG: %s\n", pkgError.c_str());
|
||||
return 1;
|
||||
}
|
||||
const PkgInfo &info = reader.Info();
|
||||
printf("%s (%s)\n", info.title.c_str(), info.contentId.c_str());
|
||||
printf("Category %s, %d items, %lld bytes installed\n", info.category.c_str(),
|
||||
(int)info.items.size(), (long long)PkgInstalledSize(info));
|
||||
if (info.isGameUpdate) {
|
||||
printf("Game update for %s v%s -> app version %s (firmware %s)\n", info.discId.c_str(),
|
||||
info.discVersion.c_str(), info.appVer.c_str(), info.systemVer.c_str());
|
||||
} else {
|
||||
fprintf(stderr, "This PKG isn't a game update - nothing we know how to install\n");
|
||||
return 1;
|
||||
}
|
||||
if (!InstallPkg(reader, Path(cmdLineOptions.installPkg.value()), nullptr, &pkgError)) {
|
||||
fprintf(stderr, "Install failed: %s\n", pkgError.c_str());
|
||||
return 1;
|
||||
}
|
||||
printf("Installed into %s\n", cmdLineOptions.installPkg.value().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_Config.RestoreDefaults(RestoreSettingsBits::SETTINGS | RestoreSettingsBits::CONTROLS | RestoreSettingsBits::RECENT, false);
|
||||
|
||||
Core_RegisterDebugOutputListeners(&SendDebugOutput, &SendDebugScreenshot);
|
||||
|
||||
Reference in new issue
Block a user