Add support for importing title seeds.

This commit is contained in:
Steven Smith 2016-05-07 22:57:15 -07:00
parent c2ac82f074
commit f08e517906
9 changed files with 102 additions and 1 deletions

View File

@ -234,4 +234,46 @@ void util_get_parent_path(char* out, const char* path, u32 size) {
u32 terminatorPos = end - path + 1 < size - 1 ? end - path + 1 : size - 1;
strncpy(out, path, terminatorPos);
out[terminatorPos] = '\0';
}
static Result FSUSER_AddSeed(u64 titleId, const void* seed) {
u32 *cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = 0x087a0180;
cmdbuf[1] = (u32) (titleId & 0xFFFFFFFF);
cmdbuf[2] = (u32) (titleId >> 32);
memcpy(&cmdbuf[3], seed, 16);
Result ret = 0;
if(R_FAILED(ret = svcSendSyncRequest(*fsGetSessionHandle()))) return ret;
ret = cmdbuf[1];
return ret;
}
Result util_import_seed(u64 titleId) {
char pathBuf[64];
snprintf(pathBuf, 64, "/fbi/seed/%016llX.dat", titleId);
Result res = 0;
FS_Path* fsPath = util_make_path_utf8(pathBuf);
if(fsPath != NULL) {
Handle fileHandle = 0;
if(R_SUCCEEDED(res = FSUSER_OpenFileDirectly(&fileHandle, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""), *fsPath, FS_OPEN_READ, 0))) {
u32 bytesRead = 0;
u8 seed[16];
if(R_SUCCEEDED(res = FSFILE_Read(fileHandle, &bytesRead, 0, seed, sizeof(seed)))) {
res = FSUSER_AddSeed(titleId, seed);
}
FSFILE_Close(fileHandle);
}
util_free_path_utf8(fsPath);
} else {
res = R_FBI_OUT_OF_MEMORY;
}
return res;
}

View File

@ -49,4 +49,6 @@ bool util_is_dir(FS_Archive archive, const char* path);
Result util_ensure_dir(FS_Archive archive, const char* path);
void util_get_path_file(char* out, const char* path, u32 size);
void util_get_parent_path(char* out, const char* path, u32 size);
void util_get_parent_path(char* out, const char* path, u32 size);
Result util_import_seed(u64 titleId);

View File

@ -36,6 +36,7 @@ void action_install_cdn_noprompt(volatile bool* done, ticket_info* info, bool fi
void action_delete_title(linked_list* items, list_item* selected);
void action_launch_title(linked_list* items, list_item* selected);
void action_extract_smdh(linked_list* items, list_item* selected);
void action_import_seed(linked_list* items, list_item* selected);
void action_browse_title_save_data(linked_list* items, list_item* selected);
void action_import_secure_value(linked_list* items, list_item* selected);
void action_export_secure_value(linked_list* items, list_item* selected);

View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <3ds.h>
#include "action.h"
#include "../task/task.h"
#include "../../error.h"
#include "../../info.h"
#include "../../list.h"
#include "../../prompt.h"
#include "../../ui.h"
#include "../../../core/linkedlist.h"
#include "../../../core/screen.h"
#include "../../../core/util.h"
static void action_import_seed_update(ui_view* view, void* data, float* progress, char* text) {
title_info* info = (title_info*) data;
Result res = util_import_seed(info->titleId);
ui_pop();
info_destroy(view);
if(R_SUCCEEDED(res)) {
prompt_display("Success", "Seed imported.", COLOR_TEXT, false, info, NULL, ui_draw_title_info, NULL);
} else {
error_display_res(NULL, info, ui_draw_title_info, res, "Failed to import seed.");
}
}
static void action_import_seed_onresponse(ui_view* view, void* data, bool response) {
if(response) {
info_display("Importing Seed", "", false, data, action_import_seed_update, ui_draw_title_info);
}
}
void action_import_seed(linked_list* items, list_item* selected) {
prompt_display("Confirmation", "Import the seed of the selected title?", COLOR_TEXT, true, selected->data, NULL, ui_draw_title_info, action_import_seed_onresponse);
}

View File

@ -12,6 +12,7 @@
#include "../../ui.h"
#include "../../../core/linkedlist.h"
#include "../../../core/screen.h"
#include "../../../core/util.h"
#define CONTENTS_MAX 64
@ -181,6 +182,8 @@ static void action_install_cdn_update(ui_view* view, void* data, float* progress
if(R_SUCCEEDED(installData->installInfo.result)) {
if(R_SUCCEEDED(res = AM_InstallTitleFinish())
&& R_SUCCEEDED(res = AM_CommitImportTitles(((installData->ticket->titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD, 1, false, &installData->ticket->titleId))) {
util_import_seed(installData->ticket->titleId);
if(installData->ticket->titleId == 0x0004013800000002 || installData->ticket->titleId == 0x0004013820000002) {
res = AM_InstallFirm(installData->ticket->titleId);
}

View File

@ -156,6 +156,8 @@ static Result action_install_cias_close_dst(void* data, u32 index, bool succeede
Result res = 0;
if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) {
util_import_seed(installData->currTitleId);
if(installData->currTitleId == 0x0004013800000002 || installData->currTitleId == 0x0004013820000002) {
res = AM_InstallFirm(installData->currTitleId);
}

View File

@ -16,6 +16,7 @@
#include "../prompt.h"
#include "../ui.h"
#include "../../core/screen.h"
#include "../../core/util.h"
typedef struct {
int serverSocket;
@ -171,6 +172,8 @@ static Result networkinstall_close_dst(void* data, u32 index, bool succeeded, u3
}
} else {
if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) {
util_import_seed(networkInstallData->currTitleId);
if(networkInstallData->currTitleId == 0x0004013800000002 || networkInstallData->currTitleId == 0x0004013820000002) {
res = AM_InstallFirm(networkInstallData->currTitleId);
}

View File

@ -12,6 +12,7 @@
#include "../prompt.h"
#include "../ui.h"
#include "../../core/screen.h"
#include "../../core/util.h"
#include "../../quirc/quirc_internal.h"
#define IMAGE_WIDTH 400
@ -171,6 +172,8 @@ static Result qrinstall_close_dst(void* data, u32 index, bool succeeded, u32 han
}
} else {
if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) {
util_import_seed(qrInstallData->currTitleId);
if(qrInstallData->currTitleId == 0x0004013800000002 || qrInstallData->currTitleId == 0x0004013820000002) {
res = AM_InstallFirm(qrInstallData->currTitleId);
}

View File

@ -15,6 +15,7 @@
static list_item launch_title = {"Launch Title", COLOR_TEXT, action_launch_title};
static list_item delete_title = {"Delete Title", COLOR_TEXT, action_delete_title};
static list_item extract_smdh = {"Extract SMDH", COLOR_TEXT, action_extract_smdh};
static list_item import_seed = {"Import Seed", COLOR_TEXT, action_import_seed};
static list_item browse_save_data = {"Browse Save Data", COLOR_TEXT, action_browse_title_save_data};
static list_item import_secure_value = {"Import Secure Value", COLOR_TEXT, action_import_secure_value};
static list_item export_secure_value = {"Export Secure Value", COLOR_TEXT, action_export_secure_value};
@ -71,6 +72,11 @@ static void titles_action_update(ui_view* view, void* data, linked_list* items,
if(!info->twl) {
linked_list_add(items, &extract_smdh);
if(info->mediaType != MEDIATYPE_GAME_CARD) {
linked_list_add(items, &import_seed);
}
linked_list_add(items, &browse_save_data);
if(info->mediaType != MEDIATYPE_GAME_CARD) {