static Result action_url_install_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) { url_install_data* installData = (url_install_data*) data; Result res = 0; installData->responseCode = 0; installData->ticket = false; installData->currTitleId = 0; installData->n3dsContinue = false; memset(&installData->ticketInfo, 0, sizeof(installData->ticketInfo)); if(*(u16*) initialReadBlock == 0x0100) { if(!installData->cdnDecided) { ui_view* view = prompt_display("Optional", "Install ticket titles from CDN?", COLOR_TEXT, true, data, NULL, action_url_install_cdn_check_onresponse); if(view != NULL) { svcWaitSynchronization(view->active, U64_MAX); } } installData->ticket = true; installData->ticketInfo.titleId = util_get_ticket_title_id((u8*) initialReadBlock); AM_DeleteTicket(installData->ticketInfo.titleId); res = AM_InstallTicketBegin(handle); } else if(*(u16*) initialReadBlock == 0x2020) { u64 titleId = util_get_cia_title_id((u8*) initialReadBlock); FS_MediaType dest = (titleId & 0x0000801000000002) != 0 ? MEDIATYPE_NAND : MEDIATYPE_SD; bool n3ds = false; if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) { ui_view* view = prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, NULL, action_url_install_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. 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))) { installData->currTitleId = titleId; } } else {
static void action_paste_files_update(ui_view* view, void* data, float* progress, char* text) { paste_files_data* pasteData = (paste_files_data*) data; if(pasteData->pasteInfo.finished) { FSUSER_ControlArchive(pasteData->target->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); linked_list_sort(pasteData->items, util_compare_file_infos); ui_pop(); info_destroy(view); if(R_SUCCEEDED(pasteData->pasteInfo.result)) { prompt_display("Success", "Contents pasted.", COLOR_TEXT, false, NULL, NULL, NULL); } action_paste_files_free_data(pasteData); return; } if((hidKeysDown() & KEY_B) && !pasteData->pasteInfo.finished) { svcSignalEvent(pasteData->pasteInfo.cancelEvent); } *progress = pasteData->pasteInfo.currTotal != 0 ? (float) ((double) pasteData->pasteInfo.currProcessed / (double) pasteData->pasteInfo.currTotal) : 0; snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f %s / %.2f %s", pasteData->pasteInfo.processed, pasteData->pasteInfo.total, util_get_display_size(pasteData->pasteInfo.currProcessed), util_get_display_size_units(pasteData->pasteInfo.currProcessed), util_get_display_size(pasteData->pasteInfo.currTotal), util_get_display_size_units(pasteData->pasteInfo.currTotal)); }
enum e_prompt_status prompt_move_last_word(char *buf) { t_sh *sh; t_list *cur; sh = t_sh_recover(); if (!SHIFT_LEFT) return (TRYING); while (sh->c_prompt->cursor_index > 0) { cur = ft_lstget_at(sh->c_prompt->chars, sh->c_prompt->cursor_index - 1); if (cur && ft_isspace(*(char *)cur->content)) sh->c_prompt->cursor_index--; else break ; } while (sh->c_prompt->cursor_index > 0) { cur = ft_lstget_at( sh->c_prompt->chars, sh->c_prompt->cursor_index - 1); if (cur && !ft_isspace(*(char *)cur->content)) sh->c_prompt->cursor_index--; else break ; } prompt_display(1); return (READING); }
void dumpnand_open() { data_op_data* data = (data_op_data*) calloc(1, sizeof(data_op_data)); if(data == NULL) { error_display(NULL, NULL, NULL, "Failed to allocate dump NAND data."); return; } data->data = data; data->op = DATAOP_COPY; data->copyEmpty = true; data->total = 1; data->isSrcDirectory = dumpnand_is_src_directory; data->makeDstDirectory = dumpnand_make_dst_directory; data->openSrc = dumpnand_open_src; data->closeSrc = dumpnand_close_src; data->getSrcSize = dumpnand_get_src_size; data->readSrc = dumpnand_read_src; data->openDst = dumpnand_open_dst; data->closeDst = dumpnand_close_dst; data->writeDst = dumpnand_write_dst; data->error = dumpnand_error; data->finished = true; prompt_display("Confirmation", "Dump raw NAND image to the SD card?", COLOR_TEXT, true, data, NULL, NULL, dumpnand_onresponse); }
static void action_delete_title_update(ui_view* view, void* data, float* progress, char* text) { delete_title_data* deleteData = (delete_title_data*) data; title_info* info = (title_info*) deleteData->selected->data; Result res = 0; if(R_SUCCEEDED(res = AM_DeleteTitle(info->mediaType, info->titleId)) && deleteData->ticket) { res = AM_DeleteTicket(info->titleId); } ui_pop(); info_destroy(view); if(R_FAILED(res)) { error_display_res(info, ui_draw_title_info, res, "Failed to delete title."); } else { linked_list_remove(deleteData->items, deleteData->selected); task_free_title(deleteData->selected); prompt_display("Success", "Title deleted.", COLOR_TEXT, false, NULL, NULL, NULL); } free(data); }
void action_delete_title(title_info* info, bool* populated) { delete_title_data* data = (delete_title_data*) calloc(1, sizeof(delete_title_data)); data->info = info; data->populated = populated; prompt_display("Confirmation", "Delete the selected title?", COLOR_TEXT, true, data, NULL, action_delete_title_draw_top, action_delete_title_onresponse); }
void action_change_locale_dir(config_info* info, bool* populated) { config_info* data = calloc(1, sizeof(config_info)); strncpy(data->path, info->path, PATH_MAX); char *pattern = "Set locale path to %s"; char *message = (char*) calloc(1, strlen(pattern) + strlen(info->path) + 1); sprintf(message, pattern, info->path); prompt_display("Confirmation", message, COLOR_TEXT, true, data, NULL, NULL, action_write_locale_dir_config); }
static bool dumpnand_error(void* data, u32 index, Result res) { if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Dump cancelled.", COLOR_TEXT, false, NULL, NULL, NULL, NULL); } else { error_display_res(NULL, NULL, NULL, res, "Failed to dump NAND."); } return false; }
static void action_delete_system_save_data_update(ui_view* view, void* data, float* progress, char* text) { delete_system_save_data_data* deleteData = (delete_system_save_data_data*) data; system_save_data_info* info = (system_save_data_info*) deleteData->selected->data; FS_SystemSaveDataInfo sysInfo = {.mediaType = MEDIATYPE_NAND, .saveId = info->systemSaveDataId}; Result res = FSUSER_DeleteSystemSaveData(sysInfo); ui_pop(); info_destroy(view); if(R_FAILED(res)) { error_display_res(info, ui_draw_system_save_data_info, res, "Failed to delete system save data."); } else { linked_list_remove(deleteData->items, deleteData->selected); task_free_system_save_data(deleteData->selected); prompt_display("Success", "System save data deleted.", COLOR_TEXT, false, NULL, NULL, NULL); } free(data); } static void action_delete_system_save_data_onresponse(ui_view* view, void* data, bool response) { if(response) { info_display("Deleting System Save Data", "", false, data, action_delete_system_save_data_update, action_delete_system_save_data_draw_top); } else { free(data); } } void action_delete_system_save_data(linked_list* items, list_item* selected) { delete_system_save_data_data* data = (delete_system_save_data_data*) calloc(1, sizeof(delete_system_save_data_data)); if(data == NULL) { error_display(NULL, NULL, "Failed to allocate delete system save data data."); return; } data->items = items; data->selected = selected; prompt_display("Confirmation", "Delete the selected system save data?", COLOR_TEXT, true, data, action_delete_system_save_data_draw_top, action_delete_system_save_data_onresponse); }
static void action_rename_kbd_finished(void* data, char* input) { rename_data* renameData = (rename_data*) data; if(strlen(input) == 0) { error_display(NULL, NULL, NULL, "No name specified."); } file_info* targetInfo = (file_info*) renameData->target->data; Result res = 0; char parentPath[FILE_PATH_MAX] = {'\0'}; util_get_parent_path(parentPath, targetInfo->path, FILE_PATH_MAX); char dstPath[FILE_PATH_MAX] = {'\0'}; snprintf(dstPath, FILE_PATH_MAX, "%s%s", parentPath, input); FS_Path* srcFsPath = util_make_path_utf8(targetInfo->path); if(srcFsPath != NULL) { FS_Path* dstFsPath = util_make_path_utf8(dstPath); if(dstFsPath != NULL) { if(targetInfo->isDirectory) { res = FSUSER_RenameDirectory(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath); } else { res = FSUSER_RenameFile(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath); } util_free_path_utf8(dstFsPath); } else { res = R_FBI_OUT_OF_MEMORY; } util_free_path_utf8(srcFsPath); } else { res = R_FBI_OUT_OF_MEMORY; } if(R_SUCCEEDED(res)) { if(strncmp(renameData->target->name, "<current directory>", LIST_ITEM_NAME_MAX) != 0 && strncmp(renameData->target->name, "<current file>", LIST_ITEM_NAME_MAX) != 0) { strncpy(renameData->target->name, input, LIST_ITEM_NAME_MAX); } strncpy(targetInfo->name, input, FILE_NAME_MAX); strncpy(targetInfo->path, dstPath, FILE_PATH_MAX); linked_list_sort(renameData->items, util_compare_file_infos); prompt_display("Success", "Renamed.", COLOR_TEXT, false, NULL, NULL, NULL); } else { error_display_res(NULL, NULL, NULL, res, "Failed to perform rename."); } free(data); }
static bool action_import_twl_save_error(void* data, u32 index, Result res) { import_twl_save_data* importData = (import_twl_save_data*) data; if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Import cancelled.", COLOR_TEXT, false, importData->title, ui_draw_title_info, NULL); } else { error_display_res(importData->title, ui_draw_title_info, res, "Failed to import save."); } return false; }
bool action_install_cdn_error(void* data, u32 index, Result res) { install_cdn_data* installData = (install_cdn_data*) data; if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Install cancelled.", COLOR_TEXT, false, installData->ticket, NULL, ui_draw_ticket_info, NULL); } else if(res == R_FBI_HTTP_RESPONSE_CODE) { error_display(NULL, installData->ticket, ui_draw_ticket_info, "Failed to install CDN title.\nHTTP server returned response code %d", installData->responseCode); } else { error_display_res(NULL, installData->ticket, ui_draw_ticket_info, res, "Failed to install CDN title."); } return false; }
void error_display(volatile bool* dismissed, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2), const char* text, ...) { error_data* errorData = (error_data*) calloc(1, sizeof(error_data)); errorData->data = data; errorData->dismissed = dismissed; errorData->drawTop = drawTop; va_list list; va_start(list, text); vsnprintf(errorData->fullText, 4096, text, list); va_end(list); prompt_display("Error", errorData->fullText, COLOR_TEXT, false, errorData, NULL, error_draw_top, error_onresponse); }
void action_delete_ticket(linked_list* items, list_item* selected) { delete_ticket_data* data = (delete_ticket_data*) calloc(1, sizeof(delete_ticket_data)); if(data == NULL) { error_display(NULL, NULL, NULL, "Failed to allocate delete ticket data."); return; } data->items = items; data->selected = selected; prompt_display("Confirmation", "Delete the selected ticket?", COLOR_TEXT, true, data, NULL, action_delete_ticket_draw_top, action_delete_ticket_onresponse); }
static void action_delete_title_internal(linked_list* items, list_item* selected, const char* message, bool ticket) { delete_title_data* data = (delete_title_data*) calloc(1, sizeof(delete_title_data)); if(data == NULL) { error_display(NULL, NULL, "Failed to allocate delete title data."); return; } data->items = items; data->selected = selected; data->ticket = ticket; prompt_display("Confirmation", message, COLOR_TEXT, true, data, action_delete_title_draw_top, action_delete_title_onresponse); }
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 bool action_paste_files_error(void* data, u32 index, Result res) { paste_files_data* pasteData = (paste_files_data*) data; if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Paste cancelled.", COLOR_TEXT, false, NULL, NULL, NULL); return false; } else { ui_view* view = error_display_res(data, action_paste_files_draw_top, res, "Failed to paste content."); if(view != NULL) { svcWaitSynchronization(view->active, U64_MAX); } } return index < pasteData->pasteInfo.total - 1; }
static void action_delete_secure_value_update(ui_view* view, void* data, float* progress, char* text) { title_info* info = (title_info*) data; u64 param = ((u64) SECUREVALUE_SLOT_SD << 32) | (info->titleId & 0xFFFFFFF); u8 out = 0; Result res = FSUSER_ControlSecureSave(SECURESAVE_ACTION_DELETE, ¶m, sizeof(param), &out, sizeof(out)); ui_pop(); info_destroy(view); if(R_FAILED(res)) { error_display_res(info, ui_draw_title_info, res, "Failed to delete secure value."); } else { prompt_display("Success", "Secure value deleted.", COLOR_TEXT, false, info, ui_draw_title_info, NULL); } }
void error_display_errno(volatile bool* dismissed, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2), int err, const char* text, ...) { error_data* errorData = (error_data*) calloc(1, sizeof(error_data)); errorData->data = data; errorData->dismissed = dismissed; errorData->drawTop = drawTop; char textBuf[1024]; va_list list; va_start(list, text); vsnprintf(textBuf, 1024, text, list); va_end(list); snprintf(errorData->fullText, 4096, "%s\nI/O Error: %s (%d)", textBuf, strerror(err), err); prompt_display("Error", errorData->fullText, COLOR_TEXT, false, errorData, NULL, error_draw_top, error_onresponse); }
static void action_write_locale_dir_config(ui_view* view, void* data, bool response) { config_info *info = (config_info*) data; if(response) { FILE* config_file = fopen("/locales.conf", "w"); // TODO hardcoding if (config_file != NULL) { fprintf(config_file, "%s\n", info->path); fclose(config_file); char* msg = (char*) calloc(PATH_MAX+18, sizeof(char)); sprintf(msg, "Wrote %s to /locales.conf", info->path); prompt_display("Success", msg, COLOR_TEXT, false, NULL, NULL, NULL, NULL); } else { error_display(NULL, NULL, NULL, "Failed to write config."); } } }
static void action_delete_title_update(ui_view* view, void* data, float* progress, char* text) { delete_title_data* deleteData = (delete_title_data*) data; Result res = AM_DeleteTitle(deleteData->info->mediaType, deleteData->info->titleId); ui_pop(); info_destroy(view); if(R_FAILED(res)) { error_display_res(NULL, deleteData->info, ui_draw_title_info, res, "Failed to delete title."); } else { *deleteData->populated = false; prompt_display("Success", "Title deleted.", COLOR_TEXT, false, deleteData->info, NULL, ui_draw_title_info, NULL); } free(data); }
void action_import_twl_save(linked_list* items, list_item* selected) { import_twl_save_data* data = (import_twl_save_data*) calloc(1, sizeof(import_twl_save_data)); if(data == NULL) { error_display(NULL, NULL, "Failed to allocate import TWL save data."); return; } data->title = (title_info*) selected->data; data->importInfo.data = data; data->importInfo.op = DATAOP_COPY; data->importInfo.copyBufferSize = 16 * 1024; data->importInfo.copyEmpty = true; data->importInfo.total = 1; data->importInfo.isSrcDirectory = action_import_twl_save_is_src_directory; data->importInfo.makeDstDirectory = action_import_twl_save_make_dst_directory; data->importInfo.openSrc = action_import_twl_save_open_src; data->importInfo.closeSrc = action_import_twl_save_close_src; data->importInfo.getSrcSize = action_import_twl_save_get_src_size; data->importInfo.readSrc = action_import_twl_save_read_src; data->importInfo.openDst = action_import_twl_save_open_dst; data->importInfo.closeDst = action_import_twl_save_close_dst; data->importInfo.writeDst = action_import_twl_save_write_dst; data->importInfo.suspendCopy = action_import_twl_save_suspend_copy; data->importInfo.restoreCopy = action_import_twl_save_restore_copy; data->importInfo.suspend = action_import_twl_save_suspend; data->importInfo.restore = action_import_twl_save_restore; data->importInfo.error = action_import_twl_save_error; data->importInfo.finished = true; prompt_display("Confirmation", "Import the save of the selected title?", COLOR_TEXT, true, data, action_import_twl_save_draw_top, action_import_twl_save_onresponse); }
void error_display_res(volatile bool* dismissed, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2), Result result, const char* text, ...) { error_data* errorData = (error_data*) calloc(1, sizeof(error_data)); errorData->data = data; errorData->dismissed = dismissed; errorData->drawTop = drawTop; char textBuf[1024]; va_list list; va_start(list, text); vsnprintf(textBuf, 1024, text, list); va_end(list); int level = R_LEVEL(result); int summary = R_SUMMARY(result); int module = R_MODULE(result); int description = R_DESCRIPTION(result); snprintf(errorData->fullText, 4096, "%s\nResult code: 0x%08lX\nLevel: %s (%d)\nSummary: %s (%d)\nModule: %s (%d)\nDesc: %s (%d)", textBuf, result, level_to_string(result), level, summary_to_string(result), summary, module_to_string(result), module, description_to_string(result), description); prompt_display("Error", errorData->fullText, COLOR_TEXT, false, errorData, NULL, error_draw_top, error_onresponse); }
static bool action_install_tickets_error(void* data, u32 index, Result res) { install_tickets_data* installData = (install_tickets_data*) data; if(res == R_FBI_CANCELLED) { prompt_display("Failure", "Install cancelled.", COLOR_TEXT, false, installData->base, NULL, ui_draw_file_info, NULL); return false; } else { char* path = installData->contents[index]; volatile bool dismissed = false; if(strlen(path) > 48) { error_display_res(&dismissed, installData->base, ui_draw_file_info, res, "Failed to install ticket.\n%.45s...", path); } else { error_display_res(&dismissed, installData->base, ui_draw_file_info, res, "Failed to install ticket.\n%.48s", path); } while(!dismissed) { svcSleepThread(1000000); } } return index < installData->installInfo.total - 1; }
static void action_install_tickets_update(ui_view* view, void* data, float* progress, char* text) { install_tickets_data* installData = (install_tickets_data*) data; if(installData->installInfo.finished) { ui_pop(); info_destroy(view); if(!installData->installInfo.premature) { prompt_display("Success", "Install finished.", COLOR_TEXT, false, installData->base, NULL, ui_draw_file_info, NULL); } action_install_tickets_free_data(installData); return; } if(hidKeysDown() & KEY_B) { svcSignalEvent(installData->cancelEvent); } *progress = installData->installInfo.currTotal != 0 ? (float) ((double) installData->installInfo.currProcessed / (double) installData->installInfo.currTotal) : 0; snprintf(text, PROGRESS_TEXT_MAX, "%lu / %lu\n%.2f MB / %.2f MB", installData->installInfo.processed, installData->installInfo.total, installData->installInfo.currProcessed / 1024.0 / 1024.0, installData->installInfo.currTotal / 1024.0 / 1024.0); }
static void action_import_twl_save_update(ui_view* view, void* data, float* progress, char* text) { import_twl_save_data* importData = (import_twl_save_data*) data; if(importData->importInfo.finished) { ui_pop(); info_destroy(view); if(R_SUCCEEDED(importData->importInfo.result)) { prompt_display("Success", "Save imported.", COLOR_TEXT, false, importData->title, ui_draw_title_info, NULL); } free(data); return; } if(hidKeysDown() & KEY_B) { svcSignalEvent(importData->importInfo.cancelEvent); } *progress = importData->importInfo.currTotal != 0 ? (float) ((double) importData->importInfo.currProcessed / (double) importData->importInfo.currTotal) : 0; snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s", util_get_display_size(importData->importInfo.currProcessed), util_get_display_size_units(importData->importInfo.currProcessed), util_get_display_size(importData->importInfo.currTotal), util_get_display_size_units(importData->importInfo.currTotal)); }
static void dumpnand_update(ui_view* view, void* data, float* progress, char* text) { data_op_data* dumpData = (data_op_data*) data; if(dumpData->finished) { ui_pop(); info_destroy(view); if(R_SUCCEEDED(dumpData->result)) { prompt_display("Success", "NAND dumped.", COLOR_TEXT, false, NULL, NULL, NULL, NULL); } free(dumpData); return; } if(hidKeysDown() & KEY_B) { svcSignalEvent(dumpData->cancelEvent); } *progress = dumpData->currTotal != 0 ? (float) ((double) dumpData->currProcessed / (double) dumpData->currTotal) : 0; snprintf(text, PROGRESS_TEXT_MAX, "%.2f MiB / %.2f MiB", dumpData->currProcessed / 1024.0f / 1024.0f, dumpData->currTotal / 1024.0f / 1024.0f); }
void action_install_tickets(file_info* info, bool* populated) { install_tickets_data* data = (install_tickets_data*) calloc(1, sizeof(install_tickets_data)); data->base = info; data->installInfo.data = data; data->installInfo.op = DATAOP_COPY; data->installInfo.copyEmpty = false; data->installInfo.isSrcDirectory = action_install_tickets_is_src_directory; data->installInfo.makeDstDirectory = action_install_tickets_make_dst_directory; data->installInfo.openSrc = action_install_tickets_open_src; data->installInfo.closeSrc = action_install_tickets_close_src; data->installInfo.getSrcSize = action_install_tickets_get_src_size; data->installInfo.readSrc = action_install_tickets_read_src; data->installInfo.openDst = action_install_tickets_open_dst; data->installInfo.closeDst = action_install_tickets_close_dst; data->installInfo.writeDst = action_install_tickets_write_dst; data->installInfo.error = action_install_tickets_error; data->cancelEvent = 0; Result res = 0; if(R_FAILED(res = util_populate_contents(&data->contents, &data->installInfo.total, info->archive, info->path, false, false, ".tik", util_filter_file_extension))) { error_display_res(NULL, info, ui_draw_file_info, res, "Failed to retrieve content list."); free(data); return; } prompt_display("Confirmation", "Install the selected ticket(s)?", COLOR_TEXT, true, data, NULL, action_install_tickets_draw_top, action_install_tickets_onresponse); }
static void action_install_cdn_update(ui_view* view, void* data, float* progress, char* text) { install_cdn_data* installData = (install_cdn_data*) data; if(installData->installInfo.finished) { ui_pop(); info_destroy(view); Result res = 0; 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); } } } if(R_SUCCEEDED(installData->installInfo.result) && R_SUCCEEDED(res)) { if(installData->finishedPrompt) { 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); return; }
void action_paste_contents(linked_list* items, list_item* selected) { if(!clipboard_has_contents()) { prompt_display("Failure", "Clipboard empty.", COLOR_TEXT, false, NULL, NULL, NULL); return; } paste_files_data* data = (paste_files_data*) calloc(1, sizeof(paste_files_data)); if(data == NULL) { error_display(NULL, NULL, "Failed to allocate paste files data."); return; } data->items = items; data->target = (file_info*) selected->data; data->pasteInfo.data = data; data->pasteInfo.op = DATAOP_COPY; data->pasteInfo.copyBufferSize = 256 * 1024; data->pasteInfo.copyEmpty = true; data->pasteInfo.isSrcDirectory = action_paste_files_is_src_directory; data->pasteInfo.makeDstDirectory = action_paste_files_make_dst_directory; data->pasteInfo.openSrc = action_paste_files_open_src; data->pasteInfo.closeSrc = action_paste_files_close_src; data->pasteInfo.getSrcSize = action_paste_files_get_src_size; data->pasteInfo.readSrc = action_paste_files_read_src; data->pasteInfo.openDst = action_paste_files_open_dst; data->pasteInfo.closeDst = action_paste_files_close_dst; data->pasteInfo.writeDst = action_paste_files_write_dst; data->pasteInfo.suspendCopy = action_paste_files_suspend_copy; data->pasteInfo.restoreCopy = action_paste_files_restore_copy; data->pasteInfo.suspend = action_paste_files_suspend; data->pasteInfo.restore = action_paste_files_restore; data->pasteInfo.error = action_paste_files_error; data->pasteInfo.finished = true; linked_list_init(&data->contents); populate_files_data popData; memset(&popData, 0, sizeof(popData)); popData.items = &data->contents; popData.archive = clipboard_get_archive(); strncpy(popData.path, clipboard_get_path(), FILE_PATH_MAX); popData.recursive = true; popData.includeBase = !clipboard_is_contents_only() || !util_is_dir(clipboard_get_archive(), clipboard_get_path()); popData.filter = NULL; popData.filterData = NULL; Result listRes = task_populate_files(&popData); if(R_FAILED(listRes)) { error_display_res(NULL, NULL, listRes, "Failed to initiate clipboard content list population."); action_paste_files_free_data(data); return; } while(!popData.finished) { svcSleepThread(1000000); } if(R_FAILED(popData.result)) { error_display_res(NULL, NULL, popData.result, "Failed to populate clipboard content list."); action_paste_files_free_data(data); return; } data->pasteInfo.total = linked_list_size(&data->contents); data->pasteInfo.processed = data->pasteInfo.total; prompt_display("Confirmation", "Paste clipboard contents to the current directory?", COLOR_TEXT, true, data, action_paste_files_draw_top, action_paste_files_onresponse); }