diff --git a/include/iosuhax.h b/include/iosuhax.h index 5b5f1c2..f4890dc 100644 --- a/include/iosuhax.h +++ b/include/iosuhax.h @@ -38,25 +38,26 @@ extern "C" { #define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) #define FSA_MOUNTFLAGS_GLOBAL (1 << 1) -int IOSUHAX_UnlockFSClient(FSClient *client); +FSError IOSUHAX_UnlockFSClient(FSClient *client); +FSError IOSUHAX_UnlockFSClientEx(int clientHandle); -int IOSUHAX_FSAMount(FSClient *client, const char *source, const char *target); -int IOSUHAX_FSAMountEx(int clientHandle, const char *source, const char *target); +FSError IOSUHAX_FSAMount(FSClient *client, const char *source, const char *target, uint32_t flags, void *arg_buf, uint32_t arg_len); +FSError IOSUHAX_FSAMountEx(int clientHandle, const char *source, const char *target, uint32_t flags, void *arg_buf, uint32_t arg_len); -int IOSUHAX_FSAUnmount(FSClient *client, const char *mountedTarget); -int IOSUHAX_FSAUnmountEx(int clientHandle, const char *mountedTarget); +FSError IOSUHAX_FSAUnmount(FSClient *client, const char *mountedTarget); +FSError IOSUHAX_FSAUnmountEx(int clientHandle, const char *mountedTarget); -int IOSUHAX_FSARawOpen(FSClient *client, char *device_path, int32_t *outHandle); -int IOSUHAX_FSARawOpenEx(int clientHandle, char *device_path, int32_t *outHandle); +FSError IOSUHAX_FSARawOpen(FSClient *client, char *device_path, int32_t *outHandle); +FSError IOSUHAX_FSARawOpenEx(int clientHandle, char *device_path, int32_t *outHandle); -int IOSUHAX_FSARawRead(FSClient *client, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); -int IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); +FSError IOSUHAX_FSARawRead(FSClient *client, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); +FSError IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); -int IOSUHAX_FSARawWrite(FSClient *client, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); -int IOSUHAX_FSARawWriteEx(int clientHandle, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); +FSError IOSUHAX_FSARawWrite(FSClient *client, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); +FSError IOSUHAX_FSARawWriteEx(int clientHandle, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle); -int IOSUHAX_FSARawClose(FSClient *client, int32_t device_handle); -int IOSUHAX_FSARawCloseEx(int clientHandle, int32_t device_handle); +FSError IOSUHAX_FSARawClose(FSClient *client, int32_t device_handle); +FSError IOSUHAX_FSARawCloseEx(int clientHandle, int32_t device_handle); int IOSUHAX_Open(const char *dev); // if dev == NULL the default path /dev/iosuhax will be used int IOSUHAX_Close(void); diff --git a/source/iosuhax.cpp b/source/iosuhax.cpp index e12203d..a7338b9 100644 --- a/source/iosuhax.cpp +++ b/source/iosuhax.cpp @@ -48,34 +48,43 @@ static int iosuhaxHandle = -1; #define ALIGN_0x40 ALIGN(0x40) #define ROUNDUP(x, align) (((x) + ((align) -1)) & ~((align) -1)) -int IOSUHAX_UnlockFSClient(FSClient *client) { +FSError IOSUHAX_UnlockFSClient(FSClient *client) { if (!client) { - return -1; + return FS_ERROR_INVALID_CLIENTHANDLE; } + + return IOSUHAX_UnlockFSClientEx(FSGetClientBody(client)->clientHandle); +} + +FSError IOSUHAX_UnlockFSClientEx(int clientHandle) { ALIGN(0x40) int dummy[0x40 >> 2]; - return IOS_Ioctl(FSGetClientBody(client)->clientHandle, 0x28, dummy, sizeof(dummy), dummy, sizeof(dummy)); -} - -#define __FSAShimSetupRequestMount ((int (*)(FSAShimBuffer *, uint32_t, const char *, const char *, uint32_t, uint32_t, uint32_t))(0x101C400 + 0x042f88)) -#define __FSAShimSetupRequestUnmount ((int (*)(FSAShimBuffer *, uint32_t, const char *, uint32_t))(0x101C400 + 0x43130)) -#define __FSAShimSend ((int (*)(FSAShimBuffer *, uint32_t))(0x101C400 + 0x042d90)) - -int IOSUHAX_FSAMount(FSClient *client, const char *source, const char *target) { - if (!client) { - return -1; + if (IOS_Ioctl(clientHandle, 0x28, dummy, sizeof(dummy), dummy, sizeof(dummy)) == 0) { + return static_cast(0); } - return IOSUHAX_FSAMountEx(FSGetClientBody(client)->clientHandle, source, target); + return FS_ERROR_PERMISSION_ERROR; } -int IOSUHAX_FSAMountEx(int clientHandle, const char *source, const char *target) { +#define __FSAShimSetupRequestMount ((FSError(*)(FSAShimBuffer *, uint32_t, const char *, const char *, uint32_t, void *, uint32_t))(0x101C400 + 0x042f88)) +#define __FSAShimSetupRequestUnmount ((FSError(*)(FSAShimBuffer *, uint32_t, const char *, uint32_t))(0x101C400 + 0x43130)) +#define __FSAShimSend ((FSError(*)(FSAShimBuffer *, uint32_t))(0x101C400 + 0x042d90)) +#define __FSAStatusToFSStatus ((FSStatus(*)(FSError))(0x101C400 + 0x58ad4)) + + +FSError IOSUHAX_FSAMount(FSClient *client, const char *source, const char *target, uint32_t flags, void *arg_buf, uint32_t arg_len) { + if (!client) { + return FS_ERROR_INVALID_CLIENTHANDLE; + } + return IOSUHAX_FSAMountEx(FSGetClientBody(client)->clientHandle, source, target, flags, arg_buf, arg_len); +} + +FSError IOSUHAX_FSAMountEx(int clientHandle, const char *source, const char *target, uint32_t flags, void *arg_buf, uint32_t arg_len) { auto *buffer = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); if (!buffer) { - return -1; + return FS_ERROR_INVALID_BUFFER; } - - int res = __FSAShimSetupRequestMount(buffer, clientHandle, source, target, 0, 0, 0); + auto res = __FSAShimSetupRequestMount(buffer, clientHandle, source, target, 2, arg_buf, arg_len); if (res != 0) { free(buffer); return res; @@ -85,20 +94,20 @@ int IOSUHAX_FSAMountEx(int clientHandle, const char *source, const char *target) return res; } -int IOSUHAX_FSAUnmount(FSClient *client, const char *mountedTarget) { +FSError IOSUHAX_FSAUnmount(FSClient *client, const char *mountedTarget) { if (!client) { - return -1; + return FS_ERROR_INVALID_CLIENTHANDLE; } return IOSUHAX_FSAUnmountEx(FSGetClientBody(client)->clientHandle, mountedTarget); } -int IOSUHAX_FSAUnmountEx(int clientHandle, const char *mountedTarget) { +FSError IOSUHAX_FSAUnmountEx(int clientHandle, const char *mountedTarget) { auto *buffer = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); if (!buffer) { - return -1; + return FS_ERROR_INVALID_BUFFER; } - int res = __FSAShimSetupRequestUnmount(buffer, clientHandle, mountedTarget, 0 /*0x80000000 for FSBindUnmount*/); + auto res = __FSAShimSetupRequestUnmount(buffer, clientHandle, mountedTarget, 0 /*0x80000000 for FSBindUnmount*/); if (res != 0) { free(buffer); return res; @@ -108,17 +117,23 @@ int IOSUHAX_FSAUnmountEx(int clientHandle, const char *mountedTarget) { return res; } -int IOSUHAX_FSARawOpen(FSClient *client, char *device_path, int32_t *outHandle) { +FSError IOSUHAX_FSARawOpen(FSClient *client, char *device_path, int32_t *outHandle) { if (!client) { - return -1; + return FS_ERROR_INVALID_CLIENTHANDLE; } return IOSUHAX_FSARawOpenEx(FSGetClientBody(client)->clientHandle, device_path, outHandle); } -int IOSUHAX_FSARawOpenEx(int clientHandle, char *device_path, int32_t *outHandle) { +FSError IOSUHAX_FSARawOpenEx(int clientHandle, char *device_path, int32_t *outHandle) { + if (!outHandle) { + return FS_ERROR_INVALID_BUFFER; + } + if (!device_path) { + return FS_ERROR_INVALID_PATH; + } auto *shim = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); if (!shim) { - return -1; + return FS_ERROR_INVALID_BUFFER; } shim->clientHandle = clientHandle; @@ -130,7 +145,7 @@ int IOSUHAX_FSARawOpenEx(int clientHandle, char *device_path, int32_t *outHandle strncpy(requestBuffer->path, device_path, 0x27F); - int res = __FSAShimSend(shim, 0); + auto res = __FSAShimSend(shim, 0); if (res >= 0) { *outHandle = shim->response.rawOpen.handle; } @@ -138,14 +153,17 @@ int IOSUHAX_FSARawOpenEx(int clientHandle, char *device_path, int32_t *outHandle return res; } -int IOSUHAX_FSARawClose(FSClient *client, int32_t device_handle) { +FSError IOSUHAX_FSARawClose(FSClient *client, int32_t device_handle) { + if (!client) { + return FS_ERROR_INVALID_CLIENTHANDLE; + } return IOSUHAX_FSARawCloseEx(FSGetClientBody(client)->clientHandle, device_handle); } -int IOSUHAX_FSARawCloseEx(int clientHandle, int32_t device_handle) { +FSError IOSUHAX_FSARawCloseEx(int clientHandle, int32_t device_handle) { auto *buffer = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); if (!buffer) { - return -1; + return FS_ERROR_INVALID_BUFFER; } buffer->clientHandle = clientHandle; @@ -160,19 +178,25 @@ int IOSUHAX_FSARawCloseEx(int clientHandle, int32_t device_handle) { requestBuffer->handle = device_handle; - int res = __FSAShimSend(buffer, 0); + auto res = __FSAShimSend(buffer, 0); free(buffer); return res; } -int IOSUHAX_FSARawRead(FSClient *client, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { +FSError IOSUHAX_FSARawRead(FSClient *client, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { + if (!client) { + return FS_ERROR_INVALID_CLIENTHANDLE; + } return IOSUHAX_FSARawReadEx(FSGetClientBody(client)->clientHandle, data, size_bytes, cnt, blocks_offset, device_handle); } -int IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { +FSError IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { + if (data == nullptr) { + return FS_ERROR_INVALID_BUFFER; + } auto *shim = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); if (!shim) { - return -1; + return FS_ERROR_INVALID_BUFFER; } shim->clientHandle = clientHandle; @@ -188,11 +212,12 @@ int IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint auto *tmp = data; if ((uint32_t) data & 0x3F) { - OSReport("## WARNING: IOSUHAX_FSARawReadEx buffer not aligned (%08X). Align to 0x40 for best performance\n", data); auto *alignedBuffer = memalign(0x40, ROUNDUP(size_bytes * cnt, 0x40)); if (!alignedBuffer) { - return -2; + OSReport("## ERROR: IOSUHAX_FSARawReadEx buffer not aligned (%08X).\n", data); + return FS_ERROR_INVALID_ALIGNMENT; } + OSReport("## WARNING: IOSUHAX_FSARawReadEx buffer not aligned (%08X). Align to 0x40 for best performance\n", data); tmp = alignedBuffer; } @@ -208,7 +233,7 @@ int IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint request.size = size_bytes; request.device_handle = device_handle; - int res = __FSAShimSend(shim, 0); + auto res = __FSAShimSend(shim, 0); if (res >= 0 && tmp != data) { memcpy(data, tmp, size_bytes * cnt); } @@ -220,17 +245,17 @@ int IOSUHAX_FSARawReadEx(int clientHandle, void *data, uint32_t size_bytes, uint return res; } -int IOSUHAX_FSARawWrite(FSClient *client, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { +FSError IOSUHAX_FSARawWrite(FSClient *client, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { if (!client) { - return -1; + return FS_ERROR_INVALID_CLIENTHANDLE; } return IOSUHAX_FSARawWriteEx(FSGetClientBody(client)->clientHandle, data, size_bytes, cnt, blocks_offset, device_handle); } -int IOSUHAX_FSARawWriteEx(int clientHandle, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { +FSError IOSUHAX_FSARawWriteEx(int clientHandle, const void *data, uint32_t size_bytes, uint32_t cnt, uint64_t blocks_offset, int device_handle) { auto *shim = (FSAShimBuffer *) memalign(0x40, sizeof(FSAShimBuffer)); if (!shim) { - return -1; + return FS_ERROR_INVALID_BUFFER; } shim->clientHandle = clientHandle; @@ -245,11 +270,12 @@ int IOSUHAX_FSARawWriteEx(int clientHandle, const void *data, uint32_t size_byte void *tmp = (void *) data; if ((uint32_t) data & 0x3F) { - OSReport("## WARNING: IOSUHAX_FSARawWriteEx buffer not aligned (%08X). Align to 0x40 for best performance\n", data); auto *alignedBuffer = memalign(0x40, ROUNDUP(size_bytes * cnt, 0x40)); if (!alignedBuffer) { - return -2; + OSReport("## ERROR: IOSUHAX_FSARawWriteEx buffer not aligned (%08X).\n", data); + return FS_ERROR_INVALID_ALIGNMENT; } + OSReport("## WARNING: IOSUHAX_FSARawWriteEx buffer not aligned (%08X). Align to 0x40 for best performance\n", data); tmp = alignedBuffer; memcpy(tmp, data, size_bytes * cnt); } @@ -266,7 +292,7 @@ int IOSUHAX_FSARawWriteEx(int clientHandle, const void *data, uint32_t size_byte request.size = size_bytes; request.device_handle = device_handle; - int res = __FSAShimSend(shim, 0); + auto res = __FSAShimSend(shim, 0); if (tmp != data) { free(tmp); diff --git a/source/iosuhax_disc_interface.c b/source/iosuhax_disc_interface.c index c439dfc..6e0f6e0 100644 --- a/source/iosuhax_disc_interface.c +++ b/source/iosuhax_disc_interface.c @@ -54,17 +54,27 @@ static bool IOSUHAX_disc_io_fsa_open(int fsaFd) { if (fsaFd == FSA_REF_SD) { if (fsaFdSd < 0) { fsaFdSd = IOS_Open("/dev/fsa", IOS_OPEN_READWRITE); + if(fsaFdSd >= 0 && IOSUHAX_UnlockFSClientEx(fsaFdSd) < 0){ + IOS_Close(fsaFdSd); + fsaFdSd = -1; + } } - if (fsaFdSd >= 0) + if (fsaFdSd >= 0) { return true; + } } else if (fsaFd == FSA_REF_USB) { if (fsaFdUsb < 0) { fsaFdUsb = IOS_Open("/dev/fsa", IOS_OPEN_READWRITE); + if(fsaFdUsb >= 0 && IOSUHAX_UnlockFSClientEx(fsaFdUsb) < 0){ + IOS_Close(fsaFdUsb); + fsaFdUsb = -1; + } } - if (fsaFdUsb >= 0) + if (fsaFdUsb >= 0) { return true; + } } return false;