Skip to content

Commit

Permalink
Delete saves option (#196)
Browse files Browse the repository at this point in the history
* delete saves
* improve encrypted saves
  • Loading branch information
bucanero authored Dec 18, 2024
1 parent 5863fdb commit 8e80063
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 50 deletions.
2 changes: 0 additions & 2 deletions include/menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,10 @@ void drawEndLogo(void);

int load_app_settings(app_config_t* config);
int save_app_settings(app_config_t* config);
int reset_app_settings(app_config_t* config);

int initialize_jbc(void);
void terminate_jbc(void);
int initVshDataMount(void);
int get_max_pfskey_ver(void);
char* get_fw_by_pfskey_ver(int key_ver);

#endif
4 changes: 3 additions & 1 deletion include/saves.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ enum cmd_code_enum
CMD_HEX_EDIT_FILE,
CMD_COPY_PFS,
CMD_IMPORT_DATA_FILE,
CMD_DELETE_VMCSAVE,
CMD_DELETE_SAVE,

// Bulk commands
CMD_RESIGN_SAVES,
Expand Down Expand Up @@ -312,6 +312,7 @@ int regMgr_SetAccountId(int userNumber, uint64_t* psnAccountId);
int get_save_details(const save_entry_t *save, char** details);
int orbis_SaveUmount(const char* mountPath);
int orbis_SaveMount(const save_entry_t *save, uint32_t mode, char* mountPath);
int orbis_SaveDelete(const save_entry_t *save);
int orbis_UpdateSaveParams(const save_entry_t* save, const char* title, const char* subtitle, const char* details, uint32_t up);

int vmc_export_psv(const char* save, const char* out_path);
Expand All @@ -329,3 +330,4 @@ int vmp_resign(const char *src_vmp);

char* sjis2utf8(char* input);
uint8_t* getIconPS2(const char* folder, const char* iconfile);
const char* get_fw_by_pfskey_ver(int key_ver);
7 changes: 7 additions & 0 deletions source/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ int clean_directory(const char* inputdir)
if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0)
{
snprintf(dataPath, sizeof(dataPath), "%s" "%s", inputdir, dir->d_name);

if (dir->d_type == DT_DIR) {
strcat(dataPath, "/");
clean_directory(dataPath);
rmdir(dataPath);
}

unlink_secure(dataPath);
}
}
Expand Down
50 changes: 37 additions & 13 deletions source/exec_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ static void copySavePFS(const save_entry_t* save)

if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON, mount))
{
LOG("[!] Error: can't create/mount save!");
show_message("Error: can't create HDD save");
return;
}
orbis_SaveUmount(mount);
Expand All @@ -476,7 +476,6 @@ static void copySavePFS(const save_entry_t* save)

if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR, mount))
{
LOG("[!] Error: can't remount save");
show_message("Error! Can't mount encrypted save.\n(incompatible save-game firmware version)");
return;
}
Expand Down Expand Up @@ -638,9 +637,9 @@ static int webReqHandler(dWebRequest_t* req, dWebResponse_t* res, void* list)
{
base = strdup(item->path);
path = strdup(item->path);
*strrchr(base, '/') = 0;
}
*strrchr(base, '/') = 0;
*strrchr(base, '/') = 0;

id = zip_directory(base, path, res->data);
if (item->flags & SAVE_FLAG_HDD)
Expand Down Expand Up @@ -673,7 +672,7 @@ static int webReqHandler(dWebRequest_t* req, dWebResponse_t* res, void* list)
// http://ps3-ip:8080/icon/CUSA12345-DIR-NAME/sce_sys/icon0.png
if (wildcard_match(req->resource, "/icon/*/sce_sys/icon0.png"))
{
asprintf(&res->data, "%sAPOLLO/%s", selected_entry->path, req->resource + 6);
asprintf(&res->data, "%sPS4/APOLLO/%s", selected_entry->path, req->resource + 6);
return (file_exists(res->data) == SUCCESS);
}

Expand Down Expand Up @@ -891,14 +890,37 @@ static void import_save2vmc(const char* src, int type)
show_message("Error importing save:\n%s", src);
}

static int deleteVmcSave(const save_entry_t* save)
static int deleteSave(const save_entry_t* save)
{
int ret;
int ret = 0;
char fpath[256];

if (!show_dialog(DIALOG_TYPE_YESNO, "Do you want to delete %s?", save->dir_name))
return 0;

ret = (save->flags & SAVE_FLAG_PS1) ? formatSave(save->blocks) : vmc_delete_save(save->dir_name);
if (save->flags & SAVE_FLAG_PS1)
ret = formatSave(save->blocks);

else if (save->flags & SAVE_FLAG_PS2)
ret = vmc_delete_save(save->dir_name);

else if (save->flags & SAVE_FLAG_PS4)
{
if (save->flags & SAVE_FLAG_HDD)
ret = orbis_SaveDelete(save);

else if (save->flags & SAVE_FLAG_LOCKED)
{
snprintf(fpath, sizeof(fpath), "%s%s.bin", save->path, save->dir_name);
ret = (unlink_secure(fpath) == SUCCESS);

snprintf(fpath, sizeof(fpath), "%s%s", save->path, save->dir_name);
ret &= (unlink_secure(fpath) == SUCCESS);
}
else
ret = (clean_directory(save->path) == SUCCESS);
}

if (ret)
show_message("Save successfully deleted:\n%s", save->dir_name);
else
Expand Down Expand Up @@ -1298,11 +1320,13 @@ static void toggleBrowserHistory(int usr)

void execCodeCommand(code_entry_t* code, const char* codecmd)
{
char *tmp, mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
char *tmp = NULL;
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];

if (selected_entry->flags & SAVE_FLAG_HDD)
if (selected_entry->flags & (SAVE_FLAG_HDD|SAVE_FLAG_LOCKED) &&
codecmd[0] != CMD_DELETE_SAVE && codecmd[0] != CMD_COPY_PFS)
{
if (!orbis_SaveMount(selected_entry, (selected_entry->flags & SAVE_FLAG_TROPHY), mount))
if (!orbis_SaveMount(selected_entry, selected_entry->flags & (SAVE_FLAG_TROPHY|SAVE_FLAG_LOCKED), mount))
{
LOG("Error Mounting Save! Check Save Mount Patches");
return;
Expand Down Expand Up @@ -1493,8 +1517,8 @@ void execCodeCommand(code_entry_t* code, const char* codecmd)
code->activated = 0;
break;

case CMD_DELETE_VMCSAVE:
if (deleteVmcSave(selected_entry))
case CMD_DELETE_SAVE:
if (deleteSave(selected_entry))
selected_entry->flags |= SAVE_FLAG_UPDATED;
else
code->activated = 0;
Expand Down Expand Up @@ -1531,7 +1555,7 @@ void execCodeCommand(code_entry_t* code, const char* codecmd)
break;
}

if (selected_entry->flags & SAVE_FLAG_HDD)
if (tmp)
{
orbis_SaveUmount(mount);
free(selected_entry->path);
Expand Down
31 changes: 22 additions & 9 deletions source/menu_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,16 +161,29 @@ static void SetMenu(int id)
break;

case MENU_PATCHES: //Cheat Selection Menu
if (selected_entry->flags & SAVE_FLAG_UPDATED && id == MENU_PS2VMC_SAVES)
{
selected_entry->flags ^= SAVE_FLAG_UPDATED;
ReloadUserSaves(&vmc2_saves);
}
else if (selected_entry->flags & SAVE_FLAG_UPDATED && id == MENU_PS1VMC_SAVES)
if (selected_entry->flags & SAVE_FLAG_UPDATED)
{
switch (id)
{
case MENU_PS2VMC_SAVES:
ReloadUserSaves(&vmc2_saves);
break;

case MENU_PS1VMC_SAVES:
saveMemoryCard(vmc1_saves.path, 0, 0);
ReloadUserSaves(&vmc1_saves);
break;

case MENU_HDD_SAVES:
ReloadUserSaves(&hdd_saves);
break;

case MENU_USB_SAVES:
ReloadUserSaves(&usb_saves);
break;
}

selected_entry->flags ^= SAVE_FLAG_UPDATED;
saveMemoryCard(vmc1_saves.path, 0, 0);
ReloadUserSaves(&vmc1_saves);
}
break;

Expand Down Expand Up @@ -813,7 +826,7 @@ static void doPatchMenu(void)
return;
}

if (selected_centry->codes[0] == CMD_DELETE_VMCSAVE)
if (selected_centry->codes[0] == CMD_DELETE_SAVE)
{
selected_centry->activated = 0;
SetMenu(last_menu_id[MENU_PATCHES]);
Expand Down
4 changes: 2 additions & 2 deletions source/orbis_jbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ int get_max_pfskey_ver(void)
return 0;
}

char* get_fw_by_pfskey_ver(int key_ver)
const char* get_fw_by_pfskey_ver(int key_ver)
{
char* fw[] = {"???", "Any", "4.50+", "4.70+", "5.00+", "5.50+", "6.00+", "6.50+", "7.00+", "7.50+", "8.00+"};
const char* fw[] = {"???", "Any", "4.50+", "4.70+", "5.00+", "5.50+", "6.00+", "6.50+", "7.00+", "7.50+", "8.00+"};
if (key_ver > 10) key_ver = 0;

return fw[key_ver];
Expand Down
79 changes: 56 additions & 23 deletions source/saves.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,9 @@ static void _addBackupCommands(save_entry_t* item)
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_USER " View Save Details", CMD_VIEW_DETAILS);
list_append(item->codes, cmd);

cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_WARN " Delete Save Game", CMD_DELETE_SAVE);
list_append(item->codes, cmd);

cmd = _createCmdCode(PATCH_NULL, "----- " UTF8_CHAR_STAR " File Backup " UTF8_CHAR_STAR " -----", CMD_CODE_NULL);
list_append(item->codes, cmd);

Expand All @@ -728,7 +731,7 @@ static void _addBackupCommands(save_entry_t* item)
if (!(item->flags & SAVE_FLAG_HDD))
{
asprintf(&cmd->options->name[2], "Copy Save to HDD");
asprintf(&cmd->options->value[2], "%c", CMD_COPY_SAVE_HDD);
asprintf(&cmd->options->value[2], "%c", (item->flags & SAVE_FLAG_LOCKED) ? CMD_COPY_PFS : CMD_COPY_SAVE_HDD);
}
list_append(item->codes, cmd);

Expand Down Expand Up @@ -840,12 +843,19 @@ static void _addSfoCommands(save_entry_t* save)

static int set_pfs_codes(save_entry_t* item)
{
uint8_t data[16];
char savePath[256];
code_entry_t* cmd;
item->codes = list_alloc();

cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_USER " View Save Details", CMD_VIEW_DETAILS);
list_append(item->codes, cmd);
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_COPY " Copy Save game to HDD", CMD_COPY_PFS);

snprintf(savePath, sizeof(savePath), "%s%s.bin", item->path, item->dir_name);
read_file(savePath, data, sizeof(data));
snprintf(savePath, sizeof(savePath), CHAR_ICON_WARN " --- Encrypted save requires firmware %s --- " CHAR_ICON_WARN, get_fw_by_pfskey_ver(data[8]));

cmd = _createCmdCode(PATCH_NULL, savePath, CMD_CODE_NULL);
list_append(item->codes, cmd);

return list_count(item->codes);
Expand All @@ -872,18 +882,18 @@ int ReadCodes(save_entry_t * save)
char filePath[256];
char * buffer = NULL;
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
char *tmp;
char *tmp = NULL;

if (save->flags & SAVE_FLAG_LOCKED)
if (save->type == FILE_TYPE_NULL)
return set_pfs_codes(save);

save->codes = list_alloc();

if (save->flags & SAVE_FLAG_HDD)
if (save->flags & (SAVE_FLAG_HDD|SAVE_FLAG_LOCKED))
{
if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY, mount))
if (!orbis_SaveMount(save, (save->flags & SAVE_FLAG_LOCKED), mount))
{
code = _createCmdCode(PATCH_NULL, CHAR_ICON_WARN " --- Error Mounting Save! Check Save Mount Patches --- " CHAR_ICON_WARN, CMD_CODE_NULL);
code = _createCmdCode(PATCH_NULL, CHAR_ICON_WARN " --- Error Mounting Save! --- " CHAR_ICON_WARN, CMD_CODE_NULL);
list_append(save->codes, code);
return list_count(save->codes);
}
Expand Down Expand Up @@ -911,7 +921,7 @@ int ReadCodes(save_entry_t * save)
LOG("Loaded %zu codes", list_count(save->codes));

skip_end:
if (save->flags & SAVE_FLAG_HDD)
if (tmp)
{
orbis_SaveUmount(mount);
free(save->path);
Expand Down Expand Up @@ -1107,7 +1117,7 @@ int ReadVmc1Codes(save_entry_t * save)
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_USER " View Save Details", CMD_VIEW_DETAILS);
list_append(save->codes, cmd);

cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_WARN " Delete Save Game", CMD_DELETE_VMCSAVE);
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_WARN " Delete Save Game", CMD_DELETE_SAVE);
list_append(save->codes, cmd);

cmd = _createCmdCode(PATCH_NULL, "----- " UTF8_CHAR_STAR " Save Game Backup " UTF8_CHAR_STAR " -----", CMD_CODE_NULL);
Expand Down Expand Up @@ -1243,7 +1253,7 @@ int ReadVmc2Codes(save_entry_t * save)
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_USER " View Save Details", CMD_VIEW_DETAILS);
list_append(save->codes, cmd);

cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_WARN " Delete Save Game", CMD_DELETE_VMCSAVE);
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_WARN " Delete Save Game", CMD_DELETE_SAVE);
list_append(save->codes, cmd);

cmd = _createCmdCode(PATCH_NULL, "----- " UTF8_CHAR_STAR " Save Game Backup " UTF8_CHAR_STAR " -----", CMD_CODE_NULL);
Expand Down Expand Up @@ -1678,8 +1688,9 @@ static void read_usb_encrypted_saves(const char* userPath, list_t *list, uint64_
{
DIR *d, *d2;
struct dirent *dir, *dir2;
save_entry_t *item;
save_entry_t *item, tmp;
char savePath[256];
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];

d = opendir(userPath);

Expand All @@ -1704,30 +1715,51 @@ static void read_usb_encrypted_saves(const char* userPath, list_t *list, uint64_
if (dir2->d_type != DT_REG || endsWith(dir2->d_name, ".bin"))
continue;

snprintf(savePath, sizeof(savePath), "%s%s/%s.bin", userPath, dir->d_name, dir2->d_name);
if (file_exists(savePath) != SUCCESS)
snprintf(savePath, sizeof(savePath), "%s%s/", userPath, dir->d_name);
tmp.path = savePath;
tmp.title_id = dir->d_name;
tmp.dir_name = dir2->d_name;
if (!orbis_SaveMount(&tmp, SAVE_FLAG_LOCKED, mount))
{
snprintf(savePath, sizeof(savePath), CHAR_ICON_WARN "%s/%s", dir->d_name, dir2->d_name);
item = _createSaveEntry(SAVE_FLAG_PS4 | SAVE_FLAG_LOCKED, savePath);
item->type = FILE_TYPE_NULL;
item->dir_name = strdup(dir2->d_name);
asprintf(&item->path, "%s%s/", userPath, dir->d_name);
asprintf(&item->title_id, "%.9s", dir->d_name);
list_append(list, item);
continue;
}

snprintf(savePath, sizeof(savePath), APOLLO_SANDBOX_PATH "sce_sys/param.sfo", mount);
LOG("Reading %s...", savePath);

sfo_context_t* sfo = sfo_alloc();
if (sfo_read(sfo, savePath) < 0) {
LOG("Unable to read from '%s'", savePath);
sfo_free(sfo);
continue;
}

snprintf(savePath, sizeof(savePath), "(Encrypted) %s/%s", dir->d_name, dir2->d_name);
snprintf(savePath, sizeof(savePath), "%s - %s", sfo_get_param_value(sfo, "MAINTITLE"), sfo_get_param_value(sfo, "SUBTITLE"));
item = _createSaveEntry(SAVE_FLAG_PS4 | SAVE_FLAG_LOCKED, savePath);
item->type = FILE_TYPE_PS4;

item->dir_name = strdup(dir2->d_name);
asprintf(&item->path, "%s%s/", userPath, dir->d_name);
asprintf(&item->title_id, "%.9s", dir->d_name);
item->dir_name = strdup(dir2->d_name);

if (apollo_config.account_id == account)
uint64_t* int_data = (uint64_t*) sfo_get_param_value(sfo, "ACCOUNT_ID");
if (int_data && (apollo_config.account_id == *int_data))
item->flags |= SAVE_FLAG_OWNER;

snprintf(savePath, sizeof(savePath), "%s%s/%s", userPath, dir->d_name, dir2->d_name);

uint64_t size = 0;
get_file_size(savePath, &size);
item->blocks = size / ORBIS_SAVE_DATA_BLOCK_SIZE;
int_data = (uint64_t*) sfo_get_param_value(sfo, "SAVEDATA_BLOCKS");
item->blocks = (*int_data);

sfo_free(sfo);
orbis_SaveUmount(mount);

LOG("[%s] F(%X) name '%s'", item->title_id, item->flags, item->name);
list_append(list, item);

}
closedir(d2);
}
Expand Down Expand Up @@ -2127,6 +2159,7 @@ static void _ReadOnlineListEx(const char* urlPath, uint16_t flag, list_t *list)
{
*tmp++ = 0;
item = _createSaveEntry(flag | SAVE_FLAG_ONLINE, tmp);
item->type = FILE_TYPE_ZIP;
item->title_id = strdup(content);
asprintf(&item->path, "%s%s/", urlPath, item->title_id);

Expand Down

0 comments on commit 8e80063

Please sign in to comment.