From fec2db78966a8115c82cb6f7ec53dd6036d61200 Mon Sep 17 00:00:00 2001 From: koolkdev Date: Mon, 14 Aug 2017 03:14:42 +0300 Subject: [PATCH 1/9] add FSA_ChangeOwner --- wupserver/source/fsa.c | 18 ++++++++++++++++++ wupserver/source/fsa.h | 1 + wupserver/source/ipc.c | 11 +++++++++++ 3 files changed, 30 insertions(+) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index 40f0d7d..4c3bbc7 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -314,6 +314,24 @@ int FSA_ChangeMode(int fd, char *path, int mode) return ret; } +int FSA_ChangeOwner(int fd, char *path, int user, int group) +{ + u8* iobuf = allocIobuf(); + u32* inbuf = (u32*)iobuf; + u32* outbuf = (u32*)&iobuf[0x520]; + + strncpy((char*)&inbuf[0x01], path, 0x27F); + inbuf[0x284/4] = 0; // ignored + inbuf[0x288/4] = user; + inbuf[0x28C/4] = 0; // ignored + inbuf[0x290/4] = group; + + int ret = svcIoctl(fd, 0x70, inbuf, 0x520, outbuf, 0x293); + + freeIobuf(iobuf); + return ret; +} + // type 4 : // 0x08 : device size in sectors (u64) // 0x10 : device sector size (u32) diff --git a/wupserver/source/fsa.h b/wupserver/source/fsa.h index 88366bf..2971c7e 100644 --- a/wupserver/source/fsa.h +++ b/wupserver/source/fsa.h @@ -51,6 +51,7 @@ int FSA_SetPosFile(int fd, int fileHandle, u32 position); int FSA_GetStat(int fd, char *path, fileStat_s* out_data); int FSA_Remove(int fd, char *path); int FSA_ChangeMode(int fd, char *path, int mode); +int FSA_ChangeOwner(int fd, char *path, int user, int group); int FSA_RawOpen(int fd, char* device_path, int* outHandle); int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle); diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index cc70a3f..67b8dec 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -73,6 +73,7 @@ #define IOCTL_FSA_CHANGEMODE 0x58 #define IOCTL_FSA_FLUSHVOLUME 0x59 #define IOCTL_CHECK_IF_IOSUHAX 0x5B +#define IOCTL_FSA_CHANGEOWNER 0x5C //static u8 threadStack[0x1000] __attribute__((aligned(0x20))); @@ -415,6 +416,16 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode); break; + } + case IOCTL_FSA_CHANGEOWNER: + { + int fd = message->ioctl.buffer_in[0]; + char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; + int user = message->ioctl.buffer_in[2]; + int group = message->ioctl.buffer_in[3]; + + message->ioctl.buffer_io[0] = FSA_ChangeOwner(fd, path, user, group); + break; } case IOCTL_CHECK_IF_IOSUHAX: { From a5cbc703544b285846b226248bc524c753bf25ad Mon Sep 17 00:00:00 2001 From: koolkdev Date: Mon, 14 Aug 2017 10:55:16 +0300 Subject: [PATCH 2/9] In ChangeOwner changed "user" to "owner" and owner/group to unsigned --- wupserver/source/fsa.c | 4 ++-- wupserver/source/fsa.h | 2 +- wupserver/source/ipc.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index 4c3bbc7..0bedf17 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -314,7 +314,7 @@ int FSA_ChangeMode(int fd, char *path, int mode) return ret; } -int FSA_ChangeOwner(int fd, char *path, int user, int group) +int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; @@ -322,7 +322,7 @@ int FSA_ChangeOwner(int fd, char *path, int user, int group) strncpy((char*)&inbuf[0x01], path, 0x27F); inbuf[0x284/4] = 0; // ignored - inbuf[0x288/4] = user; + inbuf[0x288/4] = owner; inbuf[0x28C/4] = 0; // ignored inbuf[0x290/4] = group; diff --git a/wupserver/source/fsa.h b/wupserver/source/fsa.h index 2971c7e..26ad173 100644 --- a/wupserver/source/fsa.h +++ b/wupserver/source/fsa.h @@ -51,7 +51,7 @@ int FSA_SetPosFile(int fd, int fileHandle, u32 position); int FSA_GetStat(int fd, char *path, fileStat_s* out_data); int FSA_Remove(int fd, char *path); int FSA_ChangeMode(int fd, char *path, int mode); -int FSA_ChangeOwner(int fd, char *path, int user, int group); +int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group); int FSA_RawOpen(int fd, char* device_path, int* outHandle); int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle); diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index 67b8dec..a898294 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -421,10 +421,10 @@ static int ipc_ioctl(ipcmessage *message) { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; - int user = message->ioctl.buffer_in[2]; - int group = message->ioctl.buffer_in[3]; + u32 owner = message->ioctl.buffer_in[2]; + u32 group = message->ioctl.buffer_in[3]; - message->ioctl.buffer_io[0] = FSA_ChangeOwner(fd, path, user, group); + message->ioctl.buffer_io[0] = FSA_ChangeOwner(fd, path, owner, group); break; } case IOCTL_CHECK_IF_IOSUHAX: From cbb508b0a0b9dc852134d6f00ee68da3f09734ee Mon Sep 17 00:00:00 2001 From: koolkdev Date: Thu, 17 Aug 2017 00:23:08 +0300 Subject: [PATCH 3/9] wupserver: Update get info command --- wupserver/source/fsa.c | 43 +++++++++++++++------------------ wupserver/source/fsa.h | 55 +++++++++++++++++++++++++++++++----------- wupserver/source/ipc.c | 14 +++++------ 3 files changed, 68 insertions(+), 44 deletions(-) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index 0bedf17..18d899d 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -222,7 +222,7 @@ int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 fla return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, false); } -int FSA_StatFile(int fd, int handle, fileStat_s* out_data) +int FSA_GetStatFile(int fd, int handle, FSStat* out_data) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; @@ -232,7 +232,7 @@ int FSA_StatFile(int fd, int handle, fileStat_s* out_data) int ret = svcIoctl(fd, 0x14, inbuf, 0x520, outbuf, 0x293); - if(out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s)); + if(out_data) memcpy(out_data, &outbuf[1], sizeof(FSStat)); freeIobuf(iobuf); return ret; @@ -267,21 +267,9 @@ int FSA_SetPosFile(int fd, int fileHandle, u32 position) return ret; } -int FSA_GetStat(int fd, char *path, fileStat_s* out_data) +int FSA_GetStat(int fd, char *path, FSStat* out_data) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], path, 0x27F); - inbuf[0x284/4] = 5; - - int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293); - - if(out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s)); - - freeIobuf(iobuf); - return ret; + return FSA_GetInfo(fd, path, 5, (u32*)out_data); } int FSA_Remove(int fd, char *path) @@ -332,10 +320,19 @@ int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group) return ret; } +// 0 - FSA_GetFreeSpaceSize +// 1 - FSA_GetDirSize +// 2 - FSA_GetEntryNum +// 3 - FSA_GetFileSystemInfo +// 4 - FSA_GetDeviceInfo +// 5 - FSA_GetStat +// 6 - FSA_GetBadBlockInfo +// 7 - FSA_GetJournalFreeSpaceS +// 8 - FSA_GetFragmentBlockInfo // type 4 : // 0x08 : device size in sectors (u64) // 0x10 : device sector size (u32) -int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data) +int FSA_GetInfo(int fd, char* device_path, int type, u32* out_data) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; @@ -351,22 +348,22 @@ int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data) switch(type) { case 0: case 1: case 7: - size = 0x8; + size = sizeof(u64); break; case 2: - size = 0x4; + size = sizeof(u32); break; case 3: - size = 0x1E; + size = sizeof(FileSystemInfo); break; case 4: - size = 0x28; + size = sizeof(DeviceInfo); break; case 5: - size = 0x64; + size = sizeof(FSStat); break; case 6: case 8: - size = 0x14; + size = sizeof(BlockInfo); break; } diff --git a/wupserver/source/fsa.h b/wupserver/source/fsa.h index 26ad173..b7c9399 100644 --- a/wupserver/source/fsa.h +++ b/wupserver/source/fsa.h @@ -1,28 +1,55 @@ #ifndef FSA_H #define FSA_H +#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6 +#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3 +#define IOS_ERROR_INVALID_SIZE 0xFFFFFFE9 +#define IOS_ERROR_UNKNOWN 0xFFFFFFF7 +#define IOS_ERROR_NOEXISTS 0xFFFFFFFA + +#define FLAG_IS_LINK 0x00010000 +#define FLAG_IS_UNENCRYPTED 0x00800000 +#define FLAG_IS_FILE 0x01000000 +#define FLAG_IS_QUOTA 0x60000000 +#define FLAG_IS_DIRECTORY 0x80000000 + typedef struct { u32 flag; u32 permission; u32 owner_id; u32 group_id; - u32 size; // size in bytes - u32 physsize; // physical size on disk in bytes - u32 unk[3]; - u32 id; - u32 ctime; - u32 mtime; - u32 unk2[0x0D]; -}fileStat_s; + u32 size; // size in bytes + u32 physsize; // physical size on disk in bytes + u64 quota_size; + u32 id; + u64 ctime; + u64 mtime; + u8 attributes[48]; +} FSStat; typedef struct { - fileStat_s stat; + FSStat stat; char name[0x100]; -}directoryEntry_s; +} directoryEntry_s; + +typedef struct +{ + u8 unknown[0x1E]; +} FileSystemInfo; -#define DIR_ENTRY_IS_DIRECTORY 0x80000000 +typedef struct +{ + u8 unknown[0x28]; +} DeviceInfo; + +typedef struct +{ + u64 blocks_count; + u64 some_count; + u32 block_size; +} BlockInfo; #define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) #define FSA_MOUNTFLAGS_GLOBAL (1 << 1) @@ -33,7 +60,8 @@ int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg int FSA_Unmount(int fd, char* path, u32 flags); int FSA_FlushVolume(int fd, char* volume_path); -int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data); +int FSA_GetInfo(int fd, char* device_path, int type, u32* out_data); +int FSA_GetStat(int fd, char *path, FSStat* out_data); int FSA_MakeDir(int fd, char* path, u32 flags); int FSA_OpenDir(int fd, char* path, int* outHandle); @@ -45,10 +73,9 @@ int FSA_ChangeDir(int fd, char* path); int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle); int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); -int FSA_StatFile(int fd, int handle, fileStat_s* out_data); +int FSA_GetStatFile(int fd, int handle, FSStat* out_data); int FSA_CloseFile(int fd, int fileHandle); int FSA_SetPosFile(int fd, int fileHandle, u32 position); -int FSA_GetStat(int fd, char *path, fileStat_s* out_data); int FSA_Remove(int fd, char *path); int FSA_ChangeMode(int fd, char *path, int mode); int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group); diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index a898294..dc00ae4 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -50,7 +50,7 @@ #define IOCTL_FSA_CLOSE 0x41 #define IOCTL_FSA_MOUNT 0x42 #define IOCTL_FSA_UNMOUNT 0x43 -#define IOCTL_FSA_GETDEVICEINFO 0x44 +#define IOCTL_FSA_GETINFO 0x44 #define IOCTL_FSA_OPENDIR 0x45 #define IOCTL_FSA_READDIR 0x46 #define IOCTL_FSA_CLOSEDIR 0x47 @@ -58,7 +58,7 @@ #define IOCTL_FSA_OPENFILE 0x49 #define IOCTL_FSA_READFILE 0x4A #define IOCTL_FSA_WRITEFILE 0x4B -#define IOCTL_FSA_STATFILE 0x4C +#define IOCTL_FSA_GETSTATFILE 0x4C #define IOCTL_FSA_CLOSEFILE 0x4D #define IOCTL_FSA_SETFILEPOS 0x4E #define IOCTL_FSA_GETSTAT 0x4F @@ -240,13 +240,13 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_FlushVolume(fd, path); break; } - case IOCTL_FSA_GETDEVICEINFO: + case IOCTL_FSA_GETINFO: { int fd = message->ioctl.buffer_in[0]; char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; int type = message->ioctl.buffer_in[2]; - message->ioctl.buffer_io[0] = FSA_GetDeviceInfo(fd, device_path, type, message->ioctl.buffer_io + 1); + message->ioctl.buffer_io[0] = FSA_GetInfo(fd, device_path, type, message->ioctl.buffer_io + 1); break; } case IOCTL_FSA_OPENDIR: @@ -313,12 +313,12 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8*)message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags); break; } - case IOCTL_FSA_STATFILE: + case IOCTL_FSA_GETSTATFILE: { int fd = message->ioctl.buffer_in[0]; int fileHandle = message->ioctl.buffer_in[1]; - message->ioctl.buffer_io[0] = FSA_StatFile(fd, fileHandle, (fileStat_s*)(message->ioctl.buffer_io + 1)); + message->ioctl.buffer_io[0] = FSA_GetStatFile(fd, fileHandle, (FSStat*)(message->ioctl.buffer_io + 1)); break; } case IOCTL_FSA_CLOSEFILE: @@ -343,7 +343,7 @@ static int ipc_ioctl(ipcmessage *message) int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; - message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (fileStat_s*)(message->ioctl.buffer_io + 1)); + message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (FSStat*)(message->ioctl.buffer_io + 1)); break; } case IOCTL_FSA_REMOVE: From f3bdb61510dbb0a222d5e8d0e898a150bd3c4c0f Mon Sep 17 00:00:00 2001 From: koolkdev Date: Thu, 17 Aug 2017 12:49:18 +0300 Subject: [PATCH 4/9] Some space optimization --- wupserver/source/fsa.c | 161 ++++++++++------------------------------- wupserver/source/ipc.c | 136 +++++++++++++++------------------- 2 files changed, 97 insertions(+), 200 deletions(-) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index 18d899d..17847a1 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -90,78 +90,61 @@ int FSA_MakeDir(int fd, char* path, u32 flags) return ret; } -int FSA_OpenDir(int fd, char* path, int* outHandle) +int _ioctl_fd_handle(int fd, int handle, int ioctl_num, u32* out_data, u32 out_data_size) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; u32* outbuf = (u32*)&iobuf[0x520]; - strncpy((char*)&inbuf[0x01], path, 0x27F); + inbuf[1] = handle; - int ret = svcIoctl(fd, 0x0A, inbuf, 0x520, outbuf, 0x293); + int ret = svcIoctl(fd, ioctl_num, inbuf, 0x520, outbuf, 0x293); - if(outHandle) *outHandle = outbuf[1]; + if(out_data && out_data_size) memcpy(out_data, &outbuf[1], out_data_size); freeIobuf(iobuf); - return ret; + return ret; } -int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data) +int _ioctl_fd_path(int fd, char* path, int ioctl_num, u32* out_data, u32 out_data_size) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; u32* outbuf = (u32*)&iobuf[0x520]; - inbuf[1] = handle; + strncpy((char*)&inbuf[0x01], path, 0x27F); - int ret = svcIoctl(fd, 0x0B, inbuf, 0x520, outbuf, 0x293); + int ret = svcIoctl(fd, ioctl_num, inbuf, 0x520, outbuf, 0x293); - if(out_data) memcpy(out_data, &outbuf[1], sizeof(directoryEntry_s)); + if(out_data && out_data_size) memcpy(out_data, &outbuf[1], out_data_size); freeIobuf(iobuf); - return ret; + return ret; } -int FSA_RewindDir(int fd, int handle) +int FSA_OpenDir(int fd, char* path, int* outHandle) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - inbuf[1] = handle; + return _ioctl_fd_path(fd, path, 0x0A, (u32*)outHandle, sizeof(int)); +} - int ret = svcIoctl(fd, 0x0C, inbuf, 0x520, outbuf, 0x293); +int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data) +{ + return _ioctl_fd_handle(fd, handle, 0x0B, (u32*)out_data, sizeof(directoryEntry_s)); +} - freeIobuf(iobuf); - return ret; +int FSA_RewindDir(int fd, int handle) +{ + return _ioctl_fd_handle(fd, handle, 0x0C, NULL, 0); } int FSA_CloseDir(int fd, int handle) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - inbuf[1] = handle; - - int ret = svcIoctl(fd, 0x0D, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_handle(fd, handle, 0x0D, NULL, 0); } int FSA_ChangeDir(int fd, char* path) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], path, 0x27F); - - int ret = svcIoctl(fd, 0x05, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_path(fd, path, 0x05, NULL, 0); } int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) @@ -224,32 +207,12 @@ int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 fla int FSA_GetStatFile(int fd, int handle, FSStat* out_data) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - inbuf[1] = handle; - - int ret = svcIoctl(fd, 0x14, inbuf, 0x520, outbuf, 0x293); - - if(out_data) memcpy(out_data, &outbuf[1], sizeof(FSStat)); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_handle(fd, handle, 0x14, (u32*)out_data, sizeof(FSStat)); } int FSA_CloseFile(int fd, int fileHandle) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - inbuf[1] = fileHandle; - - int ret = svcIoctl(fd, 0x15, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_handle(fd, fileHandle, 0x15, NULL, 0); } int FSA_SetPosFile(int fd, int fileHandle, u32 position) @@ -274,16 +237,7 @@ int FSA_GetStat(int fd, char *path, FSStat* out_data) int FSA_Remove(int fd, char *path) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], path, 0x27F); - - int ret = svcIoctl(fd, 0x08, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_path(fd, path, 0x08, NULL, 0); } int FSA_ChangeMode(int fd, char *path, int mode) @@ -375,36 +329,15 @@ int FSA_GetInfo(int fd, char* device_path, int type, u32* out_data) int FSA_RawOpen(int fd, char* device_path, int* outHandle) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], device_path, 0x27F); - - int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293); - - if(outHandle) *outHandle = outbuf[1]; - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_path(fd, device_path, 0x6A, (u32*)outHandle, sizeof(int)); } int FSA_RawClose(int fd, int device_handle) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - inbuf[1] = device_handle; - - int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_handle(fd, device_handle, 0x6D, NULL, 0); } -// offset in blocks of 0x1000 bytes -int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) +int _FSA_RawReadWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle, bool read) { u8* iobuf = allocIobuf(); u8* inbuf8 = iobuf; @@ -413,7 +346,6 @@ int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, u32* inbuf = (u32*)inbuf8; u32* outbuf = (u32*)outbuf8; - // note : offset_bytes = blocks_offset * size_bytes inbuf[0x08 / 4] = (blocks_offset >> 32); inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF); inbuf[0x10 / 4] = cnt; @@ -429,38 +361,21 @@ int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, iovec[2].ptr = outbuf; iovec[2].len = 0x293; - int ret = svcIoctlv(fd, 0x6B, 1, 2, iovec); + int ret; + if(read) ret = svcIoctlv(fd, 0x6B, 1, 2, iovec); + else ret = svcIoctlv(fd, 0x6C, 2, 1, iovec); freeIobuf(iobuf); return ret; } -int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) +// offset in blocks of 0x1000 bytes +int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) { - u8* iobuf = allocIobuf(); - u8* inbuf8 = iobuf; - u8* outbuf8 = &iobuf[0x520]; - iovec_s* iovec = (iovec_s*)&iobuf[0x7C0]; - u32* inbuf = (u32*)inbuf8; - u32* outbuf = (u32*)outbuf8; - - inbuf[0x08 / 4] = (blocks_offset >> 32); - inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF); - inbuf[0x10 / 4] = cnt; - inbuf[0x14 / 4] = size_bytes; - inbuf[0x18 / 4] = device_handle; - - iovec[0].ptr = inbuf; - iovec[0].len = 0x520; - - iovec[1].ptr = data; - iovec[1].len = size_bytes * cnt; - - iovec[2].ptr = outbuf; - iovec[2].len = 0x293; - - int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec); + return _FSA_RawReadWrite(fd, data, size_bytes, cnt, blocks_offset, device_handle, true); +} - freeIobuf(iobuf); - return ret; +int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) +{ + return _FSA_RawReadWrite(fd, data, size_bytes, cnt, blocks_offset, device_handle, false); } diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index dc00ae4..caa8fa2 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -233,11 +233,19 @@ static int ipc_ioctl(ipcmessage *message) break; } case IOCTL_FSA_FLUSHVOLUME: + case IOCTL_FSA_REMOVE: + case IOCTL_FSA_CHDIR: { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; + int (* func)(int, char*); - message->ioctl.buffer_io[0] = FSA_FlushVolume(fd, path); + switch(message->ioctl.command) { + case IOCTL_FSA_FLUSHVOLUME: func = FSA_FlushVolume; break; + case IOCTL_FSA_REMOVE: func = FSA_Remove; break; + case IOCTL_FSA_CHDIR: func = FSA_ChangeDir; break; + } + message->ioctl.buffer_io[0] = func(fd, path); break; } case IOCTL_FSA_GETINFO: @@ -257,22 +265,6 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_OpenDir(fd, path, (int*)message->ioctl.buffer_io + 1); break; } - case IOCTL_FSA_READDIR: - { - int fd = message->ioctl.buffer_in[0]; - int handle = message->ioctl.buffer_in[1]; - - message->ioctl.buffer_io[0] = FSA_ReadDir(fd, handle, (directoryEntry_s*)(message->ioctl.buffer_io + 1)); - break; - } - case IOCTL_FSA_CLOSEDIR: - { - int fd = message->ioctl.buffer_in[0]; - int handle = message->ioctl.buffer_in[1]; - - message->ioctl.buffer_io[0] = FSA_CloseDir(fd, handle); - break; - } case IOCTL_FSA_MAKEDIR: { int fd = message->ioctl.buffer_in[0]; @@ -292,16 +284,6 @@ static int ipc_ioctl(ipcmessage *message) break; } case IOCTL_FSA_READFILE: - { - int fd = message->ioctl.buffer_in[0]; - u32 size = message->ioctl.buffer_in[1]; - u32 cnt = message->ioctl.buffer_in[2]; - int fileHandle = message->ioctl.buffer_in[3]; - u32 flags = message->ioctl.buffer_in[4]; - - message->ioctl.buffer_io[0] = FSA_ReadFile(fd, ((u8*)message->ioctl.buffer_io) + 0x40, size, cnt, fileHandle, flags); - break; - } case IOCTL_FSA_WRITEFILE: { int fd = message->ioctl.buffer_in[0]; @@ -309,24 +291,53 @@ static int ipc_ioctl(ipcmessage *message) u32 cnt = message->ioctl.buffer_in[2]; int fileHandle = message->ioctl.buffer_in[3]; u32 flags = message->ioctl.buffer_in[4]; - - message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8*)message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags); + u8* buffer; + int (* func)(int, void*, u32, u32, int, u32); + + switch(message->ioctl.command) { + case IOCTL_FSA_READFILE: + func = FSA_ReadFile; + buffer = ((u8*)message->ioctl.buffer_io); + break; + case IOCTL_FSA_WRITEFILE: + func = FSA_WriteFile; + buffer = ((u8*)message->ioctl.buffer_in); + break; + } + + message->ioctl.buffer_io[0] = func(fd, buffer + 0x40, size, cnt, fileHandle, flags); break; } + case IOCTL_FSA_READDIR: case IOCTL_FSA_GETSTATFILE: { int fd = message->ioctl.buffer_in[0]; - int fileHandle = message->ioctl.buffer_in[1]; + int handle = message->ioctl.buffer_in[1]; + int (* func)(int, int, void*); - message->ioctl.buffer_io[0] = FSA_GetStatFile(fd, fileHandle, (FSStat*)(message->ioctl.buffer_io + 1)); + switch(message->ioctl.command) { + case IOCTL_FSA_READDIR: func = FSA_ReadDir; break; + case IOCTL_FSA_GETSTATFILE: func = FSA_GetStatFile; break; + } + message->ioctl.buffer_io[0] = func(fd, handle, (void*)(message->ioctl.buffer_io + 1)); break; } + case IOCTL_FSA_REWINDDIR: + case IOCTL_FSA_CLOSEDIR: + case IOCTL_FSA_RAW_CLOSE: case IOCTL_FSA_CLOSEFILE: { int fd = message->ioctl.buffer_in[0]; - int fileHandle = message->ioctl.buffer_in[1]; + int handle = message->ioctl.buffer_in[1]; + int (* func)(int, int); - message->ioctl.buffer_io[0] = FSA_CloseFile(fd, fileHandle); + switch(message->ioctl.command) { + case IOCTL_FSA_REWINDDIR: func = FSA_RewindDir; break; + case IOCTL_FSA_CLOSEDIR: func = FSA_CloseDir; break; + case IOCTL_FSA_RAW_CLOSE: func = FSA_RawClose; break; + case IOCTL_FSA_CLOSEFILE: func = FSA_CloseFile; break; + } + message->ioctl.buffer_io[0] = func(fd, handle); break; } case IOCTL_FSA_SETFILEPOS: @@ -346,30 +357,6 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (FSStat*)(message->ioctl.buffer_io + 1)); break; } - case IOCTL_FSA_REMOVE: - { - int fd = message->ioctl.buffer_in[0]; - char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; - - message->ioctl.buffer_io[0] = FSA_Remove(fd, path); - break; - } - case IOCTL_FSA_REWINDDIR: - { - int fd = message->ioctl.buffer_in[0]; - int dirFd = message->ioctl.buffer_in[1]; - - message->ioctl.buffer_io[0] = FSA_RewindDir(fd, dirFd); - break; - } - case IOCTL_FSA_CHDIR: - { - int fd = message->ioctl.buffer_in[0]; - char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; - - message->ioctl.buffer_io[0] = FSA_ChangeDir(fd, path); - break; - } case IOCTL_FSA_RAW_OPEN: { int fd = message->ioctl.buffer_in[0]; @@ -379,16 +366,6 @@ static int ipc_ioctl(ipcmessage *message) break; } case IOCTL_FSA_RAW_READ: - { - int fd = message->ioctl.buffer_in[0]; - u32 block_size = message->ioctl.buffer_in[1]; - u32 cnt = message->ioctl.buffer_in[2]; - u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; - int deviceHandle = message->ioctl.buffer_in[5]; - - message->ioctl.buffer_io[0] = FSA_RawRead(fd, ((u8*)message->ioctl.buffer_io) + 0x40, block_size, cnt, sector_offset, deviceHandle); - break; - } case IOCTL_FSA_RAW_WRITE: { int fd = message->ioctl.buffer_in[0]; @@ -396,16 +373,21 @@ static int ipc_ioctl(ipcmessage *message) u32 cnt = message->ioctl.buffer_in[2]; u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; int deviceHandle = message->ioctl.buffer_in[5]; - - message->ioctl.buffer_io[0] = FSA_RawWrite(fd, ((u8*)message->ioctl.buffer_in) + 0x40, block_size, cnt, sector_offset, deviceHandle); - break; - } - case IOCTL_FSA_RAW_CLOSE: - { - int fd = message->ioctl.buffer_in[0]; - int deviceHandle = message->ioctl.buffer_in[1]; - - message->ioctl.buffer_io[0] = FSA_RawClose(fd, deviceHandle); + u8* buffer; + int (* func)(int, void*, u32, u32, u64, int); + + switch(message->ioctl.command) { + case IOCTL_FSA_RAW_READ: + func = FSA_ReadFile; + buffer = ((u8*)message->ioctl.buffer_io); + break; + case IOCTL_FSA_RAW_WRITE: + func = FSA_WriteFile; + buffer = ((u8*)message->ioctl.buffer_in); + break; + } + + message->ioctl.buffer_io[0] = func(fd, buffer + 0x40, block_size, cnt, sector_offset, deviceHandle); break; } case IOCTL_FSA_CHANGEMODE: From f04d146c485b5162c85ef71d4f73c7094558d1a0 Mon Sep 17 00:00:00 2001 From: koolkdev Date: Thu, 17 Aug 2017 18:02:19 +0300 Subject: [PATCH 5/9] Added new files api: FSA_OpenFileEx, FSA_ReadFileWithPos, FSA_WriteFileWithPos, FSA_AppendFile, FSA_AppendFileEx, FSA_FlushFile, FSA_TruncateFile, FSA_GetPosFile, FSA_IsEof --- wupserver/source/fsa.c | 89 +++++++++++++++++++++++++++++++++++++++--- wupserver/source/fsa.h | 18 +++++++-- wupserver/source/ipc.c | 74 ++++++++++++++++++++++++++++++----- 3 files changed, 163 insertions(+), 18 deletions(-) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index 17847a1..f458e87 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -147,7 +147,13 @@ int FSA_ChangeDir(int fd, char* path) return _ioctl_fd_path(fd, path, 0x05, NULL, 0); } -int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) +//int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) +//{ +// return FSA_OpenFileEx(fd, path, mode, outHandle, 0, 0x600, 0); +//} + +// flags - 1 - maybe open/create unencrypted file?, 2 - preallocated size +int FSA_OpenFileEx(int fd, char* path, char* mode, int* outHandle, u32 flags, int create_mode, u32 create_alloc_size) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; @@ -155,6 +161,9 @@ int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) strncpy((char*)&inbuf[0x01], path, 0x27F); strncpy((char*)&inbuf[0xA1], mode, 0x10); + inbuf[0xA5] = flags; + inbuf[0xA6] = create_mode; + inbuf[0xA7] = create_alloc_size; int ret = svcIoctl(fd, 0x0E, inbuf, 0x520, outbuf, 0x293); @@ -164,7 +173,7 @@ int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) return ret; } -int _FSA_ReadWriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags, bool read) +int _FSA_ReadWriteFileWithPos(int fd, void* data, u32 size, u32 cnt, int pos, int fileHandle, u32 flags, bool read) { u8* iobuf = allocIobuf(); u8* inbuf8 = iobuf; @@ -175,6 +184,7 @@ int _FSA_ReadWriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u3 inbuf[0x08 / 4] = size; inbuf[0x0C / 4] = cnt; + inbuf[0x10 / 4] = pos; inbuf[0x14 / 4] = fileHandle; inbuf[0x18 / 4] = flags; @@ -195,14 +205,46 @@ int _FSA_ReadWriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u3 return ret; } -int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags) +//int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags) +//{ +// return _FSA_ReadWriteFileWithPos(fd, data, size, cnt, 0, fileHandle, flags & (~1), true); +//} + +//int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags) +//{ +// return _FSA_ReadWriteFileWithPos(fd, data, size, cnt, 0, fileHandle, flags & (~1), false); +//} + +int FSA_ReadFileWithPos(int fd, void* data, u32 size, u32 cnt, u32 position, int fileHandle, u32 flags) { - return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, true); + return _FSA_ReadWriteFileWithPos(fd, data, size, cnt, position, fileHandle, flags, true); } -int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags) +int FSA_WriteFileWithPos(int fd, void* data, u32 size, u32 cnt, u32 position, int fileHandle, u32 flags) { - return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, false); + return _FSA_ReadWriteFileWithPos(fd, data, size, cnt, position, fileHandle, flags, false); +} + +//int FSA_AppendFile(int fd, u32 size, u32 cnt, int fileHandle) { +// return FSA_AppendFileEx(fd, size, cnt, 0); +//} + +// flags - 1 - affects the way the blocks are allocated - maybe will cause it to allocate it at the end of the quota? +int FSA_AppendFileEx(int fd, u32 size, u32 cnt, int fileHandle, u32 flags) +{ + u8* iobuf = allocIobuf(); + u32* inbuf = (u32*)iobuf; + u32* outbuf = (u32*)&iobuf[0x520]; + + inbuf[1] = size; + inbuf[2] = cnt; + inbuf[3] = fileHandle; + inbuf[4] = flags; + + int ret = svcIoctl(fd, 0x19, inbuf, 0x520, outbuf, 0x293); + + freeIobuf(iobuf); + return ret; } int FSA_GetStatFile(int fd, int handle, FSStat* out_data) @@ -215,6 +257,21 @@ int FSA_CloseFile(int fd, int fileHandle) return _ioctl_fd_handle(fd, fileHandle, 0x15, NULL, 0); } +int FSA_FlushFile(int fd, int fileHandle) +{ + return _ioctl_fd_handle(fd, fileHandle, 0x17, NULL, 0); +} + +int FSA_TruncateFile(int fd, int fileHandle) +{ + return _ioctl_fd_handle(fd, fileHandle, 0x1A, NULL, 0); +} + +int FSA_GetPosFile(int fd, int fileHandle, u32* out_position) +{ + return _ioctl_fd_handle(fd, fileHandle, 0x11, out_position, sizeof(u32)); +} + int FSA_SetPosFile(int fd, int fileHandle, u32 position) { u8* iobuf = allocIobuf(); @@ -230,6 +287,11 @@ int FSA_SetPosFile(int fd, int fileHandle, u32 position) return ret; } +int FSA_IsEof(int fd, int fileHandle) +{ + return _ioctl_fd_handle(fd, fileHandle, 0x13, NULL, 0); +} + int FSA_GetStat(int fd, char *path, FSStat* out_data) { return FSA_GetInfo(fd, path, 5, (u32*)out_data); @@ -240,6 +302,21 @@ int FSA_Remove(int fd, char *path) return _ioctl_fd_path(fd, path, 0x08, NULL, 0); } +int FSA_Rename(int fd, char *old_path, char *new_path) +{ + u8* iobuf = allocIobuf(); + u32* inbuf = (u32*)iobuf; + u32* outbuf = (u32*)&iobuf[0x520]; + + strncpy((char*)&inbuf[0x01], old_path, 0x27F); + strncpy((char*)&inbuf[0x01 + (0x280/4)], new_path, 0x27F); + + int ret = svcIoctl(fd, 0x09, inbuf, 0x520, outbuf, 0x293); + + freeIobuf(iobuf); + return ret; +} + int FSA_ChangeMode(int fd, char *path, int mode) { u8* iobuf = allocIobuf(); diff --git a/wupserver/source/fsa.h b/wupserver/source/fsa.h index b7c9399..43524df 100644 --- a/wupserver/source/fsa.h +++ b/wupserver/source/fsa.h @@ -54,6 +54,9 @@ typedef struct #define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) #define FSA_MOUNTFLAGS_GLOBAL (1 << 1) +#define FSA_OPENFLAGS_OPEN_UNENCRYPTED (1 << 0) +#define FSA_OPENFLAGS_PREALLOC_SPACE (1 << 1) + int FSA_Open(); int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len); @@ -70,12 +73,21 @@ int FSA_RewindDir(int fd, int handle); int FSA_CloseDir(int fd, int handle); int FSA_ChangeDir(int fd, char* path); -int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle); -int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); -int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); +//int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle); +int FSA_OpenFileEx(int fd, char* path, char* mode, int* outHandle, u32 flags, int create_mode, u32 create_alloc_size); +//int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); +//int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); +int FSA_ReadFileWithPos(int fd, void* data, u32 size, u32 cnt, u32 position, int fileHandle, u32 flags); +int FSA_WriteFileWithPos(int fd, void* data, u32 size, u32 cnt, u32 position, int fileHandle, u32 flags); +//int FSA_AppendFile(int fd, u32 size, u32 cnt, int fileHandle); +int FSA_AppendFileEx(int fd, u32 size, u32 cnt, int fileHandle, u32 flags); int FSA_GetStatFile(int fd, int handle, FSStat* out_data); int FSA_CloseFile(int fd, int fileHandle); +int FSA_FlushFile(int fd, int handle); +int FSA_TruncateFile(int fd, int handle); +int FSA_GetPosFile(int fd, int fileHandle, u32* out_position); int FSA_SetPosFile(int fd, int fileHandle, u32 position); +int FSA_IsEof(int fd, int fileHandle); int FSA_Remove(int fd, char *path); int FSA_ChangeMode(int fd, char *path, int mode); int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group); diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index caa8fa2..ab87f57 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -74,6 +74,15 @@ #define IOCTL_FSA_FLUSHVOLUME 0x59 #define IOCTL_CHECK_IF_IOSUHAX 0x5B #define IOCTL_FSA_CHANGEOWNER 0x5C +#define IOCTL_FSA_OPENFILEEX 0x5D +#define IOCTL_FSA_READFILEWITHPOS 0x5E +#define IOCTL_FSA_WRITEFILEWITHPOS 0x5F +#define IOCTL_FSA_APPENDFILE 0x60 +#define IOCTL_FSA_APPENDFILEEX 0x61 +#define IOCTL_FSA_FLUSHFILE 0x62 +#define IOCTL_FSA_TRUNCATEFILE 0x63 +#define IOCTL_FSA_GETPOSFILE 0x64 +#define IOCTL_FSA_ISEOF 0x65 //static u8 threadStack[0x1000] __attribute__((aligned(0x20))); @@ -275,41 +284,81 @@ static int ipc_ioctl(ipcmessage *message) break; } case IOCTL_FSA_OPENFILE: + case IOCTL_FSA_OPENFILEEX: { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; char *mode = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2]; + u32 flags = 0x600; + int create_mode = 0; + u32 create_alloc_size = 0; + if (message->ioctl.command == IOCTL_FSA_OPENFILEEX) { + flags = message->ioctl.buffer_in[3]; + create_mode = message->ioctl.buffer_in[4]; + create_alloc_size = message->ioctl.buffer_in[5]; + } - message->ioctl.buffer_io[0] = FSA_OpenFile(fd, path, mode, (int*)message->ioctl.buffer_io + 1); + message->ioctl.buffer_io[0] = FSA_OpenFileEx(fd, path, mode, (int*)message->ioctl.buffer_io + 1, flags, create_mode, create_alloc_size); break; } case IOCTL_FSA_READFILE: + case IOCTL_FSA_READFILEWITHPOS: case IOCTL_FSA_WRITEFILE: + case IOCTL_FSA_WRITEFILEWITHPOS: { int fd = message->ioctl.buffer_in[0]; u32 size = message->ioctl.buffer_in[1]; u32 cnt = message->ioctl.buffer_in[2]; - int fileHandle = message->ioctl.buffer_in[3]; - u32 flags = message->ioctl.buffer_in[4]; + int i = 3; + u32 pos = 0; + int fileHandle; + u32 flags; u8* buffer; - int (* func)(int, void*, u32, u32, int, u32); + int (* func)(int, void*, u32, u32, u32, int, u32); + switch(message->ioctl.command) { + case IOCTL_FSA_READFILEWITHPOS: + case IOCTL_FSA_WRITEFILEWITHPOS: + pos = message->ioctl.buffer_in[i++]; + } + fileHandle = message->ioctl.buffer_in[i++]; + flags = message->ioctl.buffer_in[i++] & (~1); switch(message->ioctl.command) { + case IOCTL_FSA_READFILEWITHPOS: + flags |= 1; case IOCTL_FSA_READFILE: - func = FSA_ReadFile; + func = FSA_ReadFileWithPos; buffer = ((u8*)message->ioctl.buffer_io); break; + case IOCTL_FSA_WRITEFILEWITHPOS: + flags |= 1; case IOCTL_FSA_WRITEFILE: - func = FSA_WriteFile; + func = FSA_WriteFileWithPos; buffer = ((u8*)message->ioctl.buffer_in); break; } - message->ioctl.buffer_io[0] = func(fd, buffer + 0x40, size, cnt, fileHandle, flags); + message->ioctl.buffer_io[0] = func(fd, buffer + 0x40, size, cnt, pos, fileHandle, flags); break; } + + case IOCTL_FSA_APPENDFILE: + case IOCTL_FSA_APPENDFILEEX: + { + int fd = message->ioctl.buffer_in[0]; + u32 size = message->ioctl.buffer_in[1]; + u32 cnt = message->ioctl.buffer_in[2]; + int fileHandle = message->ioctl.buffer_in[3]; + u32 flags = 0; + if (message->ioctl.command == IOCTL_FSA_APPENDFILEEX) { + flags = message->ioctl.buffer_in[4]; + } + + message->ioctl.buffer_io[0] = FSA_AppendFileEx(fd, size, cnt, fileHandle, flags); + } case IOCTL_FSA_READDIR: case IOCTL_FSA_GETSTATFILE: + case IOCTL_FSA_GETPOSFILE: { int fd = message->ioctl.buffer_in[0]; int handle = message->ioctl.buffer_in[1]; @@ -318,6 +367,7 @@ static int ipc_ioctl(ipcmessage *message) switch(message->ioctl.command) { case IOCTL_FSA_READDIR: func = FSA_ReadDir; break; case IOCTL_FSA_GETSTATFILE: func = FSA_GetStatFile; break; + case IOCTL_FSA_GETPOSFILE: func = FSA_GetPosFile; break; } message->ioctl.buffer_io[0] = func(fd, handle, (void*)(message->ioctl.buffer_io + 1)); break; @@ -326,6 +376,9 @@ static int ipc_ioctl(ipcmessage *message) case IOCTL_FSA_CLOSEDIR: case IOCTL_FSA_RAW_CLOSE: case IOCTL_FSA_CLOSEFILE: + case IOCTL_FSA_FLUSHFILE: + case IOCTL_FSA_TRUNCATEFILE: + case IOCTL_FSA_ISEOF: { int fd = message->ioctl.buffer_in[0]; int handle = message->ioctl.buffer_in[1]; @@ -336,6 +389,9 @@ static int ipc_ioctl(ipcmessage *message) case IOCTL_FSA_CLOSEDIR: func = FSA_CloseDir; break; case IOCTL_FSA_RAW_CLOSE: func = FSA_RawClose; break; case IOCTL_FSA_CLOSEFILE: func = FSA_CloseFile; break; + case IOCTL_FSA_FLUSHFILE: func = FSA_FlushFile; break; + case IOCTL_FSA_TRUNCATEFILE: func = FSA_TruncateFile; break; + case IOCTL_FSA_ISEOF: func = FSA_IsEof; break; } message->ioctl.buffer_io[0] = func(fd, handle); break; @@ -378,11 +434,11 @@ static int ipc_ioctl(ipcmessage *message) switch(message->ioctl.command) { case IOCTL_FSA_RAW_READ: - func = FSA_ReadFile; + func = FSA_RawRead; buffer = ((u8*)message->ioctl.buffer_io); break; case IOCTL_FSA_RAW_WRITE: - func = FSA_WriteFile; + func = FSA_RawWrite; buffer = ((u8*)message->ioctl.buffer_in); break; } From f7dc7cc50560d50454b98aa9612832c9ed13b37e Mon Sep 17 00:00:00 2001 From: koolkdev Date: Thu, 17 Aug 2017 18:39:47 +0300 Subject: [PATCH 6/9] Added more filesystem api: FSA_RollbackVolume, FSA_GetCwd, FSA_MakeQuota, FSA_FlushQuota, FSA_RollbackQuota, FSA_RollbackQuotaForce more space optimization --- wupserver/source/fsa.c | 159 ++++++++++++++++++++++++----------------- wupserver/source/fsa.h | 7 ++ wupserver/source/ipc.c | 34 ++++++++- 3 files changed, 132 insertions(+), 68 deletions(-) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index f458e87..90cb039 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -19,6 +19,48 @@ static void freeIobuf(void* ptr) svcFree(0xCAFF, ptr); } +int _ioctl_fd_handle(int fd, int handle, int ioctl_num, u32* out_data, u32 out_data_size) +{ + u8* iobuf = allocIobuf(); + u32* inbuf = (u32*)iobuf; + u32* outbuf = (u32*)&iobuf[0x520]; + + inbuf[1] = handle; + + int ret = svcIoctl(fd, ioctl_num, inbuf, 0x520, outbuf, 0x293); + + if(out_data && out_data_size) memcpy(out_data, &outbuf[1], out_data_size); + + freeIobuf(iobuf); + return ret; +} + +int _ioctl_fd_path_args(int fd, char* path, int ioctl_num, int args, u32 arg1, u32 arg2, u32 arg3, u32* out_data, u32 out_data_size) +{ + u8* iobuf = allocIobuf(); + u32* inbuf = (u32*)iobuf; + u32* outbuf = (u32*)&iobuf[0x520]; + + strncpy((char*)&inbuf[0x01], path, 0x27F); + switch (args) { + case 3: inbuf[0x28C / 4] = arg3; + case 2: inbuf[0x288 / 4] = arg2; + case 1: inbuf[0x284 / 4] = arg1; + } + + int ret = svcIoctl(fd, ioctl_num, inbuf, 0x520, outbuf, 0x293); + + if(out_data && out_data_size) memcpy(out_data, &outbuf[1], out_data_size); + + freeIobuf(iobuf); + return ret; +} + +int _ioctl_fd_path(int fd, char* path, int ioctl_num, u32* out_data, u32 out_data_size) +{ + return _ioctl_fd_path_args(fd, path, ioctl_num, 0, 0, 0, 0, out_data, out_data_size); +} + int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len) { u8* iobuf = allocIobuf(); @@ -48,103 +90,97 @@ int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg int FSA_Unmount(int fd, char* path, u32 flags) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], path, 0x27F); - inbuf[0x284 / 4] = flags; - - int ret = svcIoctl(fd, 0x02, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_path_args(fd, path, 0x02, 1, flags, 0, 0, NULL, 0); } int FSA_FlushVolume(int fd, char* volume_path) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; + return _ioctl_fd_path(fd, volume_path, 0x1B, NULL, 0); +} - strncpy((char*)&inbuf[0x01], volume_path, 0x27F); +int FSA_RollbackVolume(int fd, char* volume_path) +{ + return _ioctl_fd_path(fd, volume_path, 0x1C, NULL, 0); +} - int ret = svcIoctl(fd, 0x1B, inbuf, 0x520, outbuf, 0x293); +int FSA_MakeDir(int fd, char* path, u32 flags) +{ + return _ioctl_fd_path_args(fd, path, 0x07, 1, flags, 0, 0, NULL, 0); +} - freeIobuf(iobuf); - return ret; +int FSA_OpenDir(int fd, char* path, int* outHandle) +{ + return _ioctl_fd_path(fd, path, 0x0A, (u32*)outHandle, sizeof(int)); } -int FSA_MakeDir(int fd, char* path, u32 flags) +int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; + return _ioctl_fd_handle(fd, handle, 0x0B, (u32*)out_data, sizeof(directoryEntry_s)); +} - strncpy((char*)&inbuf[0x01], path, 0x27F); - inbuf[0x284 / 4] = flags; +int FSA_RewindDir(int fd, int handle) +{ + return _ioctl_fd_handle(fd, handle, 0x0C, NULL, 0); +} - int ret = svcIoctl(fd, 0x07, inbuf, 0x520, outbuf, 0x293); +int FSA_CloseDir(int fd, int handle) +{ + return _ioctl_fd_handle(fd, handle, 0x0D, NULL, 0); +} - freeIobuf(iobuf); - return ret; +int FSA_ChangeDir(int fd, char* path) +{ + return _ioctl_fd_path(fd, path, 0x05, NULL, 0); } -int _ioctl_fd_handle(int fd, int handle, int ioctl_num, u32* out_data, u32 out_data_size) +int FSA_GetCwd(int fd, char* out_data, int output_size) { u8* iobuf = allocIobuf(); u32* inbuf = (u32*)iobuf; u32* outbuf = (u32*)&iobuf[0x520]; - inbuf[1] = handle; + int ret = svcIoctl(fd, 0x06, inbuf, 0x520, outbuf, 0x293); - int ret = svcIoctl(fd, ioctl_num, inbuf, 0x520, outbuf, 0x293); - - if(out_data && out_data_size) memcpy(out_data, &outbuf[1], out_data_size); + if (output_size > 0x27F) output_size = 0x27F; + if(out_data) strncpy(out_data, (char*)&outbuf[1], output_size); freeIobuf(iobuf); - return ret; + return ret; } -int _ioctl_fd_path(int fd, char* path, int ioctl_num, u32* out_data, u32 out_data_size) +int FSA_MakeQuota(int fd, char* path, u32 flags, u64 size) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], path, 0x27F); - - int ret = svcIoctl(fd, ioctl_num, inbuf, 0x520, outbuf, 0x293); - - if(out_data && out_data_size) memcpy(out_data, &outbuf[1], out_data_size); + return _ioctl_fd_path_args(fd, path, 0x07, 3, flags, (size >> 32), (size & 0xFFFFFFFF), NULL, 0); +} - freeIobuf(iobuf); - return ret; +int FSA_FlushQuota(int fd, char* quota_path) +{ + return _ioctl_fd_path(fd, quota_path, 0x1E, NULL, 0); } -int FSA_OpenDir(int fd, char* path, int* outHandle) +static int _FSA_RollbackQuota(int fd, char* quota_path, int flag) { - return _ioctl_fd_path(fd, path, 0x0A, (u32*)outHandle, sizeof(int)); + return _ioctl_fd_path_args(fd, quota_path, 0x1F, 1, flag, 0, 0, NULL, 0); } -int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data) +int FSA_RollbackQuota(int fd, char* quota_path) { - return _ioctl_fd_handle(fd, handle, 0x0B, (u32*)out_data, sizeof(directoryEntry_s)); + return _FSA_RollbackQuota(fd, quota_path, 0); } -int FSA_RewindDir(int fd, int handle) +int FSA_RollbackQuotaForce(int fd, char* quota_path) { - return _ioctl_fd_handle(fd, handle, 0x0C, NULL, 0); + return _FSA_RollbackQuota(fd, quota_path, 0x80000000); } -int FSA_CloseDir(int fd, int handle) +int FSA_RegisterFlushQuota(int fd, char* quota_path) { - return _ioctl_fd_handle(fd, handle, 0x0D, NULL, 0); + return _ioctl_fd_path(fd, quota_path, 0x22, NULL, 0); } -int FSA_ChangeDir(int fd, char* path) +int FSA_FlushMultiQuota(int fd, char* quota_path) { - return _ioctl_fd_path(fd, path, 0x05, NULL, 0); + return _ioctl_fd_path(fd, quota_path, 0x23, NULL, 0); } //int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) @@ -319,18 +355,7 @@ int FSA_Rename(int fd, char *old_path, char *new_path) int FSA_ChangeMode(int fd, char *path, int mode) { - u8* iobuf = allocIobuf(); - u32* inbuf = (u32*)iobuf; - u32* outbuf = (u32*)&iobuf[0x520]; - - strncpy((char*)&inbuf[0x01], path, 0x27F); - inbuf[0x284/4] = mode; - inbuf[0x288/4] = 0x777; // mask - - int ret = svcIoctl(fd, 0x20, inbuf, 0x520, outbuf, 0x293); - - freeIobuf(iobuf); - return ret; + return _ioctl_fd_path_args(fd, path, 0x20, 2, mode, 0x777, 0, NULL, 0); // 0x777 - mask } int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group) diff --git a/wupserver/source/fsa.h b/wupserver/source/fsa.h index 43524df..1d2f2ab 100644 --- a/wupserver/source/fsa.h +++ b/wupserver/source/fsa.h @@ -62,6 +62,7 @@ int FSA_Open(); int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len); int FSA_Unmount(int fd, char* path, u32 flags); int FSA_FlushVolume(int fd, char* volume_path); +int FSA_RollbackVolume(int fd, char* volume_path); int FSA_GetInfo(int fd, char* device_path, int type, u32* out_data); int FSA_GetStat(int fd, char *path, FSStat* out_data); @@ -72,6 +73,12 @@ int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data); int FSA_RewindDir(int fd, int handle); int FSA_CloseDir(int fd, int handle); int FSA_ChangeDir(int fd, char* path); +int FSA_GetCwd(int fd, char* out_data, int output_size); + +int FSA_MakeQuota(int fd, char* path, u32 flags, u64 size); +int FSA_FlushQuota(int fd, char* quota_path); +int FSA_RollbackQuota(int fd, char* quota_path); +int FSA_RollbackQuotaForce(int fd, char* quota_path); //int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle); int FSA_OpenFileEx(int fd, char* path, char* mode, int* outHandle, u32 flags, int create_mode, u32 create_alloc_size); diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index ab87f57..b395008 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -74,7 +74,7 @@ #define IOCTL_FSA_FLUSHVOLUME 0x59 #define IOCTL_CHECK_IF_IOSUHAX 0x5B #define IOCTL_FSA_CHANGEOWNER 0x5C -#define IOCTL_FSA_OPENFILEEX 0x5D +#define IOCTL_FSA_OPENFILEEX 0x5D #define IOCTL_FSA_READFILEWITHPOS 0x5E #define IOCTL_FSA_WRITEFILEWITHPOS 0x5F #define IOCTL_FSA_APPENDFILE 0x60 @@ -83,6 +83,12 @@ #define IOCTL_FSA_TRUNCATEFILE 0x63 #define IOCTL_FSA_GETPOSFILE 0x64 #define IOCTL_FSA_ISEOF 0x65 +#define IOCTL_FSA_ROLLBACKVOLUME 0x66 +#define IOCTL_FSA_GETCWD 0x67 +#define IOCTL_FSA_MAKEQUOTA 0x68 +#define IOCTL_FSA_FLUSHQUOTA 0x69 +#define IOCTL_FSA_ROLLBACKQUOTA 0x6A +#define IOCTL_FSA_ROLLBACKQUOTAFORCE 0x6B //static u8 threadStack[0x1000] __attribute__((aligned(0x20))); @@ -244,6 +250,10 @@ static int ipc_ioctl(ipcmessage *message) case IOCTL_FSA_FLUSHVOLUME: case IOCTL_FSA_REMOVE: case IOCTL_FSA_CHDIR: + case IOCTL_FSA_ROLLBACKVOLUME: + case IOCTL_FSA_FLUSHQUOTA: + case IOCTL_FSA_ROLLBACKQUOTA: + case IOCTL_FSA_ROLLBACKQUOTAFORCE: { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; @@ -253,6 +263,10 @@ static int ipc_ioctl(ipcmessage *message) case IOCTL_FSA_FLUSHVOLUME: func = FSA_FlushVolume; break; case IOCTL_FSA_REMOVE: func = FSA_Remove; break; case IOCTL_FSA_CHDIR: func = FSA_ChangeDir; break; + case IOCTL_FSA_ROLLBACKVOLUME: func = FSA_RollbackVolume; break; + case IOCTL_FSA_FLUSHQUOTA: func = FSA_FlushQuota; break; + case IOCTL_FSA_ROLLBACKQUOTA: func = FSA_RollbackQuota; break; + case IOCTL_FSA_ROLLBACKQUOTAFORCE: func = FSA_RollbackQuotaForce; break; } message->ioctl.buffer_io[0] = func(fd, path); break; @@ -283,6 +297,24 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_MakeDir(fd, path, flags); break; } + case IOCTL_FSA_GETCWD: + { + int fd = message->ioctl.buffer_in[0]; + int output_size = message->ioctl.buffer_in[1]; + + message->ioctl.buffer_io[0] = FSA_GetCwd(fd, (char*)(message->ioctl.buffer_io + 1), output_size); + break; + } + case IOCTL_FSA_MAKEQUOTA: + { + int fd = message->ioctl.buffer_in[0]; + char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; + u32 flags = message->ioctl.buffer_in[2]; + u64 size = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; + + message->ioctl.buffer_io[0] = FSA_MakeQuota(fd, path, flags, size); + break; + } case IOCTL_FSA_OPENFILE: case IOCTL_FSA_OPENFILEEX: { From 23073623bbef6215fdd946fa437ffdfc2ac9aae2 Mon Sep 17 00:00:00 2001 From: koolkdev Date: Thu, 17 Aug 2017 18:41:37 +0300 Subject: [PATCH 7/9] replace tabs with spaces --- wupserver/source/ipc.c | 202 ++++++++++++++++++++--------------------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index b395008..3fa7414 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -50,7 +50,7 @@ #define IOCTL_FSA_CLOSE 0x41 #define IOCTL_FSA_MOUNT 0x42 #define IOCTL_FSA_UNMOUNT 0x43 -#define IOCTL_FSA_GETINFO 0x44 +#define IOCTL_FSA_GETINFO 0x44 #define IOCTL_FSA_OPENDIR 0x45 #define IOCTL_FSA_READDIR 0x46 #define IOCTL_FSA_CLOSEDIR 0x47 @@ -85,7 +85,7 @@ #define IOCTL_FSA_ISEOF 0x65 #define IOCTL_FSA_ROLLBACKVOLUME 0x66 #define IOCTL_FSA_GETCWD 0x67 -#define IOCTL_FSA_MAKEQUOTA 0x68 +#define IOCTL_FSA_MAKEQUOTA 0x68 #define IOCTL_FSA_FLUSHQUOTA 0x69 #define IOCTL_FSA_ROLLBACKQUOTA 0x6A #define IOCTL_FSA_ROLLBACKQUOTAFORCE 0x6B @@ -257,17 +257,17 @@ static int ipc_ioctl(ipcmessage *message) { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; - int (* func)(int, char*); - - switch(message->ioctl.command) { - case IOCTL_FSA_FLUSHVOLUME: func = FSA_FlushVolume; break; - case IOCTL_FSA_REMOVE: func = FSA_Remove; break; - case IOCTL_FSA_CHDIR: func = FSA_ChangeDir; break; - case IOCTL_FSA_ROLLBACKVOLUME: func = FSA_RollbackVolume; break; - case IOCTL_FSA_FLUSHQUOTA: func = FSA_FlushQuota; break; - case IOCTL_FSA_ROLLBACKQUOTA: func = FSA_RollbackQuota; break; - case IOCTL_FSA_ROLLBACKQUOTAFORCE: func = FSA_RollbackQuotaForce; break; - } + int (* func)(int, char*); + + switch(message->ioctl.command) { + case IOCTL_FSA_FLUSHVOLUME: func = FSA_FlushVolume; break; + case IOCTL_FSA_REMOVE: func = FSA_Remove; break; + case IOCTL_FSA_CHDIR: func = FSA_ChangeDir; break; + case IOCTL_FSA_ROLLBACKVOLUME: func = FSA_RollbackVolume; break; + case IOCTL_FSA_FLUSHQUOTA: func = FSA_FlushQuota; break; + case IOCTL_FSA_ROLLBACKQUOTA: func = FSA_RollbackQuota; break; + case IOCTL_FSA_ROLLBACKQUOTAFORCE: func = FSA_RollbackQuotaForce; break; + } message->ioctl.buffer_io[0] = func(fd, path); break; } @@ -321,14 +321,14 @@ static int ipc_ioctl(ipcmessage *message) int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; char *mode = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2]; - u32 flags = 0x600; - int create_mode = 0; - u32 create_alloc_size = 0; - if (message->ioctl.command == IOCTL_FSA_OPENFILEEX) { - flags = message->ioctl.buffer_in[3]; - create_mode = message->ioctl.buffer_in[4]; - create_alloc_size = message->ioctl.buffer_in[5]; - } + u32 flags = 0x600; + int create_mode = 0; + u32 create_alloc_size = 0; + if (message->ioctl.command == IOCTL_FSA_OPENFILEEX) { + flags = message->ioctl.buffer_in[3]; + create_mode = message->ioctl.buffer_in[4]; + create_alloc_size = message->ioctl.buffer_in[5]; + } message->ioctl.buffer_io[0] = FSA_OpenFileEx(fd, path, mode, (int*)message->ioctl.buffer_io + 1, flags, create_mode, create_alloc_size); break; @@ -341,66 +341,66 @@ static int ipc_ioctl(ipcmessage *message) int fd = message->ioctl.buffer_in[0]; u32 size = message->ioctl.buffer_in[1]; u32 cnt = message->ioctl.buffer_in[2]; - int i = 3; - u32 pos = 0; - int fileHandle; - u32 flags; - u8* buffer; - int (* func)(int, void*, u32, u32, u32, int, u32); - switch(message->ioctl.command) { - case IOCTL_FSA_READFILEWITHPOS: - case IOCTL_FSA_WRITEFILEWITHPOS: - pos = message->ioctl.buffer_in[i++]; - } + int i = 3; + u32 pos = 0; + int fileHandle; + u32 flags; + u8* buffer; + int (* func)(int, void*, u32, u32, u32, int, u32); + switch(message->ioctl.command) { + case IOCTL_FSA_READFILEWITHPOS: + case IOCTL_FSA_WRITEFILEWITHPOS: + pos = message->ioctl.buffer_in[i++]; + } fileHandle = message->ioctl.buffer_in[i++]; flags = message->ioctl.buffer_in[i++] & (~1); - switch(message->ioctl.command) { - case IOCTL_FSA_READFILEWITHPOS: - flags |= 1; - case IOCTL_FSA_READFILE: - func = FSA_ReadFileWithPos; - buffer = ((u8*)message->ioctl.buffer_io); - break; - case IOCTL_FSA_WRITEFILEWITHPOS: - flags |= 1; - case IOCTL_FSA_WRITEFILE: - func = FSA_WriteFileWithPos; - buffer = ((u8*)message->ioctl.buffer_in); - break; - } - + switch(message->ioctl.command) { + case IOCTL_FSA_READFILEWITHPOS: + flags |= 1; + case IOCTL_FSA_READFILE: + func = FSA_ReadFileWithPos; + buffer = ((u8*)message->ioctl.buffer_io); + break; + case IOCTL_FSA_WRITEFILEWITHPOS: + flags |= 1; + case IOCTL_FSA_WRITEFILE: + func = FSA_WriteFileWithPos; + buffer = ((u8*)message->ioctl.buffer_in); + break; + } + message->ioctl.buffer_io[0] = func(fd, buffer + 0x40, size, cnt, pos, fileHandle, flags); break; } - - case IOCTL_FSA_APPENDFILE: - case IOCTL_FSA_APPENDFILEEX: - { + + case IOCTL_FSA_APPENDFILE: + case IOCTL_FSA_APPENDFILEEX: + { int fd = message->ioctl.buffer_in[0]; u32 size = message->ioctl.buffer_in[1]; u32 cnt = message->ioctl.buffer_in[2]; int fileHandle = message->ioctl.buffer_in[3]; - u32 flags = 0; - if (message->ioctl.command == IOCTL_FSA_APPENDFILEEX) { - flags = message->ioctl.buffer_in[4]; - } + u32 flags = 0; + if (message->ioctl.command == IOCTL_FSA_APPENDFILEEX) { + flags = message->ioctl.buffer_in[4]; + } - message->ioctl.buffer_io[0] = FSA_AppendFileEx(fd, size, cnt, fileHandle, flags); - } + message->ioctl.buffer_io[0] = FSA_AppendFileEx(fd, size, cnt, fileHandle, flags); + } case IOCTL_FSA_READDIR: case IOCTL_FSA_GETSTATFILE: - case IOCTL_FSA_GETPOSFILE: + case IOCTL_FSA_GETPOSFILE: { int fd = message->ioctl.buffer_in[0]; int handle = message->ioctl.buffer_in[1]; - int (* func)(int, int, void*); + int (* func)(int, int, void*); - switch(message->ioctl.command) { - case IOCTL_FSA_READDIR: func = FSA_ReadDir; break; - case IOCTL_FSA_GETSTATFILE: func = FSA_GetStatFile; break; - case IOCTL_FSA_GETPOSFILE: func = FSA_GetPosFile; break; - } + switch(message->ioctl.command) { + case IOCTL_FSA_READDIR: func = FSA_ReadDir; break; + case IOCTL_FSA_GETSTATFILE: func = FSA_GetStatFile; break; + case IOCTL_FSA_GETPOSFILE: func = FSA_GetPosFile; break; + } message->ioctl.buffer_io[0] = func(fd, handle, (void*)(message->ioctl.buffer_io + 1)); break; } @@ -408,23 +408,23 @@ static int ipc_ioctl(ipcmessage *message) case IOCTL_FSA_CLOSEDIR: case IOCTL_FSA_RAW_CLOSE: case IOCTL_FSA_CLOSEFILE: - case IOCTL_FSA_FLUSHFILE: - case IOCTL_FSA_TRUNCATEFILE: - case IOCTL_FSA_ISEOF: + case IOCTL_FSA_FLUSHFILE: + case IOCTL_FSA_TRUNCATEFILE: + case IOCTL_FSA_ISEOF: { int fd = message->ioctl.buffer_in[0]; int handle = message->ioctl.buffer_in[1]; - int (* func)(int, int); - - switch(message->ioctl.command) { - case IOCTL_FSA_REWINDDIR: func = FSA_RewindDir; break; - case IOCTL_FSA_CLOSEDIR: func = FSA_CloseDir; break; - case IOCTL_FSA_RAW_CLOSE: func = FSA_RawClose; break; - case IOCTL_FSA_CLOSEFILE: func = FSA_CloseFile; break; - case IOCTL_FSA_FLUSHFILE: func = FSA_FlushFile; break; - case IOCTL_FSA_TRUNCATEFILE: func = FSA_TruncateFile; break; - case IOCTL_FSA_ISEOF: func = FSA_IsEof; break; - } + int (* func)(int, int); + + switch(message->ioctl.command) { + case IOCTL_FSA_REWINDDIR: func = FSA_RewindDir; break; + case IOCTL_FSA_CLOSEDIR: func = FSA_CloseDir; break; + case IOCTL_FSA_RAW_CLOSE: func = FSA_RawClose; break; + case IOCTL_FSA_CLOSEFILE: func = FSA_CloseFile; break; + case IOCTL_FSA_FLUSHFILE: func = FSA_FlushFile; break; + case IOCTL_FSA_TRUNCATEFILE: func = FSA_TruncateFile; break; + case IOCTL_FSA_ISEOF: func = FSA_IsEof; break; + } message->ioctl.buffer_io[0] = func(fd, handle); break; } @@ -461,20 +461,20 @@ static int ipc_ioctl(ipcmessage *message) u32 cnt = message->ioctl.buffer_in[2]; u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; int deviceHandle = message->ioctl.buffer_in[5]; - u8* buffer; - int (* func)(int, void*, u32, u32, u64, int); - - switch(message->ioctl.command) { - case IOCTL_FSA_RAW_READ: - func = FSA_RawRead; - buffer = ((u8*)message->ioctl.buffer_io); - break; - case IOCTL_FSA_RAW_WRITE: - func = FSA_RawWrite; - buffer = ((u8*)message->ioctl.buffer_in); - break; - } - + u8* buffer; + int (* func)(int, void*, u32, u32, u64, int); + + switch(message->ioctl.command) { + case IOCTL_FSA_RAW_READ: + func = FSA_RawRead; + buffer = ((u8*)message->ioctl.buffer_io); + break; + case IOCTL_FSA_RAW_WRITE: + func = FSA_RawWrite; + buffer = ((u8*)message->ioctl.buffer_in); + break; + } + message->ioctl.buffer_io[0] = func(fd, buffer + 0x40, block_size, cnt, sector_offset, deviceHandle); break; } @@ -497,15 +497,15 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = FSA_ChangeOwner(fd, path, owner, group); break; } - case IOCTL_CHECK_IF_IOSUHAX: - { - message->ioctl.buffer_io[0] = IOSUHAX_MAGIC_WORD; - break; - } + case IOCTL_CHECK_IF_IOSUHAX: + { + message->ioctl.buffer_io[0] = IOSUHAX_MAGIC_WORD; + break; + } default: res = IOS_ERROR_INVALID_ARG; break; - } + } return res; } @@ -517,9 +517,9 @@ int ipc_thread(void *arg) /*u32* messageQueue = svcAllocAlign(0xCAFF, 0x20, 0x20); int queueId = svcCreateMessageQueue(messageQueue, 0x10);*/ // mcp main thread message queue listening on "/dev/mcp" - int queueId = *(int*)0x5070AEC; - int exit = 0; - while(!exit) + int queueId = *(int*)0x5070AEC; + int exit = 0; + while(!exit) { res = svcReceiveMessage(queueId, &message, 0); if(res < 0) From 26bfeb1b6efdd6b4abbf687013b8eef3d5a00e9a Mon Sep 17 00:00:00 2001 From: koolkdev Date: Thu, 17 Aug 2017 19:28:38 +0300 Subject: [PATCH 8/9] fixed one compiling warning + add comments --- wupserver/source/ipc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index 3fa7414..bf18655 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -257,7 +257,7 @@ static int ipc_ioctl(ipcmessage *message) { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; - int (* func)(int, char*); + int (* func)(int, char*); // do not initialize switch(message->ioctl.command) { case IOCTL_FSA_FLUSHVOLUME: func = FSA_FlushVolume; break; @@ -346,7 +346,7 @@ static int ipc_ioctl(ipcmessage *message) int fileHandle; u32 flags; u8* buffer; - int (* func)(int, void*, u32, u32, u32, int, u32); + int (* func)(int, void*, u32, u32, u32, int, u32); // do not initialize switch(message->ioctl.command) { case IOCTL_FSA_READFILEWITHPOS: case IOCTL_FSA_WRITEFILEWITHPOS: @@ -394,12 +394,12 @@ static int ipc_ioctl(ipcmessage *message) { int fd = message->ioctl.buffer_in[0]; int handle = message->ioctl.buffer_in[1]; - int (* func)(int, int, void*); + int (* func)(int, int, void*); // do not initialize switch(message->ioctl.command) { - case IOCTL_FSA_READDIR: func = FSA_ReadDir; break; - case IOCTL_FSA_GETSTATFILE: func = FSA_GetStatFile; break; - case IOCTL_FSA_GETPOSFILE: func = FSA_GetPosFile; break; + case IOCTL_FSA_READDIR: func = (int (*)(int, int, void*))FSA_ReadDir; break; + case IOCTL_FSA_GETSTATFILE: func = (int (*)(int, int, void*))FSA_GetStatFile; break; + case IOCTL_FSA_GETPOSFILE: func = (int (*)(int, int, void*))FSA_GetPosFile; break; } message->ioctl.buffer_io[0] = func(fd, handle, (void*)(message->ioctl.buffer_io + 1)); break; @@ -414,7 +414,7 @@ static int ipc_ioctl(ipcmessage *message) { int fd = message->ioctl.buffer_in[0]; int handle = message->ioctl.buffer_in[1]; - int (* func)(int, int); + int (* func)(int, int); // do not initialize switch(message->ioctl.command) { case IOCTL_FSA_REWINDDIR: func = FSA_RewindDir; break; @@ -462,7 +462,7 @@ static int ipc_ioctl(ipcmessage *message) u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; int deviceHandle = message->ioctl.buffer_in[5]; u8* buffer; - int (* func)(int, void*, u32, u32, u64, int); + int (* func)(int, void*, u32, u32, u64, int); // do not initialize switch(message->ioctl.command) { case IOCTL_FSA_RAW_READ: From d1cabc7a7d626d9932fe8031b638f30ef0daf88c Mon Sep 17 00:00:00 2001 From: koolkdev Date: Fri, 18 Aug 2017 00:31:32 +0300 Subject: [PATCH 9/9] Added FSA_Rename and FSA_ChangeModeEx --- wupserver/source/fsa.c | 4 ++-- wupserver/source/fsa.h | 3 ++- wupserver/source/ipc.c | 17 ++++++++++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/wupserver/source/fsa.c b/wupserver/source/fsa.c index 90cb039..e9bb52c 100644 --- a/wupserver/source/fsa.c +++ b/wupserver/source/fsa.c @@ -353,9 +353,9 @@ int FSA_Rename(int fd, char *old_path, char *new_path) return ret; } -int FSA_ChangeMode(int fd, char *path, int mode) +int FSA_ChangeMode(int fd, char *path, int mode, int mask) { - return _ioctl_fd_path_args(fd, path, 0x20, 2, mode, 0x777, 0, NULL, 0); // 0x777 - mask + return _ioctl_fd_path_args(fd, path, 0x20, 2, mode, mask, 0, NULL, 0); // 0x777 - mask } int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group) diff --git a/wupserver/source/fsa.h b/wupserver/source/fsa.h index 1d2f2ab..8b1d01f 100644 --- a/wupserver/source/fsa.h +++ b/wupserver/source/fsa.h @@ -96,7 +96,8 @@ int FSA_GetPosFile(int fd, int fileHandle, u32* out_position); int FSA_SetPosFile(int fd, int fileHandle, u32 position); int FSA_IsEof(int fd, int fileHandle); int FSA_Remove(int fd, char *path); -int FSA_ChangeMode(int fd, char *path, int mode); +int FSA_Rename(int fd, char *old_path, char *new_path); +int FSA_ChangeMode(int fd, char *path, int mode, int mask); int FSA_ChangeOwner(int fd, char *path, u32 owner, u32 group); int FSA_RawOpen(int fd, char* device_path, int* outHandle); diff --git a/wupserver/source/ipc.c b/wupserver/source/ipc.c index bf18655..f4e1ac3 100644 --- a/wupserver/source/ipc.c +++ b/wupserver/source/ipc.c @@ -89,6 +89,7 @@ #define IOCTL_FSA_FLUSHQUOTA 0x69 #define IOCTL_FSA_ROLLBACKQUOTA 0x6A #define IOCTL_FSA_ROLLBACKQUOTAFORCE 0x6B +#define IOCTL_FSA_CHANGEMODEEX 0x6C //static u8 threadStack[0x1000] __attribute__((aligned(0x20))); @@ -271,6 +272,15 @@ static int ipc_ioctl(ipcmessage *message) message->ioctl.buffer_io[0] = func(fd, path); break; } + case IOCTL_FSA_RENAME: + { + int fd = message->ioctl.buffer_in[0]; + char *old_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; + char *new_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2]; + + message->ioctl.buffer_io[0] = FSA_Rename(fd, old_path, new_path); + break; + } case IOCTL_FSA_GETINFO: { int fd = message->ioctl.buffer_in[0]; @@ -479,12 +489,17 @@ static int ipc_ioctl(ipcmessage *message) break; } case IOCTL_FSA_CHANGEMODE: + case IOCTL_FSA_CHANGEMODEEX: { int fd = message->ioctl.buffer_in[0]; char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; int mode = message->ioctl.buffer_in[2]; + int mask = 0x777; + if (message->ioctl.command == IOCTL_FSA_CHANGEMODEEX) { + mask = message->ioctl.buffer_in[3]; + } - message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode); + message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode, mask); break; } case IOCTL_FSA_CHANGEOWNER: