diff --git a/source/ui/section/action/installcdn.c b/source/ui/section/action/installcdn.c index 558efe4..aed4f6c 100644 --- a/source/ui/section/action/installcdn.c +++ b/source/ui/section/action/installcdn.c @@ -256,6 +256,37 @@ static void action_install_cdn_update(ui_view* view, void* data, float* progress snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s", installData->installInfo.processed, installData->installInfo.total, util_get_display_size(installData->installInfo.currProcessed), util_get_display_size_units(installData->installInfo.currProcessed), util_get_display_size(installData->installInfo.currTotal), util_get_display_size_units(installData->installInfo.currTotal)); } +static void action_install_cdn_start(install_cdn_data* data) { + FS_MediaType dest = ((data->ticket->titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; + + AM_DeleteTitle(dest, data->ticket->titleId); + if(dest == MEDIATYPE_SD) { + AM_QueryAvailableExternalTitleDatabase(NULL); + } + + Result res = 0; + + if(R_SUCCEEDED(res = AM_InstallTitleBegin(dest, data->ticket->titleId, false))) { + if(R_SUCCEEDED(res = task_data_op(&data->installInfo))) { + info_display("Installing CDN Title", "Press B to cancel.", true, data, action_install_cdn_update, action_install_cdn_draw_top); + } else { + AM_InstallTitleAbort(); + } + } + + if(R_FAILED(res)) { + error_display_res(data->ticket, ui_draw_ticket_info, res, "Failed to initiate CDN title installation."); + + action_install_cdn_free_data(data); + } +} + +static void action_install_cdn_n3ds_onresponse(ui_view* view, void* data, bool response) { + if(response) { + action_install_cdn_start((install_cdn_data*) data); + } +} + static void action_install_cdn_internal(volatile bool* done, ticket_info* info, bool finishedPrompt, char* tmdVersion) { install_cdn_data* data = (install_cdn_data*) calloc(1, sizeof(install_cdn_data)); if(data == NULL) { @@ -310,32 +341,11 @@ static void action_install_cdn_internal(volatile bool* done, ticket_info* info, data->installInfo.finished = true; - Result res = 0; - bool n3ds = false; - if(R_FAILED(APT_CheckNew3DS(&n3ds)) || n3ds || ((data->ticket->titleId >> 28) & 0xF) != 2) { - FS_MediaType dest = ((data->ticket->titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; - - AM_DeleteTitle(dest, data->ticket->titleId); - if(dest == MEDIATYPE_SD) { - AM_QueryAvailableExternalTitleDatabase(NULL); - } - - if(R_SUCCEEDED(res = AM_InstallTitleBegin(dest, data->ticket->titleId, false))) { - if(R_SUCCEEDED(res = task_data_op(&data->installInfo))) { - info_display("Installing CDN Title", "Press B to cancel.", true, data, action_install_cdn_update, action_install_cdn_draw_top); - } else { - AM_InstallTitleAbort(); - } - } + if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((data->ticket->titleId >> 28) & 0xF) == 2) { + prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, action_install_cdn_draw_top, action_install_cdn_n3ds_onresponse); } else { - res = R_FBI_WRONG_SYSTEM; - } - - if(R_FAILED(res)) { - error_display_res(data->ticket, ui_draw_ticket_info, res, "Failed to initiate CDN title installation."); - - action_install_cdn_free_data(data); + action_install_cdn_start(data); } } diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index b887b16..538d9e7 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -24,10 +24,15 @@ typedef struct { bool delete; u64 currTitleId; + volatile bool n3dsContinue; data_op_data installInfo; } install_cias_data; +static void action_install_cias_n3ds_onresponse(ui_view* view, void* data, bool response) { + ((install_cias_data*) data)->n3dsContinue = response; +} + static void action_install_cias_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2) { install_cias_data* installData = (install_cias_data*) data; @@ -112,13 +117,23 @@ static Result action_install_cias_read_src(void* data, u32 handle, u32* bytesRea static Result action_install_cias_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) { install_cias_data* installData = (install_cias_data*) data; + installData->currTitleId = 0; + installData->n3dsContinue = false; + u64 titleId = util_get_cia_title_id((u8*) initialReadBlock); FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; bool n3ds = false; if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { - return R_FBI_WRONG_SYSTEM; + ui_view* view = prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, action_install_cias_draw_top, action_install_cias_n3ds_onresponse); + if(view != NULL) { + svcWaitSynchronization(view->active, U64_MAX); + } + + if(!installData->n3dsContinue) { + return R_FBI_WRONG_SYSTEM; + } } // Deleting FBI before it reinstalls itself causes issues. @@ -152,8 +167,6 @@ static Result action_install_cias_close_dst(void* data, u32 index, bool succeede } } - installData->currTitleId = 0; - return res; } else { return AM_CancelCIAInstall(handle); @@ -186,7 +199,7 @@ bool action_install_cias_error(void* data, u32 index, Result res) { if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Install cancelled.", COLOR_TEXT, false, NULL, NULL, NULL); return false; - } else { + } else if(res != R_FBI_WRONG_SYSTEM) { ui_view* view = error_display_res(data, action_install_cias_draw_top, res, "Failed to install CIA file."); if(view != NULL) { svcWaitSynchronization(view->active, U64_MAX); @@ -261,6 +274,7 @@ static void action_install_cias_internal(linked_list* items, list_item* selected data->delete = delete; data->currTitleId = 0; + data->n3dsContinue = false; data->installInfo.data = data; diff --git a/source/ui/section/networkinstall.c b/source/ui/section/networkinstall.c index 1784d19..4e199f2 100644 --- a/source/ui/section/networkinstall.c +++ b/source/ui/section/networkinstall.c @@ -27,6 +27,7 @@ typedef struct { bool ticket; u64 currTitleId; + volatile bool n3dsContinue; ticket_info ticketInfo; data_op_data installInfo; @@ -63,6 +64,10 @@ static void networkinstall_cdn_check_onresponse(ui_view* view, void* data, bool qrInstallData->cdnDecided = true; } +static void networkinstall_n3ds_onresponse(ui_view* view, void* data, bool response) { + ((network_install_data*) data)->n3dsContinue = response; +} + static Result networkinstall_is_src_directory(void* data, u32 index, bool* isDirectory) { *isDirectory = false; return 0; @@ -118,6 +123,7 @@ static Result networkinstall_open_dst(void* data, u32 index, void* initialReadBl networkInstallData->ticket = false; networkInstallData->currTitleId = 0; + networkInstallData->n3dsContinue = false; memset(&networkInstallData->ticketInfo, 0, sizeof(networkInstallData->ticketInfo)); if(*(u16*) initialReadBlock == 0x0100) { @@ -140,7 +146,14 @@ static Result networkinstall_open_dst(void* data, u32 index, void* initialReadBl bool n3ds = false; if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { - return R_FBI_WRONG_SYSTEM; + ui_view* view = prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, NULL, networkinstall_n3ds_onresponse); + if(view != NULL) { + svcWaitSynchronization(view->active, U64_MAX); + } + + if(!networkInstallData->n3dsContinue) { + return R_FBI_WRONG_SYSTEM; + } } // Deleting FBI before it reinstalls itself causes issues. @@ -190,8 +203,6 @@ static Result networkinstall_close_dst(void* data, u32 index, bool succeeded, u3 } } - networkInstallData->currTitleId = 0; - return res; } else { if(networkInstallData->ticket) { @@ -227,7 +238,7 @@ static bool networkinstall_error(void* data, u32 index, Result res) { prompt_display("Failure", "Install cancelled.", COLOR_TEXT, false, NULL, NULL, NULL); } else if(res == R_FBI_ERRNO) { error_display_errno(NULL, NULL, errno, "Failed to install over the network."); - } else { + } else if(res != R_FBI_WRONG_SYSTEM) { error_display_res(NULL, NULL, res, "Failed to install over the network."); } @@ -248,6 +259,7 @@ static void networkinstall_close_client(network_install_data* data) { data->ticket = false; data->currTitleId = 0; + data->n3dsContinue = false; memset(&data->ticketInfo, 0, sizeof(data->ticketInfo)); } @@ -365,6 +377,7 @@ void networkinstall_open() { data->ticket = false; data->currTitleId = 0; + data->n3dsContinue = false; memset(&data->ticketInfo, 0, sizeof(data->ticketInfo)); data->installInfo.data = data; diff --git a/source/ui/section/qrinstall.c b/source/ui/section/qrinstall.c index 384a8c5..1b301b2 100644 --- a/source/ui/section/qrinstall.c +++ b/source/ui/section/qrinstall.c @@ -34,6 +34,7 @@ typedef struct { u32 responseCode; bool ticket; u64 currTitleId; + volatile bool n3dsContinue; ticket_info ticketInfo; bool capturing; @@ -48,6 +49,10 @@ static void qrinstall_cdn_check_onresponse(ui_view* view, void* data, bool respo qrInstallData->cdnDecided = true; } +static void qrinstall_n3ds_onresponse(ui_view* view, void* data, bool response) { + ((qr_install_data*) data)->n3dsContinue = response; +} + static Result qrinstall_is_src_directory(void* data, u32 index, bool* isDirectory) { *isDirectory = false; return 0; @@ -121,6 +126,7 @@ static Result qrinstall_open_dst(void* data, u32 index, void* initialReadBlock, qrInstallData->responseCode = 0; qrInstallData->ticket = false; qrInstallData->currTitleId = 0; + qrInstallData->n3dsContinue = false; memset(&qrInstallData->ticketInfo, 0, sizeof(qrInstallData->ticketInfo)); if(*(u16*) initialReadBlock == 0x0100) { @@ -143,7 +149,14 @@ static Result qrinstall_open_dst(void* data, u32 index, void* initialReadBlock, bool n3ds = false; if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { - return R_FBI_WRONG_SYSTEM; + ui_view* view = prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, NULL, qrinstall_n3ds_onresponse); + if(view != NULL) { + svcWaitSynchronization(view->active, U64_MAX); + } + + if(!qrInstallData->n3dsContinue) { + return R_FBI_WRONG_SYSTEM; + } } // Deleting FBI before it reinstalls itself causes issues. @@ -193,8 +206,6 @@ static Result qrinstall_close_dst(void* data, u32 index, bool succeeded, u32 han } } - qrInstallData->currTitleId = 0; - return res; } else { if(qrInstallData->ticket) { @@ -231,7 +242,7 @@ static bool qrinstall_error(void* data, u32 index, Result res) { if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Install cancelled.", COLOR_TEXT, false, NULL, NULL, NULL); return false; - } else { + } else if(res != R_FBI_WRONG_SYSTEM) { char* url = qrInstallData->urls[index]; ui_view* view = NULL; @@ -279,6 +290,7 @@ static void qrinstall_install_update(ui_view* view, void* data, float* progress, qrInstallData->responseCode = 0; qrInstallData->ticket = false; qrInstallData->currTitleId = 0; + qrInstallData->n3dsContinue = false; memset(&qrInstallData->ticketInfo, 0, sizeof(qrInstallData->ticketInfo)); return; @@ -502,6 +514,7 @@ void qrinstall_open() { data->responseCode = 0; data->ticket = false; data->currTitleId = 0; + data->n3dsContinue = false; memset(&data->ticketInfo, 0, sizeof(data->ticketInfo)); data->installInfo.data = data;