Ensure all of Shim.SaveDataManagement is updated for 13.1.0

This commit is contained in:
Alex Barney 2022-01-18 20:45:48 -07:00
parent dc2a1cfaef
commit 74ed435dee
12 changed files with 2230 additions and 1845 deletions

View file

@ -1135,5 +1135,33 @@ namespace LibHac.Fs.Impl
(byte)',', (byte)' ', (byte)'f', (byte)'u', (byte)'n', (byte)'c', (byte)'t', (byte)'i',
(byte)'o', (byte)'n', (byte)':', (byte)' ', (byte)'"'
};
/// <summary>"<c>, cachestoragelist_handle: 0x</c>"</summary>
public static ReadOnlySpan<byte> LogCacheStorageListHandle =>
new[]
{
(byte)',', (byte)' ', (byte)'c', (byte)'a', (byte)'c', (byte)'h', (byte)'e', (byte)'s',
(byte)'t', (byte)'o', (byte)'r', (byte)'a', (byte)'g', (byte)'e', (byte)'l', (byte)'i',
(byte)'s', (byte)'t', (byte)'_', (byte)'h', (byte)'a', (byte)'n', (byte)'d', (byte)'l',
(byte)'e', (byte)':', (byte)' ', (byte)'0', (byte)'x'
};
/// <summary>"<c>, infobuffercount: 0x</c>"</summary>
public static ReadOnlySpan<byte> LogInfoBufferCount =>
new[]
{
(byte)',', (byte)' ', (byte)'i', (byte)'n', (byte)'f', (byte)'o', (byte)'b', (byte)'u',
(byte)'f', (byte)'f', (byte)'e', (byte)'r', (byte)'c', (byte)'o', (byte)'u', (byte)'n',
(byte)'t', (byte)':', (byte)' ', (byte)'0', (byte)'x'
};
/// <summary>"<c>, cache_storage_count: </c>"</summary>
public static ReadOnlySpan<byte> LogCacheStorageCount =>
new[]
{
(byte)',', (byte)' ', (byte)'c', (byte)'a', (byte)'c', (byte)'h', (byte)'e', (byte)'_',
(byte)'s', (byte)'t', (byte)'o', (byte)'r', (byte)'a', (byte)'g', (byte)'e', (byte)'_',
(byte)'c', (byte)'o', (byte)'u', (byte)'n', (byte)'t', (byte)':', (byte)' '
};
}
}

View file

@ -29,7 +29,7 @@ public static class ApplicationSaveDataManagement
Result CreateAccountSaveFunc()
{
UserId userId = ConvertAccountUidToFsUserId(uidLocal);
UserId userId = Utility.ConvertAccountUidToFsUserId(uidLocal);
return fs.CreateSaveData(applicationId, userId, saveDataOwnerId, accountSaveDataSize,
accountSaveJournalSize, SaveDataFlags.None);
}
@ -465,9 +465,4 @@ public static class ApplicationSaveDataManagement
return rc;
}
public static UserId ConvertAccountUidToFsUserId(Uid uid)
{
return new UserId(uid.Id.High, uid.Id.Low);
}
}

View file

@ -0,0 +1,19 @@
using LibHac.Common.FixedArrays;
namespace LibHac.Fs;
public readonly struct CacheStorageListHandle
{
internal readonly object Cache;
internal CacheStorageListHandle(object cache)
{
Cache = cache;
}
}
public struct CacheStorageInfo
{
public int Index;
public Array28<byte> Reserved;
}

File diff suppressed because it is too large Load diff

50
src/LibHac/Fs/Utility.cs Normal file
View file

@ -0,0 +1,50 @@
using System;
using LibHac.Account;
using LibHac.Os;
namespace LibHac.Fs;
/// <summary>
/// Contains various utility functions used by FS client code.
/// </summary>
/// <remarks>Based on nnSdk 13.4.0</remarks>
public static class Utility
{
public static UserId ConvertAccountUidToFsUserId(Uid uid)
{
return new UserId(uid.Id.High, uid.Id.Low);
}
public static Result CheckUid(HorizonClient hos, Uid uid)
{
throw new NotImplementedException();
}
public static Result DoContinuouslyUntilSaveDataListFetched(HorizonClient hos, Func<Result> listGetter)
{
const int maxTryCount = 5;
const int initialSleepTimeMs = 5;
const int sleepTimeMultiplier = 2;
Result lastResult = Result.Success;
long sleepTime = initialSleepTimeMs;
for (int i = 0; i < maxTryCount; i++)
{
Result rc = listGetter();
if (rc.IsSuccess())
return rc;
// Try again if any save data were added or removed while getting the list
if (!ResultFs.InvalidHandle.Includes(rc))
return rc.Miss();
lastResult = rc;
hos.Os.SleepThread(TimeSpan.FromMilliSeconds(sleepTime));
sleepTime *= sleepTimeMultiplier;
}
return lastResult.Log();
}
}

View file

@ -6,7 +6,8 @@ using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using LibHac.FsSrv.FsCreator;
using LibHac.FsSrv.Impl;
using Utility = LibHac.FsSrv.Impl.Utility;
namespace LibHac.FsSrv;

View file

@ -2,7 +2,8 @@
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSrv.Impl;
using Utility = LibHac.FsSrv.Impl.Utility;
namespace LibHac.FsSrv.FsCreator;

View file

@ -2,9 +2,10 @@
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSrv.Impl;
using LibHac.Util;
using Utility = LibHac.FsSrv.Impl.Utility;
namespace LibHac.FsSrv.FsCreator;
public class EmulatedSdCardFileSystemCreator : ISdCardProxyFileSystemCreator, IDisposable

View file

@ -10,6 +10,7 @@ using LibHac.FsSystem;
using LibHac.Tools.Fs;
using LibHac.Util;
using Path = LibHac.Fs.Path;
using Utility = LibHac.FsSystem.Utility;
namespace LibHac.Tools.FsSystem;

View file

@ -35,7 +35,7 @@ public class ApplicationSaveDataManagementTests
Assert.Equal(1, entriesRead);
Assert.Equal(applicationId, info[0].ProgramId);
Assert.Equal(ConvertAccountUidToFsUserId(userId), info[0].UserId);
Assert.Equal(Utility.ConvertAccountUidToFsUserId(userId), info[0].UserId);
Assert.Equal(SaveDataType.Account, info[0].Type);
}

View file

@ -577,6 +577,73 @@ public class SaveDataManagement
Assert.Equal(timeStamp, actualTimeStamp);
}
[Fact]
public void OpenCacheStorageList_ReadIntoLargeBuffer_AllIndexesAreRead()
{
var applicationId = new Ncm.ApplicationId(1);
Horizon hos = HorizonFactory.CreateBasicHorizon();
HorizonClient client = hos.CreateHorizonClient(new ProgramLocation(applicationId, StorageId.BuiltInSystem),
(AccessControlBits.Bits)ulong.MaxValue);
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 0, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 6, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 2, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 3, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.OpenCacheStorageList(out CacheStorageListHandle handle));
var infoBuffer = new CacheStorageInfo[5];
Assert.Success(client.Fs.ReadCacheStorageList(out int readCount, infoBuffer, handle));
Assert.Equal(4, readCount);
Assert.Equal(0, infoBuffer[0].Index);
Assert.Equal(2, infoBuffer[1].Index);
Assert.Equal(3, infoBuffer[2].Index);
Assert.Equal(6, infoBuffer[3].Index);
client.Fs.CloseCacheStorageList(handle);
}
[Fact]
public void OpenCacheStorageList_ReadIntoMultipleBuffers_AllIndexesAreRead()
{
var applicationId = new Ncm.ApplicationId(1);
Horizon hos = HorizonFactory.CreateBasicHorizon();
HorizonClient client = hos.CreateHorizonClient(new ProgramLocation(applicationId, StorageId.BuiltInSystem),
(AccessControlBits.Bits)ulong.MaxValue);
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 0, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 6, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 2, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 3, 0, 0, SaveDataFlags.None));
Assert.Success(client.Fs.OpenCacheStorageList(out CacheStorageListHandle handle));
var infoBuffer = new CacheStorageInfo[2];
Assert.Success(client.Fs.ReadCacheStorageList(out int readCount, infoBuffer, handle));
Assert.Equal(2, readCount);
Assert.Equal(0, infoBuffer[0].Index);
Assert.Equal(2, infoBuffer[1].Index);
Assert.Success(client.Fs.ReadCacheStorageList(out readCount, infoBuffer, handle));
Assert.Equal(2, readCount);
Assert.Equal(3, infoBuffer[0].Index);
Assert.Equal(6, infoBuffer[1].Index);
Assert.Success(client.Fs.ReadCacheStorageList(out readCount, infoBuffer, handle));
Assert.Equal(0, readCount);
client.Fs.CloseCacheStorageList(handle);
}
private static Result PopulateSaveData(FileSystemClient fs, int count, int seed = -1)
{
if (seed == -1)

View file

@ -354,4 +354,15 @@ public class TypeLayoutTests
Assert.Equal(3, GetOffset(in s, in s.CompressionRate));
Assert.Equal(4, GetOffset(in s, in s.Reserved));
}
[Fact]
public static void CacheStorageInfo_Layout()
{
var s = new CacheStorageInfo();
Assert.Equal(0x20, Unsafe.SizeOf<CacheStorageInfo>());
Assert.Equal(0, GetOffset(in s, in s.Index));
Assert.Equal(4, GetOffset(in s, in s.Reserved));
}
}