#pragma once #include "wut.h" #include "filesystem.h" #ifdef __cplusplus extern "C" { #endif typedef uint32_t FSACommand; typedef uint16_t FSAIpcRequestType; typedef IOSHandle FSAClientHandle; typedef uint32_t FSAFileHandle; typedef uint32_t FSADirectoryHandle; typedef uint32_t FSAEntryNum; typedef FSDirectoryEntry FSADirectoryEntry; typedef FSStat FSAStat; typedef uint32_t FSAFilePosition; typedef struct FSAProcessInfo FSAProcessInfo; typedef struct FSARequestRawOpen FSARequestRawOpen; typedef struct FSARequestRawClose FSARequestRawClose; typedef struct FSARequestRawRead FSARequestRawRead; typedef struct FSARequestRawWrite FSARequestRawWrite; typedef struct FSARequestAppendFile FSARequestAppendFile; typedef struct FSARequestChangeDir FSARequestChangeDir; typedef struct FSARequestChangeMode FSARequestChangeMode; typedef struct FSARequestCloseDir FSARequestCloseDir; typedef struct FSARequestCloseFile FSARequestCloseFile; typedef struct FSARequestFlushFile FSARequestFlushFile; typedef struct FSARequestFlushQuota FSARequestFlushQuota; typedef struct FSARequestGetInfoByQuery FSARequestGetInfoByQuery; typedef struct FSARequestGetPosFile FSARequestGetPosFile; typedef struct FSARequestIsEof FSARequestIsEof; typedef struct FSARequestMakeDir FSARequestMakeDir; typedef struct FSARequestMakeQuota FSARequestMakeQuota; typedef struct FSARequestMount FSARequestMount; typedef struct FSARequestMountWithProcess FSARequestMountWithProcess; typedef struct FSARequestOpenDir FSARequestOpenDir; typedef struct FSARequestOpenFile FSARequestOpenFile; typedef struct FSARequestReadDir FSARequestReadDir; typedef struct FSARequestReadFile FSARequestReadFile; typedef struct FSARequestRemove FSARequestRemove; typedef struct FSARequestRename FSARequestRename; typedef struct FSARequestRewindDir FSARequestRewindDir; typedef struct FSARequestSetPosFile FSARequestSetPosFile; typedef struct FSARequestStatFile FSARequestStatFile; typedef struct FSARequestTruncateFile FSARequestTruncateFile; typedef struct FSARequestUnmount FSARequestUnmount; typedef struct FSARequestUnmountWithProcess FSARequestUnmountWithProcess; typedef struct FSARequestWriteFile FSARequestWriteFile; typedef struct FSARequestChangeOwner FSARequestChangeOwner; typedef struct FSARequest FSARequest; typedef struct FSAResponseRawOpen FSAResponseRawOpen; typedef struct FSAResponseGetCwd FSAResponseGetCwd; typedef struct FSAResponseGetFileBlockAddress FSAResponseGetFileBlockAddress; typedef struct FSAResponseGetPosFile FSAResponseGetPosFile; typedef struct FSAResponseGetVolumeInfo FSAResponseGetVolumeInfo; typedef struct FSAResponseGetInfoByQuery FSAResponseGetInfoByQuery; typedef struct FSAResponseOpenDir FSAResponseOpenDir; typedef struct FSAResponseOpenFile FSAResponseOpenFile; typedef struct FSAResponseReadDir FSAResponseReadDir; typedef struct FSAResponseStatFile FSAResponseStatFile; typedef struct FSAResponse FSAResponse; typedef struct FSAAsyncResult FSAAsyncResult; typedef struct FSAShimBuffer FSAShimBuffer; typedef struct FSAClientAttachAsyncData FSAClientAttachAsyncData; typedef struct FSABlockInfo FSABlockInfo; typedef struct FSADeviceInfo FSADeviceInfo; typedef struct FSAFileSystemInfo FSAFileSystemInfo; typedef struct FSVolumeInfo FSAVolumeInfo; typedef void (*FSAAsyncCallbackFn)(FSError result, FSACommand command, FSARequest *request, FSAResponse *response, void *userContext); /** * Block information. */ struct FSABlockInfo { WUT_UNKNOWN_BYTES(0x14); }; WUT_CHECK_SIZE(FSABlockInfo, 0x14); /** * Device information. */ struct FSADeviceInfo { WUT_UNKNOWN_BYTES(0x08); uint64_t deviceSizeInSectors; uint32_t deviceSectorSize; WUT_UNKNOWN_BYTES(0x14); }; WUT_CHECK_OFFSET(FSADeviceInfo, 0x08, deviceSizeInSectors); WUT_CHECK_OFFSET(FSADeviceInfo, 0x10, deviceSectorSize); WUT_CHECK_SIZE(FSADeviceInfo, 0x28); /** * File System information. */ struct FSAFileSystemInfo { WUT_UNKNOWN_BYTES(0x1E); }; WUT_CHECK_SIZE(FSAFileSystemInfo, 0x1E); typedef enum FSAMountPriority { FSA_MOUNT_PRIORITY_BASE = 0x1, FSA_MOUNT_PRIORITY_RAM_DISK_CACHE = 0x4, FSA_MOUNT_PRIORITY_TITLE_UPDATE = 0x9, FSA_MOUNT_PRIORITY_UNMOUNT_ALL = 0x80000000, } FSAMountPriority; typedef enum FSAQueryInfoType { FSA_QUERY_INFO_FREE_SPACE_SIZE = 0x0, FSA_QUERY_INFO_DIR_SIZE = 0x1, FSA_QUERY_INFO_ENTRY_NUM = 0x2, FSA_QUERY_INFO_FILE_SYSTEM_INFO = 0x3, FSA_QUERY_INFO_DEVICE_INFO = 0x4, FSA_QUERY_INFO_STAT = 0x5, FSA_QUERY_INFO_BAD_BLOCK_INFO = 0x6, FSA_QUERY_INFO_JOURNAL_FREE_SPACE_SIZE = 0x7, FSA_QUERY_INFO_FRAGMENT_BLOCK_INFO = 0x8, } FSAQueryInfoType; typedef enum FSAReadFlag { FSA_READ_FLAG_NONE = 0x0, FSA_READ_FLAG_READ_WITH_POS = 0x1 } FSAReadFlag; typedef enum FSAWriteFlag { FSA_WRITE_FLAG_NONE = 0x0, FSA_WRITE_FLAG_READ_WITH_POS = 0x1 } FSAWriteFlag; /** * Process information. */ struct FSAProcessInfo { uint64_t titleId; uint32_t processId; uint32_t groupId; }; WUT_CHECK_OFFSET(FSAProcessInfo, 0x00, titleId); WUT_CHECK_OFFSET(FSAProcessInfo, 0x08, processId); WUT_CHECK_OFFSET(FSAProcessInfo, 0x0C, groupId); WUT_CHECK_SIZE(FSAProcessInfo, 0x10); struct FSARequestRawOpen { char path[0x280]; }; WUT_CHECK_OFFSET(FSARequestRawOpen, 0x0, path); WUT_CHECK_SIZE(FSARequestRawOpen, 0x280); struct FSARequestRawClose { int32_t handle; }; WUT_CHECK_OFFSET(FSARequestRawClose, 0x0, handle); WUT_CHECK_SIZE(FSARequestRawClose, 0x04); struct WUT_PACKED FSARequestRawRead { WUT_UNKNOWN_BYTES(0x4); uint64_t blocks_offset; uint32_t count; uint32_t size; uint32_t device_handle; }; WUT_CHECK_OFFSET(FSARequestRawRead, 0x04, blocks_offset); WUT_CHECK_OFFSET(FSARequestRawRead, 0x0C, count); WUT_CHECK_OFFSET(FSARequestRawRead, 0x10, size); WUT_CHECK_OFFSET(FSARequestRawRead, 0x14, device_handle); WUT_CHECK_SIZE(FSARequestRawRead, 0x18); struct WUT_PACKED FSARequestRawWrite { WUT_UNKNOWN_BYTES(0x4); uint64_t blocks_offset; uint32_t count; uint32_t size; uint32_t device_handle; }; WUT_CHECK_OFFSET(FSARequestRawWrite, 0x04, blocks_offset); WUT_CHECK_OFFSET(FSARequestRawWrite, 0x0C, count); WUT_CHECK_OFFSET(FSARequestRawWrite, 0x10, size); WUT_CHECK_OFFSET(FSARequestRawWrite, 0x14, device_handle); WUT_CHECK_SIZE(FSARequestRawWrite, 0x18); /** * Request data for Command::AppendFile */ struct FSARequestAppendFile { uint32_t size; uint32_t count; FSAFileHandle handle; uint32_t unk0x0C; }; WUT_CHECK_OFFSET(FSARequestAppendFile, 0x0, size); WUT_CHECK_OFFSET(FSARequestAppendFile, 0x4, count); WUT_CHECK_OFFSET(FSARequestAppendFile, 0x8, handle); WUT_CHECK_OFFSET(FSARequestAppendFile, 0xC, unk0x0C); WUT_CHECK_SIZE(FSARequestAppendFile, 0x10); /** * Request data for Command::ChangeDir */ struct FSARequestChangeDir { char path[FS_MAX_PATH +1]; }; WUT_CHECK_OFFSET(FSARequestChangeDir, 0x0, path); WUT_CHECK_SIZE(FSARequestChangeDir, 0x280); /** * Request data for Command::ChangeMode */ struct FSARequestChangeMode { char path[FS_MAX_PATH +1]; uint32_t mode1; uint32_t mode2; }; WUT_CHECK_OFFSET(FSARequestChangeMode, 0x0, path); WUT_CHECK_OFFSET(FSARequestChangeMode, 0x280, mode1); WUT_CHECK_OFFSET(FSARequestChangeMode, 0x284, mode2); WUT_CHECK_SIZE(FSARequestChangeMode, 0x288); /** * Request data for Command::CloseDir */ struct FSARequestCloseDir { FSADirectoryHandle handle; }; WUT_CHECK_OFFSET(FSARequestCloseDir, 0x0, handle); WUT_CHECK_SIZE(FSARequestCloseDir, 0x4); /** * Request data for Command::CloseFile */ struct FSARequestCloseFile { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSARequestCloseFile, 0x0, handle); WUT_CHECK_SIZE(FSARequestCloseFile, 0x4); /** * Request data for Command::FlushFile */ struct FSARequestFlushFile { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSARequestFlushFile, 0x0, handle); WUT_CHECK_SIZE(FSARequestFlushFile, 0x4); /** * Request data for Command::FlushQuota */ struct FSARequestFlushQuota { char path[FS_MAX_PATH +1]; }; WUT_CHECK_OFFSET(FSARequestFlushQuota, 0x0, path); WUT_CHECK_SIZE(FSARequestFlushQuota, 0x280); /** * Request data for Command::GetInfoByQuery */ struct FSARequestGetInfoByQuery { char path[FS_MAX_PATH +1]; FSAQueryInfoType type; }; WUT_CHECK_OFFSET(FSARequestGetInfoByQuery, 0x0, path); WUT_CHECK_OFFSET(FSARequestGetInfoByQuery, 0x280, type); WUT_CHECK_SIZE(FSARequestGetInfoByQuery, 0x284); /** * Request data for Command::GetPosFile */ struct FSARequestGetPosFile { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSARequestGetPosFile, 0x0, handle); WUT_CHECK_SIZE(FSARequestGetPosFile, 0x4); /** * Request data for Command::IsEof */ struct FSARequestIsEof { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSARequestIsEof, 0x0, handle); WUT_CHECK_SIZE(FSARequestIsEof, 0x4); /** * Request data for Command::MakeDir */ struct FSARequestMakeDir { char path[FS_MAX_PATH +1]; uint32_t permission; }; WUT_CHECK_OFFSET(FSARequestMakeDir, 0x0, path); WUT_CHECK_OFFSET(FSARequestMakeDir, 0x280, permission); WUT_CHECK_SIZE(FSARequestMakeDir, 0x284); /** * Request data for Command::MakeQuota */ struct WUT_PACKED FSARequestMakeQuota { char path[FS_MAX_PATH +1]; uint32_t mode; uint64_t size; }; WUT_CHECK_OFFSET(FSARequestMakeQuota, 0x0, path); WUT_CHECK_OFFSET(FSARequestMakeQuota, 0x280, mode); WUT_CHECK_OFFSET(FSARequestMakeQuota, 0x284, size); WUT_CHECK_SIZE(FSARequestMakeQuota, 0x28C); /** * Request data for Command::Mount */ struct FSARequestMount { char path[FS_MAX_PATH +1]; char target[FS_MAX_PATH +1]; uint32_t unk0x500; void* unkBuf; uint32_t unkBufLen; }; WUT_CHECK_OFFSET(FSARequestMount, 0x0, path); WUT_CHECK_OFFSET(FSARequestMount, 0x280, target); WUT_CHECK_OFFSET(FSARequestMount, 0x500, unk0x500); WUT_CHECK_OFFSET(FSARequestMount, 0x504, unkBuf); WUT_CHECK_OFFSET(FSARequestMount, 0x508, unkBufLen); WUT_CHECK_SIZE(FSARequestMount, 0x50C); /** * Request data for Command::MountWithProcess */ struct WUT_PACKED FSARequestMountWithProcess { char path[FS_MAX_PATH +1]; char target[FS_MAX_PATH +1]; FSAMountPriority priority; FSAProcessInfo process; void* unkBuf; uint32_t unkBufLen; }; WUT_CHECK_OFFSET(FSARequestMountWithProcess, 0x0, path); WUT_CHECK_OFFSET(FSARequestMountWithProcess, 0x280, target); WUT_CHECK_OFFSET(FSARequestMountWithProcess, 0x500, priority); WUT_CHECK_OFFSET(FSARequestMountWithProcess, 0x504, process); WUT_CHECK_OFFSET(FSARequestMountWithProcess, 0x514, unkBuf); WUT_CHECK_OFFSET(FSARequestMountWithProcess, 0x518, unkBufLen); WUT_CHECK_SIZE(FSARequestMountWithProcess, 0x51C); /** * Request data for Command::OpenDir */ struct FSARequestOpenDir { char path[FS_MAX_PATH +1]; }; WUT_CHECK_OFFSET(FSARequestOpenDir, 0x0, path); WUT_CHECK_SIZE(FSARequestOpenDir, 0x280); /** * Request data for Command::OpenFile */ struct FSARequestOpenFile { char path[FS_MAX_PATH +1]; char mode[FS_MODE_LENGTH]; uint32_t unk0x290; uint32_t unk0x294; uint32_t unk0x298; }; WUT_CHECK_OFFSET(FSARequestOpenFile, 0x0, path); WUT_CHECK_OFFSET(FSARequestOpenFile, 0x280, mode); WUT_CHECK_OFFSET(FSARequestOpenFile, 0x290, unk0x290); WUT_CHECK_OFFSET(FSARequestOpenFile, 0x294, unk0x294); WUT_CHECK_OFFSET(FSARequestOpenFile, 0x298, unk0x298); WUT_CHECK_SIZE(FSARequestOpenFile, 0x29C); /** * Request data for Command::ReadDir */ struct FSARequestReadDir { FSADirectoryHandle handle; }; WUT_CHECK_OFFSET(FSARequestReadDir, 0x0, handle); WUT_CHECK_SIZE(FSARequestReadDir, 0x4); /** * Request data for Command::ReadFile */ struct FSARequestReadFile { //! Virtual pointer used only by Cafe, for IOS we should use ioctlv.vecs[1] uint8_t* buffer; uint32_t size; uint32_t count; FSAFilePosition pos; FSAFileHandle handle; FSAReadFlag readFlags; }; WUT_CHECK_OFFSET(FSARequestReadFile, 0x00, buffer); WUT_CHECK_OFFSET(FSARequestReadFile, 0x04, size); WUT_CHECK_OFFSET(FSARequestReadFile, 0x08, count); WUT_CHECK_OFFSET(FSARequestReadFile, 0x0C, pos); WUT_CHECK_OFFSET(FSARequestReadFile, 0x10, handle); WUT_CHECK_OFFSET(FSARequestReadFile, 0x14, readFlags); WUT_CHECK_SIZE(FSARequestReadFile, 0x18); /** * Request data for Command::Remove */ struct FSARequestRemove { char path[FS_MAX_PATH +1]; }; WUT_CHECK_OFFSET(FSARequestRemove, 0x0, path); WUT_CHECK_SIZE(FSARequestRemove, 0x280); /** * Request data for Command::Rename */ struct FSARequestRename { char oldPath[FS_MAX_PATH +1]; char newPath[FS_MAX_PATH +1]; }; WUT_CHECK_OFFSET(FSARequestRename, 0x0, oldPath); WUT_CHECK_OFFSET(FSARequestRename, 0x280, newPath); WUT_CHECK_SIZE(FSARequestRename, 0x500); /** * Request data for Command::RewindDir */ struct FSARequestRewindDir { FSADirectoryHandle handle; }; WUT_CHECK_OFFSET(FSARequestRewindDir, 0x0, handle); WUT_CHECK_SIZE(FSARequestRewindDir, 0x4); /** * Request data for Command::SetPosFile */ struct FSARequestSetPosFile { FSAFileHandle handle; FSAFilePosition pos; }; WUT_CHECK_OFFSET(FSARequestSetPosFile, 0x0, handle); WUT_CHECK_OFFSET(FSARequestSetPosFile, 0x4, pos); WUT_CHECK_SIZE(FSARequestSetPosFile, 0x8); /** * Request data for Command::StatFile */ struct FSARequestStatFile { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSARequestStatFile, 0x0, handle); WUT_CHECK_SIZE(FSARequestStatFile, 0x4); /** * Request data for Command::TruncateFile */ struct FSARequestTruncateFile { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSARequestTruncateFile, 0x0, handle); WUT_CHECK_SIZE(FSARequestTruncateFile, 0x4); /** * Request data for Command::Unmount */ struct FSARequestUnmount { char path[FS_MAX_PATH +1]; uint32_t unk0x280; }; WUT_CHECK_OFFSET(FSARequestUnmount, 0x0, path); WUT_CHECK_OFFSET(FSARequestUnmount, 0x280, unk0x280); WUT_CHECK_SIZE(FSARequestUnmount, 0x284); /** * Request data for Command::UnmountWithProcess */ struct WUT_PACKED FSARequestUnmountWithProcess { char path[FS_MAX_PATH +1]; FSAMountPriority priority; FSAProcessInfo process; }; WUT_CHECK_OFFSET(FSARequestUnmountWithProcess, 0x0, path); WUT_CHECK_OFFSET(FSARequestUnmountWithProcess, 0x280, priority); WUT_CHECK_OFFSET(FSARequestUnmountWithProcess, 0x284, process); WUT_CHECK_SIZE(FSARequestUnmountWithProcess, 0x294); /** * Request data for Command::WriteFile */ struct FSARequestWriteFile { //! Virtual pointer used only by Cafe, for IOS we should use ioctlv.vecs[1] const uint8_t* buffer; uint32_t size; uint32_t count; FSAFilePosition pos; FSAFileHandle handle; FSAWriteFlag writeFlags; }; WUT_CHECK_OFFSET(FSARequestWriteFile, 0x00, buffer); WUT_CHECK_OFFSET(FSARequestWriteFile, 0x04, size); WUT_CHECK_OFFSET(FSARequestWriteFile, 0x08, count); WUT_CHECK_OFFSET(FSARequestWriteFile, 0x0C, pos); WUT_CHECK_OFFSET(FSARequestWriteFile, 0x10, handle); WUT_CHECK_OFFSET(FSARequestWriteFile, 0x14, writeFlags); WUT_CHECK_SIZE(FSARequestWriteFile, 0x18); struct FSARequestChangeOwner { char path[FS_MAX_PATH +1]; WUT_UNKNOWN_BYTES(4); uint32_t owner; WUT_UNKNOWN_BYTES(4); uint32_t group; }; WUT_CHECK_OFFSET(FSARequestChangeOwner, 0x0, path); WUT_CHECK_OFFSET(FSARequestChangeOwner, 0x284, owner); WUT_CHECK_OFFSET(FSARequestChangeOwner, 0x28C, group); WUT_CHECK_SIZE(FSARequestChangeOwner, 0x290); struct FSARequest { FSError emulatedError; union { FSARequestRawOpen rawOpen; FSARequestRawClose rawClose; FSARequestRawRead rawRead; FSARequestRawWrite rawWrite; FSARequestAppendFile appendFile; FSARequestChangeDir changeDir; FSARequestChangeMode changeMode; FSARequestCloseDir closeDir; FSARequestCloseFile closeFile; FSARequestFlushFile flushFile; FSARequestFlushQuota flushQuota; FSARequestGetInfoByQuery getInfoByQuery; FSARequestGetPosFile getPosFile; FSARequestIsEof isEof; FSARequestMakeDir makeDir; FSARequestMakeQuota makeQuota; FSARequestMount mount; FSARequestMountWithProcess mountWithProcess; FSARequestOpenDir openDir; FSARequestOpenFile openFile; FSARequestReadDir readDir; FSARequestReadFile readFile; FSARequestRemove remove; FSARequestRename rename; FSARequestRewindDir rewindDir; FSARequestSetPosFile setPosFile; FSARequestStatFile statFile; FSARequestTruncateFile truncateFile; FSARequestUnmount unmount; FSARequestUnmountWithProcess unmountWithProcess; FSARequestWriteFile writeFile; FSARequestChangeOwner changeOwner; WUT_UNKNOWN_BYTES(0x51C); }; }; WUT_CHECK_OFFSET(FSARequest, 0x00, emulatedError); WUT_CHECK_OFFSET(FSARequest, 0x04, rawOpen); WUT_CHECK_SIZE(FSARequest, 0x520); struct FSAResponseRawOpen { int handle; }; WUT_CHECK_OFFSET(FSAResponseRawOpen, 0x0, handle); WUT_CHECK_SIZE(FSAResponseRawOpen, 0x4); struct FSAResponseGetCwd { char path[FS_MAX_PATH +1]; }; WUT_CHECK_OFFSET(FSAResponseGetCwd, 0x0, path); WUT_CHECK_SIZE(FSAResponseGetCwd, 0x280); struct FSAResponseGetFileBlockAddress { uint32_t address; }; WUT_CHECK_OFFSET(FSAResponseGetFileBlockAddress, 0x0, address); WUT_CHECK_SIZE(FSAResponseGetFileBlockAddress, 0x4); struct FSAResponseGetPosFile { FSAFilePosition pos; }; WUT_CHECK_OFFSET(FSAResponseGetPosFile, 0x0, pos); WUT_CHECK_SIZE(FSAResponseGetPosFile, 0x4); struct FSAResponseGetVolumeInfo { FSAVolumeInfo volumeInfo; }; WUT_CHECK_OFFSET(FSAResponseGetVolumeInfo, 0x0, volumeInfo); WUT_CHECK_SIZE(FSAResponseGetVolumeInfo, 0x1BC); struct WUT_PACKED FSAResponseGetInfoByQuery { union WUT_PACKED { FSABlockInfo badBlockInfo; FSADeviceInfo deviceInfo; uint64_t dirSize; FSAEntryNum entryNum; FSAFileSystemInfo fileSystemInfo; FSABlockInfo fragmentBlockInfo; uint64_t freeSpaceSize; uint64_t journalFreeSpaceSize; FSAStat stat; }; }; WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, badBlockInfo); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, deviceInfo); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, dirSize); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, entryNum); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, fragmentBlockInfo); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, freeSpaceSize); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, fileSystemInfo); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, journalFreeSpaceSize); WUT_CHECK_OFFSET(FSAResponseGetInfoByQuery, 0x0, stat); WUT_CHECK_SIZE(FSAResponseGetInfoByQuery, 0x64); struct FSAResponseOpenFile { FSAFileHandle handle; }; WUT_CHECK_OFFSET(FSAResponseOpenFile, 0x0, handle); WUT_CHECK_SIZE(FSAResponseOpenFile, 0x4); struct FSAResponseOpenDir { FSADirectoryHandle handle; }; WUT_CHECK_OFFSET(FSAResponseOpenDir, 0x0, handle); WUT_CHECK_SIZE(FSAResponseOpenDir, 0x4); struct FSAResponseReadDir { FSADirectoryEntry entry; }; WUT_CHECK_OFFSET(FSAResponseReadDir, 0x0, entry); WUT_CHECK_SIZE(FSAResponseReadDir, 0x164); struct FSAResponseStatFile { FSAStat stat; }; WUT_CHECK_OFFSET(FSAResponseStatFile, 0x0, stat); WUT_CHECK_SIZE(FSAResponseStatFile, 0x64); struct WUT_PACKED FSAResponse { uint32_t word0; union WUT_PACKED { FSAResponseRawOpen rawOpen; FSAResponseGetCwd getCwd; FSAResponseGetFileBlockAddress getFileBlockAddress; FSAResponseGetPosFile getPosFile; FSAResponseGetVolumeInfo getVolumeInfo; FSAResponseGetInfoByQuery getInfoByQuery; FSAResponseOpenDir openDir; FSAResponseOpenFile openFile; FSAResponseReadDir readDir; FSAResponseStatFile statFile; WUT_UNKNOWN_BYTES(0x28F); }; }; WUT_CHECK_OFFSET(FSAResponse, 0x0, word0); WUT_CHECK_OFFSET(FSAResponse, 0x4, rawOpen); WUT_CHECK_SIZE(FSAResponse, 0x293); enum FSACommandEnum { FSA_COMMAND_INVALID = 0x0, FSA_COMMAND_MOUNT = 0x1, FSA_COMMAND_UNMOUNT = 0x2, FSA_COMMAND_GET_VOLUME_INFO = 0x3, FSA_COMMAND_GET_ATTACH = 0x4, FSA_COMMAND_CHANGE_DIR = 0x5, FSA_COMMAND_GET_CWD = 0x6, FSA_COMMAND_MAKE_DIR = 0x7, FSA_COMMAND_REMOVE = 0x8, FSA_COMMAND_RENAME = 0x9, FSA_COMMAND_OPEN_DIR = 0xA, FSA_COMMAND_READ_DIR = 0xB, FSA_COMMAND_REWIND_DIR = 0xC, FSA_COMMAND_CLOSE_DIR = 0xD, FSA_COMMAND_OPEN_FILE = 0xE, FSA_COMMAND_READ_FILE = 0xF, FSA_COMMAND_WRITE_FILE = 0x10, FSA_COMMAND_GET_POS_FILE = 0x11, FSA_COMMAND_SET_POS_FILE = 0x12, FSA_COMMAND_IS_EOF = 0x13, FSA_COMMAND_STAT_FILE = 0x14, FSA_COMMAND_CLOSE_FILE = 0x15, FSA_COMMAND_GET_ERROR = 0x16, FSA_COMMAND_FLUSH_FILE = 0x17, FSA_COMMAND_GET_INFO_BY_QUERY = 0x18, FSA_COMMAND_APPEND_FILE = 0x19, FSA_COMMAND_TRUNCATE_FILE = 0x1A, FSA_COMMAND_FLUSH_VOLUME = 0x1B, FSA_COMMAND_ROLLBACK_VOLUME = 0x1C, FSA_COMMAND_MAKE_QUOTA = 0x1D, FSA_COMMAND_FLUSH_QUOTA = 0x1E, FSA_COMMAND_ROLLBACK_QUOTA = 0x1F, FSA_COMMAND_CHANGE_MODE = 0x20, FSA_COMMAND_OPEN_FILE_BY_STAT = 0x21, FSA_COMMAND_REGISTER_FLUSH_QUOTA = 0x22, FSA_COMMAND_FLUSH_MULTI_QUOTA = 0x23, FSA_COMMAND_GET_FILE_BLOCK_ADDRESS = 0x25, FSA_COMMAND_ADD_USER_PROCESS = 0x65, FSA_COMMAND_DEL_USER_PROCESS = 0x66, FSA_COMMAND_MOUNT_WITH_PROCESS = 0x67, FSA_COMMAND_UNMOUNT_WITH_PROCESS = 0x68, FSA_COMMAND_FORMAT = 0x69, FSA_COMMAND_RAW_OPEN = 0x6A, FSA_COMMAND_RAW_READ = 0x6B, FSA_COMMAND_RAW_WRITE = 0x6C, FSA_COMMAND_RAW_CLOSE = 0x6D, FSA_COMMAND_GET_LAST_FAILED_VOLUME = 0x6E, FSA_COMMAND_GET_VOLUME_EXISTENCE = 0x6F, FSA_COMMAND_CHANGE_OWNER = 0x70, FSA_COMMAND_CANCEL_GET_ATTACH = 0x71, FSA_COMMAND_REMOVE_QUOTA = 0x72, FSA_COMMAND_SET_CLIENT_PRIORITY = 0x73, FSA_COMMAND_APPLY_MEMORY_CACHE = 0x74, FSA_COMMAND_MAKE_LINK = 0x75, FSA_COMMAND_XFER_PARAMS = 0x76, FSA_COMMAND_EXEC_DEBUG_PROC = 0x78, FSA_COMMAND_DEBUG_SET_TITLE_ID = 0x79, FSA_COMMAND_DEBUG_SET_CAPABILITY = 0x7A, FSA_COMMAND_SET_PROCESS_CONFIG = 0x82, FSA_COMMAND_CONFIG_SET_MEMORY_CACHE = 0x83, FSA_COMMAND_CONFIG_UNSET_MEMORY_CACHE = 0x84, FSA_COMMAND_CONFIG_SET_PRF2_CHAR_CODE = 0x85, FSA_COMMAND_GET_PROC_RESOURCE_USAGE = 0x8C, FSA_COMMAND_GET_ALL_RESOURCE_USAGE = 0x8D, FSA_COMMAND_SEND_PROFILE_CMD = 0x8E, }; enum FSAIpcRequestTypeEnum { FSA_IPC_REQUEST_IOCTL = 0, FSA_IPC_REQUEST_IOCTLV = 1, }; struct FSAAsyncResult { //! Queue to put a message on when command is complete. OSMessageQueue *ioMsgQueue; //! Message used for ioMsgQueue. FSMessage msg; //! Callback to call when the command is complete. FSAAsyncCallbackFn userCallback; //! Result. FSError error; //! FSA command. FSACommand command; //! Pointer to allocated FSA IPC Request. FSARequest *request; //! Pointer to allocated FSA IPC Response. FSAResponse *response; //! Callback to call when the command is complete. void *userContext; }; WUT_CHECK_OFFSET(FSAAsyncResult, 0x00, ioMsgQueue); WUT_CHECK_OFFSET(FSAAsyncResult, 0x04, msg); WUT_CHECK_OFFSET(FSAAsyncResult, 0x14, userCallback); WUT_CHECK_OFFSET(FSAAsyncResult, 0x18, error); WUT_CHECK_OFFSET(FSAAsyncResult, 0x1C, command); WUT_CHECK_OFFSET(FSAAsyncResult, 0x20, request); WUT_CHECK_OFFSET(FSAAsyncResult, 0x24, response); WUT_CHECK_OFFSET(FSAAsyncResult, 0x28, userContext); WUT_CHECK_SIZE(FSAAsyncResult, 0x2C); struct WUT_PACKED FSAShimBuffer { //! Buffer for FSA IPC request. FSARequest request; WUT_UNKNOWN_BYTES(0x60); //! Buffer for FSA IPC response. FSAResponse response; WUT_UNKNOWN_BYTES(0x880 - 0x813); //! Memory to use for ioctlv calls, unknown maximum count - but at least 3. IOSVec ioctlvVec[3]; WUT_UNKNOWN_BYTES(0x900 - 0x8A4); //! Command for FSA. FSACommand command; //! Handle to FSA device. uint32_t clientHandle; //! IOS IPC request type to use. FSAIpcRequestType ipcReqType; //! Number of ioctlv input vectors. uint8_t ioctlvVecIn; //! Number of ioctlv output vectors. uint8_t ioctlvVecOut; //! FSAAsyncResult used for FSA* functions. FSAAsyncResult fsaAsyncResult; }; WUT_CHECK_OFFSET(FSAShimBuffer, 0x0, request); WUT_CHECK_OFFSET(FSAShimBuffer, 0x580, response); WUT_CHECK_OFFSET(FSAShimBuffer, 0x880, ioctlvVec); WUT_CHECK_OFFSET(FSAShimBuffer, 0x900, command); WUT_CHECK_OFFSET(FSAShimBuffer, 0x904, clientHandle); WUT_CHECK_OFFSET(FSAShimBuffer, 0x908, ipcReqType); WUT_CHECK_OFFSET(FSAShimBuffer, 0x90A, ioctlvVecIn); WUT_CHECK_OFFSET(FSAShimBuffer, 0x90B, ioctlvVecOut); WUT_CHECK_OFFSET(FSAShimBuffer, 0x90C, fsaAsyncResult); WUT_CHECK_SIZE(FSAShimBuffer, 0x938); typedef void (*FSAClientAttachAsyncCallbackFn)(FSError result, FSACommand command, FSARequest *request, FSAResponse *response, void *userContext); struct FSAClientAttachAsyncData { //! Callback to call when an attach has happened. FSAClientAttachAsyncCallbackFn userCallback; //! Callback context void *userContext; //! Queue to put a message on when command is complete. OSMessageQueue *ioMsgQueue; }; WUT_CHECK_OFFSET(FSAClientAttachAsyncData, 0x00, userCallback); WUT_CHECK_OFFSET(FSAClientAttachAsyncData, 0x04, userContext); WUT_CHECK_OFFSET(FSAClientAttachAsyncData, 0x08, ioMsgQueue); WUT_CHECK_SIZE(FSAClientAttachAsyncData, 0xC); typedef enum FSAMountFlags { FSA_MOUNT_FLAG_LOCAL_MOUNT = 0, FSA_MOUNT_FLAG_BIND_MOUNT = 1, FSA_MOUNT_FLAG_GLOBAL_MOUNT = 2, } FSAMountFlags; typedef enum FSAUnmountFlags { FSA_UNMOUNT_FLAG_NONE = 0x00000000, FSA_UNMOUNT_FLAG_FORCE = 0x00000002, FSA_UNMOUNT_FLAG_BIND_MOUNT = 0x80000000, } FSAUnmountFlags; FSError FSAInit(); void FSAShutdown(); uint32_t FSAGetClientNum(); FSAClientHandle FSAAddClient(FSAClientAttachAsyncData *attachAsyncData); FSError FSADelClient(FSAClientHandle client); const char * FSAGetStatusStr(FSError error); FSError __FSAShimDecodeIosErrorToFsaStatus(IOSHandle handle, IOSError err); FSError FSAFlushMultiQuota(FSAClientHandle client, const char *path); FSError FSAFlushQuota(FSAClientHandle client, const char *path); FSError FSAFlushVolume(FSAClientHandle client, const char *path); /** * Frees the FSAShimBuffer where the given asyncResult is part of * @param asyncResult */ void FSAFreeAsyncResult(FSAAsyncResult *asyncResult); FSAAsyncResult FSAGetAsyncResult(OSMessage *asyncResult); FSError FSAMount(FSAClientHandle client, const char *source, const char *target, FSAMountFlags flags, void *arg_buf, uint32_t arg_len); FSError FSAUnmount(FSAClientHandle client, const char *mountedTarget, FSAUnmountFlags flags); FSError FSAChangeDir(FSAClientHandle client, const char *path); FSError FSAChangeMode(FSAClientHandle client, const char *path, FSMode permission); FSError FSAOpenFileEx(FSAClientHandle client, const char *path, const char *mode, FSMode createMode, FSOpenFileFlags openFlag, uint32_t preallocSize, FSAFileHandle *outFileHandle); FSError FSAOpenFileByStat(FSAClientHandle client, FSAStat *stat, const char *mode, const char *path, FSAFileHandle *outFileHandle); FSError FSAGetStatFile(FSAClientHandle client, FSAFileHandle fileHandle, FSAStat *stat); FSError FSAGetStat(FSAClientHandle client, const char *path, FSAStat *stat); FSError FSACloseFile(FSAClientHandle client, FSAFileHandle fileHandle); FSError FSAAppendFile(FSAClientHandle client, FSAFileHandle fileHandle, uint32_t size, uint32_t count); FSError FSAAppendFileEx(FSAClientHandle client, FSAFileHandle fileHandle, uint32_t size, uint32_t count, uint32_t flags); FSError FSAGetPosFile(FSAClientHandle client, FSAFileHandle fileHandle, uint32_t *outPos); FSError FSAFlushFile(FSAClientHandle client, FSAFileHandle fileHandle); FSError FSASetPosFile(FSAClientHandle client, FSAFileHandle fileHandle, uint32_t pos); FSError FSATruncateFile(FSAClientHandle client, FSAFileHandle handle); FSError FSAWriteFile(FSAClientHandle client, void *buffer, uint32_t size, uint32_t count, FSAFileHandle handle, uint32_t flags); FSError FSAWriteFileWithPos(FSAClientHandle client, void *buffer, uint32_t size, uint32_t count, uint32_t pos, FSAFileHandle handle, uint32_t flags); FSError FSAIsEof(FSAClientHandle client, FSAFileHandle fileHandle); FSError FSAReadFile(FSAClientHandle client, void *buffer, uint32_t size, uint32_t count, FSAFileHandle handle, uint32_t flags); FSError FSAReadFileWithPos(FSAClientHandle client, void *buffer, uint32_t size, uint32_t count, uint32_t pos, FSAFileHandle handle, uint32_t flags); FSError FSARemove(FSAClientHandle client, const char *path); FSError FSARename(FSAClientHandle client, const char *oldPath, const char *newPath); FSError FSAOpenDir(FSAClientHandle client, const char *path, FSADirectoryHandle *dirHandle); FSError FSAReadDir(FSAClientHandle client, FSADirectoryHandle dirHandle, FSADirectoryEntry *directoryEntry); FSError FSARewindDir(FSAClientHandle client, FSADirectoryHandle dirHandle); FSError FSACloseDir(FSAClientHandle client, FSADirectoryHandle dirHandle); FSError FSAMakeDir(FSAClientHandle client, const char *path, FSMode mode); FSError FSAGetCwd(FSAClientHandle client, char *outPath, uint32_t outPathLen); FSError FSAGetTransactionBlockPoolAttributes(uint32_t *messageSize, uint32_t *poolSize, uint32_t *numMessages); FSError FSAGetVolumeInfo(FSAClientHandle client, const char *path, FSAVolumeInfo *outVolumeInfo); FSError FSAMakeQuota(FSAClientHandle client, const char *name, uint32_t mode, uint64_t quota); FSError FSARegisterFlushQuota(FSAClientHandle client, const char *path); FSError FSARollbackQuota(FSAClientHandle client, const char *path); FSError FSARollbackQuotaForce(FSAClientHandle client, const char *path); FSError FSARollbackVolume(FSAClientHandle client, const char *path); FSError FSAGetFreeSpaceSize(FSAClientHandle client, const char *path, uint64_t *freeSpaceSize); FSError FSAGetJournalFreeSpaceSize(FSAClientHandle client, const char *path, uint64_t *journalFreeSpaceSize); FSError FSAGetDirSize(FSAClientHandle client, const char *path, uint64_t *freeDirSize); FSError FSAGetEntryNum(FSAClientHandle client, const char *path, FSAEntryNum *entryNum); FSError FSAGetFileSystemInfo(FSAClientHandle client, const char *path, FSAFileSystemInfo *fileSystemInfo); FSError FSAGetDeviceInfo(FSAClientHandle client, const char *path, FSADeviceInfo *fileSystemInfo); FSError FSAGetBadBlockInfo(FSAClientHandle client, const char *path, FSABlockInfo *blockInfo); FSError FSAGetFragmentBlockInfo(FSAClientHandle client, const char *path, FSABlockInfo *blockInfo); #ifdef __cplusplus } #endif