mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Prepare to generalize file dumping
This commit is contained in:
parent
bb0123a25e
commit
c4241e283a
7 changed files with 123 additions and 80 deletions
|
@ -329,7 +329,8 @@ static const ConfigSetting generalSettings[] = {
|
|||
ConfigSetting("PauseExitsEmulator", &g_Config.bPauseExitsEmulator, false, CfgFlag::DONT_SAVE),
|
||||
ConfigSetting("PauseMenuExitsEmulator", &g_Config.bPauseMenuExitsEmulator, false, CfgFlag::DONT_SAVE),
|
||||
|
||||
ConfigSetting("DumpDecryptedEboots", &g_Config.bDumpDecryptedEboot, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("DumpFileTypes", &g_Config.iDumpFileTypes, 0, CfgFlag::PER_GAME),
|
||||
|
||||
ConfigSetting("FullscreenOnDoubleclick", &g_Config.bFullscreenOnDoubleclick, true, CfgFlag::DONT_SAVE),
|
||||
ConfigSetting("ShowMenuBar", &g_Config.bShowMenuBar, true, CfgFlag::DEFAULT),
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
bool bDumpAudio;
|
||||
bool bSaveLoadResetsAVdumping;
|
||||
bool bEnableLogging;
|
||||
bool bDumpDecryptedEboot;
|
||||
int iDumpFileTypes; // DumpFileType bitflag enum
|
||||
bool bFullscreenOnDoubleclick;
|
||||
|
||||
// These four are Win UI only
|
||||
|
|
|
@ -165,6 +165,13 @@ enum class ShowStatusFlags {
|
|||
BATTERY_PERCENT = 1 << 3,
|
||||
};
|
||||
|
||||
enum class DumpFileType {
|
||||
EBOOT = (1 << 0),
|
||||
PRX = (1 << 1),
|
||||
Atrac3 = (1 << 2),
|
||||
};
|
||||
ENUM_CLASS_BITOPS(DumpFileType);
|
||||
|
||||
// for iTiltInputType
|
||||
enum TiltTypes {
|
||||
TILT_NULL = 0,
|
||||
|
|
|
@ -915,81 +915,6 @@ void PSPModule::Cleanup() {
|
|||
}
|
||||
}
|
||||
|
||||
static void SaveDecryptedEbootToStorageMedia(const u8 *decryptedEbootDataPtr, const u32 length, const char *name) {
|
||||
if (!decryptedEbootDataPtr) {
|
||||
ERROR_LOG(Log::sceModule, "Error saving decrypted EBOOT.BIN: invalid pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
ERROR_LOG(Log::sceModule, "Error saving decrypted EBOOT.BIN: invalid length");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string filenameToDumpTo = StringFromFormat("%s_%s.BIN", g_paramSFO.GetDiscID().c_str(), name);
|
||||
const Path dumpDirectory = GetSysDirectory(DIRECTORY_DUMP);
|
||||
const Path fullPath = dumpDirectory / filenameToDumpTo;
|
||||
|
||||
auto s = GetI18NCategory(I18NCat::SYSTEM);
|
||||
|
||||
// If the file already exists, don't dump it again.
|
||||
if (File::Exists(fullPath)) {
|
||||
INFO_LOG(Log::sceModule, "Decrypted EBOOT.BIN already exists for this game, skipping dump.");
|
||||
|
||||
char *path = new char[strlen(fullPath.c_str()) + 1];
|
||||
strcpy(path, fullPath.c_str());
|
||||
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, s->T("Dump Decrypted Eboot"), fullPath.ToVisualString(), 5.0f, "decr");
|
||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||
g_OSD.SetClickCallback("decr", [](bool clicked, void *userdata) {
|
||||
char *path = (char *)userdata;
|
||||
if (clicked) {
|
||||
System_ShowFileInFolder(Path(path));
|
||||
} else {
|
||||
delete[] path;
|
||||
}
|
||||
}, path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the dump directory exists before continuing.
|
||||
if (!File::Exists(dumpDirectory)) {
|
||||
if (!File::CreateDir(dumpDirectory)) {
|
||||
ERROR_LOG(Log::sceModule, "Unable to create directory for EBOOT dumping, aborting.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *decryptedEbootFile = File::OpenCFile(fullPath, "wb");
|
||||
if (!decryptedEbootFile) {
|
||||
ERROR_LOG(Log::sceModule, "Unable to write decrypted EBOOT.");
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t lengthToWrite = length;
|
||||
|
||||
fwrite(decryptedEbootDataPtr, sizeof(u8), lengthToWrite, decryptedEbootFile);
|
||||
fclose(decryptedEbootFile);
|
||||
INFO_LOG(Log::sceModule, "Successfully wrote decrypted EBOOT to %s", fullPath.c_str());
|
||||
|
||||
char *path = new char[strlen(fullPath.c_str()) + 1];
|
||||
strcpy(path, fullPath.c_str());
|
||||
|
||||
// Re-suing the translation string here.
|
||||
g_OSD.Show(OSDType::MESSAGE_SUCCESS, s->T("Dump Decrypted Eboot"), fullPath.ToVisualString(), 5.0f, "decr");
|
||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||
g_OSD.SetClickCallback("decr", [](bool clicked, void *userdata) {
|
||||
char *path = (char *)userdata;
|
||||
if (clicked) {
|
||||
System_ShowFileInFolder(Path(path));
|
||||
} else {
|
||||
delete[] path;
|
||||
}
|
||||
}, path);
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsHLEVersionedModule(const char *name) {
|
||||
// TODO: Only some of these are currently known to be versioned.
|
||||
// Potentially only sceMpeg_library matters.
|
||||
|
@ -1414,11 +1339,11 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
|
|||
}
|
||||
|
||||
// If we've made it this far, it should be safe to dump.
|
||||
if (g_Config.bDumpDecryptedEboot) {
|
||||
if (g_Config.iDumpFileTypes & (int)DumpFileType::EBOOT) {
|
||||
// Copy the name to ensure it's null terminated.
|
||||
char name[32]{};
|
||||
strncpy(name, head->modname, ARRAY_SIZE(head->modname));
|
||||
SaveDecryptedEbootToStorageMedia(ptr, (u32)elfSize, name);
|
||||
DumpFile(ptr, (u32)elfSize, name, DumpFileType::EBOOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
103
Core/System.cpp
103
Core/System.cpp
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Common/System/OSD.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/File/DirListing.h"
|
||||
|
@ -61,6 +63,8 @@
|
|||
#include "Core/PSPLoaders.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
#include "Core/SaveState.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/ExceptionHandlerSetup.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/Debugger/Playback.h"
|
||||
|
@ -716,3 +720,102 @@ const char *CoreStateToString(CoreState state) {
|
|||
default: return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
const char *DumpFileTypeToString(DumpFileType type) {
|
||||
switch (type) {
|
||||
case DumpFileType::EBOOT: return "EBOOT";
|
||||
case DumpFileType::PRX: return "PRX";
|
||||
case DumpFileType::Atrac3: return "AT3";
|
||||
default: return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
const char *DumpFileTypeToFileExtension(DumpFileType type) {
|
||||
switch (type) {
|
||||
case DumpFileType::EBOOT: return ".BIN";
|
||||
case DumpFileType::PRX: return ".prx";
|
||||
case DumpFileType::Atrac3: return ".at3";
|
||||
default: return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
void DumpFile(const u8 *dataPtr, const u32 length, const char *name, DumpFileType type) {
|
||||
if (!dataPtr) {
|
||||
ERROR_LOG(Log::System, "Error dumping %s: invalid pointer", DumpFileTypeToString(DumpFileType::EBOOT));
|
||||
return;
|
||||
}
|
||||
if (length == 0) {
|
||||
ERROR_LOG(Log::System, "Error dumping %s: invalid length", DumpFileTypeToString(DumpFileType::EBOOT));
|
||||
return;
|
||||
}
|
||||
|
||||
const char *extension = DumpFileTypeToFileExtension(type);
|
||||
const std::string filenameToDumpTo = StringFromFormat("%s_%s%s", g_paramSFO.GetDiscID().c_str(), name, extension);
|
||||
const Path dumpDirectory = GetSysDirectory(DIRECTORY_DUMP);
|
||||
const Path fullPath = dumpDirectory / filenameToDumpTo;
|
||||
|
||||
auto s = GetI18NCategory(I18NCat::SYSTEM);
|
||||
|
||||
std::string_view titleStr = "Dump Decrypted Eboot";
|
||||
if (type != DumpFileType::EBOOT) {
|
||||
titleStr = s->T(DumpFileTypeToString(type));
|
||||
}
|
||||
|
||||
// If the file already exists, don't dump it again.
|
||||
if (File::Exists(fullPath)) {
|
||||
INFO_LOG(Log::sceModule, "%s already exists for this game, skipping dump.", filenameToDumpTo.c_str());
|
||||
|
||||
char *path = new char[strlen(fullPath.c_str()) + 1];
|
||||
strcpy(path, fullPath.c_str());
|
||||
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, titleStr, fullPath.ToVisualString(), 5.0f, "file_dumped");
|
||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||
g_OSD.SetClickCallback("file_dumped", [](bool clicked, void *userdata) {
|
||||
char *path = (char *)userdata;
|
||||
if (clicked) {
|
||||
System_ShowFileInFolder(Path(path));
|
||||
} else {
|
||||
delete[] path;
|
||||
}
|
||||
}, path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the dump directory exists before continuing.
|
||||
if (!File::Exists(dumpDirectory)) {
|
||||
if (!File::CreateDir(dumpDirectory)) {
|
||||
ERROR_LOG(Log::sceModule, "Unable to create directory for EBOOT dumping, aborting.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *file = File::OpenCFile(fullPath, "wb");
|
||||
if (!file) {
|
||||
ERROR_LOG(Log::sceModule, "Unable to write decrypted EBOOT.");
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t lengthToWrite = length;
|
||||
|
||||
fwrite(dataPtr, sizeof(u8), lengthToWrite, file);
|
||||
fclose(file);
|
||||
|
||||
INFO_LOG(Log::sceModule, "Successfully wrote %s to %s", DumpFileTypeToString(type), fullPath.c_str());
|
||||
|
||||
char *path = new char[strlen(fullPath.c_str()) + 1];
|
||||
strcpy(path, fullPath.c_str());
|
||||
|
||||
// Re-suing the translation string here.
|
||||
g_OSD.Show(OSDType::MESSAGE_SUCCESS, titleStr, fullPath.ToVisualString(), 5.0f, "decr");
|
||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||
g_OSD.SetClickCallback("decr", [](bool clicked, void *userdata) {
|
||||
char *path = (char *)userdata;
|
||||
if (clicked) {
|
||||
System_ShowFileInFolder(Path(path));
|
||||
} else {
|
||||
delete[] path;
|
||||
}
|
||||
}, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "Common/CommonTypes.h"
|
||||
#include "Common/File/Path.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "Core/ConfigValues.h"
|
||||
|
||||
class MetaFileSystem;
|
||||
class ParamSFOData;
|
||||
|
@ -110,3 +111,6 @@ inline CoreParameter &PSP_CoreParameter() {
|
|||
extern CoreParameter g_CoreParameter;
|
||||
return g_CoreParameter;
|
||||
}
|
||||
|
||||
// Centralized place for dumping useful files, also takes care of checking for dupes and creating a clickable UI popup.
|
||||
void DumpFile(const u8 *dataPtr, const u32 length, const char *name, DumpFileType type);
|
||||
|
|
|
@ -1894,7 +1894,6 @@ void DeveloperToolsScreen::CreateViews() {
|
|||
|
||||
list->Add(new Choice(dev->T("JIT debug tools")))->OnClick.Handle(this, &DeveloperToolsScreen::OnJitDebugTools);
|
||||
list->Add(new CheckBox(&g_Config.bShowDeveloperMenu, dev->T("Show Developer Menu")));
|
||||
list->Add(new CheckBox(&g_Config.bDumpDecryptedEboot, dev->T("Dump Decrypted Eboot", "Dump Decrypted EBOOT.BIN (If Encrypted) When Booting Game")));
|
||||
|
||||
#if !PPSSPP_PLATFORM(UWP)
|
||||
Choice *cpuTests = new Choice(dev->T("Run CPU Tests"));
|
||||
|
@ -1980,6 +1979,10 @@ void DeveloperToolsScreen::CreateViews() {
|
|||
auto displayRefreshRate = list->Add(new PopupSliderChoice(&g_Config.iDisplayRefreshRate, 60, 1000, 60, dev->T("Display refresh rate"), 1, screenManager()));
|
||||
displayRefreshRate->SetFormat(si->T("%d Hz"));
|
||||
|
||||
list->Add(new ItemHeader("Dump file types"));
|
||||
list->Add(new BitCheckBox(&g_Config.iDumpFileTypes, (int)DumpFileType::EBOOT, dev->T("Dump Decrypted Eboot", "Dump Decrypted EBOOT.BIN (If Encrypted) When Booting Game")));
|
||||
list->Add(new BitCheckBox(&g_Config.iDumpFileTypes, (int)DumpFileType::PRX, dev->T("PRX")));
|
||||
|
||||
#if !PPSSPP_PLATFORM(ANDROID) && !PPSSPP_PLATFORM(IOS) && !PPSSPP_PLATFORM(SWITCH)
|
||||
list->Add(new ItemHeader(dev->T("MIPSTracer")));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue