mirror of https://github.com/cemu-project/Cemu.git
coreinit: Refactor FS functions to be more accurate (#842)
This commit is contained in:
parent
4ae5b4f8b8
commit
6073ab3ec6
|
@ -4,27 +4,62 @@ enum class FS_RESULT : sint32 // aka FSStatus
|
||||||
{
|
{
|
||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
END_ITERATION = -2, // used by FSGetMountSource / FSGetMountSourceNext to indicate when last element was reached
|
END_ITERATION = -2, // used by FSGetMountSource / FSGetMountSourceNext to indicate when last element was reached
|
||||||
FATAL_ERROR = -0x400,
|
MAX_HANDLES = -3,
|
||||||
|
|
||||||
ALREADY_EXISTS = -5,
|
ALREADY_EXISTS = -5,
|
||||||
NOT_FOUND = -6,
|
NOT_FOUND = -6,
|
||||||
NOT_FILE = -7,
|
NOT_FILE = -7,
|
||||||
NOT_DIR = -8,
|
NOT_DIR = -8,
|
||||||
PERMISSION_ERROR = -10,
|
PERMISSION_ERROR = -10,
|
||||||
|
|
||||||
INVALID_CLIENT_HANDLE = -0x30000 - 37,
|
FATAL_ERROR = -0x400,
|
||||||
|
|
||||||
ERR_PLACEHOLDER = -9999, // used when exact error code has yet to be determined
|
ERR_PLACEHOLDER = -9999, // used when exact error code has yet to be determined
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FSA_RESULT : sint32 // aka FSError/FSAStatus
|
enum class FSA_RESULT : sint32 // aka FSError/FSAStatus
|
||||||
{
|
{
|
||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
INVALID_CLIENT_HANDLE = -0x30000 - 37,
|
END_DIR = -0x30000 - 0x04,
|
||||||
INVALID_HANDLE_UKN38 = -0x30000 - 38,
|
END_FILE = -0x30000 - 0x05,
|
||||||
|
MAX_FILES = -0x30000 - 0x13,
|
||||||
|
MAX_DIRS = -0x30000 - 0x14,
|
||||||
|
ALREADY_EXISTS = -0x30000 - 0x16,
|
||||||
|
NOT_FOUND = -0x30000 - 0x17,
|
||||||
|
PERMISSION_ERROR = -0x30000 - 0x1A,
|
||||||
|
INVALID_PARAM = -0x30000 - 0x21,
|
||||||
|
INVALID_PATH = -0x30000 - 0x22,
|
||||||
|
INVALID_BUFFER = -0x30000 - 0x23,
|
||||||
|
INVALID_ALIGNMENT = -0x30000 - 0x24,
|
||||||
|
INVALID_CLIENT_HANDLE = -0x30000 - 0x25,
|
||||||
|
INVALID_FILE_HANDLE = -0x30000 - 0x26,
|
||||||
|
INVALID_DIR_HANDLE = -0x30000 - 0x27,
|
||||||
|
NOT_FILE = -0x30000 - 0x28,
|
||||||
|
NOT_DIR = -0x30000 - 0x29,
|
||||||
FATAL_ERROR = -0x30000 - 0x400,
|
FATAL_ERROR = -0x30000 - 0x400,
|
||||||
};
|
};
|
||||||
// todo - error handling in the IOSU part is pretty hacky right now and we use FS_RESULT in most places which we shouldn't be doing. Rework it
|
|
||||||
|
enum class FSA_CMD_OPERATION_TYPE : uint32
|
||||||
|
{
|
||||||
|
CHANGEDIR = 0x5,
|
||||||
|
GETCWD = 0x6,
|
||||||
|
MAKEDIR = 0x7,
|
||||||
|
REMOVE = 0x8,
|
||||||
|
RENAME = 0x9,
|
||||||
|
OPENDIR = 0xA,
|
||||||
|
READDIR = 0xB,
|
||||||
|
CLOSEDIR = 0xD,
|
||||||
|
OPENFILE = 0xE,
|
||||||
|
READ = 0xF,
|
||||||
|
WRITE = 0x10,
|
||||||
|
GETPOS = 0x11,
|
||||||
|
SETPOS = 0x12,
|
||||||
|
ISEOF = 0x13,
|
||||||
|
GETSTATFILE = 0x14,
|
||||||
|
CLOSEFILE = 0x15,
|
||||||
|
QUERYINFO = 0x18,
|
||||||
|
APPENDFILE = 0x19,
|
||||||
|
TRUNCATEFILE = 0x1A,
|
||||||
|
FLUSHQUOTA = 0x1E,
|
||||||
|
};
|
||||||
|
|
||||||
using FSResHandle = sint32;
|
using FSResHandle = sint32;
|
||||||
using FSFileHandle2 = FSResHandle;
|
using FSFileHandle2 = FSResHandle;
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace iosu
|
||||||
struct FSAClient // IOSU's counterpart to the coreinit FSClient struct
|
struct FSAClient // IOSU's counterpart to the coreinit FSClient struct
|
||||||
{
|
{
|
||||||
std::string workingDirectory;
|
std::string workingDirectory;
|
||||||
bool isAllocated{ false };
|
bool isAllocated{false};
|
||||||
|
|
||||||
void AllocateAndInitialize()
|
void AllocateAndInitialize()
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ namespace iosu
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < sFSAClientArray.size(); i++)
|
for (size_t i = 0; i < sFSAClientArray.size(); i++)
|
||||||
{
|
{
|
||||||
if(sFSAClientArray[i].isAllocated)
|
if (sFSAClientArray[i].isAllocated)
|
||||||
continue;
|
continue;
|
||||||
sFSAClientArray[i].AllocateAndInitialize();
|
sFSAClientArray[i].AllocateAndInitialize();
|
||||||
indexOut = (sint32)i;
|
indexOut = (sint32)i;
|
||||||
|
@ -51,16 +51,16 @@ namespace iosu
|
||||||
return (IOS_ERROR)0xFFFCFFEE;
|
return (IOS_ERROR)0xFFFCFFEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32 FSA_convertFSCtoFSStatus(sint32 fscError)
|
FSA_RESULT FSA_convertFSCtoFSAStatus(sint32 fscError)
|
||||||
{
|
{
|
||||||
if (fscError == FSC_STATUS_OK)
|
if (fscError == FSC_STATUS_OK)
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
else if (fscError == FSC_STATUS_FILE_NOT_FOUND)
|
else if (fscError == FSC_STATUS_FILE_NOT_FOUND)
|
||||||
return (sint32)FS_RESULT::NOT_FOUND;
|
return FSA_RESULT::NOT_FOUND;
|
||||||
else if (fscError == FSC_STATUS_ALREADY_EXISTS)
|
else if (fscError == FSC_STATUS_ALREADY_EXISTS)
|
||||||
return (sint32)FS_RESULT::ALREADY_EXISTS;
|
return FSA_RESULT::ALREADY_EXISTS;
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
return -1;
|
return FSA_RESULT::FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string __FSATranslatePath(FSAClient* fsaClient, std::string_view input, bool endWithSlash = false)
|
std::string __FSATranslatePath(FSAClient* fsaClient, std::string_view input, bool endWithSlash = false)
|
||||||
|
@ -152,21 +152,21 @@ namespace iosu
|
||||||
return fsc_open(translatedPath.c_str(), accessFlags, &fscStatus);
|
return fsc_open(translatedPath.c_str(), accessFlags, &fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FSAHandleTable
|
class _FSAHandleTable {
|
||||||
{
|
|
||||||
struct _FSAHandleResource
|
struct _FSAHandleResource
|
||||||
{
|
{
|
||||||
bool isAllocated{ false };
|
bool isAllocated{false};
|
||||||
FSCVirtualFile* fscFile;
|
FSCVirtualFile* fscFile;
|
||||||
uint16 handleCheckValue;
|
uint16 handleCheckValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FSA_RESULT AllocateHandle(FSResHandle& handleOut, FSCVirtualFile* fscFile)
|
FSA_RESULT AllocateHandle(FSResHandle& handleOut, FSCVirtualFile* fscFile)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_handleTable.size(); i++)
|
for (size_t i = 0; i < m_handleTable.size(); i++)
|
||||||
{
|
{
|
||||||
auto& it = m_handleTable.at(i);
|
auto& it = m_handleTable.at(i);
|
||||||
if(it.isAllocated)
|
if (it.isAllocated)
|
||||||
continue;
|
continue;
|
||||||
uint16 checkValue = (uint16)m_currentCounter;
|
uint16 checkValue = (uint16)m_currentCounter;
|
||||||
m_currentCounter++;
|
m_currentCounter++;
|
||||||
|
@ -186,12 +186,12 @@ namespace iosu
|
||||||
uint16 index = (uint16)((uint32)handle >> 16);
|
uint16 index = (uint16)((uint32)handle >> 16);
|
||||||
uint16 checkValue = (uint16)(handle & 0xFFFF);
|
uint16 checkValue = (uint16)(handle & 0xFFFF);
|
||||||
if (index >= m_handleTable.size())
|
if (index >= m_handleTable.size())
|
||||||
return FSA_RESULT::INVALID_HANDLE_UKN38;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
auto& it = m_handleTable.at(index);
|
auto& it = m_handleTable.at(index);
|
||||||
if(!it.isAllocated)
|
if (!it.isAllocated)
|
||||||
return FSA_RESULT::INVALID_HANDLE_UKN38;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
if(it.handleCheckValue != checkValue)
|
if (it.handleCheckValue != checkValue)
|
||||||
return FSA_RESULT::INVALID_HANDLE_UKN38;
|
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::SUCCESS;
|
||||||
|
@ -219,8 +219,7 @@ namespace iosu
|
||||||
_FSAHandleTable sFileHandleTable;
|
_FSAHandleTable sFileHandleTable;
|
||||||
_FSAHandleTable sDirHandleTable;
|
_FSAHandleTable sDirHandleTable;
|
||||||
|
|
||||||
|
FSA_RESULT __FSAOpenFile(FSAClient* client, const char* path, const char* accessModifierStr, sint32* fileHandle)
|
||||||
FSStatus __FSAOpenFile(FSAClient* client, const char* path, const char* accessModifierStr, sint32* fileHandle)
|
|
||||||
{
|
{
|
||||||
*fileHandle = FS_INVALID_HANDLE_VALUE;
|
*fileHandle = FS_INVALID_HANDLE_VALUE;
|
||||||
FSC_ACCESS_FLAG accessModifier = FSC_ACCESS_FLAG::NONE;
|
FSC_ACCESS_FLAG accessModifier = FSC_ACCESS_FLAG::NONE;
|
||||||
|
@ -266,11 +265,11 @@ namespace iosu
|
||||||
sint32 fscStatus;
|
sint32 fscStatus;
|
||||||
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, accessModifier, fscStatus);
|
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, accessModifier, fscStatus);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (sint32)FS_RESULT::NOT_FOUND;
|
return FSA_RESULT::NOT_FOUND;
|
||||||
if (fscFile->fscGetType() != FSC_TYPE_FILE)
|
if (fscFile->fscGetType() != FSC_TYPE_FILE)
|
||||||
{
|
{
|
||||||
delete fscFile;
|
delete fscFile;
|
||||||
return (sint32)FS_RESULT::NOT_FILE;
|
return FSA_RESULT::NOT_FILE;
|
||||||
}
|
}
|
||||||
if (isAppend)
|
if (isAppend)
|
||||||
fsc_setFileSeek(fscFile, fsc_getFileSize(fscFile));
|
fsc_setFileSeek(fscFile, fsc_getFileSize(fscFile));
|
||||||
|
@ -280,75 +279,75 @@ namespace iosu
|
||||||
{
|
{
|
||||||
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;
|
||||||
return -0x400;
|
return FSA_RESULT::MAX_FILES;
|
||||||
}
|
}
|
||||||
*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 (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus __FSAOpenDirectory(FSAClient* client, std::string_view path, sint32* dirHandle)
|
FSA_RESULT __FSAOpenDirectory(FSAClient* client, std::string_view path, sint32* dirHandle)
|
||||||
{
|
{
|
||||||
*dirHandle = FS_INVALID_HANDLE_VALUE;
|
*dirHandle = FS_INVALID_HANDLE_VALUE;
|
||||||
sint32 fscStatus;
|
sint32 fscStatus;
|
||||||
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, FSC_ACCESS_FLAG::OPEN_DIR | FSC_ACCESS_FLAG::OPEN_FILE, fscStatus);
|
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, FSC_ACCESS_FLAG::OPEN_DIR | FSC_ACCESS_FLAG::OPEN_FILE, fscStatus);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::NOT_FOUND;
|
return FSA_RESULT::NOT_FOUND;
|
||||||
if (fscFile->fscGetType() != FSC_TYPE_DIRECTORY)
|
if (fscFile->fscGetType() != FSC_TYPE_DIRECTORY)
|
||||||
{
|
{
|
||||||
delete fscFile;
|
delete fscFile;
|
||||||
return (FSStatus)(FS_RESULT::NOT_DIR);
|
return FSA_RESULT::NOT_DIR;
|
||||||
}
|
}
|
||||||
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::SUCCESS)
|
||||||
{
|
{
|
||||||
delete fscFile;
|
delete fscFile;
|
||||||
return -0x400;
|
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 (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus __FSACloseFile(uint32 fileHandle)
|
FSA_RESULT __FSACloseFile(uint32 fileHandle)
|
||||||
{
|
{
|
||||||
uint8 handleType = 0;
|
uint8 handleType = 0;
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "__FSACloseFile(): Invalid handle (0x{:08x})", fileHandle);
|
cemuLog_logDebug(LogType::Force, "__FSACloseFile(): Invalid handle (0x{:08x})", fileHandle);
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
}
|
}
|
||||||
// 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 (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_remove(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_remove(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
std::string path = __FSATranslatePath(client, (char*)cmd->cmdRemove.path);
|
std::string path = __FSATranslatePath(client, (char*)shimBuffer->request.cmdRemove.path);
|
||||||
sint32 fscStatus = FSC_STATUS_FILE_NOT_FOUND;
|
sint32 fscStatus = FSC_STATUS_FILE_NOT_FOUND;
|
||||||
fsc_remove(path.c_str(), &fscStatus);
|
fsc_remove(path.c_str(), &fscStatus);
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_makeDir(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_makeDir(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
std::string path = __FSATranslatePath(client, (char*)cmd->cmdMakeDir.path);
|
std::string path = __FSATranslatePath(client, (char*)shimBuffer->request.cmdMakeDir.path);
|
||||||
sint32 fscStatus = FSC_STATUS_FILE_NOT_FOUND;
|
sint32 fscStatus = FSC_STATUS_FILE_NOT_FOUND;
|
||||||
fsc_createDir(path.c_str(), &fscStatus);
|
fsc_createDir(path.c_str(), &fscStatus);
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_rename(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_rename(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
std::string srcPath = __FSATranslatePath(client, (char*)cmd->cmdRename.srcPath);
|
std::string srcPath = __FSATranslatePath(client, (char*)shimBuffer->request.cmdRename.srcPath);
|
||||||
std::string dstPath = __FSATranslatePath(client, (char*)cmd->cmdRename.dstPath);
|
std::string dstPath = __FSATranslatePath(client, (char*)shimBuffer->request.cmdRename.dstPath);
|
||||||
sint32 fscStatus = FSC_STATUS_FILE_NOT_FOUND;
|
sint32 fscStatus = FSC_STATUS_FILE_NOT_FOUND;
|
||||||
fsc_rename(srcPath.c_str(), dstPath.c_str(), &fscStatus);
|
fsc_rename(srcPath.c_str(), dstPath.c_str(), &fscStatus);
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __FSA_GetStatFromFSCFile(FSCVirtualFile* fscFile, FSStat_t* fsStatOut)
|
bool __FSA_GetStatFromFSCFile(FSCVirtualFile* fscFile, FSStat_t* fsStatOut)
|
||||||
|
@ -376,88 +375,68 @@ namespace iosu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus __FSA_GetFileStat(FSAClient* client, const char* path, FSStat_t* fsStatOut)
|
FSA_RESULT __FSA_GetFileStat(FSAClient* client, const char* path, FSStat_t* fsStatOut)
|
||||||
{
|
{
|
||||||
sint32 fscStatus;
|
sint32 fscStatus;
|
||||||
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::OPEN_DIR, fscStatus);
|
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::OPEN_DIR, fscStatus);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
__FSA_GetStatFromFSCFile(fscFile, fsStatOut);
|
__FSA_GetStatFromFSCFile(fscFile, fsStatOut);
|
||||||
delete fscFile;
|
delete fscFile;
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_queryInfo(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_queryInfo(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
char* path = (char*)shimBuffer->request.cmdQueryInfo.query;
|
||||||
|
uint32 queryType = shimBuffer->request.cmdQueryInfo.queryType;
|
||||||
char* path = (char*)cmd->cmdQueryInfo.query;
|
|
||||||
uint32 queryType = _swapEndianU32(cmd->cmdQueryInfo.queryType);
|
|
||||||
void* queryResult = memory_getPointerFromVirtualOffset(_swapEndianU32(fullCmd->returnValueMPTR));
|
|
||||||
// handle query
|
// handle query
|
||||||
sint32 fscStatus = FSC_STATUS_OK;
|
sint32 fscStatus = FSC_STATUS_OK;
|
||||||
if (queryType == FSA_QUERY_TYPE_STAT)
|
if (queryType == FSA_QUERY_TYPE_STAT)
|
||||||
{
|
{
|
||||||
FSStat_t* fsStat = (FSStat_t*)queryResult;
|
FSStat_t* fsStat = &shimBuffer->response.cmdQueryInfo.queryStat.stat;
|
||||||
FSStatus fsStatus = __FSA_GetFileStat(client, path, fsStat);
|
FSA_RESULT fsaStatus = __FSA_GetFileStat(client, path, fsStat);
|
||||||
return fsStatus;
|
return fsaStatus;
|
||||||
}
|
}
|
||||||
else if (queryType == FSA_QUERY_TYPE_FREESPACE)
|
else if (queryType == FSA_QUERY_TYPE_FREESPACE)
|
||||||
{
|
{
|
||||||
sint32 fscStatus;
|
sint32 fscStatus;
|
||||||
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::OPEN_DIR, fscStatus);
|
FSCVirtualFile* fscFile = __FSAOpenNode(client, path, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::OPEN_DIR, fscStatus);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
betype<uint64>* fsStatSize = (betype<uint64>*)queryResult;
|
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 (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_getStatFile(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_getStatFile(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
FSFileHandle2 fileHandle = shimBuffer->request.cmdGetStatFile.fileHandle;
|
||||||
|
FSStat_t* statOut = &shimBuffer->response.cmdStatFile.statOut;
|
||||||
FSFileHandle2 fileHandle = cmd->cmdGetStatFile.fileHandle;
|
|
||||||
FSStat_t* statOut = (FSStat_t*)memory_getPointerFromVirtualOffset(_swapEndianU32(fullCmd->returnValueMPTR));
|
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_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 (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_read(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_read(FSAClient* client, FSAShimBuffer* shimBuffer, MEMPTR<void> destPtr, uint32be transferSize)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
uint32 transferElementSize = shimBuffer->request.cmdReadFile.size;
|
||||||
|
uint32 filePos = shimBuffer->request.cmdReadFile.filePos;
|
||||||
|
uint32 fileHandle = shimBuffer->request.cmdReadFile.fileHandle;
|
||||||
|
uint32 flags = shimBuffer->request.cmdReadFile.flag;
|
||||||
|
|
||||||
uint32 filePos = _swapEndianU32(cmd->cmdDefault.transferFilePos);
|
|
||||||
uint32 fileHandle = _swapEndianU32(cmd->cmdDefault.fileHandle);
|
|
||||||
MPTR destOffset = _swapEndianU32(cmd->cmdDefault.destBufferMPTR);
|
|
||||||
void* destPtr = memory_getPointerFromVirtualOffset(destOffset);
|
|
||||||
uint32 transferSize = _swapEndianU32(fullCmd->transferSize);
|
|
||||||
uint32 transferElementSize = _swapEndianU32(fullCmd->transferElemSize);
|
|
||||||
uint32 flags = _swapEndianU32(cmd->cmdDefault.cmdFlag);
|
|
||||||
uint32 errHandling = _swapEndianU32(fullCmd->errHandling);
|
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
uint32 elementSize = transferElementSize;
|
|
||||||
uint32 elementCount = 0;
|
|
||||||
if (transferElementSize != 0)
|
|
||||||
{
|
|
||||||
elementCount = transferSize / transferElementSize;
|
|
||||||
cemu_assert_debug((transferSize % transferElementSize) == 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_debug(transferSize == 0);
|
|
||||||
}
|
|
||||||
uint32 bytesToRead = transferSize;
|
uint32 bytesToRead = transferSize;
|
||||||
// update file position if flag is set
|
// update file position if flag is set
|
||||||
if ((flags & FSA_CMD_FLAG_SET_POS) != 0)
|
if ((flags & FSA_CMD_FLAG_SET_POS) != 0)
|
||||||
|
@ -465,107 +444,91 @@ 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 0;
|
return FSA_RESULT::SUCCESS;
|
||||||
|
|
||||||
LatteBufferCache_notifyDCFlush(memory_getVirtualOffsetFromPointer(destPtr), bytesToRead);
|
LatteBufferCache_notifyDCFlush(destPtr.GetMPTR(), bytesToRead);
|
||||||
|
|
||||||
return bytesSuccessfullyRead / transferElementSize; // return number of elements read
|
return (FSA_RESULT)(bytesSuccessfullyRead / transferElementSize); // return number of elements read
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_write(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_write(FSAClient* client, FSAShimBuffer* shimBuffer, MEMPTR<void> destPtr, uint32be transferSize)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
uint32 transferElementSize = shimBuffer->request.cmdWriteFile.size;
|
||||||
|
uint32 filePos = shimBuffer->request.cmdWriteFile.filePos;
|
||||||
|
uint32 fileHandle = shimBuffer->request.cmdWriteFile.fileHandle;
|
||||||
|
uint32 flags = shimBuffer->request.cmdWriteFile.flag;
|
||||||
|
|
||||||
uint32 filePos = _swapEndianU32(cmd->cmdDefault.transferFilePos);
|
|
||||||
uint32 fileHandle = _swapEndianU32(cmd->cmdDefault.fileHandle);
|
|
||||||
MPTR destOffset = _swapEndianU32(cmd->cmdDefault.destBufferMPTR);
|
|
||||||
void* destPtr = memory_getPointerFromVirtualOffset(destOffset);
|
|
||||||
uint32 transferSize = _swapEndianU32(fullCmd->transferSize);
|
|
||||||
uint32 transferElementSize = _swapEndianU32(fullCmd->transferElemSize);
|
|
||||||
uint32 flags = _swapEndianU32(cmd->cmdDefault.cmdFlag);
|
|
||||||
uint32 errHandling = _swapEndianU32(fullCmd->errHandling);
|
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
uint32 elementSize = transferElementSize;
|
|
||||||
uint32 elementCount = transferSize / transferElementSize;
|
|
||||||
cemu_assert_debug((transferSize % transferElementSize) == 0);
|
cemu_assert_debug((transferSize % transferElementSize) == 0);
|
||||||
uint32 bytesToWrite = transferSize;
|
uint32 bytesToWrite = transferSize;
|
||||||
// check for write permission (should this happen before or after setting file position?)
|
// check for write permission (should this happen before or after setting file position?)
|
||||||
if (!fsc_isWritable(fscFile))
|
if (!fsc_isWritable(fscFile))
|
||||||
{
|
{
|
||||||
cemu_assert_debug(false);
|
cemu_assert_debug(false);
|
||||||
return (FSStatus)FS_RESULT::PERMISSION_ERROR;
|
return FSA_RESULT::PERMISSION_ERROR;
|
||||||
}
|
}
|
||||||
// update file position if flag is set
|
// update file position if flag is set
|
||||||
if ((flags & FSA_CMD_FLAG_SET_POS) != 0)
|
if ((flags & FSA_CMD_FLAG_SET_POS) != 0)
|
||||||
fsc_setFileSeek(fscFile, filePos);
|
fsc_setFileSeek(fscFile, filePos);
|
||||||
uint32 bytesSuccessfullyWritten = fsc_writeFile(fscFile, destPtr, bytesToWrite);
|
uint32 bytesSuccessfullyWritten = fsc_writeFile(fscFile, destPtr, bytesToWrite);
|
||||||
debug_printf("FSAProcessCmd_write(): Writing 0x%08x bytes (bytes actually written: 0x%08x)\n", bytesToWrite, bytesSuccessfullyWritten);
|
debug_printf("FSAProcessCmd_write(): Writing 0x%08x bytes (bytes actually written: 0x%08x)\n", bytesToWrite, bytesSuccessfullyWritten);
|
||||||
return bytesSuccessfullyWritten / transferElementSize; // return number of elements read
|
return (FSA_RESULT)(bytesSuccessfullyWritten / transferElementSize); // return number of elements read
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_setPos(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_setPos(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
uint32 fileHandle = _swapEndianU32(cmd->cmdDefault.destBufferMPTR);
|
uint32 fileHandle = shimBuffer->request.cmdSetPosFile.fileHandle;
|
||||||
uint32 filePos = _swapEndianU32(cmd->cmdDefault.ukn0008);
|
uint32 filePos = shimBuffer->request.cmdSetPosFile.filePos;
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
fsc_setFileSeek(fscFile, filePos);
|
fsc_setFileSeek(fscFile, filePos);
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_getPos(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_getPos(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
uint32 fileHandle = shimBuffer->request.cmdGetPosFile.fileHandle;
|
||||||
|
|
||||||
uint32 fileHandle = _swapEndianU32(cmd->cmdDefault.destBufferMPTR);
|
|
||||||
MPTR returnedFilePos = _swapEndianU32(fullCmd->returnValueMPTR);
|
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
uint32 filePos = fsc_getFileSeek(fscFile);
|
uint32 filePos = fsc_getFileSeek(fscFile);
|
||||||
memory_writeU32(returnedFilePos, filePos);
|
shimBuffer->response.cmdGetPosFile.filePos = filePos;
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_openFile(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_openFile(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
|
||||||
sint32 fileHandle = 0;
|
sint32 fileHandle = 0;
|
||||||
FSStatus fsStatus = __FSAOpenFile(client, (char*)cmd->cmdOpenFile.path, (char*)cmd->cmdOpenFile.mode, &fileHandle);
|
FSA_RESULT fsaResult = __FSAOpenFile(client, (char*)shimBuffer->request.cmdOpenFile.path, (char*)shimBuffer->request.cmdOpenFile.mode, &fileHandle);
|
||||||
memory_writeU32(_swapEndianU32(fullCmd->returnValueMPTR), fileHandle);
|
shimBuffer->response.cmdOpenFile.fileHandleOutput = fileHandle;
|
||||||
cmd->cmdOpenFile.fileHandleOutput = fileHandle;
|
return fsaResult;
|
||||||
return fsStatus;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_closeFile(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_closeFile(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
return __FSACloseFile(cmd->cmdCloseFile.fileHandle);
|
return __FSACloseFile(shimBuffer->request.cmdCloseFile.fileHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_openDir(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_openDir(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
|
||||||
sint32 dirHandle = 0;
|
sint32 dirHandle = 0;
|
||||||
FSStatus fsStatus = __FSAOpenDirectory(client, (const char*)cmd->cmdOpenFile.path, &dirHandle);
|
FSA_RESULT fsaResult = __FSAOpenDirectory(client, (const char*)shimBuffer->request.cmdOpenFile.path, &dirHandle);
|
||||||
memory_writeU32(_swapEndianU32(fullCmd->returnValueMPTR), dirHandle);
|
shimBuffer->response.cmdOpenDir.dirHandleOutput = dirHandle;
|
||||||
cmd->cmdOpenDir.dirHandleOutput = dirHandle;
|
return fsaResult;
|
||||||
return fsStatus;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_readDir(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_readDir(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
FSCVirtualFile* fscFile = sDirHandleTable.GetByHandle((sint32)shimBuffer->request.cmdReadDir.dirHandle);
|
||||||
|
|
||||||
FSCVirtualFile* fscFile = sDirHandleTable.GetByHandle((sint32)cmd->cmdReadDir.dirHandle);
|
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_DIR_HANDLE;
|
||||||
FSDirEntry_t* dirEntryOut = (FSDirEntry_t*)memory_getPointerFromVirtualOffset(_swapEndianU32(fullCmd->returnValueMPTR));
|
FSDirEntry_t* dirEntryOut = &shimBuffer->response.cmdReadDir.dirEntry;
|
||||||
FSCDirEntry fscDirEntry;
|
FSCDirEntry fscDirEntry;
|
||||||
if (fsc_nextDir(fscFile, &fscDirEntry) == false)
|
if (fsc_nextDir(fscFile, &fscDirEntry) == false)
|
||||||
return (FSStatus)FS_RESULT::END_ITERATION;
|
return FSA_RESULT::END_DIR;
|
||||||
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;
|
||||||
|
@ -579,173 +542,241 @@ namespace iosu
|
||||||
}
|
}
|
||||||
dirEntryOut->stat.flag = statFlag;
|
dirEntryOut->stat.flag = statFlag;
|
||||||
dirEntryOut->stat.permissions = 0x777;
|
dirEntryOut->stat.permissions = 0x777;
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_closeDir(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_closeDir(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
FSCVirtualFile* fscFile = sDirHandleTable.GetByHandle((sint32)cmd->cmdReadDir.dirHandle);
|
FSCVirtualFile* fscFile = sDirHandleTable.GetByHandle((sint32)shimBuffer->request.cmdReadDir.dirHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
{
|
{
|
||||||
cemuLog_logDebug(LogType::Force, "CloseDir: Invalid handle (0x{:08x})", (sint32)cmd->cmdReadDir.dirHandle);
|
cemuLog_logDebug(LogType::Force, "CloseDir: Invalid handle (0x{:08x})", (sint32)shimBuffer->request.cmdReadDir.dirHandle);
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_DIR_HANDLE;
|
||||||
}
|
}
|
||||||
sDirHandleTable.ReleaseHandle(cmd->cmdReadDir.dirHandle);
|
sDirHandleTable.ReleaseHandle(shimBuffer->request.cmdReadDir.dirHandle);
|
||||||
fsc_close(fscFile);
|
fsc_close(fscFile);
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_flushQuota(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_flushQuota(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_appendFile(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_appendFile(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
uint32 fileHandle = _swapEndianU32(cmd->cmdDefault.destBufferMPTR);
|
uint32 fileHandle = shimBuffer->request.cmdAppendFile.fileHandle;
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
cemuLog_log(LogType::Force, "FSAProcessCmd_appendFile(): size 0x{:08x} count 0x{:08x} (todo)\n", _swapEndianU32(cmd->cmdAppendFile.size), _swapEndianU32(cmd->cmdAppendFile.count));
|
cemuLog_log(LogType::Force, "FSAProcessCmd_appendFile(): size 0x{:08x} count 0x{:08x} (todo)\n", shimBuffer->request.cmdAppendFile.size, shimBuffer->request.cmdAppendFile.count);
|
||||||
#endif
|
#endif
|
||||||
return _swapEndianU32(cmd->cmdAppendFile.size) * _swapEndianU32(cmd->cmdAppendFile.count);
|
return (FSA_RESULT)(shimBuffer->request.cmdAppendFile.size * shimBuffer->request.cmdAppendFile.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_truncateFile(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_truncateFile(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
FSFileHandle2 fileHandle = cmd->cmdTruncateFile.fileHandle;
|
FSFileHandle2 fileHandle = shimBuffer->request.cmdTruncateFile.fileHandle;
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
fsc_setFileLength(fscFile, fsc_getFileSeek(fscFile));
|
fsc_setFileLength(fscFile, fsc_getFileSeek(fscFile));
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_isEof(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_isEof(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
uint32 fileHandle = _swapEndianU32(cmd->cmdDefault.destBufferMPTR);
|
uint32 fileHandle = shimBuffer->request.cmdIsEof.fileHandle;
|
||||||
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
|
||||||
if (!fscFile)
|
if (!fscFile)
|
||||||
return (FSStatus)FS_RESULT::ERR_PLACEHOLDER;
|
return FSA_RESULT::INVALID_FILE_HANDLE;
|
||||||
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 (FSStatus)FS_RESULT::END_ITERATION;
|
return FSA_RESULT::END_FILE;
|
||||||
return (FSStatus)FS_RESULT::SUCCESS;
|
return FSA_RESULT::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_getCwd(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_getCwd(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
coreinit::FSCmdBlockBody_t* fullCmd = (coreinit::FSCmdBlockBody_t*)cmd;
|
char* pathOutput = shimBuffer->response.cmdGetCWD.path;
|
||||||
|
sint32 pathOutputMaxLen = sizeof(shimBuffer->response.cmdGetCWD.path);
|
||||||
char* pathOutput = (char*)memory_getPointerFromVirtualOffset(_swapEndianU32(fullCmd->returnValueMPTR));
|
|
||||||
sint32 pathOutputMaxLen = _swapEndianU32(fullCmd->transferSize);
|
|
||||||
cemu_assert(pathOutputMaxLen > 0);
|
cemu_assert(pathOutputMaxLen > 0);
|
||||||
sint32 fscStatus = FSC_STATUS_OK;
|
sint32 fscStatus = FSC_STATUS_OK;
|
||||||
strncpy(pathOutput, client->workingDirectory.data(), std::min(client->workingDirectory.size() + 1, (size_t)pathOutputMaxLen));
|
strncpy(pathOutput, client->workingDirectory.data(), std::min(client->workingDirectory.size() + 1, (size_t)pathOutputMaxLen));
|
||||||
pathOutput[pathOutputMaxLen - 1] = '\0';
|
pathOutput[pathOutputMaxLen - 1] = '\0';
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSStatus FSAProcessCmd_changeDir(FSAClient* client, FSAIpcCommand* cmd)
|
FSA_RESULT FSAProcessCmd_changeDir(FSAClient* client, FSAShimBuffer* shimBuffer)
|
||||||
{
|
{
|
||||||
const char* path = (const char*)cmd->cmdChangeDir.path;
|
const char* path = (const char*)shimBuffer->request.cmdChangeDir.path;
|
||||||
cmd->cmdChangeDir.path[sizeof(cmd->cmdChangeDir.path) - 1] = '\0';
|
shimBuffer->request.cmdChangeDir.path[sizeof(shimBuffer->request.cmdChangeDir.path) - 1] = '\0';
|
||||||
sint32 fscStatus = FSC_STATUS_OK;
|
sint32 fscStatus = FSC_STATUS_OK;
|
||||||
client->workingDirectory.assign(__FSATranslatePath(client, path, true));
|
client->workingDirectory.assign(__FSATranslatePath(client, path, true));
|
||||||
return FSA_convertFSCtoFSStatus(fscStatus);
|
return FSA_convertFSCtoFSAStatus(fscStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSAHandleCommandIoctl(FSAClient* client, IPCCommandBody* cmd, uint32 operationId, void* ptrIn, void* ptrOut)
|
void FSAHandleCommandIoctlv(FSAClient* client, IPCCommandBody* cmd, FSA_CMD_OPERATION_TYPE operationId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec)
|
||||||
{
|
{
|
||||||
FSAIpcCommand* fsaCommand = (FSAIpcCommand*)ptrIn;
|
FSA_RESULT fsaResult = FSA_RESULT::FATAL_ERROR;
|
||||||
FSStatus fsStatus = (FSStatus)(FS_RESULT::FATAL_ERROR);
|
|
||||||
if (operationId == FSA_CMD_OPERATION_TYPE_REMOVE)
|
switch (operationId)
|
||||||
{
|
{
|
||||||
fsStatus = FSAProcessCmd_remove(client, fsaCommand);
|
case FSA_CMD_OPERATION_TYPE::READ:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_read(client, (FSAShimBuffer*)vec[0].basePhys.GetPtr(), vec[1].basePhys, vec[1].size);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_MAKEDIR)
|
case FSA_CMD_OPERATION_TYPE::WRITE:
|
||||||
{
|
{
|
||||||
fsStatus = FSAProcessCmd_makeDir(client, fsaCommand);
|
fsaResult = FSAProcessCmd_write(client, (FSAShimBuffer*)vec[0].basePhys.GetPtr(), vec[1].basePhys, vec[1].size);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_RENAME)
|
case FSA_CMD_OPERATION_TYPE::CHANGEDIR:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::GETCWD:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::MAKEDIR:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::RENAME:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::OPENDIR:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::READDIR:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::CLOSEDIR:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::OPENFILE:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::REMOVE:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::GETPOS:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::SETPOS:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::ISEOF:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::GETSTATFILE:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::CLOSEFILE:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::QUERYINFO:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::APPENDFILE:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::TRUNCATEFILE:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::FLUSHQUOTA:
|
||||||
{
|
{
|
||||||
fsStatus = FSAProcessCmd_rename(client, fsaCommand);
|
// These are IOCTL and no IOCTLV
|
||||||
|
cemu_assert_error();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_READ)
|
default:
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_read(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_WRITE)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_write(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_SETPOS)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_setPos(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_GETPOS)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_getPos(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_OPENFILE)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_openFile(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_CLOSEFILE)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_closeFile(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_APPENDFILE)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_appendFile(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_TRUNCATEFILE)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_truncateFile(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_ISEOF)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_isEof(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_QUERYINFO)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_queryInfo(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_GETSTATFILE)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_getStatFile(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_GETCWD)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_getCwd(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_CHANGEDIR)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_changeDir(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_OPENDIR)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_openDir(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_READDIR)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_readDir(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_CLOSEDIR)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_closeDir(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else if (operationId == FSA_CMD_OPERATION_TYPE_FLUSHQUOTA)
|
|
||||||
{
|
|
||||||
fsStatus = FSAProcessCmd_flushQuota(client, fsaCommand);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
IOS_ResourceReply(cmd, (IOS_ERROR)fsStatus);
|
}
|
||||||
|
|
||||||
|
IOS_ResourceReply(cmd, (IOS_ERROR)fsaResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSAHandleCommandIoctl(FSAClient* client, IPCCommandBody* cmd, FSA_CMD_OPERATION_TYPE operationId, void* ptrIn, void* ptrOut)
|
||||||
|
{
|
||||||
|
FSAShimBuffer* shimBuffer = (FSAShimBuffer*)ptrIn;
|
||||||
|
FSA_RESULT fsaResult = FSA_RESULT::FATAL_ERROR;
|
||||||
|
|
||||||
|
switch (operationId)
|
||||||
|
{
|
||||||
|
case FSA_CMD_OPERATION_TYPE::REMOVE:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_remove(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::CHANGEDIR:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_changeDir(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::GETCWD:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_getCwd(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::MAKEDIR:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_makeDir(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::RENAME:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_rename(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::OPENDIR:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_openDir(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::READDIR:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_readDir(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::CLOSEDIR:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_closeDir(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::OPENFILE:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_openFile(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::GETPOS:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_getPos(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::SETPOS:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_setPos(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::ISEOF:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_isEof(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::GETSTATFILE:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_getStatFile(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::CLOSEFILE:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_closeFile(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::QUERYINFO:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_queryInfo(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::APPENDFILE:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_appendFile(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::TRUNCATEFILE:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_truncateFile(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::FLUSHQUOTA:
|
||||||
|
{
|
||||||
|
fsaResult = FSAProcessCmd_flushQuota(client, shimBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSA_CMD_OPERATION_TYPE::READ:
|
||||||
|
case FSA_CMD_OPERATION_TYPE::WRITE:
|
||||||
|
{
|
||||||
|
// These commands are IOCTLVs not IOCTL
|
||||||
|
cemu_assert_error();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
cemu_assert_unimplemented();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IOS_ResourceReply(cmd, (IOS_ERROR)fsaResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSAIoThread()
|
void FSAIoThread()
|
||||||
|
@ -783,17 +814,17 @@ namespace iosu
|
||||||
{
|
{
|
||||||
cemu_assert(clientHandle < sFSAClientArray.size());
|
cemu_assert(clientHandle < sFSAClientArray.size());
|
||||||
cemu_assert(sFSAClientArray[clientHandle].isAllocated);
|
cemu_assert(sFSAClientArray[clientHandle].isAllocated);
|
||||||
FSAHandleCommandIoctl(sFSAClientArray.data() + clientHandle, cmd, cmd->args[0], MEMPTR<void>(cmd->args[1]), MEMPTR<void>(cmd->args[3]));
|
FSAHandleCommandIoctl(sFSAClientArray.data() + clientHandle, cmd, (FSA_CMD_OPERATION_TYPE)cmd->args[0].value(), MEMPTR<void>(cmd->args[1]), MEMPTR<void>(cmd->args[3]));
|
||||||
}
|
}
|
||||||
else if (cmd->cmdId == IPCCommandId::IOS_IOCTLV)
|
else if (cmd->cmdId == IPCCommandId::IOS_IOCTLV)
|
||||||
{
|
{
|
||||||
cemu_assert_unimplemented();
|
cemu_assert(clientHandle < sFSAClientArray.size());
|
||||||
//uint32 requestId = cmd->args[0];
|
cemu_assert(sFSAClientArray[clientHandle].isAllocated);
|
||||||
//uint32 numIn = cmd->args[1];
|
FSA_CMD_OPERATION_TYPE requestId = (FSA_CMD_OPERATION_TYPE)cmd->args[0].value();
|
||||||
//uint32 numOut = cmd->args[2];
|
uint32 numIn = cmd->args[1];
|
||||||
//IPCIoctlVector* vec = MEMPTR<IPCIoctlVector>{ cmd->args[3] }.GetPtr();
|
uint32 numOut = cmd->args[2];
|
||||||
IOS_ResourceReply(cmd, IOS_ERROR_INVALID);
|
IPCIoctlVector* vec = MEMPTR<IPCIoctlVector>{cmd->args[3]}.GetPtr();
|
||||||
continue;
|
FSAHandleCommandIoctlv(sFSAClientArray.data() + clientHandle, cmd, requestId, numIn, numOut, vec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -820,5 +851,5 @@ namespace iosu
|
||||||
IOS_SendMessage(sFSAIoMsgQueue, 0, 0);
|
IOS_SendMessage(sFSAIoMsgQueue, 0, 0);
|
||||||
sFSAIoThread.join();
|
sFSAIoThread.join();
|
||||||
}
|
}
|
||||||
}
|
} // namespace fsa
|
||||||
}
|
} // namespace iosu
|
||||||
|
|
|
@ -1,162 +1,197 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <IOSU/iosu_ipc_common.h>
|
||||||
#include "fsa_types.h"
|
#include "fsa_types.h"
|
||||||
|
|
||||||
namespace iosu
|
namespace iosu
|
||||||
{
|
{
|
||||||
namespace fsa
|
namespace fsa
|
||||||
{
|
{
|
||||||
struct FSAIpcCommand
|
|
||||||
|
struct FSARequest
|
||||||
|
{
|
||||||
|
uint32be ukn0;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint8 ukn04[0x51C];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<void> dest;
|
||||||
|
uint32be size;
|
||||||
|
uint32be count;
|
||||||
|
uint32be filePos;
|
||||||
|
uint32be fileHandle;
|
||||||
|
uint32be flag;
|
||||||
|
} cmdReadFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<void> dest;
|
||||||
|
uint32be size;
|
||||||
|
uint32be count;
|
||||||
|
uint32be filePos;
|
||||||
|
uint32be fileHandle;
|
||||||
|
uint32be flag;
|
||||||
|
} cmdWriteFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
uint8 mode[12]; // +0x284 note: code seems to access this value like it has a size of 0x10 but the actual struct element is only 12 bytes? Maybe a typo (10 instead of 0x10 in the struct def)
|
||||||
|
uint32be createMode; // +0x290
|
||||||
|
uint32be openFlags; // +0x294
|
||||||
|
uint32be preallocSize; // +0x298
|
||||||
|
} cmdOpenFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandle;
|
||||||
|
} cmdCloseFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
} cmdRemove;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
uint8 ukn0284[12]; // +0x284
|
||||||
|
} cmdOpenDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
betype<uint32> dirHandle;
|
||||||
|
} cmdReadDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
betype<uint32> dirHandle;
|
||||||
|
} cmdCloseDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
uint32be uknParam;
|
||||||
|
} cmdMakeDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
} cmdChangeDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 query[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
uint32be queryType;
|
||||||
|
} cmdQueryInfo;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 srcPath[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
uint8 dstPath[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
} cmdRename;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be size;
|
||||||
|
uint32be count;
|
||||||
|
uint32be fileHandle;
|
||||||
|
uint32be uknParam;
|
||||||
|
} cmdAppendFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandle;
|
||||||
|
} cmdTruncateFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandle;
|
||||||
|
} cmdGetStatFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
} cmdFlushQuota;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandle;
|
||||||
|
uint32be filePos;
|
||||||
|
} cmdSetPosFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandle;
|
||||||
|
} cmdGetPosFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandle;
|
||||||
|
} cmdIsEof;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(FSARequest) == 0x520);
|
||||||
|
|
||||||
|
struct FSAResponse
|
||||||
|
{
|
||||||
|
uint32be ukn0;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint8 ukn04[0x28F];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be fileHandleOutput; // +0x584 used to return file handle on success
|
||||||
|
} cmdOpenFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be dirHandleOutput; // +0x584 used to return dir handle on success
|
||||||
|
} cmdOpenDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be filePos;
|
||||||
|
} cmdGetPosFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FSStat_t statOut;
|
||||||
|
} cmdStatFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FSDirEntry_t dirEntry;
|
||||||
|
} cmdReadDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char path[FSA_CMD_PATH_MAX_LENGTH];
|
||||||
|
} cmdGetCWD;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
uint8 ukn04[0x64];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 ukn0000;
|
uint64be freespace;
|
||||||
uint32 destBufferMPTR; // used as fileHandle for FSSetFilePosAsync
|
} queryFreeSpace;
|
||||||
uint32 ukn0008; // used as filePos for FSSetFilePosAsync
|
|
||||||
uint32 ukn000C;
|
|
||||||
uint32 transferFilePos; // used as filePos for read/write operation
|
|
||||||
uint32 fileHandle;
|
|
||||||
uint32 cmdFlag;
|
|
||||||
uint32 ukn001C;
|
|
||||||
uint8 ukn0020[0x10];
|
|
||||||
uint8 ukn0030[0x10];
|
|
||||||
uint8 ukn0040[0x10];
|
|
||||||
uint8 ukn0050[0x10];
|
|
||||||
uint8 ukn0060[0x10];
|
|
||||||
uint8 ukn0070[0x10];
|
|
||||||
uint8 ukn0080[0x10];
|
|
||||||
uint8 ukn0090[0x10];
|
|
||||||
uint8 ukn00A0[0x10];
|
|
||||||
uint8 ukn00B0[0x10];
|
|
||||||
uint8 ukn00C0[0x10];
|
|
||||||
uint8 ukn00D0[0x10];
|
|
||||||
uint8 ukn00E0[0x10];
|
|
||||||
uint8 ukn00F0[0x10];
|
|
||||||
uint8 ukn0100[0x100];
|
|
||||||
uint8 ukn0200[0x100];
|
|
||||||
uint8 ukn0300[0x100];
|
|
||||||
uint8 ukn0400[0x100];
|
|
||||||
uint8 ukn0500[0x100];
|
|
||||||
uint8 ukn0600[0x100];
|
|
||||||
}cmdDefault;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 ukn0000;
|
FSStat_t stat;
|
||||||
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
} queryStat;
|
||||||
uint8 mode[12]; // +0x284 note: code seems to access this value like it has a size of 0x10 but the actual struct element is only 12 bytes? Maybe a typo (10 instead of 0x10 in the struct def)
|
|
||||||
uint32 createMode; // +0x290
|
|
||||||
uint32 openFlags; // +0x294
|
|
||||||
uint32 preallocSize; // +0x298
|
|
||||||
uint8 ukn[0x2E8]; // +0x29C
|
|
||||||
// output
|
|
||||||
uint32be fileHandleOutput; // +0x584 used to return file handle on success
|
|
||||||
}cmdOpenFile;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000; // +0x000
|
|
||||||
uint32be fileHandle; // +0x004
|
|
||||||
}cmdCloseFile;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
uint32 ukn0284;
|
|
||||||
uint8 ukn0288[0x80 - 8];
|
|
||||||
uint8 ukn0300[0x100];
|
|
||||||
uint8 ukn0400[0x100];
|
|
||||||
uint32 ukn0500;
|
|
||||||
}cmdRemove;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
uint8 ukn0284[12]; // +0x284
|
|
||||||
uint32 ukn0290; // +0x290
|
|
||||||
uint32 ukn0294; // +0x294
|
|
||||||
uint32 ukn0298; // +0x298
|
|
||||||
uint8 ukn[0x2E8]; // +0x29C
|
|
||||||
// output
|
|
||||||
uint32be dirHandleOutput; // +0x584 used to return dir handle on success
|
|
||||||
}cmdOpenDir;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
betype<uint32> dirHandle;
|
|
||||||
}cmdReadDir;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
betype<uint32> dirHandle;
|
|
||||||
}cmdCloseDir;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
uint32 uknParam;
|
|
||||||
uint8 ukn0288[0x80 - 8];
|
|
||||||
uint8 ukn0300[0x100];
|
|
||||||
uint8 ukn0400[0x100];
|
|
||||||
uint32 ukn0500;
|
|
||||||
}cmdMakeDir;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
uint8 ukn0284[0x80 - 4];
|
|
||||||
uint8 ukn0300[0x100];
|
|
||||||
uint8 ukn0400[0x100];
|
|
||||||
uint32 ukn0500;
|
|
||||||
}cmdChangeDir;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 query[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
uint32 queryType;
|
|
||||||
uint8 ukn0288[0x80 - 8];
|
|
||||||
uint8 ukn0300[0x100];
|
|
||||||
uint8 ukn0400[0x100];
|
|
||||||
uint32 ukn0500;
|
|
||||||
}cmdQueryInfo;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 srcPath[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
uint8 dstPath[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
}cmdRename;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint32 size;
|
|
||||||
uint32 count;
|
|
||||||
uint32 fileHandle;
|
|
||||||
uint32 uknParam;
|
|
||||||
}cmdAppendFile;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
betype<uint32> fileHandle;
|
|
||||||
uint32be ukn0008;
|
|
||||||
}cmdTruncateFile;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
betype<uint32> fileHandle;
|
|
||||||
}cmdGetStatFile;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 ukn0000;
|
|
||||||
uint8 path[FSA_CMD_PATH_MAX_LENGTH];
|
|
||||||
}cmdFlushQuota;
|
|
||||||
};
|
};
|
||||||
uint8 ukn0700[0x100];
|
} cmdQueryInfo;
|
||||||
uint8 ukn0800[0x10];
|
|
||||||
uint8 ukn0810[0x10];
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
// static_assert(sizeof(FSAResponse) == 0x293);
|
||||||
|
|
||||||
static_assert(sizeof(FSAIpcCommand) == 0x820); // exact size of this is not known
|
struct FSAShimBuffer
|
||||||
|
{
|
||||||
|
FSARequest request;
|
||||||
|
uint8 ukn0520[0x60];
|
||||||
|
FSAResponse response;
|
||||||
|
uint8 ukn0813[0x6D];
|
||||||
|
IPCIoctlVector ioctlvVec[3];
|
||||||
|
uint8 ukn08A4[0x5C];
|
||||||
|
/* +0x0900 */ uint32be operationType;
|
||||||
|
betype<IOSDevHandle> fsaDevHandle;
|
||||||
|
/* +0x0908 */ uint16be ipcReqType; // 0 -> IoctlAsync, 1 -> IoctlvAsync
|
||||||
|
uint8 ioctlvVecIn;
|
||||||
|
uint8 ioctlvVecOut;
|
||||||
|
uint32 ukn090C;
|
||||||
|
uint32 ukn0910;
|
||||||
|
uint32 ukn0914;
|
||||||
|
uint32 ukn0918;
|
||||||
|
uint32 ukn091C;
|
||||||
|
uint32 ukn0920;
|
||||||
|
uint32 ukn0924;
|
||||||
|
uint32 ukn0928;
|
||||||
|
uint32 ukn092C;
|
||||||
|
uint32 ukn0930;
|
||||||
|
uint32 ukn0934;
|
||||||
|
};
|
||||||
|
// static_assert(sizeof(FSAShimBuffer) == 0x938); // exact size of this is not known
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
}
|
} // namespace fsa
|
||||||
}
|
} // namespace iosu
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32be fileHandle;
|
uint32be fileHandle;
|
||||||
}FSFileHandleDepr_t;
|
} FSFileHandleDepr_t;
|
||||||
|
|
||||||
typedef MEMPTR<betype<FSDirHandle2>> FSDirHandlePtr;
|
typedef MEMPTR<betype<FSDirHandle2>> FSDirHandlePtr;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ typedef struct
|
||||||
MEMPTR<void> userCallback;
|
MEMPTR<void> userCallback;
|
||||||
MEMPTR<void> userContext;
|
MEMPTR<void> userContext;
|
||||||
MEMPTR<coreinit::OSMessageQueue> ioMsgQueue;
|
MEMPTR<coreinit::OSMessageQueue> ioMsgQueue;
|
||||||
}FSAsyncParamsNew_t;
|
} FSAsyncParamsNew_t;
|
||||||
|
|
||||||
static_assert(sizeof(FSAsyncParamsNew_t) == 0xC);
|
static_assert(sizeof(FSAsyncParamsNew_t) == 0xC);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ typedef struct
|
||||||
MPTR userCallback; // 0x96C
|
MPTR userCallback; // 0x96C
|
||||||
MPTR userContext;
|
MPTR userContext;
|
||||||
MPTR ioMsgQueue;
|
MPTR ioMsgQueue;
|
||||||
}FSAsyncParams_t; // legacy struct. Replace with FSAsyncParamsNew_t
|
} FSAsyncParams_t; // legacy struct. Replace with FSAsyncParamsNew_t
|
||||||
|
|
||||||
namespace coreinit
|
namespace coreinit
|
||||||
{
|
{
|
||||||
|
@ -48,8 +48,8 @@ namespace coreinit
|
||||||
};
|
};
|
||||||
DEFINE_ENUM_FLAG_OPERATORS(FSCmdQueue::QUEUE_FLAG);
|
DEFINE_ENUM_FLAG_OPERATORS(FSCmdQueue::QUEUE_FLAG);
|
||||||
|
|
||||||
#define FS_CLIENT_BUFFER_SIZE (5888)
|
#define FS_CLIENT_BUFFER_SIZE (5888)
|
||||||
#define FS_CMD_BLOCK_SIZE (2688)
|
#define FS_CMD_BLOCK_SIZE (2688)
|
||||||
|
|
||||||
struct FSClient_t
|
struct FSClient_t
|
||||||
{
|
{
|
||||||
|
@ -64,7 +64,7 @@ namespace coreinit
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 mount_it;
|
uint32 mount_it;
|
||||||
}data;
|
} data;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ namespace coreinit
|
||||||
{
|
{
|
||||||
OSMessage osMsg;
|
OSMessage osMsg;
|
||||||
FSMessage fsMsg;
|
FSMessage fsMsg;
|
||||||
}msgUnion;
|
} msgUnion;
|
||||||
|
|
||||||
/* +0x1C */ MEMPTR<FSClient_t> fsClient; // 0x0988
|
/* +0x1C */ MEMPTR<FSClient_t> fsClient; // 0x0988
|
||||||
/* +0x20 */ MEMPTR<FSCmdBlock_t> fsCmdBlock; // 0x98C
|
/* +0x20 */ MEMPTR<FSCmdBlock_t> fsCmdBlock; // 0x98C
|
||||||
|
@ -148,58 +148,66 @@ namespace coreinit
|
||||||
|
|
||||||
static_assert(sizeof(FSAsyncResult) == 0x28);
|
static_assert(sizeof(FSAsyncResult) == 0x28);
|
||||||
|
|
||||||
|
struct FSCmdBlockReturnValues_t
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint8 ukn0[0x14];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<uint32be> handlePtr;
|
||||||
|
} cmdOpenFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<uint32be> filePosPtr;
|
||||||
|
} cmdGetPosFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be transferSize;
|
||||||
|
uint32be uknVal094C;
|
||||||
|
uint32be transferElemSize;
|
||||||
|
uint32be uknVal0954;
|
||||||
|
} cmdReadFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32be transferSize;
|
||||||
|
uint32be uknVal094C;
|
||||||
|
uint32be transferElemSize;
|
||||||
|
uint32be uknVal0954;
|
||||||
|
} cmdWriteFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<uint32be> handlePtr;
|
||||||
|
} cmdOpenDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<FSDirEntry_t> dirEntryPtr;
|
||||||
|
} cmdReadDir;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<char> pathPtr;
|
||||||
|
uint32be transferSize;
|
||||||
|
} cmdGetCwd;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<void> queryResultPtr;
|
||||||
|
} cmdQueryInfo;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<void> resultPtr;
|
||||||
|
} cmdStatFile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(FSCmdBlockReturnValues_t) == 0x14);
|
||||||
|
|
||||||
struct FSCmdBlockBody_t
|
struct FSCmdBlockBody_t
|
||||||
{
|
{
|
||||||
iosu::fsa::FSAIpcCommand ipcData;
|
iosu::fsa::FSAShimBuffer fsaShimBuffer;
|
||||||
uint8 ukn0820[0x10];
|
|
||||||
uint8 ukn0830[0x10];
|
|
||||||
uint8 ukn0840[0x10];
|
|
||||||
uint8 ukn0850[0x10];
|
|
||||||
uint8 ukn0860[0x10];
|
|
||||||
uint8 ukn0870[0x10];
|
|
||||||
MPTR fsCmdBlockBodyMPTR;
|
|
||||||
uint32 ukn0884;
|
|
||||||
uint32 ukn0888;
|
|
||||||
uint32 destBuffer88CMPTR;
|
|
||||||
uint32 ukn0890;
|
|
||||||
uint32 ukn0894;
|
|
||||||
uint32 ukn0898;
|
|
||||||
uint32 ukn089C;
|
|
||||||
uint32 ukn08A0;
|
|
||||||
uint32 ukn08A4;
|
|
||||||
uint32 ukn08A8;
|
|
||||||
uint32 ukn08AC;
|
|
||||||
uint8 ukn08B0[0x10];
|
|
||||||
uint8 ukn08C0[0x10];
|
|
||||||
uint8 ukn08D0[0x10];
|
|
||||||
uint8 ukn08E0[0x10];
|
|
||||||
uint8 ukn08F0[0x10];
|
|
||||||
/* +0x0900 */ uint32be operationType;
|
|
||||||
betype<IOSDevHandle> fsaDevHandle;
|
|
||||||
/* +0x0908 */ uint16be ipcReqType; // 0 -> IoctlAsync, 1 -> IoctlvAsync
|
|
||||||
uint8 ukn090A;
|
|
||||||
uint8 ukn090B;
|
|
||||||
uint32 ukn090C;
|
|
||||||
uint32 ukn0910;
|
|
||||||
uint32 ukn0914;
|
|
||||||
uint32 ukn0918;
|
|
||||||
uint32 ukn091C;
|
|
||||||
uint32 ukn0920;
|
|
||||||
uint32 ukn0924;
|
|
||||||
uint32 ukn0928;
|
|
||||||
uint32 ukn092C;
|
|
||||||
uint32 ukn0930;
|
|
||||||
uint32 ukn0934;
|
|
||||||
/* +0x0938 */ MEMPTR<FSClientBody_t> fsClientBody;
|
/* +0x0938 */ MEMPTR<FSClientBody_t> fsClientBody;
|
||||||
/* +0x093C */ uint32 statusCode; // not a status code but rather the state? Uses weird values for some reason
|
/* +0x093C */ uint32 statusCode; // not a status code but rather the state? Uses weird values for some reason
|
||||||
/* +0x0940 */ uint32be cancelState; // bitmask. Bit 0 -> If set command has been canceled
|
/* +0x0940 */ uint32be cancelState; // bitmask. Bit 0 -> If set command has been canceled
|
||||||
// return values
|
FSCmdBlockReturnValues_t returnValues;
|
||||||
/* +0x0944 */ uint32 returnValueMPTR; // returnedFilePos (used to store pointer to variable that holds return value?), also used by QUERYINFO to store pointer for result. Also used for GetCwd() to hold the pointer for the returned dir path. Also used by OPENFILE to hold returned fileHandle
|
|
||||||
/* +0x0948 */ uint32 transferSize; // number of bytes to transfer
|
|
||||||
// transfer control?
|
|
||||||
uint32 uknVal094C;
|
|
||||||
uint32 transferElemSize; // number of bytes of a single transferred element (count of elements can be calculated via count = transferSize/transferElemSize)
|
|
||||||
uint32 uknVal0954; // this is set to max(0x10, transferSize) for reads and to min(0x40000, transferSize) for writes?
|
|
||||||
// link for cmd queue
|
// link for cmd queue
|
||||||
MPTR nextMPTR; // points towards FSCmdQueue->first
|
MPTR nextMPTR; // points towards FSCmdQueue->first
|
||||||
MPTR previousMPTR; // points towards FSCmdQueue->last
|
MPTR previousMPTR; // points towards FSCmdQueue->last
|
||||||
|
@ -226,34 +234,12 @@ namespace coreinit
|
||||||
static_assert(sizeof(FSAsyncParams_t) == 0xC);
|
static_assert(sizeof(FSAsyncParams_t) == 0xC);
|
||||||
static_assert(sizeof(FSCmdBlock_t) == 0xA80);
|
static_assert(sizeof(FSCmdBlock_t) == 0xA80);
|
||||||
|
|
||||||
#define FSA_CMD_FLAG_SET_POS (1<<0)
|
#define FSA_CMD_FLAG_SET_POS (1 << 0)
|
||||||
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_CHANGEDIR (0x5)
|
#define FSA_CMD_STATUS_CODE_D900A21 0xD900A21 // cmd block is initialized
|
||||||
#define FSA_CMD_OPERATION_TYPE_GETCWD (0x6)
|
#define FSA_CMD_STATUS_CODE_D900A22 0xD900A22 // cmd block is queued
|
||||||
#define FSA_CMD_OPERATION_TYPE_MAKEDIR (0x7)
|
#define FSA_CMD_STATUS_CODE_D900A24 0xD900A24 // cmd block was processed and is available again
|
||||||
#define FSA_CMD_OPERATION_TYPE_REMOVE (0x8)
|
#define FSA_CMD_STATUS_CODE_D900A26 0xD900A26 // cmd block result is being processed
|
||||||
#define FSA_CMD_OPERATION_TYPE_RENAME (0x9)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_OPENDIR (0xA)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_READDIR (0xB)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_CLOSEDIR (0xD)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_OPENFILE (0xE)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_READ (0xF)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_WRITE (0x10)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_GETPOS (0x11)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_SETPOS (0x12)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_ISEOF (0x13)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_GETSTATFILE (0x14)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_CLOSEFILE (0x15)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_QUERYINFO (0x18)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_APPENDFILE (0x19)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_TRUNCATEFILE (0x1A)
|
|
||||||
#define FSA_CMD_OPERATION_TYPE_FLUSHQUOTA (0x1E)
|
|
||||||
|
|
||||||
|
|
||||||
#define FSA_CMD_STATUS_CODE_D900A21 0xD900A21 // cmd block is initialized
|
|
||||||
#define FSA_CMD_STATUS_CODE_D900A22 0xD900A22 // cmd block is queued
|
|
||||||
#define FSA_CMD_STATUS_CODE_D900A24 0xD900A24 // cmd block was processed and is available again
|
|
||||||
#define FSA_CMD_STATUS_CODE_D900A26 0xD900A26 // cmd block result is being processed
|
|
||||||
|
|
||||||
enum FS_VOLSTATE : sint32
|
enum FS_VOLSTATE : sint32
|
||||||
{
|
{
|
||||||
|
@ -321,5 +307,4 @@ namespace coreinit
|
||||||
FS_VOLSTATE FSGetVolumeState(FSClient_t* fsClient);
|
FS_VOLSTATE FSGetVolumeState(FSClient_t* fsClient);
|
||||||
|
|
||||||
void InitializeFS();
|
void InitializeFS();
|
||||||
};
|
}; // namespace coreinit
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue