diff --git a/src/LibHac/Fs/Shim/Mmc.cs b/src/LibHac/Fs/Shim/Mmc.cs new file mode 100644 index 00000000..b3ff1a6f --- /dev/null +++ b/src/LibHac/Fs/Shim/Mmc.cs @@ -0,0 +1,171 @@ +using System; +using LibHac.Common; +using LibHac.FsSrv.Sf; +using LibHac.Sf; + +namespace LibHac.Fs.Shim; + +/// +/// Contains functions used for interacting with the MMC. +/// +/// Based on nnSdk 14.3.0 +public static class Mmc +{ + public static Result GetMmcSpeedMode(this FileSystemClient fs, out MmcSpeedMode outSpeedMode) + { + UnsafeHelpers.SkipParamInit(out outSpeedMode); + + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.GetMmcSpeedMode(out long speedMode); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + outSpeedMode = (MmcSpeedMode)speedMode; + return Result.Success; + } + + public static Result GetMmcCid(this FileSystemClient fs, Span outCidBuffer) + { + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.GetMmcCid(new OutBuffer(outCidBuffer), outCidBuffer.Length); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } + + public static Result EraseMmc(this FileSystemClient fs, MmcPartition partition) + { + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.EraseMmc((uint)partition); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } + + public static Result GetMmcPartitionSize(this FileSystemClient fs, out long outPartitionSize, + MmcPartition partition) + { + UnsafeHelpers.SkipParamInit(out outPartitionSize); + + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.GetMmcPartitionSize(out outPartitionSize, (uint)partition); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } + + public static Result GetMmcPatrolCount(this FileSystemClient fs, out uint outPatrolCount) + { + UnsafeHelpers.SkipParamInit(out outPatrolCount); + + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.GetMmcPatrolCount(out outPatrolCount); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } + + public static Result GetAndClearMmcErrorInfo(this FileSystemClient fs, out StorageErrorInfo outErrorInfo, + out long outLogSize, Span logBuffer) + { + UnsafeHelpers.SkipParamInit(out outErrorInfo, out outLogSize); + + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.GetAndClearMmcErrorInfo(out outErrorInfo, out long logSize, new OutBuffer(logBuffer), + logBuffer.Length); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + outLogSize = logSize; + + return Result.Success; + } + + public static Result GetMmcExtendedCsd(this FileSystemClient fs, Span outBuffer) + { + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.GetMmcExtendedCsd(new OutBuffer(outBuffer), outBuffer.Length); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } + + public static Result SuspendMmcPatrol(this FileSystemClient fs) + { + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.SuspendMmcPatrol(); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } + + public static Result ResumeMmcPatrol(this FileSystemClient fs) + { + using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); + using var deviceOperator = new SharedRef(); + + Result rc = fileSystemProxy.Get.OpenDeviceOperator(ref deviceOperator.Ref()); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + rc = deviceOperator.Get.ResumeMmcPatrol(); + fs.Impl.AbortIfNeeded(rc); + if (rc.IsFailure()) return rc.Miss(); + + return Result.Success; + } +} \ No newline at end of file