diff --git a/source/ui/section/action/installcdn.c b/source/ui/section/action/installcdn.c index 5a435fb..b47d2af 100644 --- a/source/ui/section/action/installcdn.c +++ b/source/ui/section/action/installcdn.c @@ -167,18 +167,25 @@ static void action_install_cdn_update(ui_view* view, void* data, float* progress ui_pop(); info_destroy(view); - if(!installData->installInfo.premature) { - Result res = 0; - if(R_SUCCEEDED(res = AM_InstallTitleFinish()) - && R_SUCCEEDED(res = AM_CommitImportTitlesAndUpdateFirmwareAuto(((installData->ticket->ticketId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD, 1, false, &installData->ticket->ticketId))) { - prompt_display("Success", "Install finished.", COLOR_TEXT, false, installData->ticket, NULL, ui_draw_ticket_info, NULL); - } else { - AM_InstallTitleAbort(); + Result res = 0; - error_display_res(NULL, installData->ticket, ui_draw_ticket_info, res, "Failed to install CDN title."); + if(!installData->installInfo.premature) { + if(R_SUCCEEDED(res = AM_InstallTitleFinish()) + && R_SUCCEEDED(res = AM_CommitImportTitles(((installData->ticket->ticketId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD, 1, false, &installData->ticket->ticketId))) { + if(installData->ticket->ticketId == 0x0004013800000002 || installData->ticket->ticketId == 0x0004013820000002) { + res = AM_InstallFirm(installData->ticket->ticketId); + } } + } + + if(!installData->installInfo.premature && R_SUCCEEDED(res)) { + prompt_display("Success", "Install finished.", COLOR_TEXT, false, installData->ticket, NULL, ui_draw_ticket_info, NULL); } else { AM_InstallTitleAbort(); + + if(R_FAILED(res)) { + error_display_res(NULL, installData->ticket, ui_draw_ticket_info, res, "Failed to install CDN title."); + } } action_install_cdn_free_data(installData); diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index 119b098..06b1ed7 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -78,11 +78,11 @@ 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, u32* handle) { install_cias_data* installData = (install_cias_data*) data; - u8* buffer = (u8*) initialReadBlock; + u8* cia = (u8*) initialReadBlock; - u32 headerSize = *(u32*) &buffer[0x00]; - u32 certSize = *(u32*) &buffer[0x08]; - u64 titleId = __builtin_bswap64(*(u64*) &buffer[((headerSize + 0x3F) & ~0x3F) + ((certSize + 0x3F) & ~0x3F) + 0x1DC]); + u32 headerSize = *(u32*) &cia[0x00]; + u32 certSize = *(u32*) &cia[0x08]; + u64 titleId = __builtin_bswap64(*(u64*) &cia[((headerSize + 0x3F) & ~0x3F) + ((certSize + 0x3F) & ~0x3F) + 0x1DC]); FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; diff --git a/source/ui/section/networkinstall.c b/source/ui/section/networkinstall.c index 9d0caee..0c8a1d7 100644 --- a/source/ui/section/networkinstall.c +++ b/source/ui/section/networkinstall.c @@ -19,6 +19,7 @@ typedef struct { int clientSocket; u64 currTitleId; + bool ticket; data_op_info installInfo; Handle cancelEvent; @@ -99,51 +100,67 @@ static Result networkinstall_read_src(void* data, u32 handle, u32* bytesRead, vo static Result networkinstall_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) { network_install_data* networkInstallData = (network_install_data*) data; - u8* buffer = (u8*) initialReadBlock; + networkInstallData->ticket = *(u16*) initialReadBlock == 0x0100; - u32 headerSize = *(u32*) &buffer[0x00]; - u32 certSize = *(u32*) &buffer[0x08]; - u64 titleId = __builtin_bswap64(*(u64*) &buffer[((headerSize + 0x3F) & ~0x3F) + ((certSize + 0x3F) & ~0x3F) + 0x1DC]); + Result res = 0; - FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; + if(networkInstallData->ticket) { + res = AM_InstallTicketBegin(handle); + } else { + u8* cia = (u8*) initialReadBlock; - u8 n3ds = false; - if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { - return R_FBI_WRONG_SYSTEM; - } + u32 headerSize = *(u32*) &cia[0x00]; + u32 certSize = *(u32*) &cia[0x08]; + u64 titleId = __builtin_bswap64(*(u64*) &cia[((headerSize + 0x3F) & ~0x3F) + ((certSize + 0x3F) & ~0x3F) + 0x1DC]); - // Deleting FBI before it reinstalls itself causes issues. - if(((titleId >> 8) & 0xFFFFF) != 0xF8001) { - AM_DeleteTitle(dest, titleId); - AM_DeleteTicket(titleId); + FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; - if(dest == MEDIATYPE_SD) { - AM_QueryAvailableExternalTitleDatabase(NULL); + u8 n3ds = false; + if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { + return R_FBI_WRONG_SYSTEM; } - } - Result res = AM_StartCiaInstall(dest, handle); - if(R_SUCCEEDED(res)) { - networkInstallData->currTitleId = titleId; + // Deleting FBI before it reinstalls itself causes issues. + if(((titleId >> 8) & 0xFFFFF) != 0xF8001) { + AM_DeleteTitle(dest, titleId); + AM_DeleteTicket(titleId); + + if(dest == MEDIATYPE_SD) { + AM_QueryAvailableExternalTitleDatabase(NULL); + } + } + + if(R_SUCCEEDED(res = AM_StartCiaInstall(dest, handle))) { + networkInstallData->currTitleId = titleId; + } } return res; } static Result networkinstall_close_dst(void* data, u32 index, bool succeeded, u32 handle) { - if(succeeded) { - network_install_data* networkInstallData = (network_install_data*) data; + network_install_data* networkInstallData = (network_install_data*) data; + if(succeeded) { Result res = 0; - if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) { - if(networkInstallData->currTitleId == 0x0004013800000002 || networkInstallData->currTitleId == 0x0004013820000002) { - res = AM_InstallFirm(networkInstallData->currTitleId); + + if(networkInstallData->ticket) { + res = AM_InstallTicketFinish(handle); + } else { + if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) { + if(networkInstallData->currTitleId == 0x0004013800000002 || networkInstallData->currTitleId == 0x0004013820000002) { + res = AM_InstallFirm(networkInstallData->currTitleId); + } } } return res; } else { - return AM_CancelCIAInstall(handle); + if(networkInstallData->ticket) { + return AM_InstallTicketAbort(handle); + } else { + return AM_CancelCIAInstall(handle); + } } } @@ -155,11 +172,11 @@ static bool networkinstall_error(void* data, u32 index, Result res) { if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Install cancelled.", COLOR_TEXT, false, NULL, NULL, NULL, NULL); } else if(res == R_FBI_ERRNO) { - error_display_errno(NULL, NULL, NULL, errno, "Failed to install CIA file."); + error_display_errno(NULL, NULL, NULL, errno, "Failed to install over the network."); } else if(res == R_FBI_WRONG_SYSTEM) { - error_display(NULL, NULL, NULL, "Failed to install CIA file.\nAttempted to install N3DS title to O3DS."); + error_display(NULL, NULL, NULL, "Failed to install over the network.\nAttempted to install N3DS title to O3DS."); } else { - error_display_res(NULL, NULL, NULL, res, "Failed to install CIA file."); + error_display_res(NULL, NULL, NULL, res, "Failed to install over the network."); } return false; @@ -205,9 +222,9 @@ static void networkinstall_confirm_onresponse(ui_view* view, void* data, bool re if(response) { networkInstallData->cancelEvent = task_data_op(&networkInstallData->installInfo); if(networkInstallData->cancelEvent != 0) { - info_display("Installing CIA(s)", "Press B to cancel.", true, data, networkinstall_install_update, NULL); + info_display("Installing Over Network", "Press B to cancel.", true, data, networkinstall_install_update, NULL); } else { - error_display(NULL, NULL, NULL, "Failed to initiate CIA installation."); + error_display(NULL, NULL, NULL, "Failed to initiate installation."); networkinstall_close_client(networkInstallData); } @@ -244,7 +261,7 @@ static void networkinstall_wait_update(ui_view* view, void* data, float* progres networkInstallData->installInfo.total = ntohl(networkInstallData->installInfo.total); networkInstallData->clientSocket = sock; - prompt_display("Confirmation", "Install received CIA(s)?", COLOR_TEXT, true, data, NULL, NULL, networkinstall_confirm_onresponse); + prompt_display("Confirmation", "Install the received file(s)?", COLOR_TEXT, true, data, NULL, NULL, networkinstall_confirm_onresponse); } else if(errno != EAGAIN) { error_display_errno(NULL, NULL, NULL, errno, "Failed to open socket."); } @@ -299,6 +316,7 @@ void networkinstall_open() { data->clientSocket = 0; data->currTitleId = 0; + data->ticket = false; data->installInfo.data = data; diff --git a/source/ui/section/qrinstall.c b/source/ui/section/qrinstall.c index 5db9065..1b10501 100644 --- a/source/ui/section/qrinstall.c +++ b/source/ui/section/qrinstall.c @@ -29,6 +29,7 @@ typedef struct { u32 responseCode; u64 currTitleId; + bool ticket; data_op_info installInfo; Handle installCancelEvent; @@ -95,51 +96,67 @@ static Result qrinstall_read_src(void* data, u32 handle, u32* bytesRead, void* b static Result qrinstall_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) { qr_install_data* qrInstallData = (qr_install_data*) data; - u8* buffer = (u8*) initialReadBlock; + qrInstallData->ticket = *(u16*) initialReadBlock == 0x0100; - u32 headerSize = *(u32*) &buffer[0x00]; - u32 certSize = *(u32*) &buffer[0x08]; - u64 titleId = __builtin_bswap64(*(u64*) &buffer[((headerSize + 0x3F) & ~0x3F) + ((certSize + 0x3F) & ~0x3F) + 0x1DC]); + Result res = 0; - FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; + if(qrInstallData->ticket) { + res = AM_InstallTicketBegin(handle); + } else { + u8* cia = (u8*) initialReadBlock; - u8 n3ds = false; - if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { - return R_FBI_WRONG_SYSTEM; - } + u32 headerSize = *(u32*) &cia[0x00]; + u32 certSize = *(u32*) &cia[0x08]; + u64 titleId = __builtin_bswap64(*(u64*) &cia[((headerSize + 0x3F) & ~0x3F) + ((certSize + 0x3F) & ~0x3F) + 0x1DC]); - // Deleting FBI before it reinstalls itself causes issues. - if(((titleId >> 8) & 0xFFFFF) != 0xF8001) { - AM_DeleteTitle(dest, titleId); - AM_DeleteTicket(titleId); + FS_MediaType dest = ((titleId >> 32) & 0x8010) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; - if(dest == MEDIATYPE_SD) { - AM_QueryAvailableExternalTitleDatabase(NULL); + u8 n3ds = false; + if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { + return R_FBI_WRONG_SYSTEM; } - } - Result res = AM_StartCiaInstall(dest, handle); - if(R_SUCCEEDED(res)) { - qrInstallData->currTitleId = titleId; + // Deleting FBI before it reinstalls itself causes issues. + if(((titleId >> 8) & 0xFFFFF) != 0xF8001) { + AM_DeleteTitle(dest, titleId); + AM_DeleteTicket(titleId); + + if(dest == MEDIATYPE_SD) { + AM_QueryAvailableExternalTitleDatabase(NULL); + } + } + + if(R_SUCCEEDED(res = AM_StartCiaInstall(dest, handle))) { + qrInstallData->currTitleId = titleId; + } } return res; } static Result qrinstall_close_dst(void* data, u32 index, bool succeeded, u32 handle) { - if(succeeded) { - qr_install_data* qrInstallData = (qr_install_data*) data; + qr_install_data* qrInstallData = (qr_install_data*) data; + if(succeeded) { Result res = 0; - if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) { - if(qrInstallData->currTitleId == 0x0004013800000002 || qrInstallData->currTitleId == 0x0004013820000002) { - res = AM_InstallFirm(qrInstallData->currTitleId); + + if(qrInstallData->ticket) { + res = AM_InstallTicketFinish(handle); + } else { + if(R_SUCCEEDED(res = AM_FinishCiaInstall(handle))) { + if(qrInstallData->currTitleId == 0x0004013800000002 || qrInstallData->currTitleId == 0x0004013820000002) { + res = AM_InstallFirm(qrInstallData->currTitleId); + } } } return res; } else { - return AM_CancelCIAInstall(handle); + if(qrInstallData->ticket) { + return AM_InstallTicketAbort(handle); + } else { + return AM_CancelCIAInstall(handle); + } } } @@ -159,21 +176,21 @@ static bool qrinstall_error(void* data, u32 index, Result res) { volatile bool dismissed = false; if(res == R_FBI_WRONG_SYSTEM) { if(strlen(url) > 48) { - error_display(&dismissed, NULL, NULL, "Failed to install CIA file.\n%.45s...\nAttempted to install N3DS title to O3DS.", url); + error_display(&dismissed, NULL, NULL, "Failed to install from QR code.\n%.45s...\nAttempted to install N3DS title to O3DS.", url); } else { - error_display(&dismissed, NULL, NULL, "Failed to install CIA file.\n%.48s\nAttempted to install N3DS title to O3DS.", url); + error_display(&dismissed, NULL, NULL, "Failed to install from QR code.\n%.48s\nAttempted to install N3DS title to O3DS.", url); } } else if(res == R_FBI_HTTP_RESPONSE_CODE) { if(strlen(url) > 48) { - error_display(&dismissed, NULL, NULL, "Failed to install CIA file.\n%.45s...\nHTTP server returned response code %d", url, qrInstallData->responseCode); + error_display(&dismissed, NULL, NULL, "Failed to install from QR code.\n%.45s...\nHTTP server returned response code %d", url, qrInstallData->responseCode); } else { - error_display(&dismissed, NULL, NULL, "Failed to install CIA file.\n%.48s\nHTTP server returned response code %d", url, qrInstallData->responseCode); + error_display(&dismissed, NULL, NULL, "Failed to install from QR code.\n%.48s\nHTTP server returned response code %d", url, qrInstallData->responseCode); } } else { if(strlen(url) > 48) { - error_display_res(&dismissed, NULL, NULL, res, "Failed to install CIA file.\n%.45s...", url); + error_display_res(&dismissed, NULL, NULL, res, "Failed to install from QR code.\n%.45s...", url); } else { - error_display_res(&dismissed, NULL, NULL, res, "Failed to install CIA file.\n%.48s", url); + error_display_res(&dismissed, NULL, NULL, res, "Failed to install from QR code.\n%.48s", url); } } @@ -213,9 +230,9 @@ static void qrinstall_confirm_onresponse(ui_view* view, void* data, bool respons if(response) { qrInstallData->installCancelEvent = task_data_op(&qrInstallData->installInfo); if(qrInstallData->installCancelEvent != 0) { - info_display("Installing CIA(s)", "Press B to cancel.", true, data, qrinstall_install_update, NULL); + info_display("Installing From QR Code", "Press B to cancel.", true, data, qrinstall_install_update, NULL); } else { - error_display(NULL, NULL, NULL, "Failed to initiate CIA installation."); + error_display(NULL, NULL, NULL, "Failed to initiate installation."); } } } @@ -370,6 +387,7 @@ void qrinstall_open() { data->responseCode = 0; data->currTitleId = 0; + data->ticket = false; data->installInfo.data = data;