Skip to content

Commit ed7df44

Browse files
bucaneroPharaoh2k
andauthored
Bulk encrypted saves copy enhancement (#209) (#217)
* Bulk encrypted saves copy enhancement (#209) --------- Co-authored-by: Pharaoh2k <5753365+Pharaoh2k@users.noreply.github.com>
1 parent 43611c4 commit ed7df44

2 files changed

Lines changed: 99 additions & 58 deletions

File tree

source/exec_cmd.c

Lines changed: 98 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,15 @@ static int _update_save_details(const char* sys_path, const save_entry_t* save)
176176
LOG("Update Save Details :: Reading %s...", file_path);
177177

178178
sfo_context_t* sfo = sfo_alloc();
179-
if (sfo_read(sfo, file_path) < 0)
179+
if ((sfo_read(sfo, file_path) < 0) || !orbis_UpdateSaveParams(save,
180+
(char*) sfo_get_param_value(sfo, "MAINTITLE"), (char*) sfo_get_param_value(sfo, "SUBTITLE"),
181+
(char*) sfo_get_param_value(sfo, "DETAIL"), *(uint32_t*) sfo_get_param_value(sfo, "SAVEDATA_LIST_PARAM")))
180182
{
181183
LOG("Unable to read from '%s'", file_path);
182184
sfo_free(sfo);
183185
return 0;
184186
}
185187

186-
orbis_UpdateSaveParams(save,
187-
(char*) sfo_get_param_value(sfo, "MAINTITLE"),
188-
(char*) sfo_get_param_value(sfo, "SUBTITLE"),
189-
(char*) sfo_get_param_value(sfo, "DETAIL"),
190-
*(uint32_t*) sfo_get_param_value(sfo, "SAVEDATA_LIST_PARAM"));
191-
192188
sfo_free(sfo);
193189

194190
snprintf(file_path, sizeof(file_path), "%s" "icon0.png", sys_path);
@@ -308,6 +304,70 @@ static int _copy_save_hdd(const save_entry_t* save)
308304
return 1;
309305
}
310306

307+
static int _copy_save_pfs(const save_entry_t* save)
308+
{
309+
char src_path[256];
310+
char hdd_path[256];
311+
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
312+
sfo_patch_t patch = {
313+
.user_id = apollo_config.user_id,
314+
.account_id = apollo_config.account_id,
315+
};
316+
317+
snprintf(src_path, sizeof(src_path), "%s%s.bin", save->path, save->dir_name);
318+
if ((read_file(src_path, (uint8_t*) mount, 0x10) < 0) || get_max_pfskey_ver() < mount[8])
319+
{
320+
LOG("Error: Encrypted save Required firmware: %s", get_fw_by_pfskey_ver(mount[8]));
321+
return (0x80001000 | mount[8]);
322+
}
323+
324+
if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON, mount))
325+
{
326+
LOG("Error: can't create HDD save");
327+
return -1;
328+
}
329+
orbis_SaveUmount(mount);
330+
331+
// Copy the sdimg file
332+
snprintf(src_path, sizeof(src_path), "%s%s", save->path, save->dir_name);
333+
snprintf(hdd_path, sizeof(hdd_path), SAVES_PATH_HDD "%s/sdimg_%s", apollo_config.user_id, save->title_id, save->dir_name);
334+
LOG("Copying <%s> to %s...", src_path, hdd_path);
335+
336+
if (copy_file(src_path, hdd_path) != SUCCESS)
337+
{
338+
LOG("Error: can't copy %s", hdd_path);
339+
return -2;
340+
}
341+
342+
// Copy the .bin file
343+
snprintf(src_path, sizeof(src_path), "%s%s.bin", save->path, save->dir_name);
344+
snprintf(hdd_path, sizeof(hdd_path), SAVES_PATH_HDD "%s/%s.bin", apollo_config.user_id, save->title_id, save->dir_name);
345+
LOG("Copying <%s> to %s...", src_path, hdd_path);
346+
347+
if (copy_file(src_path, hdd_path) != SUCCESS)
348+
{
349+
LOG("Error: can't copy %s", hdd_path);
350+
return -3;
351+
}
352+
353+
// Now remount from HDD to patch SFO
354+
if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR, mount))
355+
{
356+
LOG("Error! Can't mount encrypted save.");
357+
return -4;
358+
}
359+
360+
snprintf(hdd_path, sizeof(hdd_path), APOLLO_SANDBOX_PATH "sce_sys/param.sfo", mount);
361+
patch_sfo(hdd_path, &patch);
362+
363+
*strrchr(hdd_path, 'p') = 0;
364+
_update_save_details(hdd_path, save);
365+
orbis_SaveUmount(mount);
366+
367+
LOG("Encrypted save copied: %s/%s", save->title_id, save->dir_name);
368+
return SUCCESS;
369+
}
370+
311371
static void copySaveHDD(const save_entry_t* save)
312372
{
313373
//source save is already on HDD
@@ -329,7 +389,7 @@ static void copySaveHDD(const save_entry_t* save)
329389

330390
static void copyAllSavesHDD(const save_entry_t* save, int all)
331391
{
332-
int err_count = 0;
392+
int done = 0, err_count = 0;
333393
list_node_t *node;
334394
save_entry_t *item;
335395
uint64_t progress = 0;
@@ -341,16 +401,19 @@ static void copyAllSavesHDD(const save_entry_t* save, int all)
341401
for (node = list_head(list); (item = list_get(node)); node = list_next(node))
342402
{
343403
update_progress_bar(progress++, list_count(list), item->name);
344-
if (item->type == FILE_TYPE_PS4 && !(item->flags & SAVE_FLAG_LOCKED) && (all || item->flags & SAVE_FLAG_SELECTED))
345-
err_count += ! _copy_save_hdd(item);
404+
405+
if (item->type != FILE_TYPE_PS4 || !(all || (item->flags & SAVE_FLAG_SELECTED)))
406+
continue;
407+
408+
if (item->flags & SAVE_FLAG_LOCKED)
409+
(_copy_save_pfs(item) == SUCCESS) ? done++ : err_count++;
410+
else
411+
_copy_save_hdd(item) ? done++ : err_count++;
346412
}
347413

348414
end_progress_bar();
349415

350-
if (err_count)
351-
show_message("Error: %d Saves couldn't be copied to HDD", err_count);
352-
else
353-
show_message("All Saves copied to HDD");
416+
show_message("%d/%d Saves copied to HDD", done, done+err_count);
354417
}
355418

356419
void extractArchive(const char* file_path)
@@ -560,62 +623,39 @@ static void activateAccount(int user)
560623

561624
static void copySavePFS(const save_entry_t* save)
562625
{
563-
char src_path[256];
564626
char hdd_path[256];
565-
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
566-
sfo_patch_t patch = {
567-
.user_id = apollo_config.user_id,
568-
.account_id = apollo_config.account_id,
569-
};
570627

571-
snprintf(src_path, sizeof(src_path), "%s%s.bin", save->path, save->dir_name);
572-
if ((read_file(src_path, (uint8_t*) mount, 0x10) < 0) || get_max_pfskey_ver() < mount[8])
573-
{
574-
show_message("Error: Encrypted save from a newer firmware version!\n\n"
575-
"Required firmware: %s", get_fw_by_pfskey_ver(mount[8]));
628+
snprintf(hdd_path, sizeof(hdd_path), SAVES_PATH_HDD "%s/%s.bin", apollo_config.user_id, save->title_id, save->dir_name);
629+
if (file_exists(hdd_path) == SUCCESS && !show_dialog(DIALOG_TYPE_YESNO,
630+
"Save game already exists:\n%s/%s\n\nOverwrite?", save->title_id, save->dir_name))
576631
return;
577-
}
578632

579-
if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON, mount))
633+
switch (_copy_save_pfs(save))
580634
{
635+
case SUCCESS:
636+
show_message("Encrypted save copied successfully!\n%s/%s", save->title_id, save->dir_name);
637+
return;
638+
639+
case -1:
581640
show_message("Error: can't create HDD save");
582641
return;
583-
}
584-
orbis_SaveUmount(mount);
585642

586-
snprintf(src_path, sizeof(src_path), "%s%s", save->path, save->dir_name);
587-
snprintf(hdd_path, sizeof(hdd_path), SAVES_PATH_HDD "%s/sdimg_%s", apollo_config.user_id, save->title_id, save->dir_name);
588-
LOG("Copying <%s> to %s...", src_path, hdd_path);
589-
if (copy_file(src_path, hdd_path) != SUCCESS)
590-
{
591-
show_message("Error: can't copy %s", hdd_path);
643+
case -2:
644+
show_message("Error: can't copy file\n%s%s", save->path, save->dir_name);
592645
return;
593-
}
594646

595-
snprintf(src_path, sizeof(src_path), "%s%s.bin", save->path, save->dir_name);
596-
snprintf(hdd_path, sizeof(hdd_path), SAVES_PATH_HDD "%s/%s.bin", apollo_config.user_id, save->title_id, save->dir_name);
597-
LOG("Copying <%s> to %s...", src_path, hdd_path);
598-
if (copy_file(src_path, hdd_path) != SUCCESS)
599-
{
600-
show_message("Error: can't copy %s", hdd_path);
647+
case -3:
648+
show_message("Error: can't copy file\n%s%s.bin", save->path, save->dir_name);
601649
return;
602-
}
603650

604-
if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR, mount))
605-
{
651+
case -4:
606652
show_message("Error! Can't mount encrypted save.\n(incompatible save-game firmware version)");
607653
return;
608-
}
609654

610-
snprintf(hdd_path, sizeof(hdd_path), APOLLO_SANDBOX_PATH "sce_sys/param.sfo", mount);
611-
patch_sfo(hdd_path, &patch);
612-
613-
*strrchr(hdd_path, 'p') = 0;
614-
_update_save_details(hdd_path, save);
615-
orbis_SaveUmount(mount);
616-
617-
show_message("Encrypted save copied successfully!\n%s/%s", save->title_id, save->dir_name);
618-
return;
655+
default:
656+
show_message("Error: can't copy save %s", save->title_id);
657+
return;
658+
}
619659
}
620660

621661
static void copyKeystone(const save_entry_t* entry, int import)
@@ -831,6 +871,7 @@ static void enableWebServer(dWebReqHandler_t handler, void* data, int port)
831871

832872
static void copyAllSavesUSB(const save_entry_t* save, const char* dst_path, int all)
833873
{
874+
int done = 0, err_count = 0;
834875
char copy_path[256];
835876
char save_path[256];
836877
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
@@ -860,13 +901,13 @@ static void copyAllSavesUSB(const save_entry_t* save, const char* dst_path, int
860901
snprintf(copy_path, sizeof(copy_path), "%s%08x_%s_%s/", dst_path, apollo_config.user_id, item->title_id, item->dir_name);
861902

862903
LOG("Copying <%s> to %s...", save_path, copy_path);
863-
copy_directory(save_path, save_path, copy_path);
904+
(copy_directory(save_path, save_path, copy_path) == SUCCESS) ? done++ : err_count++;
864905

865906
orbis_SaveUmount(mount);
866907
}
867908

868909
end_progress_bar();
869-
show_message("All Saves copied to:\n%s", dst_path);
910+
show_message("%d/%d Saves copied to:\n%s", done, done+err_count, dst_path);
870911
}
871912

872913
static void exportAllSavesVMC(const save_entry_t* save, int dev, int all)

source/saves.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ list_t * ReadUsbList(const char* userPath)
17571757
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_COPY " Copy selected Saves to HDD", CMD_COPY_SAVES_HDD);
17581758
list_append(item->codes, cmd);
17591759

1760-
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_COPY " Copy all decrypted Saves to HDD", CMD_COPY_ALL_SAVES_HDD);
1760+
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_COPY " Copy all Saves to HDD", CMD_COPY_ALL_SAVES_HDD);
17611761
list_append(item->codes, cmd);
17621762

17631763
cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_NET " Start local Web Server", CMD_SAVE_WEBSERVER);

0 commit comments

Comments
 (0)