Skip to content

Commit

Permalink
coreinit: Fix FSGetMountSource and FSAppendFile implementation (#863)
Browse files Browse the repository at this point in the history
Fixes SD access in SSBU
  • Loading branch information
Maschell committed Jun 17, 2023
1 parent 950e956 commit fd3b5b7
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 23 deletions.
5 changes: 2 additions & 3 deletions src/Cafe/IOSU/fsa/iosu_fsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,14 +611,13 @@ namespace iosu

FSA_RESULT FSAProcessCmd_appendFile(FSAClient* client, FSAShimBuffer* shimBuffer)
{
uint32 fileHandle = shimBuffer->request.cmdAppendFile.fileHandle;
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(fileHandle);
FSCVirtualFile* fscFile = sFileHandleTable.GetByHandle(shimBuffer->request.cmdAppendFile.fileHandle);
if (!fscFile)
return FSA_RESULT::INVALID_FILE_HANDLE;
#ifdef CEMU_DEBUG_ASSERT
cemuLog_log(LogType::Force, "FSAProcessCmd_appendFile(): size 0x{:08x} count 0x{:08x} (todo)\n", shimBuffer->request.cmdAppendFile.size, shimBuffer->request.cmdAppendFile.count);
#endif
return (FSA_RESULT)(shimBuffer->request.cmdAppendFile.size * shimBuffer->request.cmdAppendFile.count);
return (FSA_RESULT)(shimBuffer->request.cmdAppendFile.count.value());
}

FSA_RESULT FSAProcessCmd_truncateFile(FSAClient* client, FSAShimBuffer* shimBuffer)
Expand Down
47 changes: 27 additions & 20 deletions src/Cafe/OS/libs/coreinit/coreinit_FS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,32 +74,39 @@ namespace coreinit

FS_RESULT FSGetMountSourceNext(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, MOUNT_TYPE mountSourceType, FS_MOUNT_SOURCE* mountSourceInfo, FS_ERROR_MASK errMask)
{
// hacky
static FS_MOUNT_SOURCE* s_last_source = nullptr;
if (s_last_source != mountSourceInfo)
if (mountSourceType == MOUNT_TYPE::SD)
{
s_last_source = mountSourceInfo;
fsCmdBlock->data.mount_it = 0;
// This function is supposed to be called after an initial FSGetMountSource call => always returns FS_RESULT::END_ITERATION because we only have one SD Card
// It *might* causes issues if this function is called for getting the first MountSource (instead of "FSGetMountSource")
cemu_assert_suspicious();
return FS_RESULT::END_ITERATION;
}
else
{
cemu_assert_unimplemented();
}

fsCmdBlock->data.mount_it++;
return FS_RESULT::END_ITERATION;
}

// SD
if (mountSourceType == MOUNT_TYPE::SD && fsCmdBlock->data.mount_it == 1)
FS_RESULT FSGetMountSource(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, MOUNT_TYPE mountSourceType, FS_MOUNT_SOURCE* mountSourceInfo, FS_ERROR_MASK errMask)
{
// This implementation is simplified A LOT compared to what the Wii U is actually doing. On Cemu we expect to only have one mountable source (SD Card) anyway,
// so we can just hard code it. Other mount types are not (yet) supported.
if (mountSourceType == MOUNT_TYPE::SD)
{
mountSourceInfo->sourceType = 0;
strcpy(mountSourceInfo->path, "/sd");
return FS_RESULT::SUCCESS;
}
else
{
cemu_assert_unimplemented();
}

return FS_RESULT::END_ITERATION;
}

FS_RESULT FSGetMountSource(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, MOUNT_TYPE mountSourceType, FS_MOUNT_SOURCE* mountSourceInfo, FS_ERROR_MASK errMask)
{
return FSGetMountSourceNext(fsClient, fsCmdBlock, mountSourceType, mountSourceInfo, errMask);
}

bool _sdCard01Mounted = false;
bool _mlc01Mounted = false;

Expand Down Expand Up @@ -1399,7 +1406,7 @@ namespace coreinit
return __FSProcessAsyncResult(fsClient, fsCmdBlock, fsAsyncRet, errorMask);
}

FSA_RESULT __FSPrepareCmd_AppendFile(iosu::fsa::FSAShimBuffer* fsaShimBuffer, IOSDevHandle fsaHandle, uint32 fileHandle, uint32 size, uint32 count, uint32 uknParam)
FSA_RESULT __FSPrepareCmd_AppendFile(iosu::fsa::FSAShimBuffer* fsaShimBuffer, IOSDevHandle fsaHandle, uint32 size, uint32 count, uint32 fileHandle, uint32 uknParam)
{
if (fsaShimBuffer == nullptr)
return FSA_RESULT::INVALID_BUFFER;
Expand All @@ -1408,29 +1415,29 @@ namespace coreinit
fsaShimBuffer->operationType = (uint32)FSA_CMD_OPERATION_TYPE::APPENDFILE;

fsaShimBuffer->request.cmdAppendFile.fileHandle = fileHandle;
fsaShimBuffer->request.cmdAppendFile.count = size;
fsaShimBuffer->request.cmdAppendFile.size = count;
fsaShimBuffer->request.cmdAppendFile.count = count;
fsaShimBuffer->request.cmdAppendFile.size = size;
fsaShimBuffer->request.cmdAppendFile.uknParam = uknParam;

return FSA_RESULT::OK;
}

sint32 FSAppendFileAsync(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, uint32 fileHandle, uint32 size, uint32 count, uint32 errorMask, FSAsyncParamsNew_t* fsAsyncParams)
sint32 FSAppendFileAsync(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, uint32 size, uint32 count, uint32 fileHandle, uint32 errorMask, FSAsyncParamsNew_t* fsAsyncParams)
{
_FSCmdIntro();
FSA_RESULT prepareResult = __FSPrepareCmd_AppendFile(&fsCmdBlockBody->fsaShimBuffer, fsClientBody->iosuFSAHandle, fileHandle, size, count, 0);
FSA_RESULT prepareResult = __FSPrepareCmd_AppendFile(&fsCmdBlockBody->fsaShimBuffer, fsClientBody->iosuFSAHandle, size, count, fileHandle, 0);
if (prepareResult != FSA_RESULT::OK)
return (FSStatus)_FSAStatusToFSStatus(prepareResult);

__FSQueueCmd(&fsClientBody->fsCmdQueue, fsCmdBlockBody, RPLLoader_MakePPCCallable(export___FSQueueDefaultFinishFunc));
return (FSStatus)FS_RESULT::SUCCESS;
}

sint32 FSAppendFile(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, uint32 fileHandle, uint32 size, uint32 count, uint32 errorMask)
sint32 FSAppendFile(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, uint32 size, uint32 count, uint32 fileHandle, uint32 errorMask)
{
StackAllocator<FSAsyncParamsNew_t> asyncParams;
__FSAsyncToSyncInit(fsClient, fsCmdBlock, asyncParams);
sint32 fsAsyncRet = FSAppendFileAsync(fsClient, fsCmdBlock, fileHandle, size, count, errorMask, asyncParams.GetPointer());
sint32 fsAsyncRet = FSAppendFileAsync(fsClient, fsCmdBlock, size, count, fileHandle, errorMask, asyncParams.GetPointer());
return __FSProcessAsyncResult(fsClient, fsCmdBlock, fsAsyncRet, errorMask);
}

Expand Down

0 comments on commit fd3b5b7

Please sign in to comment.