coreinit: Implement several FSA functions and fix some bugs (#844)

This commit is contained in:
Maschell 2023-06-15 21:05:16 +02:00 committed by GitHub
parent ae4cb45cf3
commit f1ebfa9941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1032 additions and 121 deletions

View File

@ -302,6 +302,15 @@ public:
return true; return true;
} }
bool fscRewindDir() override
{
if (!dirIterator)
return true;
dirIterator->index = 0;
return true;
}
void addUniqueDirEntry(const FSCDirEntry& dirEntry) void addUniqueDirEntry(const FSCDirEntry& dirEntry)
{ {
// skip if already in list // skip if already in list
@ -378,6 +387,7 @@ FSCVirtualFile* fsc_open(const char* path, FSC_ACCESS_FLAG accessFlags, sint32*
{ {
// return first found file // return first found file
cemu_assert_debug(HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE)); cemu_assert_debug(HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE));
fscVirtualFile->m_isAppend = HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::IS_APPEND);
fscLeave(); fscLeave();
return fscVirtualFile; return fscVirtualFile;
} }
@ -598,6 +608,9 @@ uint32 fsc_writeFile(FSCVirtualFile* fscFile, void* buffer, uint32 size)
fscLeave(); fscLeave();
return 0; return 0;
} }
if (fscFile->m_isAppend)
fsc_setFileSeek(fscFile, fsc_getFileSize(fscFile));
uint32 fscStatus = fscFile->fscWriteData(buffer, size); uint32 fscStatus = fscFile->fscWriteData(buffer, size);
fscLeave(); fscLeave();
return fscStatus; return fscStatus;

View File

@ -24,7 +24,10 @@ enum class FSC_ACCESS_FLAG : uint8
// which types can be opened // which types can be opened
// invalid operation if neither is set // invalid operation if neither is set
OPEN_DIR = (1 << 4), OPEN_DIR = (1 << 4),
OPEN_FILE = (1 << 5) OPEN_FILE = (1 << 5),
// Writing seeks to the end of the file if set
IS_APPEND = (1 << 6)
}; };
DEFINE_ENUM_FLAG_OPERATORS(FSC_ACCESS_FLAG); DEFINE_ENUM_FLAG_OPERATORS(FSC_ACCESS_FLAG);
@ -149,7 +152,15 @@ struct FSCVirtualFile
return false; return false;
} }
virtual bool fscRewindDir()
{
cemu_assert_unimplemented();
return false;
}
FSCDirIteratorState* dirIterator{}; FSCDirIteratorState* dirIterator{};
bool m_isAppend{ false };
}; };
#define FSC_PRIORITY_BASE (0) #define FSC_PRIORITY_BASE (0)

View File

@ -17,9 +17,11 @@ enum class FS_RESULT : sint32 // aka FSStatus
enum class FSA_RESULT : sint32 // aka FSError/FSAStatus enum class FSA_RESULT : sint32 // aka FSError/FSAStatus
{ {
SUCCESS = 0, OK = 0,
END_DIR = -0x30000 - 0x04, NOT_INIT = -0x30000 - 0x01,
END_FILE = -0x30000 - 0x05, END_OF_DIRECTORY = -0x30000 - 0x04,
END_OF_FILE = -0x30000 - 0x05,
MAX_CLIENTS = -0x30000 - 0x12,
MAX_FILES = -0x30000 - 0x13, MAX_FILES = -0x30000 - 0x13,
MAX_DIRS = -0x30000 - 0x14, MAX_DIRS = -0x30000 - 0x14,
ALREADY_EXISTS = -0x30000 - 0x16, ALREADY_EXISTS = -0x30000 - 0x16,
@ -34,6 +36,7 @@ enum class FSA_RESULT : sint32 // aka FSError/FSAStatus
INVALID_DIR_HANDLE = -0x30000 - 0x27, INVALID_DIR_HANDLE = -0x30000 - 0x27,
NOT_FILE = -0x30000 - 0x28, NOT_FILE = -0x30000 - 0x28,
NOT_DIR = -0x30000 - 0x29, NOT_DIR = -0x30000 - 0x29,
OUT_OF_RESOURCES = -0x30000 - 0x2C,
FATAL_ERROR = -0x30000 - 0x400, FATAL_ERROR = -0x30000 - 0x400,
}; };
@ -46,6 +49,7 @@ enum class FSA_CMD_OPERATION_TYPE : uint32
RENAME = 0x9, RENAME = 0x9,
OPENDIR = 0xA, OPENDIR = 0xA,
READDIR = 0xB, READDIR = 0xB,
REWINDDIR = 0xC,
CLOSEDIR = 0xD, CLOSEDIR = 0xD,
OPENFILE = 0xE, OPENFILE = 0xE,
READ = 0xF, READ = 0xF,
@ -55,6 +59,7 @@ enum class FSA_CMD_OPERATION_TYPE : uint32
ISEOF = 0x13, ISEOF = 0x13,
GETSTATFILE = 0x14, GETSTATFILE = 0x14,
CLOSEFILE = 0x15, CLOSEFILE = 0x15,
FLUSHFILE = 0x17,
QUERYINFO = 0x18, QUERYINFO = 0x18,
APPENDFILE = 0x19, APPENDFILE = 0x19,
TRUNCATEFILE = 0x1A, TRUNCATEFILE = 0x1A,
@ -81,6 +86,7 @@ enum class FSFlag : uint32
{ {
NONE = 0, NONE = 0,
IS_DIR = 0x80000000, IS_DIR = 0x80000000,
IS_FILE = 0x01000000,
}; };
DEFINE_ENUM_FLAG_OPERATORS(FSFlag); DEFINE_ENUM_FLAG_OPERATORS(FSFlag);
@ -111,8 +117,18 @@ struct FSDirEntry_t
static_assert(sizeof(FSDirEntry_t) == 0xE4); static_assert(sizeof(FSDirEntry_t) == 0xE4);
struct FSADeviceInfo_t
{
uint8 ukn0[0x8];
uint64be deviceSizeInSectors;
uint32be deviceSectorSize;
uint8 ukn014[0x14];
};
static_assert(sizeof(FSADeviceInfo_t) == 0x28);
#pragma pack() #pragma pack()
// query types for QueryInfo // query types for QueryInfo
#define FSA_QUERY_TYPE_FREESPACE 0 #define FSA_QUERY_TYPE_FREESPACE 0
#define FSA_QUERY_TYPE_DEVICE_INFO 4
#define FSA_QUERY_TYPE_STAT 5 #define FSA_QUERY_TYPE_STAT 5

View File

@ -54,7 +54,7 @@ namespace iosu
FSA_RESULT FSA_convertFSCtoFSAStatus(sint32 fscError) FSA_RESULT FSA_convertFSCtoFSAStatus(sint32 fscError)
{ {
if (fscError == FSC_STATUS_OK) if (fscError == FSC_STATUS_OK)
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
else if (fscError == FSC_STATUS_FILE_NOT_FOUND) else if (fscError == FSC_STATUS_FILE_NOT_FOUND)
return FSA_RESULT::NOT_FOUND; return FSA_RESULT::NOT_FOUND;
else if (fscError == FSC_STATUS_ALREADY_EXISTS) else if (fscError == FSC_STATUS_ALREADY_EXISTS)
@ -175,7 +175,7 @@ namespace iosu
it.isAllocated = true; it.isAllocated = true;
uint32 handleVal = ((uint32)i << 16) | (uint32)checkValue; uint32 handleVal = ((uint32)i << 16) | (uint32)checkValue;
handleOut = (FSResHandle)handleVal; handleOut = (FSResHandle)handleVal;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
cemuLog_log(LogType::Force, "FSA: Ran out of file handles"); cemuLog_log(LogType::Force, "FSA: Ran out of file handles");
return FSA_RESULT::FATAL_ERROR; return FSA_RESULT::FATAL_ERROR;
@ -194,7 +194,7 @@ namespace iosu
return FSA_RESULT::INVALID_FILE_HANDLE; return FSA_RESULT::INVALID_FILE_HANDLE;
it.fscFile = nullptr; it.fscFile = nullptr;
it.isAllocated = false; it.isAllocated = false;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSCVirtualFile* GetByHandle(FSResHandle handle) FSCVirtualFile* GetByHandle(FSResHandle handle)
@ -229,10 +229,9 @@ namespace iosu
accessModifier = FSC_ACCESS_FLAG::READ_PERMISSION; accessModifier = FSC_ACCESS_FLAG::READ_PERMISSION;
else if (strcmp(accessModifierStr, "r+") == 0) else if (strcmp(accessModifierStr, "r+") == 0)
{ {
// r+ will create a new file if it doesn't exist
// the cursor will be set to the beginning of the file // the cursor will be set to the beginning of the file
// allows read and write access // allows read and write access
accessModifier = FSC_ACCESS_FLAG::READ_PERMISSION | FSC_ACCESS_FLAG::WRITE_PERMISSION | FSC_ACCESS_FLAG::FILE_ALLOW_CREATE; // create if non exists, read, write accessModifier = FSC_ACCESS_FLAG::READ_PERMISSION | FSC_ACCESS_FLAG::WRITE_PERMISSION; // read, write
} }
else if (strcmp(accessModifierStr, "w") == 0) else if (strcmp(accessModifierStr, "w") == 0)
{ {
@ -252,10 +251,12 @@ namespace iosu
} }
else if (strcmp(accessModifierStr, "a+") == 0) else if (strcmp(accessModifierStr, "a+") == 0)
{ {
cemu_assert_debug(false); // a+ is kind of special. Writing always happens at the end but the read cursor can dynamically move accessModifier = FSC_ACCESS_FLAG::READ_PERMISSION | FSC_ACCESS_FLAG::WRITE_PERMISSION | FSC_ACCESS_FLAG::FILE_ALLOW_CREATE | FSC_ACCESS_FLAG::IS_APPEND;
// but Cafe OS might not support this. Needs investigation. isAppend = true;
// this also used to be FILE_ALWAYS_CREATE in 1.26.2 and before }
accessModifier = FSC_ACCESS_FLAG::READ_PERMISSION | FSC_ACCESS_FLAG::WRITE_PERMISSION | FSC_ACCESS_FLAG::FILE_ALLOW_CREATE; else if (strcmp(accessModifierStr, "a") == 0)
{
accessModifier = FSC_ACCESS_FLAG::WRITE_PERMISSION | FSC_ACCESS_FLAG::FILE_ALLOW_CREATE | FSC_ACCESS_FLAG::IS_APPEND;
isAppend = true; isAppend = true;
} }
else else
@ -275,7 +276,7 @@ namespace iosu
fsc_setFileSeek(fscFile, fsc_getFileSize(fscFile)); fsc_setFileSeek(fscFile, fsc_getFileSize(fscFile));
FSResHandle fsFileHandle; FSResHandle fsFileHandle;
FSA_RESULT r = sFileHandleTable.AllocateHandle(fsFileHandle, fscFile); FSA_RESULT r = sFileHandleTable.AllocateHandle(fsFileHandle, fscFile);
if (r != FSA_RESULT::SUCCESS) if (r != FSA_RESULT::OK)
{ {
cemuLog_log(LogType::Force, "Exceeded maximum number of FSA file handles"); cemuLog_log(LogType::Force, "Exceeded maximum number of FSA file handles");
delete fscFile; delete fscFile;
@ -283,7 +284,7 @@ namespace iosu
} }
*fileHandle = fsFileHandle; *fileHandle = fsFileHandle;
cemuLog_log(LogType::CoreinitFile, "Open file {} (access: {} result: ok handle: 0x{})", path, accessModifierStr, (uint32)*fileHandle); cemuLog_log(LogType::CoreinitFile, "Open file {} (access: {} result: ok handle: 0x{})", path, accessModifierStr, (uint32)*fileHandle);
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT __FSAOpenDirectory(FSAClient* client, std::string_view path, sint32* dirHandle) FSA_RESULT __FSAOpenDirectory(FSAClient* client, std::string_view path, sint32* dirHandle)
@ -300,14 +301,14 @@ namespace iosu
} }
FSResHandle fsDirHandle; FSResHandle fsDirHandle;
FSA_RESULT r = sDirHandleTable.AllocateHandle(fsDirHandle, fscFile); FSA_RESULT r = sDirHandleTable.AllocateHandle(fsDirHandle, fscFile);
if (r != FSA_RESULT::SUCCESS) if (r != FSA_RESULT::OK)
{ {
delete fscFile; delete fscFile;
return FSA_RESULT::MAX_DIRS; return FSA_RESULT::MAX_DIRS;
} }
*dirHandle = fsDirHandle; *dirHandle = fsDirHandle;
cemuLog_log(LogType::CoreinitFile, "Open directory {} (result: ok handle: 0x{})", path, (uint32)*dirHandle); cemuLog_log(LogType::CoreinitFile, "Open directory {} (result: ok handle: 0x{})", path, (uint32)*dirHandle);
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT __FSACloseFile(uint32 fileHandle) FSA_RESULT __FSACloseFile(uint32 fileHandle)
@ -322,7 +323,7 @@ namespace iosu
// unregister file // unregister file
sFileHandleTable.ReleaseHandle(fileHandle); // todo - use the error code of this sFileHandleTable.ReleaseHandle(fileHandle); // todo - use the error code of this
fsc_close(fscFile); fsc_close(fscFile);
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_remove(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_remove(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -383,7 +384,7 @@ namespace iosu
return FSA_convertFSCtoFSAStatus(fscStatus); return FSA_convertFSCtoFSAStatus(fscStatus);
__FSA_GetStatFromFSCFile(fscFile, fsStatOut); __FSA_GetStatFromFSCFile(fscFile, fsStatOut);
delete fscFile; delete fscFile;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_queryInfo(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_queryInfo(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -407,7 +408,16 @@ namespace iosu
betype<uint64>* fsStatSize = &shimBuffer->response.cmdQueryInfo.queryFreeSpace.freespace; betype<uint64>* fsStatSize = &shimBuffer->response.cmdQueryInfo.queryFreeSpace.freespace;
*fsStatSize = 30ull * 1024 * 1024 * 1024; // placeholder value. How is this determined? *fsStatSize = 30ull * 1024 * 1024 * 1024; // placeholder value. How is this determined?
delete fscFile; delete fscFile;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
}
else if (queryType == FSA_QUERY_TYPE_DEVICE_INFO)
{
FSADeviceInfo_t* deviceInfo = &shimBuffer->response.cmdQueryInfo.queryDeviceInfo.info;
// always report hardcoded values for now.
deviceInfo->deviceSectorSize = 512;
deviceInfo->deviceSizeInSectors = (32ull * 1024 * 1024 * 1024) / deviceInfo->deviceSectorSize;
cemu_assert_suspicious();
return FSA_RESULT::OK;
} }
else else
cemu_assert_unimplemented(); cemu_assert_unimplemented();
@ -423,7 +433,7 @@ namespace iosu
return FSA_RESULT::NOT_FOUND; return FSA_RESULT::NOT_FOUND;
cemu_assert_debug(fsc_isFile(fscFile)); cemu_assert_debug(fsc_isFile(fscFile));
__FSA_GetStatFromFSCFile(fscFile, statOut); __FSA_GetStatFromFSCFile(fscFile, statOut);
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_read(FSAClient* client, FSAShimBuffer* shimBuffer, MEMPTR<void> destPtr, uint32be transferSize) FSA_RESULT FSAProcessCmd_read(FSAClient* client, FSAShimBuffer* shimBuffer, MEMPTR<void> destPtr, uint32be transferSize)
@ -444,7 +454,7 @@ namespace iosu
// todo: File permissions // todo: File permissions
uint32 bytesSuccessfullyRead = fsc_readFile(fscFile, destPtr, bytesToRead); uint32 bytesSuccessfullyRead = fsc_readFile(fscFile, destPtr, bytesToRead);
if (transferElementSize == 0) if (transferElementSize == 0)
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
LatteBufferCache_notifyDCFlush(destPtr.GetMPTR(), bytesToRead); LatteBufferCache_notifyDCFlush(destPtr.GetMPTR(), bytesToRead);
@ -485,7 +495,7 @@ namespace iosu
if (!fscFile) if (!fscFile)
return FSA_RESULT::INVALID_FILE_HANDLE; return FSA_RESULT::INVALID_FILE_HANDLE;
fsc_setFileSeek(fscFile, filePos); fsc_setFileSeek(fscFile, filePos);
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_getPos(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_getPos(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -496,7 +506,7 @@ namespace iosu
return FSA_RESULT::INVALID_FILE_HANDLE; return FSA_RESULT::INVALID_FILE_HANDLE;
uint32 filePos = fsc_getFileSeek(fscFile); uint32 filePos = fsc_getFileSeek(fscFile);
shimBuffer->response.cmdGetPosFile.filePos = filePos; shimBuffer->response.cmdGetPosFile.filePos = filePos;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_openFile(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_openFile(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -528,7 +538,7 @@ namespace iosu
FSDirEntry_t* dirEntryOut = &shimBuffer->response.cmdReadDir.dirEntry; FSDirEntry_t* dirEntryOut = &shimBuffer->response.cmdReadDir.dirEntry;
FSCDirEntry fscDirEntry; FSCDirEntry fscDirEntry;
if (fsc_nextDir(fscFile, &fscDirEntry) == false) if (fsc_nextDir(fscFile, &fscDirEntry) == false)
return FSA_RESULT::END_DIR; return FSA_RESULT::END_OF_DIRECTORY;
strcpy(dirEntryOut->name, fscDirEntry.path); strcpy(dirEntryOut->name, fscDirEntry.path);
FSFlag statFlag = FSFlag::NONE; FSFlag statFlag = FSFlag::NONE;
dirEntryOut->stat.size = 0; dirEntryOut->stat.size = 0;
@ -538,11 +548,12 @@ namespace iosu
} }
else if (fscDirEntry.isFile) else if (fscDirEntry.isFile)
{ {
statFlag |= FSFlag::IS_FILE;
dirEntryOut->stat.size = fscDirEntry.fileSize; dirEntryOut->stat.size = fscDirEntry.fileSize;
} }
dirEntryOut->stat.flag = statFlag; dirEntryOut->stat.flag = statFlag;
dirEntryOut->stat.permissions = 0x777; dirEntryOut->stat.permissions = 0x777;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_closeDir(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_closeDir(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -555,12 +566,31 @@ namespace iosu
} }
sDirHandleTable.ReleaseHandle(shimBuffer->request.cmdReadDir.dirHandle); sDirHandleTable.ReleaseHandle(shimBuffer->request.cmdReadDir.dirHandle);
fsc_close(fscFile); fsc_close(fscFile);
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_flushQuota(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_flushQuota(FSAClient* client, FSAShimBuffer* shimBuffer)
{ {
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
}
FSA_RESULT FSAProcessCmd_rewindDir(FSAClient* client, FSAShimBuffer* shimBuffer)
{
FSCVirtualFile* fscFile = sDirHandleTable.GetByHandle((sint32)shimBuffer->request.cmdRewindDir.dirHandle);
if (!fscFile)
{
cemuLog_logDebug(LogType::Force, "RewindDir: Invalid handle (0x{:08x})", (sint32)shimBuffer->request.cmdRewindDir.dirHandle);
return FSA_RESULT::INVALID_DIR_HANDLE;
}
if (!fscFile->fscRewindDir())
return FSA_RESULT::FATAL_ERROR;
return FSA_RESULT::OK;
}
FSA_RESULT FSAProcessCmd_flushFile(FSAClient* client, FSAShimBuffer* shimBuffer)
{
return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_appendFile(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_appendFile(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -582,7 +612,7 @@ namespace iosu
if (!fscFile) if (!fscFile)
return FSA_RESULT::INVALID_FILE_HANDLE; return FSA_RESULT::INVALID_FILE_HANDLE;
fsc_setFileLength(fscFile, fsc_getFileSeek(fscFile)); fsc_setFileLength(fscFile, fsc_getFileSeek(fscFile));
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_isEof(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_isEof(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -594,8 +624,8 @@ namespace iosu
uint32 filePos = fsc_getFileSeek(fscFile); uint32 filePos = fsc_getFileSeek(fscFile);
uint32 fileSize = fsc_getFileSize(fscFile); uint32 fileSize = fsc_getFileSize(fscFile);
if (filePos >= fileSize) if (filePos >= fileSize)
return FSA_RESULT::END_FILE; return FSA_RESULT::END_OF_FILE;
return FSA_RESULT::SUCCESS; return FSA_RESULT::OK;
} }
FSA_RESULT FSAProcessCmd_getCwd(FSAClient* client, FSAShimBuffer* shimBuffer) FSA_RESULT FSAProcessCmd_getCwd(FSAClient* client, FSAShimBuffer* shimBuffer)
@ -764,17 +794,22 @@ namespace iosu
fsaResult = FSAProcessCmd_flushQuota(client, shimBuffer); fsaResult = FSAProcessCmd_flushQuota(client, shimBuffer);
break; break;
} }
case FSA_CMD_OPERATION_TYPE::REWINDDIR:
{
fsaResult = FSAProcessCmd_rewindDir(client, shimBuffer);
break;
}
case FSA_CMD_OPERATION_TYPE::FLUSHFILE:
{
fsaResult = FSAProcessCmd_flushFile(client, shimBuffer);
break;
}
case FSA_CMD_OPERATION_TYPE::READ: case FSA_CMD_OPERATION_TYPE::READ:
case FSA_CMD_OPERATION_TYPE::WRITE: case FSA_CMD_OPERATION_TYPE::WRITE:
{ {
// These commands are IOCTLVs not IOCTL // These commands are IOCTLVs not IOCTL
cemu_assert_error(); cemu_assert_error();
} }
default:
{
cemu_assert_unimplemented();
break;
}
} }
IOS_ResourceReply(cmd, (IOS_ERROR)fsaResult); IOS_ResourceReply(cmd, (IOS_ERROR)fsaResult);
} }

View File

@ -111,10 +111,25 @@ namespace iosu
{ {
uint32be fileHandle; uint32be fileHandle;
} cmdIsEof; } cmdIsEof;
struct
{
uint32be dirHandle;
} cmdRewindDir;
struct
{
uint32be fileHandle;
} cmdFlushFile;
struct
{
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
uint32be mode1;
uint32be mode2;
} cmdChangeMode;
}; };
}; };
static_assert(sizeof(FSARequest) == 0x520); static_assert(sizeof(FSARequest) == 0x520);
#pragma pack(1)
struct FSAResponse struct FSAResponse
{ {
uint32be ukn0; uint32be ukn0;
@ -158,11 +173,16 @@ namespace iosu
{ {
FSStat_t stat; FSStat_t stat;
} queryStat; } queryStat;
struct
{
FSADeviceInfo_t info;
} queryDeviceInfo;
}; };
} cmdQueryInfo; } cmdQueryInfo;
}; };
}; };
// static_assert(sizeof(FSAResponse) == 0x293); static_assert(sizeof(FSAResponse) == 0x293);
#pragma pack()
struct FSAShimBuffer struct FSAShimBuffer
{ {
@ -189,7 +209,7 @@ namespace iosu
uint32 ukn0930; uint32 ukn0930;
uint32 ukn0934; uint32 ukn0934;
}; };
// static_assert(sizeof(FSAShimBuffer) == 0x938); // exact size of this is not known static_assert(sizeof(FSAShimBuffer) == 0x938); // exact size of this is not known
void Initialize(); void Initialize();
void Shutdown(); void Shutdown();

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,8 @@ typedef struct
typedef MEMPTR<betype<FSDirHandle2>> FSDirHandlePtr; typedef MEMPTR<betype<FSDirHandle2>> FSDirHandlePtr;
typedef uint32 FSAClientHandle;
typedef struct typedef struct
{ {
MEMPTR<void> userCallback; MEMPTR<void> userCallback;

View File

@ -1,40 +1,9 @@
#include "Cafe/OS/common/OSCommon.h" #include "Cafe/OS/common/OSCommon.h"
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h" #include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "coreinit_IPCBuf.h"
namespace coreinit namespace coreinit
{ {
struct FIFOEntry_t
{
MEMPTR<uint8> p;
};
struct IPCFifo_t
{
uint32be writeIndex;
uint32be readIndex;
uint32be availableEntries; // number of available entries
uint32be entryCount;
MEMPTR<FIFOEntry_t> entryArray;
};
struct IPCBufPool_t
{
/* +0x00 */ uint32be magic;
/* +0x04 */ MEMPTR<void> fullBufferPtr;
/* +0x08 */ uint32be fullBufferSize;
/* +0x0C */ uint32be uknFromParamR7; // boolean?
/* +0x10 */ uint32be ukn10; // set to zero on init
/* +0x14 */ uint32be entrySize1;
/* +0x18 */ uint32be entrySize2; // set to same value as entrySize1
/* +0x1C */ uint32be entryCount; // actual number of used entries
/* +0x20 */ MEMPTR<uint8> entryStartPtr;
/* +0x24 */ uint32be entryCountMul4;
/* +0x28 */ IPCFifo_t fifo;
/* +0x3C */ coreinit::OSMutex mutex;
// full size is 0x68
};
void FIFOInit(IPCFifo_t* fifo, uint32 entryCount, void* entryArray) void FIFOInit(IPCFifo_t* fifo, uint32 entryCount, void* entryArray)
{ {
fifo->entryCount = entryCount; fifo->entryCount = entryCount;
@ -90,8 +59,6 @@ namespace coreinit
return (uint8*)v; return (uint8*)v;
} }
static_assert(sizeof(IPCBufPool_t) == 0x68);
IPCBufPool_t* IPCBufPoolCreate(uint8* bufferArea, uint32 bufferSize, uint32 entrySize, uint32be* entryCountOutput, uint32 uknR7) IPCBufPool_t* IPCBufPoolCreate(uint8* bufferArea, uint32 bufferSize, uint32 entrySize, uint32be* entryCountOutput, uint32 uknR7)
{ {
memset(bufferArea, 0, bufferSize); memset(bufferArea, 0, bufferSize);

View File

@ -2,5 +2,43 @@
namespace coreinit namespace coreinit
{ {
struct FIFOEntry_t
{
MEMPTR<uint8> p;
};
struct IPCFifo_t
{
uint32be writeIndex;
uint32be readIndex;
uint32be availableEntries; // number of available entries
uint32be entryCount;
MEMPTR<FIFOEntry_t> entryArray;
};
struct IPCBufPool_t
{
/* +0x00 */ uint32be magic;
/* +0x04 */ MEMPTR<void> fullBufferPtr;
/* +0x08 */ uint32be fullBufferSize;
/* +0x0C */ uint32be uknFromParamR7; // boolean?
/* +0x10 */ uint32be ukn10; // set to zero on init
/* +0x14 */ uint32be entrySize1;
/* +0x18 */ uint32be entrySize2; // set to same value as entrySize1
/* +0x1C */ uint32be entryCount; // actual number of used entries
/* +0x20 */ MEMPTR<uint8> entryStartPtr;
/* +0x24 */ uint32be entryCountMul4;
/* +0x28 */ IPCFifo_t fifo;
/* +0x3C */ coreinit::OSMutex mutex;
/* +0x68 */ uint32 ukn68;
// full size is 0x6C
};
static_assert(sizeof(IPCBufPool_t) == 0x6C);
uint8* IPCBufPoolAllocate(IPCBufPool_t* ipcBufPool, uint32 size);
IPCBufPool_t* IPCBufPoolCreate(uint8* bufferArea, uint32 bufferSize, uint32 entrySize, uint32be* entryCountOutput, uint32 uknR7);
sint32 IPCBufPoolFree(IPCBufPool_t* ipcBufPool, uint8* entry);
void InitializeIPCBuf(); void InitializeIPCBuf();
} } // namespace coreinit

View File

@ -49,6 +49,13 @@ public:
m_tempData.insert(m_tempData.end(), count - l.size(), T()); m_tempData.insert(m_tempData.end(), count - l.size(), T());
} }
template <size_t N>
SysAllocator(const char(&str)[N])
{
m_tempData.reserve(count);
m_tempData.insert(m_tempData.begin(), str, str + N);
}
constexpr uint32 GetCount() const constexpr uint32 GetCount() const
{ {
return count; return count;
@ -135,6 +142,9 @@ private:
std::vector<T> m_tempData; std::vector<T> m_tempData;
}; };
template <size_t N>
SysAllocator(const char(&str)[N]) -> SysAllocator<char, N>;
template<typename T> template<typename T>
class SysAllocator<T, 1> : public SysAllocatorBase class SysAllocator<T, 1> : public SysAllocatorBase
{ {