mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add SaveDataCreationInfo2
This commit is contained in:
parent
e13661a4dd
commit
3725c21928
4 changed files with 269 additions and 134 deletions
33
src/LibHac/Common/FixedArrays/Array356.cs
Normal file
33
src/LibHac/Common/FixedArrays/Array356.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma warning disable CS0169, CS0649, IDE0051 // Field is never used, Field is never assigned to, Remove unused private members
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace LibHac.Common.FixedArrays;
|
||||||
|
|
||||||
|
public struct Array356<T>
|
||||||
|
{
|
||||||
|
public const int Length = 356;
|
||||||
|
|
||||||
|
private Array256<T> _0;
|
||||||
|
private Array64<T> _256;
|
||||||
|
private Array32<T> _320;
|
||||||
|
private Array4<T> _352;
|
||||||
|
|
||||||
|
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 Array356<T> value) => value.ItemsRo;
|
||||||
|
}
|
|
@ -5,8 +5,127 @@ using LibHac.FsSrv.Impl;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
|
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
namespace LibHac.Fs;
|
namespace LibHac.Fs;
|
||||||
|
|
||||||
|
public enum SaveDataSpaceId : byte
|
||||||
|
{
|
||||||
|
System = 0,
|
||||||
|
User = 1,
|
||||||
|
SdSystem = 2,
|
||||||
|
Temporary = 3,
|
||||||
|
SdUser = 4,
|
||||||
|
ProperSystem = 100,
|
||||||
|
SafeMode = 101,
|
||||||
|
BisAuto = 127
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SaveDataType : byte
|
||||||
|
{
|
||||||
|
System = 0,
|
||||||
|
Account = 1,
|
||||||
|
Bcat = 2,
|
||||||
|
Device = 3,
|
||||||
|
Temporary = 4,
|
||||||
|
Cache = 5,
|
||||||
|
SystemBcat = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SaveDataRank : byte
|
||||||
|
{
|
||||||
|
Primary = 0,
|
||||||
|
Secondary = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SaveDataFormatType : byte
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
NoJournal = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum SaveDataFlags
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
KeepAfterResettingSystemSaveData = 1 << 0,
|
||||||
|
KeepAfterRefurbishment = 1 << 1,
|
||||||
|
KeepAfterResettingSystemSaveDataWithoutUserSaveData = 1 << 2,
|
||||||
|
NeedsSecureDelete = 1 << 3,
|
||||||
|
Restore = 1 << 4
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SaveDataState : byte
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
Processing = 1,
|
||||||
|
State2 = 2,
|
||||||
|
MarkedForDeletion = 3,
|
||||||
|
Extending = 4,
|
||||||
|
ImportSuspended = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SaveDataMetaInfo
|
||||||
|
{
|
||||||
|
public int Size;
|
||||||
|
public SaveDataMetaType Type;
|
||||||
|
public Array11<byte> Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SaveDataMetaType : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Thumbnail = 1,
|
||||||
|
ExtensionContext = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SaveDataInfo
|
||||||
|
{
|
||||||
|
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<byte> Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SaveDataExtraData
|
||||||
|
{
|
||||||
|
public SaveDataAttribute Attribute;
|
||||||
|
public ulong OwnerId;
|
||||||
|
public long TimeStamp;
|
||||||
|
public SaveDataFlags Flags;
|
||||||
|
public long DataSize;
|
||||||
|
public long JournalSize;
|
||||||
|
public long CommitId;
|
||||||
|
public Array400<byte> Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CommitOption
|
||||||
|
{
|
||||||
|
public CommitOptionFlag Flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum CommitOptionFlag
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
ClearRestoreFlag = 1,
|
||||||
|
SetRestoreFlag = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct HashSalt
|
||||||
|
{
|
||||||
|
private Array32<byte> _value;
|
||||||
|
|
||||||
|
public Span<byte> Hash => _value.Items;
|
||||||
|
public readonly ReadOnlySpan<byte> HashRo => _value.ItemsRo;
|
||||||
|
}
|
||||||
|
|
||||||
public struct SaveDataAttribute : IEquatable<SaveDataAttribute>, IComparable<SaveDataAttribute>
|
public struct SaveDataAttribute : IEquatable<SaveDataAttribute>, IComparable<SaveDataAttribute>
|
||||||
{
|
{
|
||||||
public ProgramId ProgramId;
|
public ProgramId ProgramId;
|
||||||
|
@ -60,8 +179,8 @@ public struct SaveDataAttribute : IEquatable<SaveDataAttribute>, IComparable<Sav
|
||||||
Type == other.Type &&
|
Type == other.Type &&
|
||||||
UserId.Equals(other.UserId) &&
|
UserId.Equals(other.UserId) &&
|
||||||
StaticSaveDataId == other.StaticSaveDataId &&
|
StaticSaveDataId == other.StaticSaveDataId &&
|
||||||
Rank == other.Rank &&
|
Index == other.Index &&
|
||||||
Index == other.Index;
|
Rank == other.Rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(SaveDataAttribute left, SaveDataAttribute right) => left.Equals(right);
|
public static bool operator ==(SaveDataAttribute left, SaveDataAttribute right) => left.Equals(right);
|
||||||
|
@ -84,9 +203,9 @@ public struct SaveDataAttribute : IEquatable<SaveDataAttribute>, IComparable<Sav
|
||||||
if (userIdComparison != 0) return userIdComparison;
|
if (userIdComparison != 0) return userIdComparison;
|
||||||
int saveDataIdComparison = StaticSaveDataId.CompareTo(other.StaticSaveDataId);
|
int saveDataIdComparison = StaticSaveDataId.CompareTo(other.StaticSaveDataId);
|
||||||
if (saveDataIdComparison != 0) return saveDataIdComparison;
|
if (saveDataIdComparison != 0) return saveDataIdComparison;
|
||||||
int rankComparison = ((int)Rank).CompareTo((int)other.Rank);
|
int indexComparison = Index.CompareTo(other.Index);
|
||||||
if (rankComparison != 0) return rankComparison;
|
if (indexComparison != 0) return indexComparison;
|
||||||
return Index.CompareTo(other.Index);
|
return ((int)Rank).CompareTo((int)other.Rank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +242,53 @@ public struct SaveDataCreationInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct SaveDataCreationInfo2
|
||||||
|
{
|
||||||
|
internal const uint SaveDataCreationInfo2Version = 0x00010000;
|
||||||
|
|
||||||
|
public uint Version;
|
||||||
|
public SaveDataAttribute Attribute;
|
||||||
|
public long Size;
|
||||||
|
public long JournalSize;
|
||||||
|
public long BlockSize;
|
||||||
|
public ulong OwnerId;
|
||||||
|
public SaveDataFlags Flags;
|
||||||
|
public SaveDataSpaceId SpaceId;
|
||||||
|
public SaveDataFormatType FormatType;
|
||||||
|
public Array2<byte> Reserved1;
|
||||||
|
public bool IsHashSaltEnabled;
|
||||||
|
public Array3<byte> Reserved2;
|
||||||
|
public HashSalt HashSalt;
|
||||||
|
public SaveDataMetaType MetaType;
|
||||||
|
public Array3<byte> Reserved3;
|
||||||
|
public int MetaSize;
|
||||||
|
public Array356<byte> Reserved4;
|
||||||
|
|
||||||
|
public static Result Make(out SaveDataCreationInfo2 creationInfo, in SaveDataAttribute attribute, long size,
|
||||||
|
long journalSize, long blockSize, ulong ownerId, SaveDataFlags flags, SaveDataSpaceId spaceId,
|
||||||
|
SaveDataFormatType formatType)
|
||||||
|
{
|
||||||
|
UnsafeHelpers.SkipParamInit(out creationInfo);
|
||||||
|
SaveDataCreationInfo2 tempCreationInfo = default;
|
||||||
|
|
||||||
|
tempCreationInfo.Version = SaveDataCreationInfo2Version;
|
||||||
|
tempCreationInfo.Attribute = attribute;
|
||||||
|
tempCreationInfo.Size = size;
|
||||||
|
tempCreationInfo.JournalSize = journalSize;
|
||||||
|
tempCreationInfo.BlockSize = blockSize;
|
||||||
|
tempCreationInfo.OwnerId = ownerId;
|
||||||
|
tempCreationInfo.Flags = flags;
|
||||||
|
tempCreationInfo.SpaceId = spaceId;
|
||||||
|
tempCreationInfo.FormatType = formatType;
|
||||||
|
|
||||||
|
if (!SaveDataTypesValidity.IsValid(in tempCreationInfo))
|
||||||
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
|
||||||
|
creationInfo = tempCreationInfo;
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct SaveDataFilter
|
public struct SaveDataFilter
|
||||||
{
|
{
|
||||||
public bool FilterByProgramId;
|
public bool FilterByProgramId;
|
||||||
|
@ -201,64 +367,45 @@ public struct SaveDataFilter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct HashSalt
|
|
||||||
{
|
|
||||||
private Array32<byte> _value;
|
|
||||||
|
|
||||||
public Span<byte> Hash => _value.Items;
|
|
||||||
public readonly ReadOnlySpan<byte> HashRo => _value.ItemsRo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SaveDataMetaInfo
|
|
||||||
{
|
|
||||||
public int Size;
|
|
||||||
public SaveDataMetaType Type;
|
|
||||||
public Array11<byte> Reserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SaveDataInfo
|
|
||||||
{
|
|
||||||
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<byte> Reserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SaveDataExtraData
|
|
||||||
{
|
|
||||||
public SaveDataAttribute Attribute;
|
|
||||||
public ulong OwnerId;
|
|
||||||
public long TimeStamp;
|
|
||||||
public SaveDataFlags Flags;
|
|
||||||
public long DataSize;
|
|
||||||
public long JournalSize;
|
|
||||||
public long CommitId;
|
|
||||||
public Array400<byte> Reserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct CommitOption
|
|
||||||
{
|
|
||||||
public CommitOptionFlag Flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class SaveDataTypesValidity
|
internal static class SaveDataTypesValidity
|
||||||
{
|
{
|
||||||
public static bool IsValid(in SaveDataAttribute attribute)
|
public static bool IsValid(in SaveDataAttribute attribute)
|
||||||
{
|
{
|
||||||
return IsValid(in attribute.Type) && IsValid(in attribute.Rank);
|
return IsValid(in attribute.Type)&& IsValid(in attribute.Rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValid(in SaveDataCreationInfo creationInfo)
|
public static bool IsValid(in SaveDataCreationInfo creationInfo)
|
||||||
{
|
{
|
||||||
return creationInfo.Size >= 0 && creationInfo.JournalSize >= 0 && creationInfo.BlockSize >= 0 &&
|
return creationInfo.Size >= 0
|
||||||
IsValid(in creationInfo.SpaceId);
|
&& creationInfo.JournalSize >= 0
|
||||||
|
&& creationInfo.BlockSize >= 0
|
||||||
|
&& IsValid(in creationInfo.SpaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValid(in SaveDataCreationInfo2 creationInfo)
|
||||||
|
{
|
||||||
|
foreach (byte b in creationInfo.Reserved1.ItemsRo)
|
||||||
|
if (b != 0) return false;
|
||||||
|
|
||||||
|
foreach (byte b in creationInfo.Reserved2.ItemsRo)
|
||||||
|
if (b != 0) return false;
|
||||||
|
|
||||||
|
foreach (byte b in creationInfo.Reserved3.ItemsRo)
|
||||||
|
if (b != 0) return false;
|
||||||
|
|
||||||
|
foreach (byte b in creationInfo.Reserved4.ItemsRo)
|
||||||
|
if (b != 0) return false;
|
||||||
|
|
||||||
|
foreach (byte b in creationInfo.Attribute.Reserved.ItemsRo)
|
||||||
|
if (b != 0) return false;
|
||||||
|
|
||||||
|
return IsValid(in creationInfo.Attribute)
|
||||||
|
&& creationInfo.Size >= 0
|
||||||
|
&& creationInfo.JournalSize >= 0
|
||||||
|
&& creationInfo.BlockSize >= 0
|
||||||
|
&& IsValid(in creationInfo.SpaceId)
|
||||||
|
&& IsValid(in creationInfo.FormatType)
|
||||||
|
&& IsValid(in creationInfo.MetaType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValid(in SaveDataMetaInfo metaInfo)
|
public static bool IsValid(in SaveDataMetaInfo metaInfo)
|
||||||
|
@ -277,6 +424,11 @@ internal static class SaveDataTypesValidity
|
||||||
return (uint)type <= (uint)SaveDataType.Cache;
|
return (uint)type <= (uint)SaveDataType.Cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsValid(in SaveDataFormatType type)
|
||||||
|
{
|
||||||
|
return (uint)type <= (uint)SaveDataFormatType.NoJournal;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsValid(in SaveDataRank rank)
|
public static bool IsValid(in SaveDataRank rank)
|
||||||
{
|
{
|
||||||
return (uint)rank <= (uint)SaveDataRank.Secondary;
|
return (uint)rank <= (uint)SaveDataRank.Secondary;
|
||||||
|
@ -284,8 +436,9 @@ internal static class SaveDataTypesValidity
|
||||||
|
|
||||||
public static bool IsValid(in SaveDataSpaceId spaceId)
|
public static bool IsValid(in SaveDataSpaceId spaceId)
|
||||||
{
|
{
|
||||||
return (uint)spaceId <= (uint)SaveDataSpaceId.SdUser || spaceId == SaveDataSpaceId.ProperSystem ||
|
return (uint)spaceId <= (uint)SaveDataSpaceId.SdUser
|
||||||
spaceId == SaveDataSpaceId.SafeMode;
|
|| spaceId == SaveDataSpaceId.ProperSystem
|
||||||
|
|| spaceId == SaveDataSpaceId.SafeMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValid(in SaveDataMetaType metaType)
|
public static bool IsValid(in SaveDataMetaType metaType)
|
|
@ -46,18 +46,6 @@ public enum GameCardPartitionRaw
|
||||||
RootWriteOnly = 2
|
RootWriteOnly = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SaveDataSpaceId : byte
|
|
||||||
{
|
|
||||||
System = 0,
|
|
||||||
User = 1,
|
|
||||||
SdSystem = 2,
|
|
||||||
Temporary = 3,
|
|
||||||
SdUser = 4,
|
|
||||||
ProperSystem = 100,
|
|
||||||
SafeMode = 101,
|
|
||||||
BisAuto = 127
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CustomStorageId
|
public enum CustomStorageId
|
||||||
{
|
{
|
||||||
System = 0,
|
System = 0,
|
||||||
|
@ -86,22 +74,6 @@ public enum FileSystemProxyType
|
||||||
RegisteredUpdate = 8
|
RegisteredUpdate = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SaveDataMetaType : byte
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Thumbnail = 1,
|
|
||||||
ExtensionContext = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SaveDataState : byte
|
|
||||||
{
|
|
||||||
Normal = 0,
|
|
||||||
Processing = 1,
|
|
||||||
State2 = 2,
|
|
||||||
MarkedForDeletion = 3,
|
|
||||||
Extending = 4,
|
|
||||||
ImportSuspended = 5
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum ImageDirectoryId
|
public enum ImageDirectoryId
|
||||||
{
|
{
|
||||||
|
@ -153,48 +125,6 @@ public enum OperationId
|
||||||
ReadyLazyLoadFile = 10001
|
ReadyLazyLoadFile = 10001
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SaveDataType : byte
|
|
||||||
{
|
|
||||||
System = 0,
|
|
||||||
Account = 1,
|
|
||||||
Bcat = 2,
|
|
||||||
Device = 3,
|
|
||||||
Temporary = 4,
|
|
||||||
Cache = 5,
|
|
||||||
SystemBcat = 6
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SaveDataRank : byte
|
|
||||||
{
|
|
||||||
Primary = 0,
|
|
||||||
Secondary = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SaveDataFormatType : byte
|
|
||||||
{
|
|
||||||
Normal = 0,
|
|
||||||
NoJournal = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum SaveDataFlags
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
KeepAfterResettingSystemSaveData = 1 << 0,
|
|
||||||
KeepAfterRefurbishment = 1 << 1,
|
|
||||||
KeepAfterResettingSystemSaveDataWithoutUserSaveData = 1 << 2,
|
|
||||||
NeedsSecureDelete = 1 << 3,
|
|
||||||
Restore = 1 << 4
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum CommitOptionFlag
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
ClearRestoreFlag = 1,
|
|
||||||
SetRestoreFlag = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CacheStorageTargetMedia
|
public enum CacheStorageTargetMedia
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -294,10 +224,3 @@ public enum SdmmcPort
|
||||||
SdCard = 1,
|
SdCard = 1,
|
||||||
GcAsic = 2
|
GcAsic = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StorageType
|
|
||||||
{
|
|
||||||
SaveData = 0,
|
|
||||||
RomFs = 1,
|
|
||||||
Authoring = 2
|
|
||||||
}
|
|
|
@ -41,6 +41,32 @@ public class TypeLayoutTests
|
||||||
Assert.Equal(0x26, GetOffset(in s, in s.Reserved));
|
Assert.Equal(0x26, GetOffset(in s, in s.Reserved));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public static void SaveDataCreationInfo2_Layout()
|
||||||
|
{
|
||||||
|
var s = new SaveDataCreationInfo2();
|
||||||
|
|
||||||
|
Assert.Equal(0x200, Unsafe.SizeOf<SaveDataCreationInfo2>());
|
||||||
|
|
||||||
|
Assert.Equal(0x00, GetOffset(in s, in s.Version));
|
||||||
|
Assert.Equal(0x08, GetOffset(in s, in s.Attribute));
|
||||||
|
Assert.Equal(0x48, GetOffset(in s, in s.Size));
|
||||||
|
Assert.Equal(0x50, GetOffset(in s, in s.JournalSize));
|
||||||
|
Assert.Equal(0x58, GetOffset(in s, in s.BlockSize));
|
||||||
|
Assert.Equal(0x60, GetOffset(in s, in s.OwnerId));
|
||||||
|
Assert.Equal(0x68, GetOffset(in s, in s.Flags));
|
||||||
|
Assert.Equal(0x6C, GetOffset(in s, in s.SpaceId));
|
||||||
|
Assert.Equal(0x6D, GetOffset(in s, in s.FormatType));
|
||||||
|
Assert.Equal(0x6E, GetOffset(in s, in s.Reserved1));
|
||||||
|
Assert.Equal(0x70, GetOffset(in s, in s.IsHashSaltEnabled));
|
||||||
|
Assert.Equal(0x71, GetOffset(in s, in s.Reserved2));
|
||||||
|
Assert.Equal(0x74, GetOffset(in s, in s.HashSalt));
|
||||||
|
Assert.Equal(0x94, GetOffset(in s, in s.MetaType));
|
||||||
|
Assert.Equal(0x95, GetOffset(in s, in s.Reserved3));
|
||||||
|
Assert.Equal(0x98, GetOffset(in s, in s.MetaSize));
|
||||||
|
Assert.Equal(0x9C, GetOffset(in s, in s.Reserved4));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public static void SaveDataFilter_Layout()
|
public static void SaveDataFilter_Layout()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue