Beispiel #1
0
static Result task_populate_ext_save_data_from(populate_ext_save_data_data* data, FS_MediaType mediaType) {
    Result res = 0;

    u32 extSaveDataCount = 0;
    u64* extSaveDataIds = (u64*) calloc(data->max, sizeof(u64));
    if(extSaveDataIds != NULL) {
        if(R_SUCCEEDED(res = FSUSER_EnumerateExtSaveData(&extSaveDataCount, data->max, mediaType, 8, mediaType == MEDIATYPE_NAND, (u8*) extSaveDataIds))) {
            qsort(extSaveDataIds, extSaveDataCount, sizeof(u64), util_compare_u64);

            SMDH smdh;
            for(u32 i = 0; i < extSaveDataCount && i < data->max; i++) {
                if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) {
                    break;
                }

                ext_save_data_info* extSaveDataInfo = (ext_save_data_info*) calloc(1, sizeof(ext_save_data_info));
                if(extSaveDataInfo != NULL) {
                    extSaveDataInfo->mediaType = mediaType;
                    extSaveDataInfo->extSaveDataId = extSaveDataIds[i];
                    extSaveDataInfo->shared = mediaType == MEDIATYPE_NAND;

                    list_item* item = &data->items[*data->count];

                    FS_ExtSaveDataInfo info = {.mediaType = mediaType, .saveId = extSaveDataIds[i]};
                    u32 smdhBytesRead = 0;
                    if(R_SUCCEEDED(FSUSER_ReadExtSaveDataIcon(&smdhBytesRead, info, sizeof(SMDH), (u8*) &smdh)) && smdhBytesRead == sizeof(SMDH)) {
                        u8 systemLanguage = CFG_LANGUAGE_EN;
                        CFGU_GetSystemLanguage(&systemLanguage);

                        utf16_to_utf8((uint8_t*) item->name, smdh.titles[systemLanguage].shortDescription, NAME_MAX);

                        extSaveDataInfo->hasSmdh = true;
                        utf16_to_utf8((uint8_t*) extSaveDataInfo->smdhInfo.shortDescription, smdh.titles[systemLanguage].shortDescription, sizeof(extSaveDataInfo->smdhInfo.shortDescription));
                        utf16_to_utf8((uint8_t*) extSaveDataInfo->smdhInfo.longDescription, smdh.titles[systemLanguage].longDescription, sizeof(extSaveDataInfo->smdhInfo.longDescription));
                        utf16_to_utf8((uint8_t*) extSaveDataInfo->smdhInfo.publisher, smdh.titles[systemLanguage].publisher, sizeof(extSaveDataInfo->smdhInfo.publisher));
                        extSaveDataInfo->smdhInfo.texture = screen_load_texture_tiled_auto(smdh.largeIcon, sizeof(smdh.largeIcon), 48, 48, GPU_RGB565, false);
                    } else {
                        extSaveDataInfo->hasSmdh = false;
                    }

                    bool empty = strlen(item->name) == 0;
                    if(!empty) {
                        empty = true;

                        char* curr = item->name;
                        while(*curr) {
                            if(*curr != ' ') {
                                empty = false;
                                break;
                            }

                            curr++;
                        }
                    }

                    if(empty) {
                        snprintf(item->name, NAME_MAX, "%016llX", extSaveDataIds[i]);
                    }

                    if(mediaType == MEDIATYPE_NAND) {
                        item->rgba = COLOR_NAND;
                    } else if(mediaType == MEDIATYPE_SD) {
                        item->rgba = COLOR_SD;
                    }

                    item->data = extSaveDataInfo;

                    (*data->count)++;
                }
            }
        }

        free(extSaveDataIds);
    } else {
Beispiel #2
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;
}