Update struct layout of Ns structs

This commit is contained in:
Alex Barney 2022-01-02 16:52:57 -07:00
parent b7e8ea8249
commit b0e679d000
23 changed files with 759 additions and 337 deletions

View file

@ -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 Array1024<T>
{
public const int Length = 1024;
private Array512<T> _0;
private Array512<T> _512;
public ref T this[int i] => ref Items[i];
public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}
public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array1024<T> value) => value.ItemsRo;
}

View file

@ -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 Array2048<T>
{
public const int Length = 2048;
private Array1024<T> _0;
private Array1024<T> _1024;
public ref T this[int i] => ref Items[i];
public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}
public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array2048<T> value) => value.ItemsRo;
}

View file

@ -0,0 +1,34 @@
#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 Array3000<T>
{
public const int Length = 3000;
private Array2048<T> _0;
private Array512<T> _2048;
private Array256<T> _2560;
private Array128<T> _2816;
private Array56<T> _2944;
public ref T this[int i] => ref Items[i];
public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}
public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array3000<T> value) => value.ItemsRo;
}

View file

@ -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 Array37<T>
{
public const int Length = 37;
private Array32<T> _0;
private Array5<T> _32;
public ref T this[int i] => ref Items[i];
public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}
public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array37<T> value) => value.ItemsRo;
}

View file

@ -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 Array65<T>
{
public const int Length = 65;
private Array64<T> _0;
private T _64;
public ref T this[int i] => ref Items[i];
public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}
public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array65<T> value) => value.ItemsRo;
}

View file

@ -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 Array768<T>
{
public const int Length = 768;
private Array512<T> _0;
private Array256<T> _512;
public ref T this[int i] => ref Items[i];
public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}
public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array768<T> value) => value.ItemsRo;
}

View file

@ -1,51 +0,0 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace LibHac.Common;
// In order for the Visual Studio debugger to accurately display a struct, every offset
// in the struct that is used for the debugger display must be part of a field.
// These padding structs make it easier to accomplish that.
[StructLayout(LayoutKind.Sequential, Size = 0x10)]
internal struct Padding10
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding00;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding08;
}
[StructLayout(LayoutKind.Sequential, Size = 0x20)]
internal struct Padding20
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding00;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding08;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding10;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong Padding18;
}
[StructLayout(LayoutKind.Sequential, Size = 0x40)]
internal struct Padding40
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding20 Padding00;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding20 Padding20;
}
[StructLayout(LayoutKind.Sequential, Size = 0x80)]
internal struct Padding80
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding40 Padding00;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding40 Padding40;
}
[StructLayout(LayoutKind.Sequential, Size = 0x100)]
internal struct Padding100
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding80 Padding00;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding80 Padding80;
}
[StructLayout(LayoutKind.Sequential, Size = 0x200)]
internal struct Padding200
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding000;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding100;
}

View file

@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis;
using LibHac.Account;
using LibHac.Common;
using LibHac.Fs.Shim;
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Util;
@ -18,7 +17,7 @@ public static class ApplicationSaveDataManagement
long requiredSizeSum = 0;
// Create local variable for use in closures
ProgramId saveDataOwnerId = nacp.SaveDataOwnerId;
ulong saveDataOwnerId = nacp.SaveDataOwnerId;
// Ensure the user account save exists
if (uid != Uid.Zero && nacp.UserAccountSaveDataSize > 0)
@ -31,7 +30,7 @@ public static class ApplicationSaveDataManagement
Result CreateAccountSaveFunc()
{
UserId userId = ConvertAccountUidToFsUserId(uidLocal);
return fs.CreateSaveData(applicationId, userId, saveDataOwnerId.Value, accountSaveDataSize,
return fs.CreateSaveData(applicationId, userId, saveDataOwnerId, accountSaveDataSize,
accountSaveJournalSize, SaveDataFlags.None);
}
@ -53,8 +52,8 @@ public static class ApplicationSaveDataManagement
long deviceSaveDataSize = nacp.DeviceSaveDataSize;
long deviceSaveJournalSize = nacp.DeviceSaveDataJournalSize;
Result CreateDeviceSaveFunc() => fs.CreateDeviceSaveData(applicationId, saveDataOwnerId.Value,
deviceSaveDataSize, deviceSaveJournalSize, 0);
Result CreateDeviceSaveFunc() => fs.CreateDeviceSaveData(applicationId, saveDataOwnerId, deviceSaveDataSize,
deviceSaveJournalSize, 0);
var filter = new SaveDataFilter();
filter.SetProgramId(applicationId);
@ -108,7 +107,7 @@ public static class ApplicationSaveDataManagement
}
else
{
Result createRc = fs.CreateTemporaryStorage(applicationId, nacp.SaveDataOwnerId.Value,
Result createRc = fs.CreateTemporaryStorage(applicationId, nacp.SaveDataOwnerId,
nacp.TemporaryStorageSize, 0);
if (createRc.IsFailure())
@ -311,7 +310,7 @@ public static class ApplicationSaveDataManagement
public static Result EnsureApplicationCacheStorage(this FileSystemClient fs, out long requiredSize,
Ncm.ApplicationId applicationId, ref ApplicationControlProperty nacp)
{
return EnsureApplicationCacheStorageImpl(fs, out requiredSize, out _, applicationId, nacp.SaveDataOwnerId.Value,
return EnsureApplicationCacheStorageImpl(fs, out requiredSize, out _, applicationId, nacp.SaveDataOwnerId,
0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true);
}
@ -324,7 +323,7 @@ public static class ApplicationSaveDataManagement
return Result.Success;
return EnsureApplicationCacheStorageImpl(fs, out requiredSize, out target, applicationId,
nacp.SaveDataOwnerId.Value, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true);
nacp.SaveDataOwnerId, 0, nacp.CacheStorageSize, nacp.CacheStorageJournalSize, true);
}
@ -334,14 +333,14 @@ public static class ApplicationSaveDataManagement
{
UnsafeHelpers.SkipParamInit(out requiredSize, out target);
if (index > nacp.CacheStorageMaxIndex)
if (index > nacp.CacheStorageIndexMax)
return ResultFs.CacheStorageIndexTooLarge.Log();
if (dataSize + journalSize > nacp.CacheStorageMaxSizeAndMaxJournalSize)
if (dataSize + journalSize > nacp.CacheStorageDataAndJournalSizeMax)
return ResultFs.CacheStorageSizeTooLarge.Log();
Result rc = fs.EnsureApplicationCacheStorage(out requiredSize, out target, applicationId,
nacp.SaveDataOwnerId.Value, index, dataSize, journalSize, false);
nacp.SaveDataOwnerId, index, dataSize, journalSize, false);
fs.Impl.AbortIfNeeded(rc);
return rc;

View file

@ -1,11 +1,11 @@
using System;
using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Common.FixedArrays;
using LibHac.Diag;
using LibHac.Fs.Fsa;
using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf;
using LibHac.FsSystem;
using LibHac.Os;
using LibHac.Util;
using static LibHac.Fs.StringTraits;
@ -65,11 +65,11 @@ public static class Host
private class HostCommonMountNameGenerator : ICommonMountNameGenerator
{
private FsPath _path;
private Array769<byte> _path;
public HostCommonMountNameGenerator(U8Span path)
{
StringUtils.Strlcpy(_path.Str, path, FsPath.MaxLength + 1);
StringUtils.Strlcpy(_path.Items, path, PathTool.EntryNameLengthMax + 1);
}
public void Dispose() { }
@ -77,13 +77,13 @@ public static class Host
public Result GenerateCommonMountName(Span<byte> nameBuffer)
{
int requiredNameBufferSize =
StringUtils.GetLength(_path.Str, FsPath.MaxLength + 1) + HostRootFileSystemPathLength;
StringUtils.GetLength(_path, PathTool.EntryNameLengthMax + 1) + HostRootFileSystemPathLength;
if (nameBuffer.Length < requiredNameBufferSize)
return ResultFs.TooLongPath.Log();
var sb = new U8StringBuilder(nameBuffer);
sb.Append(HostRootFileSystemPath).Append(_path.Str);
sb.Append(HostRootFileSystemPath).Append(_path);
Assert.SdkEqual(sb.Length, requiredNameBufferSize - 1);
@ -533,4 +533,4 @@ public static class Host
fs.Impl.LogResultErrorMessage(rc);
Abort.DoAbortUnless(rc.IsSuccess());
}
}
}

View file

@ -79,10 +79,10 @@ internal class LocationResolverSet : IDisposable
var pathFlags = new PathFlags();
pathFlags.AllowMountName();
if (Utility.IsHostFsMountName(lrPath.Str))
if (Utility.IsHostFsMountName(lrPath.Value))
pathFlags.AllowWindowsPath();
Result rc = outPath.InitializeWithReplaceUnc(lrPath.Str);
Result rc = outPath.InitializeWithReplaceUnc(lrPath.Value);
if (rc.IsFailure()) return rc;
rc = outPath.Normalize(pathFlags);
@ -170,7 +170,7 @@ internal class LocationResolverSet : IDisposable
rc = resolver.ResolveApplicationHtmlDocumentPath(out Lr.Path path, applicationId);
if (rc.IsFailure()) return rc;
isDirectory = PathUtility.IsDirectoryPath(path.Str);
isDirectory = PathUtility.IsDirectoryPath(path.Value);
return SetUpFsPath(ref outPath, in path);
}
@ -185,7 +185,7 @@ internal class LocationResolverSet : IDisposable
rc = resolver.ResolveProgramPath(out Lr.Path path, programId);
if (rc.IsFailure()) return rc;
isDirectory = PathUtility.IsDirectoryPath(path.Str);
isDirectory = PathUtility.IsDirectoryPath(path.Value);
return SetUpFsPath(ref outPath, in path);
}
@ -200,7 +200,7 @@ internal class LocationResolverSet : IDisposable
rc = resolver.ResolveProgramPathForDebug(out Lr.Path path, programId);
if (rc.IsFailure()) return rc;
isDirectory = PathUtility.IsDirectoryPath(path.Str);
isDirectory = PathUtility.IsDirectoryPath(path.Value);
return SetUpFsPath(ref outPath, in path);
}
@ -291,4 +291,4 @@ internal class LocationResolverSet : IDisposable
_ => -1
};
}
}
}

View file

@ -474,7 +474,7 @@ public class NcaFileSystemServiceImpl
return ResultFs.PathNotFound.Log();
}
if (StringUtils.GetLength(path, FsPath.MaxLength) == 0)
if (StringUtils.GetLength(path, PathTool.EntryNameLengthMax) == 0)
{
shouldContinue = false;
}

View file

@ -1,42 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Util;
namespace LibHac.FsSystem;
[StructLayout(LayoutKind.Sequential, Size = MaxLength + 1)]
public struct FsPath
{
internal const int MaxLength = 0x300;
#if DEBUG
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding000;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding100;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding200;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly byte Padding300;
#endif
public Span<byte> Str => SpanHelpers.AsByteSpan(ref this);
public static Result FromSpan(out FsPath fsPath, ReadOnlySpan<byte> path)
{
UnsafeHelpers.SkipParamInit(out fsPath);
// Ensure null terminator even if the creation fails for safety
fsPath.Str[MaxLength] = 0;
var sb = new U8StringBuilder(fsPath.Str);
bool overflowed = sb.Append(path).Overflowed;
return overflowed ? ResultFs.TooLongPath.Log() : Result.Success;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator U8Span(in FsPath value) => new U8Span(SpanHelpers.AsReadOnlyByteSpan(in value));
public override string ToString() => StringUtils.Utf8ZToString(Str);
}

View file

@ -1,16 +1,8 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Common.FixedArrays;
namespace LibHac.FsSystem;
[StructLayout(LayoutKind.Sequential, Size = 0x20)]
public struct Hash
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1;
public readonly ReadOnlySpan<byte> Bytes => SpanHelpers.AsReadOnlyByteSpan(in this);
public Span<byte> BytesMutable => SpanHelpers.AsByteSpan(ref this);
}
public Array32<byte> Value;
}

View file

@ -359,7 +359,7 @@ public class PartitionFileSystemCore<T> : IFileSystem where T : unmanaged, IPart
U8Span name = ParentFs._metaData.GetName(CurrentIndex);
StringUtils.Copy(entryBuffer[i].Name.Items, name);
entryBuffer[i].Name[FsPath.MaxLength] = 0;
entryBuffer[i].Name[PathTool.EntryNameLengthMax] = 0;
CurrentIndex++;
}

View file

@ -1,6 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Diag;
using LibHac.Fs;
@ -96,8 +95,6 @@ public class InitialProcessBinaryReader : IDisposable
return Result.Success;
}
[StructLayout(LayoutKind.Sequential, Size = 0x10)]
public struct IniHeader
{
public uint Magic;
@ -105,4 +102,4 @@ public class InitialProcessBinaryReader : IDisposable
public int ProcessCount;
public uint Reserved;
}
}
}

View file

@ -2,56 +2,57 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Common.FixedArrays;
namespace LibHac.Kernel;
[StructLayout(LayoutKind.Explicit, Size = 0x100)]
[StructLayout(LayoutKind.Sequential)]
public struct KipHeader
{
public const uint Kip1Magic = 0x3150494B; // KIP1
public const int NameSize = 12;
public const int SegmentCount = 6;
public static readonly uint Kip1Magic = 0x3150494B; // KIP1
public static readonly int SegmentCount = 6;
[FieldOffset(0x00)] public uint Magic;
public uint Magic;
[FieldOffset(0x04)] private byte _name;
public Array12<byte> Name;
[FieldOffset(0x10)] public ulong ProgramId;
[FieldOffset(0x18)] public int Version;
public ulong ProgramId;
public int Version;
[FieldOffset(0x1C)] public byte Priority;
[FieldOffset(0x1D)] public byte IdealCoreId;
[FieldOffset(0x1F)] public Flag Flags;
public byte Priority;
public byte IdealCoreId;
private byte _reserved1E;
public Flag Flags;
[FieldOffset(0x20)] public int TextMemoryOffset;
[FieldOffset(0x24)] public int TextSize;
[FieldOffset(0x28)] public int TextFileSize;
public int TextMemoryOffset;
public int TextSize;
public int TextFileSize;
[FieldOffset(0x2C)] public int AffinityMask;
public int AffinityMask;
[FieldOffset(0x30)] public int RoMemoryOffset;
[FieldOffset(0x34)] public int RoSize;
[FieldOffset(0x38)] public int RoFileSize;
public int RoMemoryOffset;
public int RoSize;
public int RoFileSize;
[FieldOffset(0x3C)] public int StackSize;
public int StackSize;
[FieldOffset(0x40)] public int DataMemoryOffset;
[FieldOffset(0x44)] public int DataSize;
[FieldOffset(0x48)] public int DataFileSize;
public int DataMemoryOffset;
public int DataSize;
public int DataFileSize;
private byte _reserved4C;
[FieldOffset(0x50)] public int BssMemoryOffset;
[FieldOffset(0x54)] public int BssSize;
[FieldOffset(0x58)] public int BssFileSize;
public int BssMemoryOffset;
public int BssSize;
public int BssFileSize;
private byte _reserved5C;
[FieldOffset(0x80)] private uint _capabilities;
private Array2<SegmentHeader> _unusedSegmentHeaders;
public Span<byte> Name => SpanHelpers.CreateSpan(ref _name, NameSize);
public Array32<uint> Capabilities;
public Span<SegmentHeader> Segments =>
SpanHelpers.CreateSpan(ref Unsafe.As<int, SegmentHeader>(ref TextMemoryOffset), SegmentCount);
public Span<uint> Capabilities => SpanHelpers.CreateSpan(ref _capabilities, 0x80 / sizeof(uint));
public bool IsValid => Magic == Kip1Magic;
[Flags]
@ -65,11 +66,12 @@ public struct KipHeader
UseSecureMemory = 1 << 5
}
[StructLayout(LayoutKind.Sequential, Size = 0x10)]
[StructLayout(LayoutKind.Sequential)]
public struct SegmentHeader
{
public int MemoryOffset;
public int Size;
public int FileSize;
private int _unused;
}
}
}

View file

@ -1,24 +1,13 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Common.FixedArrays;
using LibHac.Util;
namespace LibHac.Lr;
[StructLayout(LayoutKind.Sequential, Size = PathTool.EntryNameLengthMax)]
public struct Path
{
#if DEBUG
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding000;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding100;
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Padding100 Padding200;
#endif
public readonly ReadOnlySpan<byte> Str => SpanHelpers.AsReadOnlyByteSpan(in this);
public Span<byte> StrMutable => SpanHelpers.AsByteSpan(ref this);
public Array768<byte> Value;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InitEmpty(out Path path)
@ -30,5 +19,5 @@ public struct Path
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator U8Span(in Path value) => new U8Span(SpanHelpers.AsReadOnlyByteSpan(in value));
public readonly override string ToString() => StringUtils.Utf8ZToString(Str);
public readonly override string ToString() => StringUtils.Utf8ZToString(Value);
}

View file

@ -1,188 +1,302 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
using LibHac.Common;
using LibHac.Ncm;
using LibHac.Common.FixedArrays;
namespace LibHac.Ns;
[StructLayout(LayoutKind.Explicit, Size = 0x4000)]
public struct ApplicationControlProperty
{
private const int TitleCount = 0x10;
private const int IsbnSize = 0x25;
private const int RatingAgeCount = 0x20;
private const int DisplayVersionSize = 0x10;
private const int ApplicationErrorCodeCategorySize = 8;
private const int LocalCommunicationIdCount = 8;
private const int Reserved30F3Size = 3;
private const int BcatPassphraseSize = 0x41;
private const int ReservedForUserAccountSaveDataOperationSize = 6;
private const int PlayLogQueryableApplicationIdCount = 0x10;
private const int ReceivableDataConfigurationCount = 0x10;
public Array16<ApplicationTitle> Title;
public Array37<byte> Isbn;
public StartupUserAccountValue StartupUserAccount;
public UserAccountSwitchLockValue UserAccountSwitchLock;
public AddOnContentRegistrationTypeValue AddOnContentRegistrationType;
public AttributeFlagValue AttributeFlag;
public uint SupportedLanguageFlag;
public ParentalControlFlagValue ParentalControlFlag;
public ScreenshotValue Screenshot;
public VideoCaptureValue VideoCapture;
public DataLossConfirmationValue DataLossConfirmation;
public PlayLogPolicyValue PlayLogPolicy;
public ulong PresenceGroupId;
public Array32<sbyte> RatingAge;
public Array16<byte> DisplayVersion;
public ulong AddOnContentBaseId;
public ulong SaveDataOwnerId;
public long UserAccountSaveDataSize;
public long UserAccountSaveDataJournalSize;
public long DeviceSaveDataSize;
public long DeviceSaveDataJournalSize;
public long BcatDeliveryCacheStorageSize;
public Array8<byte> ApplicationErrorCodeCategory;
public Array8<ulong> LocalCommunicationId;
public LogoTypeValue LogoType;
public LogoHandlingValue LogoHandling;
public RuntimeAddOnContentInstallValue RuntimeAddOnContentInstall;
public RuntimeParameterDeliveryValue RuntimeParameterDelivery;
public Array2<byte> Reserved30F4;
public CrashReportValue CrashReport;
public HdcpValue Hdcp;
public ulong SeedForPseudoDeviceId;
public Array65<byte> BcatPassphrase;
public StartupUserAccountOptionFlagValue StartupUserAccountOption;
public Array6<byte> ReservedForUserAccountSaveDataOperation;
public long UserAccountSaveDataSizeMax;
public long UserAccountSaveDataJournalSizeMax;
public long DeviceSaveDataSizeMax;
public long DeviceSaveDataJournalSizeMax;
public long TemporaryStorageSize;
public long CacheStorageSize;
public long CacheStorageJournalSize;
public long CacheStorageDataAndJournalSizeMax;
public ushort CacheStorageIndexMax;
public byte Reserved318A;
public byte RuntimeUpgrade;
public uint SupportingLimitedLicenses;
public Array16<ulong> PlayLogQueryableApplicationId;
public PlayLogQueryCapabilityValue PlayLogQueryCapability;
public RepairFlagValue RepairFlag;
public byte ProgramIndex;
public RequiredNetworkServiceLicenseOnLaunchValue RequiredNetworkServiceLicenseOnLaunchFlag;
public Array4<byte> Reserved3214;
public ApplicationNeighborDetectionClientConfiguration NeighborDetectionClientConfiguration;
public ApplicationJitConfiguration JitConfiguration;
public RequiredAddOnContentsSetBinaryDescriptor RequiredAddOnContentsSetBinaryDescriptors;
public PlayReportPermissionValue PlayReportPermission;
public CrashScreenshotForProdValue CrashScreenshotForProd;
public CrashScreenshotForDevValue CrashScreenshotForDev;
public byte ContentsAvailabilityTransitionPolicy;
public Array4<byte> Reserved3404;
public AccessibleLaunchRequiredVersionValue AccessibleLaunchRequiredVersion;
public Array3000<byte> Reserved3448;
[FieldOffset(0x0000)] private byte _titles;
[FieldOffset(0x3000)] private byte _isbn;
[FieldOffset(0x3025)] public StartupUserAccount StartupUserAccount;
[FieldOffset(0x3026)] public byte UserAccountSwitchLock;
[FieldOffset(0x3027)] public byte AddOnContentRegistrationType;
[FieldOffset(0x3028)] public ApplicationAttribute ApplicationAttribute;
[FieldOffset(0x302C)] public uint SupportedLanguages;
[FieldOffset(0x3030)] public ParentalControlFlagValue ParentalControl;
[FieldOffset(0x3034)] public ScreenshotValue Screenshot;
[FieldOffset(0x3035)] public VideoCaptureValue VideoCaptureMode;
[FieldOffset(0x3036)] public byte DataLossConfirmation;
[FieldOffset(0x3037)] public byte PlayLogPolicy;
[FieldOffset(0x3038)] public ulong PresenceGroupId;
[FieldOffset(0x3040)] private sbyte _ratingAge;
[FieldOffset(0x3060)] private byte _displayVersion;
[FieldOffset(0x3070)] public ulong AddOnContentBaseId;
[FieldOffset(0x3078)] public ProgramId SaveDataOwnerId;
[FieldOffset(0x3080)] public long UserAccountSaveDataSize;
[FieldOffset(0x3088)] public long UserAccountSaveDataJournalSize;
[FieldOffset(0x3090)] public long DeviceSaveDataSize;
[FieldOffset(0x3098)] public long DeviceSaveDataJournalSize;
[FieldOffset(0x30A0)] public long BcatDeliveryCacheStorageSize;
[FieldOffset(0x30A8)] private byte _applicationErrorCodeCategory;
[FieldOffset(0x30B0)] private ulong _localCommunicationIds;
[FieldOffset(0x30F0)] public LogoType LogoType;
[FieldOffset(0x30F1)] public LogoHandling LogoHandling;
[FieldOffset(0x30F2)] public byte RuntimeAddOnContentInstall;
[FieldOffset(0x30F3)] public byte _reserved30F3;
[FieldOffset(0x30F6)] public byte CrashReport;
[FieldOffset(0x30F7)] public byte Hdcp;
[FieldOffset(0x30F8)] public ulong SeedForPseudoDeviceId;
[FieldOffset(0x3100)] private byte _bcatPassphrase;
[FieldOffset(0x3141)] public byte StartupUserAccountOption;
[FieldOffset(0x3142)] private byte _reservedForUserAccountSaveDataOperation;
[FieldOffset(0x3148)] public long UserAccountSaveDataMaxSize;
[FieldOffset(0x3150)] public long UserAccountSaveDataMaxJournalSize;
[FieldOffset(0x3158)] public long DeviceSaveDataMaxSize;
[FieldOffset(0x3160)] public long DeviceSaveDataMaxJournalSize;
[FieldOffset(0x3168)] public long TemporaryStorageSize;
[FieldOffset(0x3170)] public long CacheStorageSize;
[FieldOffset(0x3178)] public long CacheStorageJournalSize;
[FieldOffset(0x3180)] public long CacheStorageMaxSizeAndMaxJournalSize;
[FieldOffset(0x3188)] public long CacheStorageMaxIndex;
[FieldOffset(0x3190)] private ulong _playLogQueryableApplicationId;
[FieldOffset(0x3210)] public PlayLogQueryCapability PlayLogQueryCapability;
[FieldOffset(0x3211)] public byte RepairFlag;
[FieldOffset(0x3212)] public byte ProgramIndex;
[FieldOffset(0x3213)] public byte RequiredNetworkServiceLicenseOnLaunchFlag;
[FieldOffset(0x3214)] public uint Reserved3214;
[FieldOffset(0x3218)] public ApplicationControlDataConfiguration SendDataConfiguration;
[FieldOffset(0x3230)] private ApplicationControlDataConfiguration _receivableDataConfigurations;
[FieldOffset(0x32B0)] public ulong JitConfigurationFlag;
[FieldOffset(0x32B8)] public long MemorySize;
public struct ApplicationTitle
{
private Array512<byte> _name;
private Array256<byte> _publisher;
[FieldOffset(0x3000), DebuggerBrowsable(DebuggerBrowsableState.Never)] private Padding200 _padding1;
[FieldOffset(0x3200), DebuggerBrowsable(DebuggerBrowsableState.Never)] private Padding100 _padding2;
public U8SpanMutable Name => new U8SpanMutable(_name.Items);
public U8SpanMutable Publisher => new U8SpanMutable(_publisher.Items);
}
public Span<ApplicationControlTitle> Titles => SpanHelpers.CreateSpan(ref Unsafe.As<byte, ApplicationControlTitle>(ref _titles), TitleCount);
public U8SpanMutable Isbn => new U8SpanMutable(SpanHelpers.CreateSpan(ref _isbn, IsbnSize));
public Span<sbyte> RatingAge => SpanHelpers.CreateSpan(ref _ratingAge, RatingAgeCount);
public U8SpanMutable DisplayVersion => new U8SpanMutable(SpanHelpers.CreateSpan(ref _displayVersion, DisplayVersionSize));
public struct ApplicationNeighborDetectionClientConfiguration
{
public ApplicationNeighborDetectionGroupConfiguration SendGroupConfiguration;
public Array16<ApplicationNeighborDetectionGroupConfiguration> ReceivableGroupConfigurations;
}
public U8SpanMutable ApplicationErrorCodeCategory =>
new U8SpanMutable(SpanHelpers.CreateSpan(ref _applicationErrorCodeCategory,
ApplicationErrorCodeCategorySize));
public struct ApplicationNeighborDetectionGroupConfiguration
{
public ulong GroupId;
public Array16<byte> Key;
}
public Span<ulong> LocalCommunicationIds => SpanHelpers.CreateSpan(ref _localCommunicationIds, LocalCommunicationIdCount);
public Span<byte> Reserved30F3 => SpanHelpers.CreateSpan(ref _reserved30F3, Reserved30F3Size);
public U8SpanMutable BcatPassphrase => new U8SpanMutable(SpanHelpers.CreateSpan(ref _bcatPassphrase, BcatPassphraseSize));
public struct ApplicationJitConfiguration
{
public JitConfigurationFlag Flags;
public long MemorySize;
}
public Span<byte> ReservedForUserAccountSaveDataOperation =>
SpanHelpers.CreateSpan(ref _reservedForUserAccountSaveDataOperation,
ReservedForUserAccountSaveDataOperationSize);
public struct RequiredAddOnContentsSetBinaryDescriptor
{
public Array32<ushort> Descriptors;
}
public Span<ulong> PlayLogQueryableApplicationId =>
SpanHelpers.CreateSpan(ref _playLogQueryableApplicationId, PlayLogQueryableApplicationIdCount);
public struct AccessibleLaunchRequiredVersionValue
{
public Array8<ulong> ApplicationId;
}
public Span<ApplicationControlDataConfiguration> ReceivableDataConfigurations =>
SpanHelpers.CreateSpan(ref _receivableDataConfigurations, ReceivableDataConfigurationCount);
}
public enum Language
{
AmericanEnglish = 0,
BritishEnglish = 1,
Japanese = 2,
French = 3,
German = 4,
LatinAmericanSpanish = 5,
Spanish = 6,
Italian = 7,
Dutch = 8,
CanadianFrench = 9,
Portuguese = 10,
Russian = 11,
Korean = 12,
TraditionalChinese = 13,
SimplifiedChinese = 14,
BrazilianPortuguese = 15
}
[StructLayout(LayoutKind.Explicit, Size = 0x300)]
public struct ApplicationControlTitle
{
private const int NameLength = 0x200;
private const int PublisherLength = 0x100;
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum Organization
{
CERO = 0,
GRACGCRB = 1,
GSRMR = 2,
ESRB = 3,
ClassInd = 4,
USK = 5,
PEGI = 6,
PEGIPortugal = 7,
PEGIBBFC = 8,
Russian = 9,
ACB = 10,
OFLC = 11,
IARCGeneric = 12
}
[FieldOffset(0x000)] private byte _name;
[FieldOffset(0x200)] private byte _publisher;
public enum StartupUserAccountValue : byte
{
None = 0,
Required = 1,
RequiredWithNetworkServiceAccountAvailable = 2
}
[FieldOffset(0x000), DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Padding200 _padding0;
public enum UserAccountSwitchLockValue : byte
{
Disable = 0,
Enable = 1
}
[FieldOffset(0x200), DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Padding100 _padding200;
public enum AddOnContentRegistrationTypeValue : byte
{
AllOnLaunch = 0,
OnDemand = 1
}
public U8SpanMutable Name => new U8SpanMutable(SpanHelpers.CreateSpan(ref _name, NameLength));
public U8SpanMutable Publisher => new U8SpanMutable(SpanHelpers.CreateSpan(ref _publisher, PublisherLength));
}
[Flags]
public enum AttributeFlagValue
{
None = 0,
Demo = 1 << 0,
RetailInteractiveDisplay = 1 << 1,
}
[StructLayout(LayoutKind.Explicit, Size = 0x18)]
public struct ApplicationControlDataConfiguration
{
[FieldOffset(0)] public ulong Id;
[FieldOffset(8)] private byte _key;
public enum ParentalControlFlagValue
{
None = 0,
FreeCommunication = 1
}
[FieldOffset(8), DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Padding10 _keyPadding;
public enum ScreenshotValue : byte
{
Allow = 0,
Deny = 1
}
public Span<byte> Key => SpanHelpers.CreateSpan(ref _key, 0x10);
}
public enum VideoCaptureValue : byte
{
Disable = 0,
Manual = 1,
Enable = 2
}
public enum StartupUserAccount : byte
{
None = 0,
Required = 1,
RequiredWithNetworkServiceAccountAvailable = 2
}
public enum DataLossConfirmationValue : byte
{
None = 0,
Required = 1
}
public enum LogoHandling : byte
{
Auto = 0,
Manual = 1
}
public enum PlayLogPolicyValue : byte
{
Open = 0,
LogOnly = 1,
None = 2,
Closed = 3,
All = 0
}
public enum LogoType : byte
{
LicensedByNintendo = 0,
DistributedByNintendo = 1,
Nintendo = 2
}
public enum LogoTypeValue : byte
{
LicensedByNintendo = 0,
DistributedByNintendo = 1,
Nintendo = 2
}
[Flags]
public enum ApplicationAttribute
{
None = 0,
Demo = 1
}
public enum LogoHandlingValue : byte
{
Auto = 0,
Manual = 1
}
public enum PlayLogQueryCapability : byte
{
None = 0,
WhiteList = 1,
All = 2
}
public enum RuntimeAddOnContentInstallValue : byte
{
Deny = 0,
AllowAppend = 1,
AllowAppendButDontDownloadWhenUsingNetwork = 2
}
public enum ParentalControlFlagValue
{
None = 0,
FreeCommunication = 1
}
public enum RuntimeParameterDeliveryValue : byte
{
Always = 0,
AlwaysIfUserStateMatched = 1,
OnRestart = 2
}
public enum ScreenshotValue : byte
{
Allow = 0,
Deny = 1
}
public enum CrashReportValue : byte
{
Deny = 0,
Allow = 1
}
public enum VideoCaptureValue : byte
{
Deny = 0,
Allow = 1,
Automatic = 2
}
public enum HdcpValue : byte
{
None = 0,
Required = 1
}
[Flags]
public enum StartupUserAccountOptionFlagValue : byte
{
None = 0,
IsOptional = 1 << 0
}
public enum PlayLogQueryCapabilityValue : byte
{
None = 0,
WhiteList = 1,
All = 2
}
[Flags]
public enum RepairFlagValue : byte
{
None = 0,
SuppressGameCardAccess = 1 << 0
}
[Flags]
public enum RequiredNetworkServiceLicenseOnLaunchValue : byte
{
None = 0,
Common = 1 << 0
}
[Flags]
public enum JitConfigurationFlag : ulong
{
None = 0,
Enabled = 1 << 0
}
[Flags]
public enum PlayReportPermissionValue : byte
{
None = 0,
TargetMarketing = 1 << 0
}
public enum CrashScreenshotForProdValue : byte
{
Deny = 0,
Allow = 1
}
public enum CrashScreenshotForDevValue : byte
{
Deny = 0,
Allow = 1
}
}

View file

@ -229,7 +229,7 @@ public class SwitchFs : IDisposable
control.Get.Read(out _, 0, title.Control.ByteSpan).ThrowIfFailure();
}
foreach (ref ApplicationControlTitle desc in title.Control.Value.Titles)
foreach (ref readonly ApplicationControlProperty.ApplicationTitle desc in title.Control.Value.Title.ItemsRo)
{
if (!desc.Name.IsEmpty())
{

View file

@ -0,0 +1,19 @@
using System.Runtime.CompilerServices;
using LibHac.FsSystem;
using Xunit;
using static LibHac.Tests.Common.Layout;
namespace LibHac.Tests.FsSystem;
public class TypeLayoutTests
{
[Fact]
public static void Hash_Layout()
{
var s = new Hash();
Assert.Equal(0x20, Unsafe.SizeOf<Hash>());
Assert.Equal(0x0, GetOffset(in s, in s.Value));
}
}

View file

@ -0,0 +1,69 @@
using System.Runtime.CompilerServices;
using LibHac.Kernel;
using Xunit;
using static LibHac.Kernel.InitialProcessBinaryReader;
using static LibHac.Kernel.KipHeader;
using static LibHac.Tests.Common.Layout;
namespace LibHac.Tests.Kernel;
public class TypeLayoutTests
{
[Fact]
public static void IniHeader_Layout()
{
var s = new IniHeader();
Assert.Equal(0x10, Unsafe.SizeOf<IniHeader>());
Assert.Equal(0x0, GetOffset(in s, in s.Magic));
Assert.Equal(0x4, GetOffset(in s, in s.Size));
Assert.Equal(0x8, GetOffset(in s, in s.ProcessCount));
Assert.Equal(0xC, GetOffset(in s, in s.Reserved));
}
[Fact]
public static void KipHeader_Layout()
{
var s = new KipHeader();
Assert.Equal(0x100, Unsafe.SizeOf<KipHeader>());
Assert.Equal(0x00, GetOffset(in s, in s.Magic));
Assert.Equal(0x04, GetOffset(in s, in s.Name));
Assert.Equal(0x10, GetOffset(in s, in s.ProgramId));
Assert.Equal(0x18, GetOffset(in s, in s.Version));
Assert.Equal(0x1C, GetOffset(in s, in s.Priority));
Assert.Equal(0x1D, GetOffset(in s, in s.IdealCoreId));
Assert.Equal(0x1F, GetOffset(in s, in s.Flags));
Assert.Equal(0x20, GetOffset(in s, in s.TextMemoryOffset));
Assert.Equal(0x24, GetOffset(in s, in s.TextSize));
Assert.Equal(0x28, GetOffset(in s, in s.TextFileSize));
Assert.Equal(0x2C, GetOffset(in s, in s.AffinityMask));
Assert.Equal(0x30, GetOffset(in s, in s.RoMemoryOffset));
Assert.Equal(0x34, GetOffset(in s, in s.RoSize));
Assert.Equal(0x38, GetOffset(in s, in s.RoFileSize));
Assert.Equal(0x3C, GetOffset(in s, in s.StackSize));
Assert.Equal(0x40, GetOffset(in s, in s.DataMemoryOffset));
Assert.Equal(0x44, GetOffset(in s, in s.DataSize));
Assert.Equal(0x48, GetOffset(in s, in s.DataFileSize));
Assert.Equal(0x50, GetOffset(in s, in s.BssMemoryOffset));
Assert.Equal(0x54, GetOffset(in s, in s.BssSize));
Assert.Equal(0x58, GetOffset(in s, in s.BssFileSize));
Assert.Equal(0x80, GetOffset(in s, in s.Capabilities));
Assert.Equal(0x20, GetOffset(in s, in s.Segments[0]));
}
[Fact]
public static void KipSegmentHeader_Layout()
{
var s = new SegmentHeader();
Assert.Equal(0x10, Unsafe.SizeOf<SegmentHeader>());
Assert.Equal(0x0, GetOffset(in s, in s.MemoryOffset));
Assert.Equal(0x4, GetOffset(in s, in s.Size));
Assert.Equal(0x8, GetOffset(in s, in s.FileSize));
}
}

View file

@ -0,0 +1,19 @@
using System.Runtime.CompilerServices;
using LibHac.Lr;
using Xunit;
using static LibHac.Tests.Common.Layout;
namespace LibHac.Tests.Lr;
public class TypeLayoutTests
{
[Fact]
public static void IniHeader_Layout()
{
var s = new Path();
Assert.Equal(0x300, Unsafe.SizeOf<Path>());
Assert.Equal(0x0, GetOffset(in s, in s.Value));
}
}

View file

@ -0,0 +1,126 @@
using System.Runtime.CompilerServices;
using LibHac.Ns;
using Xunit;
using static LibHac.Ns.ApplicationControlProperty;
using static LibHac.Tests.Common.Layout;
namespace LibHac.Tests.Ns;
public class TypeLayoutTests
{
[Fact]
public static void ApplicationTitle_Layout()
{
var s = new ApplicationTitle();
Assert.Equal(0x300, Unsafe.SizeOf<ApplicationTitle>());
Assert.Equal(0x000, GetOffset(in s, in s.Name.Value[0]));
Assert.Equal(0x200, GetOffset(in s, in s.Publisher.Value[0]));
}
[Fact]
public static void ApplicationNeighborDetectionGroupConfiguration_Layout()
{
var s = new ApplicationNeighborDetectionGroupConfiguration();
Assert.Equal(0x18, Unsafe.SizeOf<ApplicationNeighborDetectionGroupConfiguration>());
Assert.Equal(0x0, GetOffset(in s, in s.GroupId));
Assert.Equal(0x8, GetOffset(in s, in s.Key));
}
[Fact]
public static void ApplicationNeighborDetectionClientConfiguration_Layout()
{
var s = new ApplicationNeighborDetectionClientConfiguration();
Assert.Equal(0x198, Unsafe.SizeOf<ApplicationNeighborDetectionClientConfiguration>());
Assert.Equal(0x00, GetOffset(in s, in s.SendGroupConfiguration));
Assert.Equal(0x18, GetOffset(in s, in s.ReceivableGroupConfigurations));
}
[Fact]
public static void ApplicationJitConfiguration_Layout()
{
var s = new ApplicationJitConfiguration();
Assert.Equal(0x10, Unsafe.SizeOf<ApplicationJitConfiguration>());
Assert.Equal(0x0, GetOffset(in s, in s.Flags));
Assert.Equal(0x8, GetOffset(in s, in s.MemorySize));
}
[Fact]
public static void ApplicationControlProperty_Layout()
{
var s = new ApplicationControlProperty();
Assert.Equal(0x4000, Unsafe.SizeOf<ApplicationControlProperty>());
Assert.Equal(0x0000, GetOffset(in s, in s.Title));
Assert.Equal(0x3000, GetOffset(in s, in s.Isbn));
Assert.Equal(0x3025, GetOffset(in s, in s.StartupUserAccount));
Assert.Equal(0x3026, GetOffset(in s, in s.UserAccountSwitchLock));
Assert.Equal(0x3027, GetOffset(in s, in s.AddOnContentRegistrationType));
Assert.Equal(0x3028, GetOffset(in s, in s.AttributeFlag));
Assert.Equal(0x302C, GetOffset(in s, in s.SupportedLanguageFlag));
Assert.Equal(0x3030, GetOffset(in s, in s.ParentalControlFlag));
Assert.Equal(0x3034, GetOffset(in s, in s.Screenshot));
Assert.Equal(0x3035, GetOffset(in s, in s.VideoCapture));
Assert.Equal(0x3036, GetOffset(in s, in s.DataLossConfirmation));
Assert.Equal(0x3037, GetOffset(in s, in s.PlayLogPolicy));
Assert.Equal(0x3038, GetOffset(in s, in s.PresenceGroupId));
Assert.Equal(0x3040, GetOffset(in s, in s.RatingAge));
Assert.Equal(0x3060, GetOffset(in s, in s.DisplayVersion));
Assert.Equal(0x3070, GetOffset(in s, in s.AddOnContentBaseId));
Assert.Equal(0x3078, GetOffset(in s, in s.SaveDataOwnerId));
Assert.Equal(0x3080, GetOffset(in s, in s.UserAccountSaveDataSize));
Assert.Equal(0x3088, GetOffset(in s, in s.UserAccountSaveDataJournalSize));
Assert.Equal(0x3090, GetOffset(in s, in s.DeviceSaveDataSize));
Assert.Equal(0x3098, GetOffset(in s, in s.DeviceSaveDataJournalSize));
Assert.Equal(0x30A0, GetOffset(in s, in s.BcatDeliveryCacheStorageSize));
Assert.Equal(0x30A8, GetOffset(in s, in s.ApplicationErrorCodeCategory));
Assert.Equal(0x30B0, GetOffset(in s, in s.LocalCommunicationId));
Assert.Equal(0x30F0, GetOffset(in s, in s.LogoType));
Assert.Equal(0x30F1, GetOffset(in s, in s.LogoHandling));
Assert.Equal(0x30F2, GetOffset(in s, in s.RuntimeAddOnContentInstall));
Assert.Equal(0x30F3, GetOffset(in s, in s.RuntimeParameterDelivery));
Assert.Equal(0x30F4, GetOffset(in s, in s.Reserved30F4));
Assert.Equal(0x30F6, GetOffset(in s, in s.CrashReport));
Assert.Equal(0x30F7, GetOffset(in s, in s.Hdcp));
Assert.Equal(0x30F8, GetOffset(in s, in s.SeedForPseudoDeviceId));
Assert.Equal(0x3100, GetOffset(in s, in s.BcatPassphrase));
Assert.Equal(0x3141, GetOffset(in s, in s.StartupUserAccountOption));
Assert.Equal(0x3142, GetOffset(in s, in s.ReservedForUserAccountSaveDataOperation));
Assert.Equal(0x3148, GetOffset(in s, in s.UserAccountSaveDataSizeMax));
Assert.Equal(0x3150, GetOffset(in s, in s.UserAccountSaveDataJournalSizeMax));
Assert.Equal(0x3158, GetOffset(in s, in s.DeviceSaveDataSizeMax));
Assert.Equal(0x3160, GetOffset(in s, in s.DeviceSaveDataJournalSizeMax));
Assert.Equal(0x3168, GetOffset(in s, in s.TemporaryStorageSize));
Assert.Equal(0x3170, GetOffset(in s, in s.CacheStorageSize));
Assert.Equal(0x3178, GetOffset(in s, in s.CacheStorageJournalSize));
Assert.Equal(0x3180, GetOffset(in s, in s.CacheStorageDataAndJournalSizeMax));
Assert.Equal(0x3188, GetOffset(in s, in s.CacheStorageIndexMax));
Assert.Equal(0x318A, GetOffset(in s, in s.Reserved318A));
Assert.Equal(0x318B, GetOffset(in s, in s.RuntimeUpgrade));
Assert.Equal(0x318C, GetOffset(in s, in s.SupportingLimitedLicenses));
Assert.Equal(0x3190, GetOffset(in s, in s.PlayLogQueryableApplicationId));
Assert.Equal(0x3210, GetOffset(in s, in s.PlayLogQueryCapability));
Assert.Equal(0x3211, GetOffset(in s, in s.RepairFlag));
Assert.Equal(0x3212, GetOffset(in s, in s.ProgramIndex));
Assert.Equal(0x3213, GetOffset(in s, in s.RequiredNetworkServiceLicenseOnLaunchFlag));
Assert.Equal(0x3214, GetOffset(in s, in s.Reserved3214));
Assert.Equal(0x3218, GetOffset(in s, in s.NeighborDetectionClientConfiguration));
Assert.Equal(0x33B0, GetOffset(in s, in s.JitConfiguration));
Assert.Equal(0x33C0, GetOffset(in s, in s.RequiredAddOnContentsSetBinaryDescriptors));
Assert.Equal(0x3400, GetOffset(in s, in s.PlayReportPermission));
Assert.Equal(0x3401, GetOffset(in s, in s.CrashScreenshotForProd));
Assert.Equal(0x3402, GetOffset(in s, in s.CrashScreenshotForDev));
Assert.Equal(0x3403, GetOffset(in s, in s.ContentsAvailabilityTransitionPolicy));
Assert.Equal(0x3404, GetOffset(in s, in s.Reserved3404));
Assert.Equal(0x3408, GetOffset(in s, in s.AccessibleLaunchRequiredVersion));
Assert.Equal(0x3448, GetOffset(in s, in s.Reserved3448));
}
}