mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Ensure all of Shim.SaveDataManagement is updated for 13.1.0
This commit is contained in:
parent
dc2a1cfaef
commit
74ed435dee
12 changed files with 2230 additions and 1845 deletions
|
@ -1135,5 +1135,33 @@ namespace LibHac.Fs.Impl
|
||||||
(byte)',', (byte)' ', (byte)'f', (byte)'u', (byte)'n', (byte)'c', (byte)'t', (byte)'i',
|
(byte)',', (byte)' ', (byte)'f', (byte)'u', (byte)'n', (byte)'c', (byte)'t', (byte)'i',
|
||||||
(byte)'o', (byte)'n', (byte)':', (byte)' ', (byte)'"'
|
(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)' '
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@ public static class ApplicationSaveDataManagement
|
||||||
|
|
||||||
Result CreateAccountSaveFunc()
|
Result CreateAccountSaveFunc()
|
||||||
{
|
{
|
||||||
UserId userId = ConvertAccountUidToFsUserId(uidLocal);
|
UserId userId = Utility.ConvertAccountUidToFsUserId(uidLocal);
|
||||||
return fs.CreateSaveData(applicationId, userId, saveDataOwnerId, accountSaveDataSize,
|
return fs.CreateSaveData(applicationId, userId, saveDataOwnerId, accountSaveDataSize,
|
||||||
accountSaveJournalSize, SaveDataFlags.None);
|
accountSaveJournalSize, SaveDataFlags.None);
|
||||||
}
|
}
|
||||||
|
@ -465,9 +465,4 @@ public static class ApplicationSaveDataManagement
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserId ConvertAccountUidToFsUserId(Uid uid)
|
|
||||||
{
|
|
||||||
return new UserId(uid.Id.High, uid.Id.Low);
|
|
||||||
}
|
|
||||||
}
|
}
|
19
src/LibHac/Fs/CacheStorageTypes.cs
Normal file
19
src/LibHac/Fs/CacheStorageTypes.cs
Normal 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
50
src/LibHac/Fs/Utility.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,8 @@ using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.Fs.Shim;
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSrv.FsCreator;
|
using LibHac.FsSrv.FsCreator;
|
||||||
using LibHac.FsSrv.Impl;
|
|
||||||
|
using Utility = LibHac.FsSrv.Impl.Utility;
|
||||||
|
|
||||||
namespace LibHac.FsSrv;
|
namespace LibHac.FsSrv;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.FsSrv.Impl;
|
|
||||||
|
using Utility = LibHac.FsSrv.Impl.Utility;
|
||||||
|
|
||||||
namespace LibHac.FsSrv.FsCreator;
|
namespace LibHac.FsSrv.FsCreator;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.FsSrv.Impl;
|
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
|
|
||||||
|
using Utility = LibHac.FsSrv.Impl.Utility;
|
||||||
|
|
||||||
namespace LibHac.FsSrv.FsCreator;
|
namespace LibHac.FsSrv.FsCreator;
|
||||||
|
|
||||||
public class EmulatedSdCardFileSystemCreator : ISdCardProxyFileSystemCreator, IDisposable
|
public class EmulatedSdCardFileSystemCreator : ISdCardProxyFileSystemCreator, IDisposable
|
||||||
|
|
|
@ -10,6 +10,7 @@ using LibHac.FsSystem;
|
||||||
using LibHac.Tools.Fs;
|
using LibHac.Tools.Fs;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
using Path = LibHac.Fs.Path;
|
using Path = LibHac.Fs.Path;
|
||||||
|
using Utility = LibHac.FsSystem.Utility;
|
||||||
|
|
||||||
namespace LibHac.Tools.FsSystem;
|
namespace LibHac.Tools.FsSystem;
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class ApplicationSaveDataManagementTests
|
||||||
|
|
||||||
Assert.Equal(1, entriesRead);
|
Assert.Equal(1, entriesRead);
|
||||||
Assert.Equal(applicationId, info[0].ProgramId);
|
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);
|
Assert.Equal(SaveDataType.Account, info[0].Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -577,6 +577,73 @@ public class SaveDataManagement
|
||||||
Assert.Equal(timeStamp, actualTimeStamp);
|
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)
|
private static Result PopulateSaveData(FileSystemClient fs, int count, int seed = -1)
|
||||||
{
|
{
|
||||||
if (seed == -1)
|
if (seed == -1)
|
||||||
|
|
|
@ -354,4 +354,15 @@ public class TypeLayoutTests
|
||||||
Assert.Equal(3, GetOffset(in s, in s.CompressionRate));
|
Assert.Equal(3, GetOffset(in s, in s.CompressionRate));
|
||||||
Assert.Equal(4, GetOffset(in s, in s.Reserved));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue