#include #include #include #include #include "../config.h" #include "blob.h" #include "panic.h" #include "isfs.h" #define ROUNDUP32B(x) ((x + 32 - 1) & ~(32 - 1)) static fstats __st ATTRIBUTE_ALIGN(32); s32 isfs_get(const char *path, u8 **buf, u32 expected, u32 maxsize, bool use_blob) { s32 ret; s32 fd; u8 *__buf; gprintf("reading %s (expecting %lu bytes)\n", path, expected); ret = ISFS_Open(path, ISFS_OPEN_READ); if (ret < 0) { gprintf("ISFS_Open failed (%ld)\n", ret); return ret; } fd = ret; ret = ISFS_GetFileStats(fd, &__st); if (ret < 0) { gprintf("ISFS_GetFileStats failed (%ld)\n", ret); return ret; } DCInvalidateRange(&__st, sizeof(__st)); if ((__st.file_length == 0) || (maxsize && (__st.file_length > maxsize)) || (expected && (__st.file_length != expected))) { gprintf("invalid size: %lu\n", __st.file_length); ISFS_Close(fd); return -1; } if (use_blob) { __buf = blob_alloc(ROUNDUP32B(__st.file_length + 1)); if (!__buf) panic(); } else { __buf = pmemalign(32, ROUNDUP32B(__st.file_length + 1)); } gprintf("reading %lu bytes\n", __st.file_length); ret = ISFS_Read(fd, __buf, __st.file_length); if (ret < 0) { gprintf("ISFS_Read failed (%ld)\n", ret); free(__buf); ISFS_Close(fd); return ret; } DCInvalidateRange(__buf, __st.file_length + 1); __buf[__st.file_length] = 0; if (ret != __st.file_length) { gprintf("ISFS_Read short read (%ld)\n", ret); free(__buf); ISFS_Close(fd); return -1; } ret = ISFS_Close(fd); if (ret < 0) { gprintf("ISFS_Close failed (%ld)\n", ret); free(__buf); return ret; } *buf = __buf; return __st.file_length; } s32 isfs_put(const char *path, const void *buf, u32 len) { s32 fd, ret; ISFS_Delete(path); gprintf("writing %s (%lu bytes)\n", path, len); ret = ISFS_CreateFile(path, 0, 3, 3, 0); if (ret < 0) { gprintf("ISFS_CreateFile failed (%ld)\n", ret); return ret; } ret = ISFS_Open(path, 3); if (ret < 0) { gprintf("ISFS_Open failed (%ld)\n", ret); ISFS_Delete(path); return ret; } fd = ret; DCFlushRange((void *) buf, len); ret = ISFS_Write(fd, buf, len); if (ret < 0) { gprintf("ISFS_Write failed (%ld)\n", ret); ISFS_Close(fd); ISFS_Delete(path); return ret; } if (ret != len) { gprintf("ISFS_Write short write (%ld)\n", ret); ISFS_Close(fd); ISFS_Delete(path); return -1; } ret = ISFS_Close(fd); if (ret < 0) { gprintf("ISFS_Close failed (%ld)\n", ret); ISFS_Delete(path); return ret; } return 0; }