Beispiel #1
0
static void titles_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
    titles_data* listData = (titles_data*) data;

    if(hidKeysDown() & KEY_B) {
        if(!listData->populateData.finished) {
            svcSignalEvent(listData->populateData.cancelEvent);
            while(!listData->populateData.finished) {
                svcSleepThread(1000000);
            }
        }

        ui_pop();

        task_clear_titles(items);
        list_destroy(view);

        free(listData);
        return;
    }

    if(hidKeysDown() & KEY_SELECT) {
        titles_options_open(listData);
        return;
    }

    if(!listData->populated || (hidKeysDown() & KEY_X)) {
        if(!listData->populateData.finished) {
            svcSignalEvent(listData->populateData.cancelEvent);
            while(!listData->populateData.finished) {
                svcSleepThread(1000000);
            }
        }

        listData->populateData.items = items;
        Result res = task_populate_titles(&listData->populateData);
        if(R_FAILED(res)) {
            error_display_res(NULL, NULL, res, "Failed to initiate title list population.");
        }

        listData->populated = true;
    }

    if(listData->populateData.finished && R_FAILED(listData->populateData.result)) {
        error_display_res(NULL, NULL, listData->populateData.result, "Failed to populate title list.");

        listData->populateData.result = 0;
    }

    if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) {
        titles_action_open(items, selected);
        return;
    }
}
static void action_delete_system_save_data_update(ui_view* view, void* data, float* progress, char* progressText) {
    delete_system_save_data_data* deleteData = (delete_system_save_data_data*) data;

    FS_SystemSaveDataInfo sysInfo = {.mediaType = MEDIATYPE_NAND, .saveId = deleteData->info->systemSaveDataId};
    Result res = FSUSER_DeleteSystemSaveData(sysInfo);

    progressbar_destroy(view);
    ui_pop();

    if(R_FAILED(res)) {
        error_display_res(deleteData->info, ui_draw_system_save_data_info, res, "Failed to delete system save data.");
    } else {
        *deleteData->populated = false;

        ui_push(prompt_create("Success", "System save data deleted.", COLOR_TEXT, false, deleteData->info, NULL, ui_draw_system_save_data_info, action_delete_system_save_data_success_onresponse));
    }

    free(data);
}

static void action_delete_system_save_data_onresponse(ui_view* view, void* data, bool response) {
    prompt_destroy(view);

    if(response) {
        ui_push(progressbar_create("Deleting System Save Data", "", data, action_delete_system_save_data_update, action_delete_system_save_data_draw_top));
    } else {
        free(data);
    }
}
Beispiel #3
0
static void files_repopulate(files_data* listData, linked_list* items) {
    if(!listData->populateData.finished) {
        svcSignalEvent(listData->populateData.cancelEvent);
        while(!listData->populateData.finished) {
            svcSleepThread(1000000);
        }
    }

    if(listData->dirItem != NULL) {
        task_free_file(listData->dirItem);
        listData->dirItem = NULL;
    }

    Result res = 0;
    if(R_SUCCEEDED(res = task_create_file_item(&listData->dirItem, listData->archive, listData->currDir))) {
        listData->populateData.items = items;
        listData->populateData.base = (file_info*) listData->dirItem->data;

        res = task_populate_files(&listData->populateData);
    }

    if(R_FAILED(res)) {
        error_display_res(NULL, NULL, NULL, res, "Failed to initiate file list population.");
    }

    listData->populated = true;
}
Beispiel #4
0
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);
}
Beispiel #5
0
Handle task_populate_pending_titles(list_item* items, u32* count, u32 max) {
    if(items == NULL || count == NULL || max == 0) {
        return 0;
    }

    task_clear_pending_titles(items, count);

    populate_pending_titles_data* data = (populate_pending_titles_data*) calloc(1, sizeof(populate_pending_titles_data));
    data->items = items;
    data->count = count;
    data->max = max;

    Result eventRes = svcCreateEvent(&data->cancelEvent, 1);
    if(R_FAILED(eventRes)) {
        error_display_res(NULL, NULL, eventRes, "Failed to create pending title list cancel event.");

        free(data);
        return 0;
    }

    if(threadCreate(task_populate_pending_titles_thread, data, 0x4000, 0x18, 1, true) == NULL) {
        error_display(NULL, NULL, "Failed to create pending title list thread.");

        svcCloseHandle(data->cancelEvent);
        free(data);
        return 0;
    }

    return data->cancelEvent;
}
Beispiel #6
0
static void files_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
    files_data* listData = (files_data*) data;

    while(!util_is_dir(listData->archive, listData->currDir)) {
        char parentDir[FILE_PATH_MAX] = {'\0'};
        util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX);

        files_navigate(listData, items, parentDir);
    }

    if(hidKeysDown() & KEY_B) {
        if(strncmp(listData->currDir, "/", FILE_PATH_MAX) == 0) {
            ui_pop();

            files_free_data(listData);

            task_clear_files(items);
            list_destroy(view);

            return;
        } else {
            char parentDir[FILE_PATH_MAX] = {'\0'};
            util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX);

            files_navigate(listData, items, parentDir);
        }
    }

    if(hidKeysDown() & KEY_SELECT) {
        files_filters_open(listData);
        return;
    }

    if((hidKeysDown() & KEY_Y) && listData->dirItem != NULL) {
        files_action_open(items, listData->dirItem, listData);
        return;
    }

    if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) {
        file_info* fileInfo = (file_info*) selected->data;

        if(fileInfo->isDirectory) {
            files_navigate(listData, items, fileInfo->path);
        } else {
            files_action_open(items, selected, listData);
            return;
        }
    }

    if(!listData->populated || (hidKeysDown() & KEY_X)) {
        files_repopulate(listData, items);
    }

    if(listData->populateData.finished && R_FAILED(listData->populateData.result)) {
        error_display_res(NULL, NULL, NULL, listData->populateData.result, "Failed to populate file list.");

        listData->populateData.result = 0;
    }
}
Beispiel #7
0
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;
}
Beispiel #8
0
void action_copy_contents(file_info* info, bool* populated) {
    Result res = 0;
    if(R_FAILED(res = clipboard_set_contents(*info->archive, info->path))) {
        error_display_res(info, ui_draw_file_info, res, "Failed to copy contents to clipboard.");

        return;
    }

    ui_push(prompt_create("Success", "Content copied to clipboard.", COLOR_TEXT, false, info, NULL, ui_draw_file_info, action_copy_files_success_onresponse));
}
Beispiel #9
0
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);
}
Beispiel #10
0
static void task_populate_pending_titles_thread(void* arg) {
    populate_pending_titles_data* data = (populate_pending_titles_data*) arg;

    Result res = 0;
    if(R_FAILED(res = task_populate_pending_titles_from(data, MEDIATYPE_SD)) || R_FAILED(res = task_populate_pending_titles_from(data, MEDIATYPE_NAND))) {
        error_display_res(NULL, NULL, res, "Failed to load pending title listing.");
    }

    svcCloseHandle(data->cancelEvent);
    free(data);
}
Beispiel #11
0
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;
}
Beispiel #12
0
void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
    files_data* data = (files_data*) calloc(1, sizeof(files_data));
    if(data == NULL) {
        error_display(NULL, NULL, NULL, "Failed to allocate files data.");

        return;
    }

    data->populateData.recursive = false;
    data->populateData.includeBase = false;
    data->populateData.dirsFirst = true;

    data->populateData.filter = files_filter;
    data->populateData.filterData = data;

    data->populateData.finished = true;

    data->populated = false;

    data->showDirectories = true;
    data->showCias = true;
    data->showTickets = true;
    data->showMisc = true;

    data->archiveId = archiveId;
    data->archivePath.type = archivePath.type;
    data->archivePath.size = archivePath.size;
    if(archivePath.data != NULL) {
        data->archivePath.data = calloc(1, data->archivePath.size);
        if(data->archivePath.data == NULL) {
            error_display(NULL, NULL, NULL, "Failed to allocate files data.");

            files_free_data(data);
            return;
        }

        memcpy((void*) data->archivePath.data, archivePath.data, data->archivePath.size);
    } else {
        data->archivePath.data = NULL;
    }

    snprintf(data->currDir, FILE_PATH_MAX, "/");
    data->dirItem = NULL;

    Result res = 0;
    if(R_FAILED(res = FSUSER_OpenArchive(&data->archive, archiveId, archivePath))) {
        error_display_res(NULL, NULL, NULL, res, "Failed to open file listing archive.");

        files_free_data(data);
        return;
    }

    list_display("Files", "A: Select, B: Back, X: Refresh, Y: Dir, Select: Filter", data, files_update, files_draw_top);
}
Beispiel #13
0
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;
}
Beispiel #14
0
static void dumpnand_onresponse(ui_view* view, void* data, bool response) {
    if(response) {
        data_op_data* dumpData = (data_op_data*) data;

        Result res = task_data_op(dumpData);
        if(R_SUCCEEDED(res)) {
            info_display("Dumping NAND", "Press B to cancel.", true, data, dumpnand_update, NULL);
        } else {
            error_display_res(NULL, NULL, NULL, res, "Failed to initiate NAND dump.");
        }
    } else {
        free(data);
    }
}
Beispiel #15
0
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;
}
Beispiel #16
0
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.");
    }
}
Beispiel #17
0
static void action_paste_files_onresponse(ui_view* view, void* data, bool response) {
    paste_files_data* pasteData = (paste_files_data*) data;
    if(response) {
        Result res = task_data_op(&pasteData->pasteInfo);
        if(R_SUCCEEDED(res)) {
            info_display("Pasting Contents", "Press B to cancel.", true, data, action_paste_files_update, action_paste_files_draw_top);
        } else {
            error_display_res(pasteData->target, ui_draw_file_info, res, "Failed to initiate paste operation.");

            action_paste_files_free_data(pasteData);
        }
    } else {
        action_paste_files_free_data(pasteData);
    }
}
Beispiel #18
0
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;
}
Beispiel #19
0
static void action_import_twl_save_onresponse(ui_view* view, void* data, bool response) {
    if(response) {
        import_twl_save_data* importData = (import_twl_save_data*) data;

        Result res = task_data_op(&importData->importInfo);
        if(R_SUCCEEDED(res)) {
            info_display("Importing Save", "Press B to cancel.", true, data, action_import_twl_save_update, action_import_twl_save_draw_top);
        } else {
            error_display_res(importData->title, ui_draw_title_info, res, "Failed to initiate save import.");
            free(data);
        }
    } else {
        free(data);
    }
}
Beispiel #20
0
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, &param, 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);
    }
}
Beispiel #21
0
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);
}
Beispiel #22
0
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);
}
Beispiel #23
0
static void files_repopulate(files_data* listData, linked_list* items) {
    if(!listData->populateData.finished) {
        svcSignalEvent(listData->populateData.cancelEvent);
        while(!listData->populateData.finished) {
            svcSleepThread(1000000);
        }
    }

    listData->populateData.items = items;
    listData->populateData.archive = listData->archive;
    strncpy(listData->populateData.path, listData->currDir, FILE_PATH_MAX);

    Result res = task_populate_files(&listData->populateData);
    if(R_FAILED(res)) {
        error_display_res(NULL, NULL, res, "Failed to initiate file list population.");
    }

    listData->populated = true;
}
Beispiel #24
0
static void action_launch_title_update(ui_view* view, void* data, float* progress, char* text) {
    title_info* info = (title_info*) data;

    Result res = 0;

    aptOpenSession();

    if(R_SUCCEEDED(res = APT_PrepareToDoAppJump(0, info->titleId, info->mediaType))) {
        u8 buf0[0x300];
        u8 buf1[0x20];

        res = APT_DoAppJump(0x300, 0x20, buf0, buf1);
    }

    aptCloseSession();

    if(R_FAILED(res)) {
        ui_pop();
        info_destroy(view);

        error_display_res(NULL, info, ui_draw_title_info, res, "Failed to launch title.");
    }
}
Beispiel #25
0
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;
    }
Beispiel #26
0
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);
}
Beispiel #27
0
void files_open(FS_Archive archive) {
    files_data* data = (files_data*) calloc(1, sizeof(files_data));
    data->archive = archive;

    if(data->archive.lowPath.size > 0) {
        data->archivePath = calloc(1,  data->archive.lowPath.size);
        memcpy(data->archivePath,  data->archive.lowPath.data,  data->archive.lowPath.size);
        data->archive.lowPath.data = data->archivePath;
    }

    data->archive.handle = 0;

    Result res = 0;
    if(R_FAILED(res = FSUSER_OpenArchive(&data->archive))) {
        error_display_res(NULL, NULL, NULL, res, "Failed to open file listing archive.");

        if(data->archivePath != NULL) {
            free(data->archivePath);
        }

        free(data);
        return;
    }

    data->currDir.archive = &data->archive;
    snprintf(data->currDir.path, PATH_MAX, "/");
    util_get_path_file(data->currDir.name, data->currDir.path, NAME_MAX);
    data->currDir.isDirectory = true;
    data->currDir.containsCias = false;
    data->currDir.size = 0;
    data->currDir.isCia = false;

    memcpy(&data->parentDir, &data->currDir, sizeof(data->parentDir));

    list_display("Files", "A: Select, B: Back, X: Refresh, Y: Directory Action", data, files_update, files_draw_top);
}
Beispiel #28
0
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);
}
Beispiel #29
0
static void files_action_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
    files_action_data* actionData = (files_action_data*) data;

    if(hidKeysDown() & KEY_B) {
        ui_pop();
        list_destroy(view);

        free(data);

        return;
    }

    if(selected != NULL && (selected->data != NULL || selected == &copy || selected == &copy_all_contents) && (selectedTouched || (hidKeysDown() & KEY_A))) {
        void(*action)(linked_list*, list_item*) = (void(*)(linked_list*, list_item*)) selected->data;

        ui_pop();
        list_destroy(view);

        if(selected == &copy || selected == &copy_all_contents) {
            file_info* info = (file_info*) actionData->selected->data;

            Result res = 0;
            if(R_SUCCEEDED(res = clipboard_set_contents(actionData->parent->archiveId, &actionData->parent->archivePath, info->path, selected == &copy_all_contents))) {
                prompt_display("Success", selected == &copy_all_contents ? "Current directory contents copied to clipboard." : info->isDirectory ? "Current directory copied to clipboard." : "File copied to clipboard.", COLOR_TEXT, false, info, NULL, ui_draw_file_info, NULL);
            } else {
                error_display_res(NULL, info, ui_draw_file_info, res, "Failed to copy to clipboard.");
            }
        } else {
            action(actionData->items, actionData->selected);
        }

        free(data);

        return;
    }

    if(linked_list_size(items) == 0) {
        file_info* info = (file_info*) actionData->selected->data;

        if(info->isDirectory) {
            if(info->containsCias) {
                linked_list_add(items, &install_all_cias);
                linked_list_add(items, &install_and_delete_all_cias);
                linked_list_add(items, &delete_all_cias);
            }

            if(info->containsTickets) {
                linked_list_add(items, &install_all_tickets);
                linked_list_add(items, &install_and_delete_all_tickets);
                linked_list_add(items, &delete_all_tickets);
            }

            linked_list_add(items, &delete_all_contents);
            linked_list_add(items, &copy_all_contents);

            linked_list_add(items, &delete_dir);
        } else {
            if(info->isCia) {
                linked_list_add(items, &install_cia);
                linked_list_add(items, &install_and_delete_cia);
            }

            if(info->isTicket) {
                linked_list_add(items, &install_ticket);
                linked_list_add(items, &install_and_delete_ticket);
            }

            linked_list_add(items, &delete_file);
        }

        linked_list_add(items, &copy);
        linked_list_add(items, &paste);
    }
}
Beispiel #30
0
static void files_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
    files_data* listData = (files_data*) data;

    if(listData->populated) {
        // Detect whether the current directory was renamed by an action.
        list_item* currDirItem = linked_list_get(items, 0);
        if(currDirItem != NULL && strncmp(listData->currDir, ((file_info*) currDirItem->data)->path, FILE_PATH_MAX) != 0) {
            strncpy(listData->currDir, ((file_info*) currDirItem->data)->path, FILE_PATH_MAX);
        }
    }

    while(!util_is_dir(listData->archive, listData->currDir)) {
        char parentDir[FILE_PATH_MAX] = {'\0'};
        util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX);

        files_navigate(listData, items, parentDir);
    }

    if(hidKeysDown() & KEY_B) {
        if(strncmp(listData->currDir, "/", FILE_PATH_MAX) == 0) {
            ui_pop();

            files_free_data(listData);

            task_clear_files(items);
            list_destroy(view);

            return;
        } else {
            char parentDir[FILE_PATH_MAX] = {'\0'};
            util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX);

            files_navigate(listData, items, parentDir);
        }
    }

    if(hidKeysDown() & KEY_SELECT) {
        files_filters_open(listData);
        return;
    }

    if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) {
        file_info* fileInfo = (file_info*) selected->data;

        if((fileInfo->attributes & FS_ATTRIBUTE_DIRECTORY) && strncmp(selected->name, "<current directory>", LIST_ITEM_NAME_MAX) != 0) {
            files_navigate(listData, items, fileInfo->path);
        } else {
            files_action_open(items, selected, listData);
            return;
        }
    }

    if(!listData->populated || (hidKeysDown() & KEY_X)) {
        files_repopulate(listData, items);
    }

    if(listData->populateData.finished && R_FAILED(listData->populateData.result)) {
        error_display_res(NULL, NULL, listData->populateData.result, "Failed to populate file list.");

        listData->populateData.result = 0;
    }
}