static Result action_paste_files_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; char dstPath[FILE_PATH_MAX]; action_paste_files_get_dst_path(pasteData, index, dstPath); FS_Path* fsPath = util_make_path_utf8(dstPath); if(fsPath != NULL) { Handle currHandle; pasteData->currExists = R_SUCCEEDED(FSUSER_OpenFile(&currHandle, pasteData->target->archive, *fsPath, FS_OPEN_READ, 0)); if(pasteData->currExists) { FSFILE_Close(currHandle); } else { res = FSUSER_CreateFile(pasteData->target->archive, *fsPath, 0, size); } if(R_SUCCEEDED(res)) { res = FSUSER_OpenFile(handle, pasteData->target->archive, *fsPath, FS_OPEN_WRITE, 0); } util_free_path_utf8(fsPath); } else { res = R_FBI_OUT_OF_MEMORY; } return res; }
Result getFile(u8 ** buffer, u64 * size) { Result ret = 0; Handle filehandle = 0; u32 tmpval = 0; ret = FSUSER_OpenFile(&filehandle, extdata_archive, verListPath, FS_OPEN_READ, 0); if (ret != 0) return ret; ret = FSFILE_GetSize(filehandle, size); if (ret != 0) return ret; if (*size <= ENTRY_SIZE) { *size = 0; return ret; } if (mode == MODE_ALL) *size = ENTRY_SIZE; *buffer = malloc(*size); ret = FSFILE_Read(filehandle, &tmpval, 0, *buffer, *size); if (ret != 0) return ret; FSFILE_Close(filehandle); return ret; }
Result FS_WriteFile(const char* path, const void* src, u64 size, FS_Archive archive, u32* bytesWritten) { if (!path || !src || !archive || !bytesWritten) return -1; Result ret; Handle fileHandle; debug_print("FS_WriteFile:\n"); ret = FSUSER_OpenFile(&fileHandle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_WRITE | FS_OPEN_CREATE, FS_ATTRIBUTE_NONE); r(" > FSUSER_OpenFile: %lx\n", ret); if (R_FAILED(ret)) return ret; if (R_SUCCEEDED(ret)) { ret = FSFILE_Write(fileHandle, bytesWritten, 0L, src, size, FS_WRITE_FLUSH); r(" > FSFILE_Write: %lx\n", ret); if (R_FAILED(ret) || *bytesWritten != size) ret = -2; } FSFILE_Close(fileHandle); r(" > FSFILE_Close\n"); return ret; }
struct VFile* VFileOpen3DS(FS_Archive* archive, const char* path, int flags) { struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS)); if (!vf3d) { return 0; } uint16_t utf16Path[PATH_MAX + 1]; ssize_t units = utf8_to_utf16(utf16Path, (const uint8_t*) path, PATH_MAX); utf16Path[units] = 0; FS_Path newPath = fsMakePath(PATH_UTF16, utf16Path); Result res = FSUSER_OpenFile(&vf3d->handle, *archive, newPath, flags, 0); if (res & 0xFFFC03FF) { free(vf3d); return 0; } vf3d->offset = 0; vf3d->d.close = _vf3dClose; vf3d->d.seek = _vf3dSeek; vf3d->d.read = _vf3dRead; vf3d->d.readline = VFileReadline; vf3d->d.write = _vf3dWrite; vf3d->d.map = _vf3dMap; vf3d->d.unmap = _vf3dUnmap; vf3d->d.truncate = _vf3dTruncate; vf3d->d.size = _vf3dSize; vf3d->d.sync = _vf3dSync; return &vf3d->d; }
struct VFile* VFileOpen3DS(FS_Archive* archive, const char* path, int flags) { struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS)); if (!vf3d) { return 0; } // TODO: Use UTF-16 FS_Path newPath = fsMakePath(PATH_ASCII, path); Result res = FSUSER_OpenFile(&vf3d->handle, *archive, newPath, flags, 0); if (res & 0xFFFC03FF) { free(vf3d); return 0; } vf3d->offset = 0; vf3d->d.close = _vf3dClose; vf3d->d.seek = _vf3dSeek; vf3d->d.read = _vf3dRead; vf3d->d.readline = VFileReadline; vf3d->d.write = _vf3dWrite; vf3d->d.map = _vf3dMap; vf3d->d.unmap = _vf3dUnmap; vf3d->d.truncate = _vf3dTruncate; vf3d->d.size = _vf3dSize; vf3d->d.sync = _vf3dSync; return &vf3d->d; }
Result write_savedata(char* path, u8* data, u32 size) { if(!path || !data || !size)return -1; Handle outFileHandle; u32 bytesWritten; Result ret = 0; int fail = 0; ret = FSUSER_OpenFile(&saveGameFsHandle, &outFileHandle, saveGameArchive, FS_makePath(PATH_CHAR, path), FS_OPEN_CREATE | FS_OPEN_WRITE, FS_ATTRIBUTE_NONE); if(ret){fail = -8; goto writeFail;} ret = FSFILE_Write(outFileHandle, &bytesWritten, 0x0, data, size, 0x10001); if(ret){fail = -9; goto writeFail;} ret = FSFILE_Close(outFileHandle); if(ret){fail = -10; goto writeFail;} ret = FSUSER_ControlArchive(saveGameFsHandle, saveGameArchive); writeFail: if(fail)sprintf(status, "Failed to write to file: %d\n %08X %08X", fail, (unsigned int)ret, (unsigned int)bytesWritten); else sprintf(status, "Successfully wrote to file!\n %08X ", (unsigned int)bytesWritten); return ret; }
// ================================================== Result FS_loadFile(char* path, void* dst, FS_archive* fsArchive, Handle* fsHandle, u64 maxSize, u32* bytesRead) // -------------------------------------------------- { if (!path || !dst || !fsArchive) return -1; Result ret = 0; u64 size; Handle fileHandle; if (!ret) { ret = FSUSER_OpenFile(fsHandle, &fileHandle, *fsArchive, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if (ret) return ret; } if (!ret) { ret = FSFILE_GetSize(fileHandle, &size); if (ret || size > maxSize) ret = -2; } if (!ret) { ret = FSFILE_Read(fileHandle, bytesRead, 0, dst, size); if (ret || *bytesRead < size) ret=-3; } FSFILE_Close(fileHandle); return ret; }
Result archive_getfilesize(Archive archive, char *path, u32 *outsize) { Result ret=0; struct stat filestats; u64 tmp64=0; Handle filehandle=0; char filepath[256]; if(archive==SDArchive) { memset(filepath, 0, 256); strncpy(filepath, path, 255); if(stat(filepath, &filestats)==-1)return errno; *outsize = filestats.st_size; return 0; } ret = FSUSER_OpenFile(NULL, &filehandle, extdata_archive, FS_makePath(PATH_CHAR, path), 1, 0); if(ret!=0)return ret; ret = FSFILE_GetSize(filehandle, &tmp64); if(ret==0)*outsize = (u32)tmp64; FSFILE_Close(filehandle); return ret; }
Result FS_ReadFile(const char* path, void* dst, u64 maxSize, FS_Archive archive, u32* bytesRead) { if (!path || !dst || !archive || !bytesRead) return -1; Result ret; u64 size; Handle fileHandle; debug_print("FS_ReadFile:\n"); ret = FSUSER_OpenFile(&fileHandle, archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); r(" > FSUSER_OpenFile: %lx\n", ret); if (R_FAILED(ret)) return ret; ret = FSFILE_GetSize(fileHandle, &size); r(" > FSFILE_GetSize: %lx\n", ret); if (R_FAILED(ret) || size > maxSize) ret = -2; if (R_SUCCEEDED(ret)) { ret = FSFILE_Read(fileHandle, bytesRead, 0x0, dst, size); r(" > FSFILE_Read: %lx\n", ret); if (R_FAILED(ret) || *bytesRead < size) ret = -3; } FSFILE_Close(fileHandle); r(" > FSFILE_Close\n"); return ret; }
static Result action_install_tickets_open_src(void* data, u32 index, u32* handle) { install_tickets_data* installData = (install_tickets_data*) data; FS_Path* fsPath = util_make_path_utf8(installData->contents[index]); Result res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0); util_free_path_utf8(fsPath); return res; }
Result write_savedata(const char* path, const void* data, size_t size) { if(!path || !data || size == 0) return -1; Result ret = -1; int fail = 0; fsUseSession(save_session); ret = FSUSER_OpenArchive(&save_archive, ARCHIVE_SAVEDATA, (FS_Path){PATH_EMPTY, 1, (u8*)""}); if(R_FAILED(ret)) { fail = -1; goto writeFail; } // delete file FSUSER_DeleteFile(save_archive, fsMakePath(PATH_ASCII, path)); FSUSER_ControlArchive(save_archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); Handle file = 0; ret = FSUSER_OpenFile(&file, save_archive, fsMakePath(PATH_ASCII, path), FS_OPEN_CREATE | FS_OPEN_WRITE, 0); if(R_FAILED(ret)) { fail = -2; goto writeFail; } u32 bytes_written = 0; ret = FSFILE_Write(file, &bytes_written, 0, data, size, FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME); if(R_FAILED(ret)) { fail = -3; goto writeFail; } ret = FSFILE_Close(file); if(R_FAILED(ret)) { fail = -4; goto writeFail; } ret = FSUSER_ControlArchive(save_archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0); if(R_FAILED(ret)) fail = -5; writeFail: FSUSER_CloseArchive(save_archive); fsEndUseSession(); if(fail) sprintf(status, "Failed to write to file: %d\n %08lX %08lX", fail, ret, bytes_written); else sprintf(status, "Successfully wrote to file!\n %08lX ", bytes_written); return ret; }
static Result action_paste_files_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; char dstPath[FILE_PATH_MAX]; action_paste_files_get_dst_path(pasteData, index, dstPath); FS_Path* fsPath = util_make_path_utf8(dstPath); if(fsPath != NULL) { Handle currHandle; if(R_SUCCEEDED(FSUSER_OpenFile(&currHandle, pasteData->target->archive, *fsPath, FS_OPEN_READ, 0))) { FSFILE_Close(currHandle); if(R_SUCCEEDED(res = FSUSER_DeleteFile(pasteData->target->archive, *fsPath))) { linked_list_iter iter; linked_list_iterate(pasteData->items, &iter); while(linked_list_iter_has_next(&iter)) { list_item* item = (list_item*) linked_list_iter_next(&iter); file_info* currInfo = (file_info*) item->data; if(strncmp(currInfo->path, dstPath, FILE_PATH_MAX) == 0) { linked_list_iter_remove(&iter); task_free_file(item); } } } } if(R_SUCCEEDED(res) && R_SUCCEEDED(res = FSUSER_CreateFile(pasteData->target->archive, *fsPath, ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes & ~FS_ATTRIBUTE_READ_ONLY, size))) { res = FSUSER_OpenFile(handle, pasteData->target->archive, *fsPath, FS_OPEN_WRITE, 0); } util_free_path_utf8(fsPath); } else { res = R_FBI_OUT_OF_MEMORY; } return res; }
Handle openFileHandle(const char *path, u32 openFlags) { Handle fileHandle = 0; LOG_VERBOSE("openFileHandle: %s, %d", path, openFlags); FS_Path filePath = fsMakePath(PATH_ASCII, path); if(R_FAILED(FSUSER_OpenFile(&fileHandle, sdmcArchive, filePath, openFlags, 0))) { LOG_VERBOSE("FSUSER_OpenFile failed."); return(0); } LOG_VERBOSE("File opened successfully."); return(fileHandle); }
int saveBitmap(const char* filename, u8* buffer, u32 w, u32 h) { u8* temp=(u8*)malloc(w*h*3+sizeof(INFOHEADER)+sizeof(HEADER)); HEADER* header=(HEADER*)temp; INFOHEADER* infoheader=(INFOHEADER*)(temp+sizeof(HEADER)); write16(&header->type, 0x4D42); write32(&header->size, w*h*3+sizeof(INFOHEADER)+sizeof(HEADER)); write32(&header->offset, sizeof(INFOHEADER)+sizeof(HEADER)); write16(&header->reserved1, 0); write16(&header->reserved2, 0); write16(&infoheader->bits, 24); write32(&infoheader->size, sizeof(INFOHEADER)); write32(&infoheader->compression, 0); write32(&infoheader->width, w); write32(&infoheader->height, h); write16(&infoheader->planes, 1); write32(&infoheader->imagesize, w*h*3); write32(&infoheader->xresolution, 0); write32(&infoheader->yresolution, 0); write32(&infoheader->importantcolours, 0); write32(&infoheader->ncolours, 0); int y,x; for(y=0;y<h;y++) { for(x=0;x<w;x++) { temp[((y*w)+x)*3+sizeof(INFOHEADER)+sizeof(HEADER)]=buffer[(x*h+y)*3+0]; temp[((y*w)+x)*3+1+sizeof(INFOHEADER)+sizeof(HEADER)]=buffer[(x*h+y)*3+1]; temp[((y*w)+x)*3+2+sizeof(INFOHEADER)+sizeof(HEADER)]=buffer[(x*h+y)*3+2]; } } Handle file; Result ret=FSUSER_OpenFile(NULL, &file, configuration.sdmc, FS_makePath(PATH_CHAR, filename), FS_OPEN_WRITE|FS_OPEN_CREATE, FS_ATTRIBUTE_NONE); if(ret){svcCloseHandle(file); return -2;} u32 size=w*h*3+sizeof(INFOHEADER)+sizeof(HEADER); u32 bytesWritten=0; ret=FSFILE_Write(file, &bytesWritten, 0, temp, size, FS_WRITE_FLUSH); if(ret || bytesWritten!=size)return -2; FSFILE_Close(file); svcCloseHandle(file); free(temp); return 0; }
bool fileExists(char *path) { if (!path)return false; Result ret; Handle fileHandle; ret = FSUSER_OpenFile(NULL, &fileHandle, sdmcArchive, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if (ret != 0)return false; ret = FSFILE_Close(fileHandle); if (ret != 0)return false; return true; }
void getNextScreenshotCnt() { //open files while incrementing screenshotCnt until file doesn't exist static char path[256]; Result ret=0; while(!ret && screenshotCnt<MAX_SCREENSHOTS) { screenshotCnt++; snprintf(path, 256, "%s/scr_%d_left.bmp", configuration.path, screenshotCnt); Handle file; ret=FSUSER_OpenFile(NULL, &file, configuration.sdmc, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSFILE_Close(file); svcCloseHandle(file); } }
void dbg_save(char* path, void* buf, int size) { Handle sram; FS_path sramPath; sramPath.type = PATH_CHAR; sramPath.size = strlen(path) + 1; sramPath.data = (u8*)path; Result res = FSUSER_OpenFile(NULL, &sram, sdmcArchive, sramPath, FS_OPEN_CREATE|FS_OPEN_WRITE, FS_ATTRIBUTE_NONE); if ((res & 0xFFFC03FF) == 0) { u32 byteswritten = 0; FSFILE_Write(sram, &byteswritten, 0, (u32*)buf, size, 0x10001); FSFILE_Close(sram); } }
static Result action_paste_files_open_src(void* data, u32 index, u32* handle) { paste_files_data* pasteData = (paste_files_data*) data; Result res = 0; FS_Path* fsPath = util_make_path_utf8(((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->path); if(fsPath != NULL) { res = FSUSER_OpenFile(handle, clipboard_get_archive(), *fsPath, FS_OPEN_READ, 0); util_free_path_utf8(fsPath); } else { res = R_FBI_OUT_OF_MEMORY; } return res; }
// ================================================== Result FS_saveFile(char* path, void* src, u64 size, FS_archive* fsArchive, Handle* fsHandle, u32* bytesWritten) // -------------------------------------------------- { if (!path || !src || !fsArchive) return -1; Result ret; Handle fileHandle; ret = FSUSER_OpenFile(fsHandle, &fileHandle, *fsArchive, FS_makePath(PATH_CHAR, path), FS_OPEN_WRITE | FS_OPEN_CREATE, FS_ATTRIBUTE_NONE); if (ret) return ret; ret = FSFILE_Write(fileHandle, bytesWritten, 0, src, size, FS_WRITE_NOFLUSH); if (ret) return ret; FSFILE_Close(fileHandle); return ret; }
Result archive_writefile(Archive archive, char *path, u8 *buffer, u32 size) { Result ret=0; Handle filehandle=0; u32 tmpval=0; FILE *f; char filepath[256]; if(archive==SDArchive) { memset(filepath, 0, 256); strncpy(filepath, path, 255); f = fopen(filepath, "w+"); if(f==NULL)return errno; tmpval = fwrite(buffer, 1, size, f); fclose(f); if(tmpval!=size)return -2; return 0; } FS_path fspath = FS_makePath(PATH_CHAR, path); ret = FSUSER_DeleteFile(NULL, extdata_archive, fspath); ret = FSUSER_CreateFile(NULL, extdata_archive, fspath, size); if(ret!=0)return ret; ret = FSUSER_OpenFile(NULL, &filehandle, extdata_archive, fspath, FS_OPEN_WRITE, 0); if(ret!=0)return ret; ret = FSFILE_Write(filehandle, &tmpval, 0, buffer, size, FS_WRITE_FLUSH); FSFILE_Close(filehandle); if(ret==0 && tmpval!=size)ret=-2; return ret; }
void DumpSharedRomFS(u8* archive_binary_lowpath) { std::string output_file = BuildSharedRomFSFilename(archive_binary_lowpath); // Read RomFS bin from SaveDataCheck... Handle romfs_handle; u64 romfs_size = 0; u32 romfs_bytes_read = 0; FS_archive savedatacheck_archive = { 0x2345678a, { PATH_BINARY, 16, archive_binary_lowpath } }; u8 file_binary_lowpath[20] = {}; FS_path romfs_path = { PATH_BINARY, 20, file_binary_lowpath }; print(GFX_TOP, "Dumping SaveDataCheck RomFS (%s)... ", output_file.c_str()); FSUSER_OpenFileDirectly(NULL, &romfs_handle, savedatacheck_archive, romfs_path, FS_OPEN_READ, FS_ATTRIBUTE_NONE); FSFILE_GetSize(romfs_handle, &romfs_size); std::unique_ptr<u8> romfs_data_buffer(new u8[romfs_size]); FSFILE_Read(romfs_handle, &romfs_bytes_read, 0, romfs_data_buffer.get(), romfs_size); FSFILE_Close(romfs_handle); // Dump RomFS bin to SDMC... Handle file_handle; u32 bytes_written = 0; FS_path fs_path = FS_makePath(PATH_CHAR, output_file.c_str()); FS_archive sdmc_archive = (FS_archive) { 0x00000009, { PATH_EMPTY, 1, (u8*) "" } }; FSUSER_OpenArchive(NULL, &sdmc_archive); FSUSER_OpenFile(NULL, &file_handle, sdmc_archive, fs_path, FS_OPEN_CREATE | FS_OPEN_WRITE, FS_ATTRIBUTE_NONE); Result res = FSFILE_Write(file_handle, &bytes_written, 0x0, romfs_data_buffer.get(), romfs_size, FS_WRITE_FLUSH); FSFILE_Close(file_handle); FSUSER_CloseArchive(NULL, &sdmc_archive); // Check result... if (res == 0 && bytes_written == romfs_size) print(GFX_TOP, "Done!\n"); else print(GFX_TOP, "Failed!\n"); }
Result putFile(u8 * buffer, u64 size) { Result ret = 0; Handle filehandle = 0; u32 tmpval = 0; ret = FSUSER_DeleteFile(extdata_archive, verListPath); ret = FSUSER_CreateFile(extdata_archive, verListPath, 0, size); if (ret != 0) return ret; ret = FSUSER_OpenFile(&filehandle, extdata_archive, verListPath, FS_OPEN_WRITE, 0); if (ret != 0) return ret; ret = FSFILE_Write(filehandle, &tmpval, 0, buffer, size, FS_WRITE_FLUSH); FSFILE_Close(filehandle); return ret; }
App appGetCiaInfo(const std::string file, MediaType mediaType) { if(!serviceRequire("am")) { return {}; } FS_archive archive = (FS_archive) {ARCH_SDMC, (FS_path) {PATH_EMPTY, 1, (u8*) ""}}; Result archiveResult = FSUSER_OpenArchive(NULL, &archive); if(archiveResult != 0) { platformSetError(serviceParseError((u32) archiveResult)); return {}; } Handle handle = 0; Result openResult = FSUSER_OpenFile(NULL, &handle, archive, FS_makePath(PATH_CHAR, file.c_str()), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if(openResult != 0) { platformSetError(serviceParseError((u32) openResult)); return {}; } TitleList titleInfo; Result infoResult = AM_GetCiaFileInfo(appMediatypeToByte(mediaType), &titleInfo, handle); if(infoResult != 0) { platformSetError(serviceParseError((u32) infoResult)); return {}; } FSFILE_Close(handle); FSUSER_CloseArchive(NULL, &archive); App app; app.titleId = titleInfo.titleID; app.uniqueId = ((u32*) &titleInfo.titleID)[0]; strcpy(app.productCode, "<N/A>"); app.mediaType = mediaType; app.platform = appPlatformFromId(((u16*) &titleInfo.titleID)[3]); app.category = appCategoryFromId(((u16*) &titleInfo.titleID)[2]); app.version = titleInfo.titleVersion; app.size = titleInfo.size; return app; }
/*! Get file stats * * @param[in,out] r newlib reentrancy struct * @param[in] file Path to file * @param[out] st Pointer to file stats to fill * * @returns 0 for success * @returns -1 for error */ static int sdmc_stat(struct _reent *r, const char *file, struct stat *st) { Handle fd; Result rc; FS_Path fs_path; fs_path = sdmc_utf16path(r, file); if(fs_path.data == NULL) return -1; if(R_SUCCEEDED(rc = FSUSER_OpenFile(&fd, sdmcArchive, fs_path, FS_OPEN_READ, 0))) { sdmc_file_t tmpfd = { .fd = fd }; rc = sdmc_fstat(r, &tmpfd, st); FSFILE_Close(fd); return rc; } else if(R_SUCCEEDED(rc = FSUSER_OpenDirectory(&fd, sdmcArchive, fs_path)))
Result archive_readfile(Archive archive, char *path, u8 *buffer, u32 size) { Result ret=0; Handle filehandle=0; u32 tmpval=0; FILE *f; char filepath[256]; if(archive==SDArchive) { memset(filepath, 0, 256); strncpy(filepath, path, 255); f = fopen(filepath, "r"); if(f==NULL)return errno; tmpval = fread(buffer, 1, size, f); fclose(f); if(tmpval!=size)return -2; return 0; } ret = FSUSER_OpenFile(NULL, &filehandle, extdata_archive, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, 0); if(ret!=0)return ret; ret = FSFILE_Read(filehandle, &tmpval, 0, buffer, size); FSFILE_Close(filehandle); if(ret==0 && tmpval!=size)ret=-2; return ret; }
int loadFile(char* path, void* dst, FS_archive* archive, u64 maxSize) { if(!path || !dst || !archive)return -1; u64 size; u32 bytesRead; Result ret; Handle fileHandle; ret=FSUSER_OpenFile(&fileHandle, *archive, FS_makePath(PATH_CHAR, path), FS_OPEN_READ, FS_ATTRIBUTE_NONE); if(ret!=0)return ret; ret=FSFILE_GetSize(fileHandle, &size); if(ret!=0)goto loadFileExit; if(size>maxSize){ret=-2; goto loadFileExit;} ret=FSFILE_Read(fileHandle, &bytesRead, 0x0, dst, size); if(ret!=0)goto loadFileExit; if(bytesRead<size){ret=-3; goto loadFileExit;} loadFileExit: FSFILE_Close(fileHandle); return ret; }
Result read_savedata(const char* path, void** data, size_t* size) { if(!path || !data || !size) return -1; Result ret = -1; int fail = 0; void* buffer = NULL; fsUseSession(save_session); ret = FSUSER_OpenArchive(&save_archive, ARCHIVE_SAVEDATA, (FS_Path){PATH_EMPTY, 1, (u8*)""}); if(R_FAILED(ret)) { fail = -1; goto readFail; } Handle file = 0; ret = FSUSER_OpenFile(&file, save_archive, fsMakePath(PATH_ASCII, path), FS_OPEN_READ, 0); if(R_FAILED(ret)) { fail = -2; goto readFail; } u64 file_size = 0; ret = FSFILE_GetSize(file, &file_size); buffer = malloc(file_size); if(!buffer) { fail = -3; goto readFail; } u32 bytes_read = 0; ret = FSFILE_Read(file, &bytes_read, 0, buffer, file_size); if(R_FAILED(ret)) { fail = -4; goto readFail; } ret = FSFILE_Close(file); if(R_FAILED(ret)) { fail = -5; goto readFail; } readFail: FSUSER_CloseArchive(save_archive); fsEndUseSession(); if(fail) { sprintf(status, "Failed to read file: %d\n %08lX %08lX", fail, ret, bytes_read); if(buffer) free(buffer); } else { sprintf(status, "Successfully read file.\n %08lX ", bytes_read); *data = buffer; *size = bytes_read; } return ret; }
/*! Open a file * * @param[in,out] r newlib reentrancy struct * @param[out] fileStruct Pointer to file struct to fill in * @param[in] path Path to open * @param[in] flags Open flags from open(2) * @param[in] mode Permissions to set on create * * @returns 0 for success * @returns -1 for error */ static int sdmc_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { Handle fd; Result rc; u32 sdmc_flags = 0; u32 attributes = 0; FS_Path fs_path; fs_path = sdmc_utf16path(r, path); if(fs_path.data == NULL) return -1; /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fileStruct; /* check access mode */ switch(flags & O_ACCMODE) { /* read-only: do not allow O_APPEND */ case O_RDONLY: sdmc_flags |= FS_OPEN_READ; if(flags & O_APPEND) { r->_errno = EINVAL; return -1; } break; /* write-only */ case O_WRONLY: sdmc_flags |= FS_OPEN_WRITE; break; /* read and write */ case O_RDWR: sdmc_flags |= (FS_OPEN_READ | FS_OPEN_WRITE); break; /* an invalid option was supplied */ default: r->_errno = EINVAL; return -1; } /* create file */ if(flags & O_CREAT) sdmc_flags |= FS_OPEN_CREATE; /* Test O_EXCL. */ if((flags & O_CREAT) && (flags & O_EXCL)) { rc = FSUSER_CreateFile(sdmcArchive, fs_path, attributes, 0); if(R_FAILED(rc)) { r->_errno = sdmc_translate_error(rc); return -1; } } /* set attributes */ /*if(!(mode & S_IWUSR)) attributes |= FS_ATTRIBUTE_READONLY;*/ /* open the file */ rc = FSUSER_OpenFile(&fd, sdmcArchive, fs_path, sdmc_flags, attributes); if(R_SUCCEEDED(rc)) { if((flags & O_ACCMODE) != O_RDONLY && (flags & O_TRUNC)) { rc = FSFILE_SetSize(fd, 0); if(R_FAILED(rc)) { FSFILE_Close(fd); r->_errno = sdmc_translate_error(rc); return -1; } } file->fd = fd; file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC)); file->offset = 0; return 0; } r->_errno = sdmc_translate_error(rc); return -1; }
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; }
/*! Open a file * * @param[in,out] r newlib reentrancy struct * @param[out] fileStruct Pointer to file struct to fill in * @param[in] path Path to open * @param[in] flags Open flags from open(2) * @param[in] mode Permissions to set on create * * @returns 0 for success * @returns -1 for error */ static int sdmc_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { Handle fd; Result rc; u32 sdmc_flags = 0; u32 attributes = FS_ATTRIBUTE_NONE; const char *pathptr = NULL; pathptr = sdmc_fixpath(path); if(pathptr==NULL) { r->_errno=EINVAL; return -1; } /* get pointer to our data */ sdmc_file_t *file = (sdmc_file_t*)fileStruct; /* check access mode */ switch(flags & O_ACCMODE) { /* read-only: do not allow O_APPEND */ case O_RDONLY: sdmc_flags |= FS_OPEN_READ; if(flags & O_APPEND) { r->_errno = EINVAL; return -1; } break; /* write-only */ case O_WRONLY: sdmc_flags |= FS_OPEN_WRITE; break; /* read and write */ case O_RDWR: sdmc_flags |= (FS_OPEN_READ | FS_OPEN_WRITE); break; /* an invalid option was supplied */ default: r->_errno = EINVAL; return -1; } /* create file */ if(flags & O_CREAT) sdmc_flags |= FS_OPEN_CREATE; /* TODO: Test O_EXCL. */ /* set attributes */ /*if(!(mode & S_IWUSR)) attributes |= FS_ATTRIBUTE_READONLY;*/ /* open the file */ rc = FSUSER_OpenFile(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr), sdmc_flags, attributes); if(rc == 0) { file->fd = fd; file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC)); file->offset = 0; return 0; } r->_errno = rc; return -1; }