Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete saves option #196

Merged
merged 2 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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