mirror of
https://github.com/fail0verflow/hbc.git
synced 2024-11-17 23:29:21 +01:00
130 lines
2.5 KiB
C
130 lines
2.5 KiB
C
|
#include <malloc.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <gccore.h>
|
||
|
|
||
|
#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;
|
||
|
}
|
||
|
|