Ejemplo n.º 1
0
static void files_repopulate(files_data* listData) {
    if(listData->cancelEvent != 0) {
        svcSignalEvent(listData->cancelEvent);
        while(svcWaitSynchronization(listData->cancelEvent, 0) == 0) {
            svcSleepThread(1000000);
        }

        listData->cancelEvent = 0;
    }

    while(!util_is_dir(&listData->archive, listData->currDir.path)) {
        char parentPath[PATH_MAX];

        util_get_parent_path(parentPath, listData->currDir.path, PATH_MAX);
        strncpy(listData->currDir.path, parentPath, PATH_MAX);
        util_get_path_file(listData->currDir.name, listData->currDir.path, NAME_MAX);

        util_get_parent_path(parentPath, listData->currDir.path, PATH_MAX);
        strncpy(listData->parentDir.path, parentPath, PATH_MAX);
        util_get_path_file(listData->parentDir.name, listData->parentDir.path, NAME_MAX);
    }

    listData->cancelEvent = task_populate_files(listData->items, &listData->count, FILES_MAX, &listData->currDir);
    listData->populated = true;
}
Ejemplo n.º 2
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;
    }
}
Ejemplo n.º 3
0
static void files_update(ui_view* view, void* data, list_item** items, u32** itemCount, list_item* selected, bool selectedTouched) {
    files_data* listData = (files_data*) data;

    if(hidKeysDown() & KEY_B) {
        if(strcmp(listData->currDir.path, "/") == 0) {
            if(listData->archive.handle != 0) {
                FSUSER_CloseArchive(&listData->archive);
                listData->archive.handle = 0;
            }

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

            if(listData->cancelEvent != 0) {
                svcSignalEvent(listData->cancelEvent);
                while(svcWaitSynchronization(listData->cancelEvent, 0) == 0) {
                    svcSleepThread(1000000);
                }

                listData->cancelEvent = 0;
            }

            ui_pop();
            list_destroy(view);

            free(listData);
            return;
        } else {
            files_navigate(listData, listData->parentDir.path);
        }
    }

    if(hidKeysDown() & KEY_Y) {
        files_action_open(&listData->currDir, &listData->populated);
        return;
    }

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

        if(util_is_dir(&listData->archive, fileInfo->path)) {
            files_navigate(listData, fileInfo->path);
        } else {
            files_action_open(fileInfo, &listData->populated);
            return;
        }
    }

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

    if(*itemCount != &listData->count || *items != listData->items) {
        *itemCount = &listData->count;
        *items = listData->items;
    }
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
Result task_create_file_item(list_item** out, FS_Archive archive, const char* path) {
    Result res = 0;

    list_item* item = (list_item*) calloc(1, sizeof(list_item));
    if(item != NULL) {
        file_info* fileInfo = (file_info*) calloc(1, sizeof(file_info));
        if(fileInfo != NULL) {
            fileInfo->archive = archive;
            util_get_path_file(fileInfo->name, path, FILE_NAME_MAX);
            fileInfo->attributes = 0;

            fileInfo->size = 0;
            fileInfo->isCia = false;
            fileInfo->isTicket = false;

            if(util_is_dir(archive, path)) {
                item->color = COLOR_DIRECTORY;

                size_t len = strlen(path);
                if(len > 1 && path[len - 1] != '/') {
                    snprintf(fileInfo->path, FILE_PATH_MAX, "%s/", path);
                } else {
                    strncpy(fileInfo->path, path, FILE_PATH_MAX);
                }

                fileInfo->attributes = FS_ATTRIBUTE_DIRECTORY;
            } else {
                item->color = COLOR_FILE;

                strncpy(fileInfo->path, path, FILE_PATH_MAX);

                FS_Path* fileFsPath = util_make_path_utf8(fileInfo->path);
                if(fileFsPath != NULL) {
                    Handle fileHandle;
                    if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, archive, *fileFsPath, FS_OPEN_READ, 0))) {
                        FSFILE_GetAttributes(fileHandle, &fileInfo->attributes);
                        FSFILE_GetSize(fileHandle, &fileInfo->size);

                        size_t len = strlen(fileInfo->path);
                        if(len > 4) {
                            if(strcasecmp(&fileInfo->path[len - 4], ".cia") == 0) {
                                AM_TitleEntry titleEntry;
                                if(R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_SD, &titleEntry, fileHandle))) {
                                    fileInfo->isCia = true;
                                    fileInfo->ciaInfo.titleId = titleEntry.titleID;
                                    fileInfo->ciaInfo.version = titleEntry.version;
                                    fileInfo->ciaInfo.installedSize = titleEntry.size;
                                    fileInfo->ciaInfo.hasMeta = false;

                                    if((titleEntry.titleID & 0x0000801000000002) != 0 && R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_NAND, &titleEntry, fileHandle))) {
                                        fileInfo->ciaInfo.installedSize = titleEntry.size;
                                    }

                                    SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
                                    if(smdh != NULL) {
                                        if(R_SUCCEEDED(util_get_cia_file_smdh(smdh, fileHandle))) {
                                            if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
                                                u8 systemLanguage = CFG_LANGUAGE_EN;
                                                CFGU_GetSystemLanguage(&systemLanguage);

                                                fileInfo->ciaInfo.hasMeta = true;
                                                utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(fileInfo->ciaInfo.meta.shortDescription) - 1);
                                                utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(fileInfo->ciaInfo.meta.longDescription) - 1);
                                                utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(fileInfo->ciaInfo.meta.publisher) - 1);
                                                fileInfo->ciaInfo.meta.region = smdh->region;
                                                fileInfo->ciaInfo.meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
                                            }
                                        }

                                        free(smdh);
                                    }
                                }
                            } else if(strcasecmp(&fileInfo->path[len - 4], ".tik") == 0) {
                                u32 bytesRead = 0;

                                u8 sigType = 0;
                                if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, 3, &sigType, sizeof(sigType))) && bytesRead == sizeof(sigType) && sigType <= 5) {
                                    static u32 dataOffsets[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80};
                                    static u32 titleIdOffset = 0x9C;

                                    u64 titleId = 0;
                                    if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, dataOffsets[sigType] + titleIdOffset, &titleId, sizeof(titleId))) && bytesRead == sizeof(titleId)) {
                                        fileInfo->isTicket = true;
                                        fileInfo->ticketInfo.titleId = __builtin_bswap64(titleId);
                                    }
                                }
                            }
                        }

                        FSFILE_Close(fileHandle);
                    }

                    util_free_path_utf8(fileFsPath);
                }
            }

            strncpy(item->name, fileInfo->name, LIST_ITEM_NAME_MAX);
            item->data = fileInfo;

            *out = item;
        } else {
            free(item);

            res = R_FBI_OUT_OF_MEMORY;
        }
    } else {
        res = R_FBI_OUT_OF_MEMORY;
    }

    return res;
}
Ejemplo n.º 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;

    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;
    }
}