diff --git a/src/LibHac/Arp/ApplicationLaunchProperty.cs b/src/LibHac/Arp/ApplicationLaunchProperty.cs index 4d73db27..3477555b 100644 --- a/src/LibHac/Arp/ApplicationLaunchProperty.cs +++ b/src/LibHac/Arp/ApplicationLaunchProperty.cs @@ -1,12 +1,16 @@ -using System.Runtime.InteropServices; +namespace LibHac.Arp; -namespace LibHac.Arp; - -[StructLayout(LayoutKind.Explicit, Size = 0x10)] public struct ApplicationLaunchProperty { - [FieldOffset(0x0)] public ApplicationId ApplicationId; - [FieldOffset(0x8)] public uint Version; - [FieldOffset(0xC)] public Ncm.StorageId BaseStorageId; - [FieldOffset(0xD)] public Ncm.StorageId UpdateStorageId; + public ApplicationId ApplicationId; + public uint Version; + public Ncm.StorageId StorageId; + public Ncm.StorageId PatchStorageId; + public ApplicationKind ApplicationKind; } + +public enum ApplicationKind : byte +{ + Application = 0, + MicroApplication = 1 +} \ No newline at end of file diff --git a/src/LibHac/Bcat/DeliveryCacheDirectoryEntry.cs b/src/LibHac/Bcat/DeliveryCacheDirectoryEntry.cs index ea81f9ef..2b18afbd 100644 --- a/src/LibHac/Bcat/DeliveryCacheDirectoryEntry.cs +++ b/src/LibHac/Bcat/DeliveryCacheDirectoryEntry.cs @@ -1,18 +1,15 @@ -using System.Runtime.InteropServices; +namespace LibHac.Bcat; -namespace LibHac.Bcat; - -[StructLayout(LayoutKind.Explicit, Size = 0x38)] public struct DeliveryCacheDirectoryEntry { - [FieldOffset(0x00)] public FileName Name; - [FieldOffset(0x20)] public long Size; - [FieldOffset(0x28)] public Digest Digest; + public FileName Name; + public long Size; + public Digest Digest; - public DeliveryCacheDirectoryEntry(ref FileName name, long size, ref Digest digest) + public DeliveryCacheDirectoryEntry(in FileName name, long size, in Digest digest) { Name = name; Size = size; Digest = digest; } -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Digest.cs b/src/LibHac/Bcat/Digest.cs index 241e970e..108ef0aa 100644 --- a/src/LibHac/Bcat/Digest.cs +++ b/src/LibHac/Bcat/Digest.cs @@ -1,28 +1,16 @@ -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using LibHac.Common; +using System.Diagnostics; +using LibHac.Common.FixedArrays; using LibHac.Util; namespace LibHac.Bcat; [DebuggerDisplay("{ToString()}")] -[StructLayout(LayoutKind.Sequential, Size = 16)] public struct Digest { - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1; + public Array16 Value; - public byte this[int i] + public readonly override string ToString() { - get => Bytes[i]; - set => Bytes[i] = value; + return Value.ItemsRo.ToHexString(); } - - public Span Bytes => SpanHelpers.AsByteSpan(ref this); - - public override string ToString() - { - return Bytes.ToHexString(); - } -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/DirectoryName.cs b/src/LibHac/Bcat/DirectoryName.cs index fb0497cd..990daeeb 100644 --- a/src/LibHac/Bcat/DirectoryName.cs +++ b/src/LibHac/Bcat/DirectoryName.cs @@ -1,33 +1,20 @@ using System; using System.Diagnostics; -using System.Runtime.InteropServices; -using LibHac.Common; +using LibHac.Common.FixedArrays; using LibHac.Util; namespace LibHac.Bcat; [DebuggerDisplay("{ToString()}")] -[StructLayout(LayoutKind.Sequential, Size = MaxSize)] public struct DirectoryName { private const int MaxSize = 0x20; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy2; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy3; + public Array32 Value; - public byte this[int i] + public readonly bool IsValid() { - get => Bytes[i]; - set => Bytes[i] = value; - } - - public Span Bytes => SpanHelpers.AsByteSpan(ref this); - - public bool IsValid() - { - Span name = Bytes; + ReadOnlySpan name = Value.ItemsRo; int i; for (i = 0; i < name.Length; i++) @@ -45,8 +32,8 @@ public struct DirectoryName return name[i] == 0; } - public override string ToString() + public readonly override string ToString() { - return StringUtils.Utf8ZToString(Bytes); + return StringUtils.Utf8ZToString(Value.ItemsRo); } -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/FileName.cs b/src/LibHac/Bcat/FileName.cs index 91c2d3a3..3c35004f 100644 --- a/src/LibHac/Bcat/FileName.cs +++ b/src/LibHac/Bcat/FileName.cs @@ -1,33 +1,20 @@ using System; using System.Diagnostics; -using System.Runtime.InteropServices; -using LibHac.Common; +using LibHac.Common.FixedArrays; using LibHac.Util; namespace LibHac.Bcat; [DebuggerDisplay("{ToString()}")] -[StructLayout(LayoutKind.Sequential, Size = MaxSize)] public struct FileName { private const int MaxSize = 0x20; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy2; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy3; + public Array32 Value; - public byte this[int i] + public readonly bool IsValid() { - get => Bytes[i]; - set => Bytes[i] = value; - } - - public Span Bytes => SpanHelpers.AsByteSpan(ref this); - - public bool IsValid() - { - Span name = Bytes; + ReadOnlySpan name = Value.ItemsRo; int i; for (i = 0; i < name.Length; i++) @@ -48,8 +35,8 @@ public struct FileName return name[i - 1] != '.'; } - public override string ToString() + public readonly override string ToString() { - return StringUtils.Utf8ZToString(Bytes); + return StringUtils.Utf8ZToString(Value.ItemsRo); } -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheDirectoryMetaEntry.cs b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheDirectoryMetaEntry.cs index 837650bd..117cafb9 100644 --- a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheDirectoryMetaEntry.cs +++ b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheDirectoryMetaEntry.cs @@ -1,10 +1,10 @@ -using System.Runtime.InteropServices; +using LibHac.Common.FixedArrays; namespace LibHac.Bcat.Impl.Service.Core; -[StructLayout(LayoutKind.Explicit, Size = 0x40)] internal struct DeliveryCacheDirectoryMetaEntry { - [FieldOffset(0x00)] public DirectoryName Name; - [FieldOffset(0x20)] public Digest Digest; -} + public DirectoryName Name; + public Digest Digest; + public Array16 Reserved; +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaAccessor.cs b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaAccessor.cs index 32efa93c..14520c29 100644 --- a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaAccessor.cs +++ b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaAccessor.cs @@ -56,7 +56,7 @@ internal class DeliveryCacheFileMetaAccessor { for (int i = 0; i < Count; i++) { - if (StringUtils.CompareCaseInsensitive(Entries[i].Name.Bytes, fileName.Bytes) == 0) + if (StringUtils.CompareCaseInsensitive(Entries[i].Name.Value, fileName.Value) == 0) { entry = Entries[i]; return Result.Success; @@ -118,4 +118,4 @@ internal class DeliveryCacheFileMetaAccessor } } } -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaEntry.cs b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaEntry.cs index d049f426..13fe72ce 100644 --- a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaEntry.cs +++ b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheFileMetaEntry.cs @@ -1,12 +1,12 @@ -using System.Runtime.InteropServices; +using LibHac.Common.FixedArrays; namespace LibHac.Bcat.Impl.Service.Core; -[StructLayout(LayoutKind.Explicit, Size = 0x80)] internal struct DeliveryCacheFileMetaEntry { - [FieldOffset(0x00)] public FileName Name; - [FieldOffset(0x20)] public long Id; - [FieldOffset(0x28)] public long Size; - [FieldOffset(0x30)] public Digest Digest; -} + public FileName Name; + public long Id; + public long Size; + public Digest Digest; + public Array64 Reserved; +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheStorageManager.cs b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheStorageManager.cs index c2d085d6..c10712b3 100644 --- a/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheStorageManager.cs +++ b/src/LibHac/Bcat/Impl/Service/Core/DeliveryCacheStorageManager.cs @@ -222,9 +222,9 @@ internal class DeliveryCacheStorageManager AppendMountName(ref sb, applicationId); sb.Append(DirectoriesPath) - .Append(DirectorySeparator).Append(directoryName.Bytes) + .Append(DirectorySeparator).Append(directoryName.Value) .Append(DirectorySeparator).Append(FilesDirectoryName) - .Append(DirectorySeparator).Append(fileName.Bytes); + .Append(DirectorySeparator).Append(fileName.Value); } } @@ -237,7 +237,7 @@ internal class DeliveryCacheStorageManager AppendMountName(ref sb, applicationId); sb.Append(DirectoriesPath) - .Append(DirectorySeparator).Append(directoryName.Bytes) + .Append(DirectorySeparator).Append(directoryName.Value) .Append(DirectorySeparator).Append(FilesMetaFileName); } } @@ -262,7 +262,7 @@ internal class DeliveryCacheStorageManager AppendMountName(ref sb, applicationId); sb.Append(DirectoriesPath) - .Append(DirectorySeparator).Append(directoryName.Bytes); + .Append(DirectorySeparator).Append(directoryName.Value); } } @@ -395,4 +395,4 @@ internal class DeliveryCacheStorageManager private static ReadOnlySpan FilesDirectoryName => // files new[] { (byte)'f', (byte)'i', (byte)'l', (byte)'e', (byte)'s' }; -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Impl/Service/DeliveryCacheDirectoryService.cs b/src/LibHac/Bcat/Impl/Service/DeliveryCacheDirectoryService.cs index 59e10aa5..586905a8 100644 --- a/src/LibHac/Bcat/Impl/Service/DeliveryCacheDirectoryService.cs +++ b/src/LibHac/Bcat/Impl/Service/DeliveryCacheDirectoryService.cs @@ -75,7 +75,7 @@ internal class DeliveryCacheDirectoryService : IDeliveryCacheDirectoryService break; } - entryBuffer[i] = new DeliveryCacheDirectoryEntry(ref entry.Name, entry.Size, ref entry.Digest); + entryBuffer[i] = new DeliveryCacheDirectoryEntry(in entry.Name, entry.Size, in entry.Digest); } entriesRead = i; @@ -103,4 +103,4 @@ internal class DeliveryCacheDirectoryService : IDeliveryCacheDirectoryService { Parent.NotifyCloseDirectory(); } -} +} \ No newline at end of file diff --git a/src/LibHac/Bcat/Impl/Service/DeliveryCacheStorageService.cs b/src/LibHac/Bcat/Impl/Service/DeliveryCacheStorageService.cs index 09fe2fb6..bfd95f59 100644 --- a/src/LibHac/Bcat/Impl/Service/DeliveryCacheStorageService.cs +++ b/src/LibHac/Bcat/Impl/Service/DeliveryCacheStorageService.cs @@ -76,7 +76,7 @@ internal class DeliveryCacheStorageService : IDeliveryCacheStorageService break; } - StringUtils.Copy(nameBuffer[i].Bytes, entry.Name.Bytes); + StringUtils.Copy(nameBuffer[i].Value.Items, entry.Name.Value); } namesRead = i; @@ -108,4 +108,4 @@ internal class DeliveryCacheStorageService : IDeliveryCacheStorageService { Server.GetStorageManager().Release(ApplicationId); } -} +} \ No newline at end of file diff --git a/src/LibHac/Common/FixedArrays/Array11.cs b/src/LibHac/Common/FixedArrays/Array11.cs new file mode 100644 index 00000000..251d6c68 --- /dev/null +++ b/src/LibHac/Common/FixedArrays/Array11.cs @@ -0,0 +1,30 @@ +#pragma warning disable CS0169, IDE0051 // Remove unused private members +using System; +using System.Runtime.CompilerServices; + +namespace LibHac.Common.FixedArrays; + +public struct Array11 +{ + public const int Length = 11; + + private T _1; + private T _2; + private T _3; + private T _4; + private T _5; + private T _6; + private T _7; + private T _8; + private T _9; + private T _10; + private T _11; + + public ref T this[int i] => ref Items[i]; + + public Span Items => SpanHelpers.CreateSpan(ref _1, Length); + public readonly ReadOnlySpan ItemsRo => SpanHelpers.CreateReadOnlySpan(in _1, Length); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator ReadOnlySpan(in Array11 value) => value.ItemsRo; +} \ No newline at end of file diff --git a/src/LibHac/Common/FixedArrays/Array24.cs b/src/LibHac/Common/FixedArrays/Array24.cs new file mode 100644 index 00000000..d4d833b4 --- /dev/null +++ b/src/LibHac/Common/FixedArrays/Array24.cs @@ -0,0 +1,31 @@ +#pragma warning disable CS0169, IDE0051 // Remove unused private members +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace LibHac.Common.FixedArrays; + +public struct Array24 +{ + public const int Length = 24; + + private Array16 _0; + private Array8 _16; + + public ref T this[int i] => ref Items[i]; + + public Span Items + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length); + } + + public readonly ReadOnlySpan ItemsRo + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator ReadOnlySpan(in Array24 value) => value.ItemsRo; +} \ No newline at end of file diff --git a/src/LibHac/Common/FixedArrays/Array26.cs b/src/LibHac/Common/FixedArrays/Array26.cs new file mode 100644 index 00000000..d447ae69 --- /dev/null +++ b/src/LibHac/Common/FixedArrays/Array26.cs @@ -0,0 +1,32 @@ +#pragma warning disable CS0169, IDE0051 // Remove unused private members +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace LibHac.Common.FixedArrays; + +public struct Array26 +{ + public const int Length = 26; + + private Array16 _0; + private Array8 _16; + private Array2 _24; + + public ref T this[int i] => ref Items[i]; + + public Span Items + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length); + } + + public readonly ReadOnlySpan ItemsRo + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator ReadOnlySpan(in Array26 value) => value.ItemsRo; +} \ No newline at end of file diff --git a/src/LibHac/Common/FixedArrays/Array36.cs b/src/LibHac/Common/FixedArrays/Array36.cs new file mode 100644 index 00000000..dae2d49f --- /dev/null +++ b/src/LibHac/Common/FixedArrays/Array36.cs @@ -0,0 +1,31 @@ +#pragma warning disable CS0169, IDE0051 // Remove unused private members +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace LibHac.Common.FixedArrays; + +public struct Array36 +{ + public const int Length = 36; + + private Array32 _0; + private Array4 _32; + + public ref T this[int i] => ref Items[i]; + + public Span Items + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length); + } + + public readonly ReadOnlySpan ItemsRo + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator ReadOnlySpan(in Array36 value) => value.ItemsRo; +} \ No newline at end of file diff --git a/src/LibHac/Common/FixedArrays/Array400.cs b/src/LibHac/Common/FixedArrays/Array400.cs new file mode 100644 index 00000000..4287386a --- /dev/null +++ b/src/LibHac/Common/FixedArrays/Array400.cs @@ -0,0 +1,32 @@ +#pragma warning disable CS0169, IDE0051 // Remove unused private members +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace LibHac.Common.FixedArrays; + +public struct Array400 +{ + public const int Length = 400; + + private Array256 _0; + private Array128 _256; + private Array16 _384; + + public ref T this[int i] => ref Items[i]; + + public Span Items + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length); + } + + public readonly ReadOnlySpan ItemsRo + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator ReadOnlySpan(in Array400 value) => value.ItemsRo; +} \ No newline at end of file diff --git a/src/LibHac/Fs/MemoryReportInfo.cs b/src/LibHac/Fs/MemoryReportInfo.cs index dd199c74..1f69acf3 100644 --- a/src/LibHac/Fs/MemoryReportInfo.cs +++ b/src/LibHac/Fs/MemoryReportInfo.cs @@ -1,8 +1,7 @@ -using System.Runtime.InteropServices; +using LibHac.Common.FixedArrays; namespace LibHac.Fs; -[StructLayout(LayoutKind.Sequential, Size = 0x80)] public struct MemoryReportInfo { public long PooledBufferFreeSizePeak; @@ -12,8 +11,10 @@ public struct MemoryReportInfo public long BufferManagerRetriedCount; public long ExpHeapFreeSizePeak; public long BufferPoolFreeSizePeak; - public long PatrolAllocateSuccessCount; - public long PatrolAllocateFailureCount; + public long PatrolReadAllocateBufferSuccessCount; + public long PatrolReadAllocateBufferFailureCount; public long BufferManagerTotalAllocatableSizePeak; public long BufferPoolAllocateSizeMax; -} + public long PooledBufferFailedIdealAllocationCountOnAsyncAccess; + public Array32 Reserved; +} \ No newline at end of file diff --git a/src/LibHac/Fs/SaveDataStructs.cs b/src/LibHac/Fs/SaveDataStructs.cs index 6a691612..6aa64c51 100644 --- a/src/LibHac/Fs/SaveDataStructs.cs +++ b/src/LibHac/Fs/SaveDataStructs.cs @@ -1,21 +1,21 @@ using System; -using System.Runtime.InteropServices; using LibHac.Common; +using LibHac.Common.FixedArrays; using LibHac.FsSrv.Impl; using LibHac.Ncm; using LibHac.Util; namespace LibHac.Fs; -[StructLayout(LayoutKind.Explicit, Size = 0x40)] public struct SaveDataAttribute : IEquatable, IComparable { - [FieldOffset(0x00)] public ProgramId ProgramId; - [FieldOffset(0x08)] public UserId UserId; - [FieldOffset(0x18)] public ulong StaticSaveDataId; - [FieldOffset(0x20)] public SaveDataType Type; - [FieldOffset(0x21)] public SaveDataRank Rank; - [FieldOffset(0x22)] public ushort Index; + public ProgramId ProgramId; + public UserId UserId; + public ulong StaticSaveDataId; + public SaveDataType Type; + public SaveDataRank Rank; + public ushort Index; + public Array24 Reserved; public SaveDataAttribute(ProgramId programId, SaveDataType type, UserId userId, ulong saveDataId) : this( programId, type, userId, saveDataId, 0, SaveDataRank.Primary) @@ -34,6 +34,7 @@ public struct SaveDataAttribute : IEquatable, IComparable(); } public static Result Make(out SaveDataAttribute attribute, ProgramId programId, SaveDataType type, @@ -109,16 +110,16 @@ public struct SaveDataAttribute : IEquatable, IComparable Reserved; public static Result Make(out SaveDataCreationInfo creationInfo, long size, long journalSize, ulong ownerId, SaveDataFlags flags, SaveDataSpaceId spaceId) @@ -142,17 +143,16 @@ public struct SaveDataCreationInfo } } -[StructLayout(LayoutKind.Explicit, Size = 0x48)] public struct SaveDataFilter { - [FieldOffset(0x00)] public bool FilterByProgramId; - [FieldOffset(0x01)] public bool FilterBySaveDataType; - [FieldOffset(0x02)] public bool FilterByUserId; - [FieldOffset(0x03)] public bool FilterBySaveDataId; - [FieldOffset(0x04)] public bool FilterByIndex; - [FieldOffset(0x05)] public SaveDataRank Rank; + public bool FilterByProgramId; + public bool FilterBySaveDataType; + public bool FilterByUserId; + public bool FilterBySaveDataId; + public bool FilterByIndex; + public SaveDataRank Rank; - [FieldOffset(0x08)] public SaveDataAttribute Attribute; + public SaveDataAttribute Attribute; public void SetProgramId(ProgramId value) { @@ -245,49 +245,46 @@ public struct SaveDataFilter } } -[StructLayout(LayoutKind.Explicit, Size = HashLength)] public struct HashSalt { - private const int HashLength = 0x20; + private Array32 _value; - [FieldOffset(0x00)] private byte _hashStart; - - public Span Hash => SpanHelpers.CreateSpan(ref _hashStart, HashLength); - public ReadOnlySpan HashRo => SpanHelpers.CreateReadOnlySpan(in _hashStart, HashLength); + public Span Hash => _value.Items; + public readonly ReadOnlySpan HashRo => _value.ItemsRo; } -[StructLayout(LayoutKind.Explicit, Size = 0x10)] public struct SaveDataMetaInfo { - [FieldOffset(0)] public int Size; - [FieldOffset(4)] public SaveDataMetaType Type; + public int Size; + public SaveDataMetaType Type; + public Array11 Reserved; } -[StructLayout(LayoutKind.Explicit, Size = 0x60)] public struct SaveDataInfo { - [FieldOffset(0x00)] public ulong SaveDataId; - [FieldOffset(0x08)] public SaveDataSpaceId SpaceId; - [FieldOffset(0x09)] public SaveDataType Type; - [FieldOffset(0x10)] public UserId UserId; - [FieldOffset(0x20)] public ulong StaticSaveDataId; - [FieldOffset(0x28)] public ProgramId ProgramId; - [FieldOffset(0x30)] public long Size; - [FieldOffset(0x38)] public ushort Index; - [FieldOffset(0x3A)] public SaveDataRank Rank; - [FieldOffset(0x3B)] public SaveDataState State; + public ulong SaveDataId; + public SaveDataSpaceId SpaceId; + public SaveDataType Type; + public UserId UserId; + public ulong StaticSaveDataId; + public ProgramId ProgramId; + public long Size; + public ushort Index; + public SaveDataRank Rank; + public SaveDataState State; + public Array36 Reserved; } -[StructLayout(LayoutKind.Explicit, Size = 0x200)] public struct SaveDataExtraData { - [FieldOffset(0x00)] public SaveDataAttribute Attribute; - [FieldOffset(0x40)] public ulong OwnerId; - [FieldOffset(0x48)] public long TimeStamp; - [FieldOffset(0x50)] public SaveDataFlags Flags; - [FieldOffset(0x58)] public long DataSize; - [FieldOffset(0x60)] public long JournalSize; - [FieldOffset(0x68)] public long CommitId; + public SaveDataAttribute Attribute; + public ulong OwnerId; + public long TimeStamp; + public SaveDataFlags Flags; + public long DataSize; + public long JournalSize; + public long CommitId; + public Array400 Reserved; } public struct CommitOption diff --git a/src/LibHac/FsSrv/StatusReportService.cs b/src/LibHac/FsSrv/StatusReportService.cs index 08d56406..774f1072 100644 --- a/src/LibHac/FsSrv/StatusReportService.cs +++ b/src/LibHac/FsSrv/StatusReportService.cs @@ -112,8 +112,8 @@ public class StatusReportServiceImpl if (_config.GetPatrolAllocateCounts != null) { - _config.GetPatrolAllocateCounts(out reportInfo.PatrolAllocateSuccessCount, - out reportInfo.PatrolAllocateFailureCount); + _config.GetPatrolAllocateCounts(out reportInfo.PatrolReadAllocateBufferSuccessCount, + out reportInfo.PatrolReadAllocateBufferFailureCount); } return Result.Success; @@ -139,4 +139,4 @@ public class StatusReportServiceImpl return 0; } } -} +} \ No newline at end of file diff --git a/tests/LibHac.Tests/Arp/TypeLayoutTests.cs b/tests/LibHac.Tests/Arp/TypeLayoutTests.cs new file mode 100644 index 00000000..73accf72 --- /dev/null +++ b/tests/LibHac.Tests/Arp/TypeLayoutTests.cs @@ -0,0 +1,23 @@ +using System.Runtime.CompilerServices; +using LibHac.Arp; +using Xunit; +using static LibHac.Tests.Common.Layout; + +namespace LibHac.Tests.Arp; + +public class TypeLayoutTests +{ + [Fact] + public static void ApplicationLaunchProperty_Layout() + { + var s = new ApplicationLaunchProperty(); + + Assert.Equal(0x10, Unsafe.SizeOf()); + + Assert.Equal(0x0, GetOffset(in s, in s.ApplicationId)); + Assert.Equal(0x8, GetOffset(in s, in s.Version)); + Assert.Equal(0xC, GetOffset(in s, in s.StorageId)); + Assert.Equal(0xD, GetOffset(in s, in s.PatchStorageId)); + Assert.Equal(0xE, GetOffset(in s, in s.ApplicationKind)); + } +} \ No newline at end of file diff --git a/tests/LibHac.Tests/Bcat/TypeLayoutTests.cs b/tests/LibHac.Tests/Bcat/TypeLayoutTests.cs new file mode 100644 index 00000000..b601bac0 --- /dev/null +++ b/tests/LibHac.Tests/Bcat/TypeLayoutTests.cs @@ -0,0 +1,78 @@ +using System.Runtime.CompilerServices; +using LibHac.Bcat; +using LibHac.Bcat.Impl.Service.Core; +using Xunit; +using static LibHac.Tests.Common.Layout; + +namespace LibHac.Tests.Bcat; + +public class TypeLayoutTests +{ + [Fact] + public static void Digest_Layout() + { + var s = new Digest(); + + Assert.Equal(0x10, Unsafe.SizeOf()); + + Assert.Equal(0x0, GetOffset(in s, in s.Value)); + } + + [Fact] + public static void DirectoryName_Layout() + { + var s = new DirectoryName(); + + Assert.Equal(0x20, Unsafe.SizeOf()); + + Assert.Equal(0x0, GetOffset(in s, in s.Value)); + } + + [Fact] + public static void FileName_Layout() + { + var s = new FileName(); + + Assert.Equal(0x20, Unsafe.SizeOf()); + + Assert.Equal(0x0, GetOffset(in s, in s.Value)); + } + + [Fact] + public static void DeliveryCacheDirectoryEntry_Layout() + { + var s = new DeliveryCacheDirectoryEntry(); + + Assert.Equal(0x38, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.Name)); + Assert.Equal(0x20, GetOffset(in s, in s.Size)); + Assert.Equal(0x28, GetOffset(in s, in s.Digest)); + } + + [Fact] + public static void DeliveryCacheDirectoryMetaEntry_Layout() + { + var s = new DeliveryCacheDirectoryMetaEntry(); + + Assert.Equal(0x40, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.Name)); + Assert.Equal(0x20, GetOffset(in s, in s.Digest)); + Assert.Equal(0x30, GetOffset(in s, in s.Reserved)); + } + + [Fact] + public static void DeliveryCacheFileMetaEntry_Layout() + { + var s = new DeliveryCacheFileMetaEntry(); + + Assert.Equal(0x80, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.Name)); + Assert.Equal(0x20, GetOffset(in s, in s.Id)); + Assert.Equal(0x28, GetOffset(in s, in s.Size)); + Assert.Equal(0x30, GetOffset(in s, in s.Digest)); + Assert.Equal(0x40, GetOffset(in s, in s.Reserved)); + } +} \ No newline at end of file diff --git a/tests/LibHac.Tests/Fs/TypeLayoutTests.cs b/tests/LibHac.Tests/Fs/TypeLayoutTests.cs new file mode 100644 index 00000000..e0746b30 --- /dev/null +++ b/tests/LibHac.Tests/Fs/TypeLayoutTests.cs @@ -0,0 +1,149 @@ +using System.Runtime.CompilerServices; +using LibHac.Fs; +using Xunit; +using static LibHac.Tests.Common.Layout; + +namespace LibHac.Tests.Fs; + +public class TypeLayoutTests +{ + [Fact] + public static void SaveDataAttribute_Layout() + { + var s = new SaveDataAttribute(); + + Assert.Equal(0x40, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.ProgramId)); + Assert.Equal(0x08, GetOffset(in s, in s.UserId)); + Assert.Equal(0x18, GetOffset(in s, in s.StaticSaveDataId)); + Assert.Equal(0x20, GetOffset(in s, in s.Type)); + Assert.Equal(0x21, GetOffset(in s, in s.Rank)); + Assert.Equal(0x22, GetOffset(in s, in s.Index)); + Assert.Equal(0x24, GetOffset(in s, in s.Reserved)); + } + + [Fact] + public static void SaveDataCreationInfo_Layout() + { + var s = new SaveDataCreationInfo(); + + Assert.Equal(0x40, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.Size)); + Assert.Equal(0x08, GetOffset(in s, in s.JournalSize)); + Assert.Equal(0x10, GetOffset(in s, in s.BlockSize)); + Assert.Equal(0x18, GetOffset(in s, in s.OwnerId)); + Assert.Equal(0x20, GetOffset(in s, in s.Flags)); + Assert.Equal(0x24, GetOffset(in s, in s.SpaceId)); + Assert.Equal(0x25, GetOffset(in s, in s.IsPseudoSaveData)); + Assert.Equal(0x26, GetOffset(in s, in s.Reserved)); + } + + [Fact] + public static void SaveDataFilter_Layout() + { + var s = new SaveDataFilter(); + + Assert.Equal(0x48, Unsafe.SizeOf()); + + Assert.Equal(0, GetOffset(in s, in s.FilterByProgramId)); + Assert.Equal(1, GetOffset(in s, in s.FilterBySaveDataType)); + Assert.Equal(2, GetOffset(in s, in s.FilterByUserId)); + Assert.Equal(3, GetOffset(in s, in s.FilterBySaveDataId)); + Assert.Equal(4, GetOffset(in s, in s.FilterByIndex)); + Assert.Equal(5, GetOffset(in s, in s.Rank)); + Assert.Equal(8, GetOffset(in s, in s.Attribute)); + } + + [Fact] + public static void SaveDataMetaInfo_Layout() + { + var s = new SaveDataMetaInfo(); + + Assert.Equal(0x10, Unsafe.SizeOf()); + + Assert.Equal(0, GetOffset(in s, in s.Size)); + Assert.Equal(4, GetOffset(in s, in s.Type)); + Assert.Equal(5, GetOffset(in s, in s.Reserved)); + } + + [Fact] + public static void HashSalt_Layout() + { + var s = new HashSalt(); + + Assert.Equal(0x20, Unsafe.SizeOf()); + + Assert.Equal(0, GetOffset(in s, in s.Hash[0])); + } + + [Fact] + public static void SaveDataInfo_Layout() + { + var s = new SaveDataInfo(); + + Assert.Equal(0x60, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.SaveDataId)); + Assert.Equal(0x08, GetOffset(in s, in s.SpaceId)); + Assert.Equal(0x09, GetOffset(in s, in s.Type)); + Assert.Equal(0x10, GetOffset(in s, in s.UserId)); + Assert.Equal(0x20, GetOffset(in s, in s.StaticSaveDataId)); + Assert.Equal(0x28, GetOffset(in s, in s.ProgramId)); + Assert.Equal(0x30, GetOffset(in s, in s.Size)); + Assert.Equal(0x38, GetOffset(in s, in s.Index)); + Assert.Equal(0x3A, GetOffset(in s, in s.Rank)); + Assert.Equal(0x3B, GetOffset(in s, in s.State)); + Assert.Equal(0x3C, GetOffset(in s, in s.Reserved)); + } + + [Fact] + public static void SaveDataExtraData_Layout() + { + var s = new SaveDataExtraData(); + + Assert.Equal(0x200, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.Attribute)); + Assert.Equal(0x40, GetOffset(in s, in s.OwnerId)); + Assert.Equal(0x48, GetOffset(in s, in s.TimeStamp)); + Assert.Equal(0x50, GetOffset(in s, in s.Flags)); + Assert.Equal(0x58, GetOffset(in s, in s.DataSize)); + Assert.Equal(0x60, GetOffset(in s, in s.JournalSize)); + Assert.Equal(0x68, GetOffset(in s, in s.CommitId)); + Assert.Equal(0x70, GetOffset(in s, in s.Reserved)); + } + + [Fact] + public static void CommitOption_Layout() + { + var s = new CommitOption(); + + Assert.Equal(4, Unsafe.SizeOf()); + + Assert.Equal(0, GetOffset(in s, in s.Flags)); + } + + [Fact] + public static void MemoryReportInfo_Layout() + { + var s = new MemoryReportInfo(); + + Assert.Equal(0x80, Unsafe.SizeOf()); + + Assert.Equal(0x00, GetOffset(in s, in s.PooledBufferFreeSizePeak)); + Assert.Equal(0x08, GetOffset(in s, in s.PooledBufferRetriedCount)); + Assert.Equal(0x10, GetOffset(in s, in s.PooledBufferReduceAllocationCount)); + Assert.Equal(0x18, GetOffset(in s, in s.BufferManagerFreeSizePeak)); + Assert.Equal(0x20, GetOffset(in s, in s.BufferManagerRetriedCount)); + Assert.Equal(0x28, GetOffset(in s, in s.ExpHeapFreeSizePeak)); + Assert.Equal(0x30, GetOffset(in s, in s.BufferPoolFreeSizePeak)); + Assert.Equal(0x38, GetOffset(in s, in s.PatrolReadAllocateBufferSuccessCount)); + Assert.Equal(0x40, GetOffset(in s, in s.PatrolReadAllocateBufferFailureCount)); + Assert.Equal(0x48, GetOffset(in s, in s.BufferManagerTotalAllocatableSizePeak)); + Assert.Equal(0x50, GetOffset(in s, in s.BufferPoolAllocateSizeMax)); + Assert.Equal(0x58, GetOffset(in s, in s.PooledBufferFailedIdealAllocationCountOnAsyncAccess)); + Assert.Equal(0x60, GetOffset(in s, in s.Reserved)); + } +} \ No newline at end of file