mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Implement DeviceOperator
This commit is contained in:
parent
612359f0a4
commit
902e3e1424
9 changed files with 942 additions and 31 deletions
|
@ -194,28 +194,30 @@ public enum SdCardSpeedMode
|
|||
|
||||
public enum SdmmcBusWidth
|
||||
{
|
||||
Width1Bit = 0,
|
||||
Width4Bit = 1,
|
||||
Width8Bit = 2,
|
||||
Unknown = 0,
|
||||
Width1Bit = 1,
|
||||
Width4Bit = 2,
|
||||
Width8Bit = 3,
|
||||
}
|
||||
|
||||
public enum SdmmcSpeedMode
|
||||
{
|
||||
MmcIdentification = 0,
|
||||
MmcLegacySpeed = 1,
|
||||
MmcHighSpeed = 2,
|
||||
MmcHs200 = 3,
|
||||
MmcHs400 = 4,
|
||||
SdCardIdentification = 5,
|
||||
SdCardDefaultSpeed = 6,
|
||||
SdCardHighSpeed = 7,
|
||||
SdCardSdr12 = 8,
|
||||
SdCardSdr25 = 9,
|
||||
SdCardSdr50 = 10,
|
||||
SdCardSdr104 = 11,
|
||||
SdCardDdr50 = 12,
|
||||
GcAsicFpgaSpeed = 13,
|
||||
GcAsicSpeed = 14
|
||||
Unknown = 0,
|
||||
MmcIdentification = 1,
|
||||
MmcLegacySpeed = 2,
|
||||
MmcHighSpeed = 3,
|
||||
MmcHs200 = 4,
|
||||
MmcHs400 = 5,
|
||||
SdCardIdentification = 6,
|
||||
SdCardDefaultSpeed = 7,
|
||||
SdCardHighSpeed = 8,
|
||||
SdCardSdr12 = 9,
|
||||
SdCardSdr25 = 10,
|
||||
SdCardSdr50 = 11,
|
||||
SdCardSdr104 = 12,
|
||||
SdCardDdr50 = 13,
|
||||
GcAsicFpgaSpeed = 14,
|
||||
GcAsicSpeed = 15
|
||||
}
|
||||
|
||||
public enum SdmmcPort
|
||||
|
|
|
@ -72,9 +72,9 @@ public static class GameCard
|
|||
}
|
||||
}
|
||||
|
||||
public static Result GetGameCardHandle(this FileSystemClient fs, out GameCardHandle handle)
|
||||
public static Result GetGameCardHandle(this FileSystemClient fs, out GameCardHandle outHandle)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out handle);
|
||||
UnsafeHelpers.SkipParamInit(out outHandle);
|
||||
|
||||
using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject();
|
||||
using var deviceOperator = new SharedRef<IDeviceOperator>();
|
||||
|
@ -83,9 +83,12 @@ public static class GameCard
|
|||
fs.Impl.AbortIfNeeded(rc);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = deviceOperator.Get.GetGameCardHandle(out handle);
|
||||
rc = deviceOperator.Get.GetGameCardHandle(out uint handle);
|
||||
fs.Impl.AbortIfNeeded(rc);
|
||||
return rc;
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outHandle = new GameCardHandle((int)handle);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static Result MountGameCardPartition(this FileSystemClient fs, U8Span mountName, GameCardHandle handle,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using LibHac.Common;
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.Sf;
|
||||
|
||||
namespace LibHac.FsSrv;
|
||||
|
||||
|
@ -17,18 +19,229 @@ public class EmulatedDeviceOperator : IDeviceOperator
|
|||
|
||||
public void Dispose() { }
|
||||
|
||||
public Result IsSdCardInserted(out bool isInserted)
|
||||
public Result IsSdCardInserted(out bool outIsInserted)
|
||||
{
|
||||
isInserted = SdCard.IsSdCardInserted();
|
||||
outIsInserted = SdCard.IsSdCardInserted();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result IsGameCardInserted(out bool isInserted)
|
||||
public Result GetSdCardSpeedMode(out long outSpeedMode)
|
||||
{
|
||||
isInserted = GameCard.IsGameCardInserted();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetSdCardCid(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetSdCardUserAreaSize(out long outSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetSdCardProtectedAreaSize(out long outSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetAndClearSdCardErrorInfo(out StorageErrorInfo outStorageErrorInfo, out long outLogSize,
|
||||
OutBuffer logBuffer, long logBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetMmcCid(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetMmcSpeedMode(out long outSpeedMode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result EraseMmc(uint partitionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetMmcPartitionSize(out long outSize, uint partitionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetMmcPatrolCount(out uint outCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetAndClearMmcErrorInfo(out StorageErrorInfo outStorageErrorInfo, out long outLogSize,
|
||||
OutBuffer logBuffer, long logBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetMmcExtendedCsd(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result SuspendMmcPatrol()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result ResumeMmcPatrol()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result IsGameCardInserted(out bool outIsInserted)
|
||||
{
|
||||
outIsInserted = GameCard.IsGameCardInserted();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result EraseGameCard(uint gameCardSize, ulong romAreaStartPageAddress)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardHandle(out uint outHandle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardUpdatePartitionInfo(out uint outCupVersion, out ulong outCupId, uint handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result FinalizeGameCardDriver()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardAttribute(out byte outAttribute, uint handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardDeviceCertificate(OutBuffer outBuffer, long outBufferSize, uint handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardAsicInfo(OutBuffer outRmaInfoBuffer, long rmaInfoBufferSize, InBuffer asicFirmwareBuffer,
|
||||
long asicFirmwareBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardIdSet(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result WriteToGameCardDirectly(long offset, OutBuffer buffer, long bufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result SetVerifyWriteEnableFlag(bool isEnabled)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardImageHash(OutBuffer outBuffer, long outBufferSize, uint handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardDeviceIdForProdCard(OutBuffer outBuffer, long outBufferSize, InBuffer devHeaderBuffer,
|
||||
long devHeaderBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result EraseAndWriteParamDirectly(InBuffer inBuffer, long inBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result ReadParamDirectly(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result ForceEraseGameCard()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardErrorInfo(out GameCardErrorInfo outErrorInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardErrorReportInfo(out GameCardErrorReportInfo outErrorInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardDeviceId(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result ChallengeCardExistence(OutBuffer outResponseBuffer, InBuffer challengeSeedBuffer,
|
||||
InBuffer challengeValueBuffer, uint handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardCompatibilityType(out byte outCompatibilityType, uint handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result SetSpeedEmulationMode(int mode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetSpeedEmulationMode(out int outMode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result SuspendSdmmcControl()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result ResumeSdmmcControl()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetSdmmcConnectionStatus(out int outSpeedMode, out int outBusWidth, int port)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result SetDeviceSimulationEvent(uint port, uint simulatedOperationType, uint simulatedFailureType,
|
||||
uint failureResult, bool autoClearEvent)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result ClearDeviceSimulationEvent(uint port)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetGameCardHandle(out GameCardHandle handle)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out handle);
|
||||
|
|
|
@ -45,6 +45,7 @@ internal struct FileSystemServerGlobals : IDisposable
|
|||
public PooledBufferGlobals PooledBuffer;
|
||||
public GameCardServiceGlobals GameCardService;
|
||||
public HierarchicalIntegrityVerificationStorageGlobals HierarchicalIntegrityVerificationStorage;
|
||||
public SpeedEmulationConfigurationGlobals SpeedEmulationConfiguration;
|
||||
|
||||
public void Initialize(HorizonClient horizonClient, FileSystemServer fsServer)
|
||||
{
|
||||
|
|
606
src/LibHac/FsSrv/Impl/DeviceOperator.cs
Normal file
606
src/LibHac/FsSrv/Impl/DeviceOperator.cs
Normal file
|
@ -0,0 +1,606 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.FsSrv.Storage;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Gc;
|
||||
using LibHac.Sdmmc;
|
||||
using LibHac.Sf;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSrv.Impl;
|
||||
|
||||
/// <summary>
|
||||
/// Verifies permissions for <see cref="IDeviceOperator"/> calls and forwards them
|
||||
/// to the appropriate <see cref="LibHac.FsSrv.Storage"/> functions.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 14.3.0</remarks>
|
||||
public class DeviceOperator : IDeviceOperator
|
||||
{
|
||||
private AccessControl _accessControl;
|
||||
// ReSharper disable once NotAccessedField.Local
|
||||
private ulong _processId;
|
||||
|
||||
// LibHac addition
|
||||
private FileSystemServer _fsServer;
|
||||
|
||||
public DeviceOperator(FileSystemServer fsServer, AccessControl accessControl, ulong processId)
|
||||
{
|
||||
_accessControl = accessControl;
|
||||
_processId = processId;
|
||||
|
||||
_fsServer = fsServer;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
private static Span<byte> GetSpan(OutBuffer buffer, long size)
|
||||
{
|
||||
Assert.True(IntUtil.IsIntValueRepresentableAsInt(size));
|
||||
|
||||
return buffer.Buffer.Slice(0, (int)size);
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetSpan(InBuffer buffer, long size)
|
||||
{
|
||||
Assert.True(IntUtil.IsIntValueRepresentableAsInt(size));
|
||||
|
||||
return buffer.Buffer.Slice(0, (int)size);
|
||||
}
|
||||
|
||||
public Result IsSdCardInserted(out bool outIsInserted)
|
||||
{
|
||||
return _fsServer.Storage.IsSdCardInserted(out outIsInserted).Ret();
|
||||
}
|
||||
|
||||
public Result GetSdCardCid(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetSdCardCid(GetSpan(outBuffer, outBufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result GetSdCardSpeedMode(out long outSpeedMode)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outSpeedMode);
|
||||
|
||||
Result rc = _fsServer.Storage.GetSdCardSpeedMode(out SdCardSpeedMode speedMode);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outSpeedMode = (long)speedMode;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetSdCardUserAreaSize(out long outSize)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outSize);
|
||||
|
||||
Result rc = _fsServer.Storage.GetSdCardUserAreaSize(out long size);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outSize = size;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetSdCardProtectedAreaSize(out long outSize)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outSize);
|
||||
|
||||
Result rc = _fsServer.Storage.GetSdCardProtectedAreaSize(out long size);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outSize = size;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetAndClearSdCardErrorInfo(out StorageErrorInfo outStorageErrorInfo, out long outLogSize,
|
||||
OutBuffer logBuffer, long logBufferSize)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outStorageErrorInfo, out outLogSize);
|
||||
|
||||
if (logBuffer.Size < logBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
Result rc = _fsServer.Storage.GetAndClearSdCardErrorInfo(out StorageErrorInfo storageErrorInfo,
|
||||
out long logSize, GetSpan(logBuffer, logBufferSize));
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outStorageErrorInfo = storageErrorInfo;
|
||||
outLogSize = logSize;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetMmcCid(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetMmcCid(GetSpan(outBuffer, outBufferSize));
|
||||
}
|
||||
|
||||
public Result GetMmcSpeedMode(out long outSpeedMode)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outSpeedMode);
|
||||
|
||||
Result rc = _fsServer.Storage.GetMmcSpeedMode(out MmcSpeedMode speedMode);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outSpeedMode = (long)speedMode;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result EraseMmc(uint partitionId)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.EraseMmc))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _fsServer.Storage.EraseMmc((MmcPartition)partitionId).Ret();
|
||||
}
|
||||
|
||||
public Result GetMmcPartitionSize(out long outSize, uint partitionId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outSize);
|
||||
|
||||
Result rc = _fsServer.Storage.GetMmcPartitionSize(out long mmcPartitionSize, (MmcPartition)partitionId);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outSize = mmcPartitionSize;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetMmcPatrolCount(out uint outCount)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outCount);
|
||||
|
||||
Result rc = _fsServer.Storage.GetMmcPatrolCount(out uint mmcPatrolCount);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outCount = mmcPatrolCount;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetAndClearMmcErrorInfo(out StorageErrorInfo outStorageErrorInfo, out long outLogSize,
|
||||
OutBuffer logBuffer, long logBufferSize)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outStorageErrorInfo, out outLogSize);
|
||||
|
||||
if (logBuffer.Size < logBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
Result rc = _fsServer.Storage.GetAndClearMmcErrorInfo(out StorageErrorInfo storageErrorInfo, out long logSize,
|
||||
GetSpan(logBuffer, logBufferSize));
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outStorageErrorInfo = storageErrorInfo;
|
||||
outLogSize = logSize;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetMmcExtendedCsd(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetMmcExtendedCsd(GetSpan(outBuffer, outBufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result SuspendMmcPatrol()
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.ControlMmcPatrol))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _fsServer.Storage.SuspendMmcPatrol().Ret();
|
||||
}
|
||||
|
||||
public Result ResumeMmcPatrol()
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.ControlMmcPatrol))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _fsServer.Storage.ResumeMmcPatrol().Ret();
|
||||
}
|
||||
|
||||
public Result IsGameCardInserted(out bool outIsInserted)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outIsInserted);
|
||||
|
||||
Result rc = _fsServer.Storage.IsGameCardInserted(out bool isInserted);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outIsInserted = isInserted;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result EraseGameCard(uint gameCardSize, ulong romAreaStartPageAddress)
|
||||
{
|
||||
Accessibility accessibility = _accessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||
|
||||
if (!accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _fsServer.Storage.EraseGameCard(gameCardSize, romAreaStartPageAddress).Ret();
|
||||
}
|
||||
|
||||
public Result GetGameCardHandle(out uint outHandle)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outHandle);
|
||||
|
||||
Result rc = _fsServer.Storage.GetInitializationResult();
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
_fsServer.Storage.IsGameCardInserted(out bool isInserted).IgnoreResult();
|
||||
if (!isInserted)
|
||||
return ResultFs.GameCardFsGetHandleFailure.Log();
|
||||
|
||||
rc = _fsServer.Storage.GetGameCardHandle(out uint handle);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outHandle = handle;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardUpdatePartitionInfo(out uint outCupVersion, out ulong outCupId, uint handle)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outCupVersion, out outCupId);
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardStatus(out GameCardStatus gameCardStatus, handle);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outCupVersion = gameCardStatus.UpdatePartitionVersion;
|
||||
outCupId = gameCardStatus.UpdatePartitionId;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result FinalizeGameCardDriver()
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.FinalizeGameCardDriver))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
_fsServer.Storage.FinalizeGameCardLibrary().IgnoreResult();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardAttribute(out byte outAttribute, uint handle)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outAttribute);
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardStatus(out GameCardStatus gameCardStatus, handle);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outAttribute = gameCardStatus.GameCardAttribute;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardCompatibilityType(out byte outCompatibilityType, uint handle)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outCompatibilityType);
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardStatus(out GameCardStatus gameCardStatus, handle);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outCompatibilityType = gameCardStatus.CompatibilityType;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardDeviceCertificate(OutBuffer outBuffer, long outBufferSize, uint handle)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.GetGameCardDeviceCertificate))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetGameCardDeviceCertificate(GetSpan(outBuffer, outBufferSize), handle).Ret();
|
||||
}
|
||||
|
||||
public Result ChallengeCardExistence(OutBuffer outResponseBuffer, InBuffer challengeSeedBuffer,
|
||||
InBuffer challengeValueBuffer, uint handle)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.ChallengeCardExistence))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _fsServer.Storage.ChallengeCardExistence(outResponseBuffer.Buffer, challengeSeedBuffer.Buffer,
|
||||
challengeValueBuffer.Buffer, handle).Ret();
|
||||
}
|
||||
|
||||
public Result GetGameCardAsicInfo(OutBuffer outRmaInfoBuffer, long rmaInfoBufferSize, InBuffer asicFirmwareBuffer,
|
||||
long asicFirmwareBufferSize)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.GetGameCardAsicInfo))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
if (outRmaInfoBuffer.Size < rmaInfoBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
if (asicFirmwareBuffer.Size < asicFirmwareBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
if (rmaInfoBufferSize != Unsafe.SizeOf<RmaInformation>())
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardAsicInfo(out RmaInformation rmaInfo,
|
||||
GetSpan(asicFirmwareBuffer, asicFirmwareBufferSize));
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
SpanHelpers.AsReadOnlyByteSpan(in rmaInfo).CopyTo(outRmaInfoBuffer.Buffer);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardIdSet(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
if (outBufferSize != Unsafe.SizeOf<GameCardIdSet>())
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardIdSet(out GameCardIdSet gcIdSet);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
SpanHelpers.AsReadOnlyByteSpan(in gcIdSet).CopyTo(outBuffer.Buffer);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result WriteToGameCardDirectly(long offset, OutBuffer buffer, long bufferSize)
|
||||
{
|
||||
Accessibility accessibility = _accessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||
|
||||
if (!accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
if (buffer.Size < bufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
// Changed: Removed the alignment check for the buffer address
|
||||
|
||||
if (!Alignment.IsAlignedPow2(bufferSize, 0x1000))
|
||||
return ResultFs.InvalidAlignment.Log();
|
||||
|
||||
return _fsServer.Storage.WriteToGameCardDirectly(offset, GetSpan(buffer, bufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result SetVerifyWriteEnableFlag(bool isEnabled)
|
||||
{
|
||||
_fsServer.Storage.SetVerifyWriteEnableFlag(isEnabled);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardImageHash(OutBuffer outBuffer, long outBufferSize, uint handle)
|
||||
{
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetGameCardImageHash(GetSpan(outBuffer, outBufferSize), handle).Ret();
|
||||
}
|
||||
|
||||
public Result GetGameCardDeviceIdForProdCard(OutBuffer outBuffer, long outBufferSize, InBuffer devHeaderBuffer,
|
||||
long devHeaderBufferSize)
|
||||
{
|
||||
Accessibility accessibility = _accessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||
|
||||
if (!accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
if (devHeaderBuffer.Size < devHeaderBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetGameCardDeviceIdForProdCard(GetSpan(outBuffer, outBufferSize),
|
||||
GetSpan(devHeaderBuffer, devHeaderBufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result EraseAndWriteParamDirectly(InBuffer inBuffer, long inBufferSize)
|
||||
{
|
||||
Accessibility accessibility = _accessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||
|
||||
if (!accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
if (inBuffer.Size < inBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.EraseAndWriteParamDirectly(GetSpan(inBuffer, inBufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result ReadParamDirectly(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
Accessibility accessibility = _accessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||
|
||||
if (!accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.ReadParamDirectly(GetSpan(outBuffer, outBufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result ForceEraseGameCard()
|
||||
{
|
||||
Accessibility accessibility = _accessControl.GetAccessibilityFor(AccessibilityType.OpenGameCardStorage);
|
||||
|
||||
if (!accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return _fsServer.Storage.ForceEraseGameCard().Ret();
|
||||
}
|
||||
|
||||
public Result GetGameCardErrorInfo(out GameCardErrorInfo outErrorInfo)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outErrorInfo);
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardErrorInfo(out GameCardErrorInfo gameCardErrorInfo);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outErrorInfo = gameCardErrorInfo;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardErrorReportInfo(out GameCardErrorReportInfo outErrorInfo)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outErrorInfo);
|
||||
|
||||
Result rc = _fsServer.Storage.GetGameCardErrorReportInfo(out GameCardErrorReportInfo gameCardErrorReportInfo);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
outErrorInfo = gameCardErrorReportInfo;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetGameCardDeviceId(OutBuffer outBuffer, long outBufferSize)
|
||||
{
|
||||
if (outBuffer.Size < outBufferSize)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return _fsServer.Storage.GetGameCardDeviceId(GetSpan(outBuffer, outBufferSize)).Ret();
|
||||
}
|
||||
|
||||
public Result SetSpeedEmulationMode(int mode)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.SetSpeedEmulationMode))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
_fsServer.SetSpeedEmulationMode((SpeedEmulationMode)mode);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetSpeedEmulationMode(out int outMode)
|
||||
{
|
||||
outMode = (int)_fsServer.GetSpeedEmulationMode();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result SuspendSdmmcControl()
|
||||
{
|
||||
Result rc = _fsServer.Storage.SuspendSdCardControl();
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
// Missing: Detach SD card device buffer
|
||||
|
||||
rc = _fsServer.Storage.SuspendMmcControl();
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
// Missing: Detach MMC device buffer
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ResumeSdmmcControl()
|
||||
{
|
||||
// Missing: Attach MMC device buffer
|
||||
|
||||
Result rc = _fsServer.Storage.ResumeMmcControl();
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
// Missing: Attach SD card device buffer
|
||||
|
||||
rc = _fsServer.Storage.ResumeSdCardControl();
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result GetSdmmcConnectionStatus(out int outSpeedMode, out int outBusWidth, int port)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outSpeedMode, out outBusWidth);
|
||||
|
||||
if ((uint)port > (uint)Port.GcAsic0)
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
|
||||
Result rc = SdmmcSrv.Common.CheckConnection(out SpeedMode speedMode, out BusWidth busWidth, (Port)port);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
SdmmcSpeedMode sdmmcSpeedMode = speedMode switch
|
||||
{
|
||||
SpeedMode.MmcIdentification => SdmmcSpeedMode.MmcIdentification,
|
||||
SpeedMode.MmcLegacySpeed => SdmmcSpeedMode.MmcLegacySpeed,
|
||||
SpeedMode.MmcHighSpeed => SdmmcSpeedMode.MmcHighSpeed,
|
||||
SpeedMode.MmcHs200 => SdmmcSpeedMode.MmcHs200,
|
||||
SpeedMode.MmcHs400 => SdmmcSpeedMode.MmcHs400,
|
||||
SpeedMode.SdCardIdentification => SdmmcSpeedMode.SdCardIdentification,
|
||||
SpeedMode.SdCardDefaultSpeed => SdmmcSpeedMode.SdCardDefaultSpeed,
|
||||
SpeedMode.SdCardHighSpeed => SdmmcSpeedMode.SdCardHighSpeed,
|
||||
SpeedMode.SdCardSdr12 => SdmmcSpeedMode.SdCardSdr12,
|
||||
SpeedMode.SdCardSdr25 => SdmmcSpeedMode.SdCardSdr25,
|
||||
SpeedMode.SdCardSdr50 => SdmmcSpeedMode.SdCardSdr50,
|
||||
SpeedMode.SdCardSdr104 => SdmmcSpeedMode.SdCardSdr104,
|
||||
SpeedMode.SdCardDdr50 => SdmmcSpeedMode.SdCardDdr50,
|
||||
SpeedMode.GcAsicFpgaSpeed => SdmmcSpeedMode.GcAsicFpgaSpeed,
|
||||
SpeedMode.GcAsicSpeed => SdmmcSpeedMode.GcAsicSpeed,
|
||||
_ => SdmmcSpeedMode.Unknown
|
||||
};
|
||||
|
||||
SdmmcBusWidth sdmmcBusWidth = busWidth switch
|
||||
{
|
||||
BusWidth.Width1Bit => SdmmcBusWidth.Width1Bit,
|
||||
BusWidth.Width4Bit => SdmmcBusWidth.Width4Bit,
|
||||
BusWidth.Width8Bit => SdmmcBusWidth.Width8Bit,
|
||||
_ => SdmmcBusWidth.Unknown
|
||||
};
|
||||
|
||||
outSpeedMode = (int)sdmmcSpeedMode;
|
||||
outBusWidth = (int)sdmmcBusWidth;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result SetDeviceSimulationEvent(uint port, uint simulatedOperationType, uint simulatedFailureType,
|
||||
uint failureResult, bool autoClearEvent)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.SimulateDevice))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
var respondingFailureResult = new Result(failureResult);
|
||||
|
||||
switch ((Port)port)
|
||||
{
|
||||
case Port.GcAsic0:
|
||||
_fsServer.Impl.GetGameCardEventSimulator().SetDeviceEvent(
|
||||
(SimulatingDeviceTargetOperation)simulatedOperationType,
|
||||
(SimulatingDeviceAccessFailureEventType)simulatedFailureType, respondingFailureResult,
|
||||
autoClearEvent);
|
||||
break;
|
||||
case Port.SdCard0:
|
||||
_fsServer.Impl.GetSdCardEventSimulator().SetDeviceEvent(
|
||||
(SimulatingDeviceTargetOperation)simulatedOperationType,
|
||||
(SimulatingDeviceAccessFailureEventType)simulatedFailureType, respondingFailureResult,
|
||||
autoClearEvent);
|
||||
break;
|
||||
case Port.Mmc0:
|
||||
return ResultFs.NotImplemented.Log();
|
||||
default:
|
||||
return ResultFs.StorageDeviceInvalidOperation.Log();
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ClearDeviceSimulationEvent(uint port)
|
||||
{
|
||||
if (!_accessControl.CanCall(OperationType.SimulateDevice))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
switch ((Port)port)
|
||||
{
|
||||
case Port.GcAsic0:
|
||||
_fsServer.Impl.GetGameCardEventSimulator().ClearDeviceEvent();
|
||||
break;
|
||||
case Port.SdCard0:
|
||||
_fsServer.Impl.GetSdCardEventSimulator().ClearDeviceEvent();
|
||||
break;
|
||||
case Port.Mmc0:
|
||||
return ResultFs.NotImplemented.Log();
|
||||
default:
|
||||
return ResultFs.StorageDeviceInvalidOperation.Log();
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,52 @@
|
|||
using System;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Sf;
|
||||
|
||||
namespace LibHac.FsSrv.Sf;
|
||||
|
||||
public interface IDeviceOperator : IDisposable
|
||||
{
|
||||
Result IsSdCardInserted(out bool isInserted);
|
||||
Result IsGameCardInserted(out bool isInserted);
|
||||
Result GetGameCardHandle(out GameCardHandle handle);
|
||||
Result IsSdCardInserted(out bool outIsInserted);
|
||||
Result GetSdCardSpeedMode(out long outSpeedMode);
|
||||
Result GetSdCardCid(OutBuffer outBuffer, long outBufferSize);
|
||||
Result GetSdCardUserAreaSize(out long outSize);
|
||||
Result GetSdCardProtectedAreaSize(out long outSize);
|
||||
Result GetAndClearSdCardErrorInfo(out StorageErrorInfo outStorageErrorInfo, out long outLogSize, OutBuffer logBuffer, long logBufferSize);
|
||||
Result GetMmcCid(OutBuffer outBuffer, long outBufferSize);
|
||||
Result GetMmcSpeedMode(out long outSpeedMode);
|
||||
Result EraseMmc(uint partitionId);
|
||||
Result GetMmcPartitionSize(out long outSize, uint partitionId);
|
||||
Result GetMmcPatrolCount(out uint outCount);
|
||||
Result GetAndClearMmcErrorInfo(out StorageErrorInfo outStorageErrorInfo, out long outLogSize, OutBuffer logBuffer, long logBufferSize);
|
||||
Result GetMmcExtendedCsd(OutBuffer outBuffer, long outBufferSize);
|
||||
Result SuspendMmcPatrol();
|
||||
Result ResumeMmcPatrol();
|
||||
Result IsGameCardInserted(out bool outIsInserted);
|
||||
Result EraseGameCard(uint gameCardSize, ulong romAreaStartPageAddress);
|
||||
Result GetGameCardHandle(out uint outHandle);
|
||||
Result GetGameCardUpdatePartitionInfo(out uint outCupVersion, out ulong outCupId, uint handle);
|
||||
Result FinalizeGameCardDriver();
|
||||
Result GetGameCardAttribute(out byte outAttribute, uint handle);
|
||||
Result GetGameCardDeviceCertificate(OutBuffer outBuffer, long outBufferSize, uint handle);
|
||||
Result GetGameCardAsicInfo(OutBuffer outRmaInfoBuffer, long rmaInfoBufferSize, InBuffer asicFirmwareBuffer, long asicFirmwareBufferSize);
|
||||
Result GetGameCardIdSet(OutBuffer outBuffer, long outBufferSize);
|
||||
Result WriteToGameCardDirectly(long offset, OutBuffer buffer, long bufferSize);
|
||||
Result SetVerifyWriteEnableFlag(bool isEnabled);
|
||||
Result GetGameCardImageHash(OutBuffer outBuffer, long outBufferSize, uint handle);
|
||||
Result GetGameCardDeviceIdForProdCard(OutBuffer outBuffer, long outBufferSize, InBuffer devHeaderBuffer, long devHeaderBufferSize);
|
||||
Result EraseAndWriteParamDirectly(InBuffer inBuffer, long inBufferSize);
|
||||
Result ReadParamDirectly(OutBuffer outBuffer, long outBufferSize);
|
||||
Result ForceEraseGameCard();
|
||||
Result GetGameCardErrorInfo(out GameCardErrorInfo outErrorInfo);
|
||||
Result GetGameCardErrorReportInfo(out GameCardErrorReportInfo outErrorInfo);
|
||||
Result GetGameCardDeviceId(OutBuffer outBuffer, long outBufferSize);
|
||||
Result ChallengeCardExistence(OutBuffer outResponseBuffer, InBuffer challengeSeedBuffer, InBuffer challengeValueBuffer, uint handle);
|
||||
Result GetGameCardCompatibilityType(out byte outCompatibilityType, uint handle);
|
||||
Result SetSpeedEmulationMode(int mode);
|
||||
Result GetSpeedEmulationMode(out int outMode);
|
||||
Result SuspendSdmmcControl();
|
||||
Result ResumeSdmmcControl();
|
||||
Result GetSdmmcConnectionStatus(out int outSpeedMode, out int outBusWidth, int port);
|
||||
Result SetDeviceSimulationEvent(uint port, uint simulatedOperationType, uint simulatedFailureType, uint failureResult, bool autoClearEvent);
|
||||
Result ClearDeviceSimulationEvent(uint port);
|
||||
}
|
26
src/LibHac/FsSystem/SpeedEmulationConfiguration.cs
Normal file
26
src/LibHac/FsSystem/SpeedEmulationConfiguration.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using LibHac.Fs;
|
||||
using LibHac.FsSrv;
|
||||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
internal struct SpeedEmulationConfigurationGlobals
|
||||
{
|
||||
public SpeedEmulationMode SpeedEmulationMode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles getting and setting the configuration for storage speed emulation.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 14.3.0</remarks>
|
||||
internal static class SpeedEmulationConfiguration
|
||||
{
|
||||
public static void SetSpeedEmulationMode(this FileSystemServer fsServer, SpeedEmulationMode mode)
|
||||
{
|
||||
fsServer.Globals.SpeedEmulationConfiguration.SpeedEmulationMode = mode;
|
||||
}
|
||||
|
||||
public static SpeedEmulationMode GetSpeedEmulationMode(this FileSystemServer fsServer)
|
||||
{
|
||||
return fsServer.Globals.SpeedEmulationConfiguration.SpeedEmulationMode;
|
||||
}
|
||||
}
|
14
src/LibHac/SdmmcSrv/Common.cs
Normal file
14
src/LibHac/SdmmcSrv/Common.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using LibHac.Sdmmc;
|
||||
|
||||
namespace LibHac.SdmmcSrv;
|
||||
|
||||
public static class Common
|
||||
{
|
||||
public static Result CheckConnection(out SpeedMode outSpeedMode, out BusWidth outBusWidth, Port port)
|
||||
{
|
||||
outSpeedMode = default;
|
||||
outBusWidth = default;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
|
@ -13,6 +13,11 @@ public static class IntUtil
|
|||
return value >= 0;
|
||||
}
|
||||
|
||||
public static bool IsIntValueRepresentableAsInt(long value)
|
||||
{
|
||||
return value >= int.MinValue && value <= int.MaxValue;
|
||||
}
|
||||
|
||||
public static bool IsIntValueRepresentableAsUInt(long value)
|
||||
{
|
||||
return value >= uint.MinValue && value <= uint.MaxValue;
|
||||
|
|
Loading…
Reference in a new issue