From fd3b5b7f279c801396b1d13c49e1eeb14380ae82 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 17 Jun 2023 13:51:55 +0200 Subject: [PATCH] coreinit: Fix FSGetMountSource and FSAppendFile implementation (#863) Fixes SD access in SSBU --- src/Cafe/IOSU/fsa/iosu_fsa.cpp | 5 +-- src/Cafe/OS/libs/coreinit/coreinit_FS.cpp | 49 +++++++++++++---------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.cpp b/src/Cafe/IOSU/fsa/iosu_fsa.cpp index e194f96d..30c620bc 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.cpp +++ b/src/Cafe/IOSU/fsa/iosu_fsa.cpp @@ -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) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp index ce1496f7..26636eae 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp @@ -74,22 +74,16 @@ 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; } - - fsCmdBlock->data.mount_it++; - - // SD - if (mountSourceType == MOUNT_TYPE::SD && fsCmdBlock->data.mount_it == 1) + else { - mountSourceInfo->sourceType = 0; - strcpy(mountSourceInfo->path, "/sd"); - return FS_RESULT::SUCCESS; + cemu_assert_unimplemented(); } return FS_RESULT::END_ITERATION; @@ -97,7 +91,20 @@ namespace coreinit 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); + // 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; } bool _sdCard01Mounted = false; @@ -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; @@ -1408,17 +1415,17 @@ 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); @@ -1426,11 +1433,11 @@ namespace coreinit 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 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); }