mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Diff some more storage related classes with FS 16
This commit is contained in:
parent
e2cbb0898c
commit
213515f06f
17 changed files with 151 additions and 25 deletions
36
src/LibHac/Common/FixedArrays/Array436.cs
Normal file
36
src/LibHac/Common/FixedArrays/Array436.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma warning disable CS0169, CS0649, IDE0051 // Field is never used, Field is never assigned to, Remove unused private members
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LibHac.Common.FixedArrays;
|
||||
|
||||
public struct Array436<T>
|
||||
{
|
||||
public const int Length = 436;
|
||||
|
||||
private Array256<T> _0;
|
||||
private Array128<T> _256;
|
||||
private Array32<T> _384;
|
||||
private Array20<T> _416;
|
||||
|
||||
[UnscopedRef] public ref T this[int i] => ref Items[i];
|
||||
|
||||
[UnscopedRef]
|
||||
public Span<T> Items
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
|
||||
}
|
||||
|
||||
[UnscopedRef]
|
||||
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 Array436<T> value) => value.ItemsRo;
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace LibHac.Fs;
|
|||
/// <summary>
|
||||
/// Contains functions for ensuring that an application's save data exists and is the correct size.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0</remarks>
|
||||
public static class ApplicationSaveDataManagement
|
||||
{
|
||||
private const int LeftoverFreeSpaceRequiredForUserAndDeviceSaves = 0x4000;
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace LibHac.Fs.Impl;
|
|||
/// <summary>
|
||||
/// Allows getting the current handle for the SD card and checking to see if a provided handle is still valid.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
internal class SdHandleManager : IDeviceHandleManager
|
||||
{
|
||||
// LibHac addition
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace LibHac.Fs;
|
|||
/// <summary>
|
||||
/// Allows interacting with a <see cref="byte"/> array via the <see cref="IStorage"/> interface.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class MemoryStorage : IStorage
|
||||
{
|
||||
private byte[] _buffer;
|
||||
|
@ -25,7 +25,6 @@ public class MemoryStorage : IStorage
|
|||
Assert.SdkRequiresNotNull(buffer);
|
||||
Assert.SdkRequiresInRange(size, 0, buffer.Length);
|
||||
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
||||
Abort.DoAbortUnless(buffer is null || 0 <= size && size < buffer.Length);
|
||||
|
||||
_buffer = buffer;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
/// <summary>
|
||||
/// Reads the root partition of a game card and handles opening the various partitions it contains.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class GameCardRootPartition : IDisposable
|
||||
{
|
||||
private const int LogoPartitionSizeMax = 0x12000;
|
||||
|
@ -209,7 +209,7 @@ public class GameCardRootPartition : IDisposable
|
|||
/// <summary>
|
||||
/// Creates <see cref="IFileSystem"/>s of the various partitions contained by the currently mounted game card.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class GameCardFileSystemCreator : IGameCardFileSystemCreator
|
||||
{
|
||||
private MemoryResource _allocator;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
/// <summary>
|
||||
/// Creates <see cref="IStorage"/>s to the currently mounted game card.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class GameCardStorageCreator : IGameCardStorageCreator
|
||||
{
|
||||
// LibHac addition so we can access fssrv::storage functions
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
/// <summary>
|
||||
/// Creates <see cref="IStorage"/>s for accessing the inserted SD card's storage.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class SdStorageCreator : ISdStorageCreator
|
||||
{
|
||||
// LibHac addition
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace LibHac.FsSrv.Storage;
|
|||
/// Manages setting storage devices as ready or not ready, and allows opening <see cref="IStorageDeviceManager"/>s for
|
||||
/// each storage device.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public interface IStorageDeviceManagerFactory : IDisposable
|
||||
{
|
||||
Result Create(ref SharedRef<IStorageDeviceManager> outDeviceManager, StorageDevicePortId portId);
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace LibHac.FsSrv.Storage.Sf;
|
|||
/// Allows reading from or writing to a storage device's storage like an <see cref="IStorage"/>, getting or validating
|
||||
/// its current handle, and opening an <see cref="IStorageDeviceOperator"/> for the storage device.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public interface IStorageDevice : IStorage
|
||||
{
|
||||
Result GetHandle(out uint handle);
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace LibHac.FsSrv.Storage.Sf;
|
|||
/// <summary>
|
||||
/// Allows getting the current state of a storage device and opening various interfaces to operate on it.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public interface IStorageDeviceManager : IDisposable
|
||||
{
|
||||
Result IsInserted(out bool isInserted);
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace LibHac.FsSrv.Storage.Sf;
|
|||
/// </summary>
|
||||
/// <remarks><para>Operation IDs are not common between implementers of the interface. Every implementer will have its own operations
|
||||
/// and expected input data.</para>
|
||||
/// <para>Based on nnSdk 15.3.0 (FS 15.0.0)</para></remarks>
|
||||
/// <para>Based on nnSdk 16.2.0 (FS 16.0.0)</para></remarks>
|
||||
public interface IStorageDeviceOperator : IDisposable
|
||||
{
|
||||
Result Operate(int operationId);
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace LibHac.FsSystem;
|
|||
/// <summary>
|
||||
/// Base class for classes that manage registering events and signaling them when a card device is inserted or removed.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
internal class CardDeviceDetectionEventManager : IDisposable
|
||||
{
|
||||
private LinkedList<CardDeviceDetectionEvent> _events;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace LibHac.FsSystem;
|
|||
/// </summary>
|
||||
/// <remarks><para>The original allocator in FS simply calls <c>nn::fs::detail::Allocate</c> and
|
||||
/// <c>nn::fs::detail::Deallocate</c>. In our implementation we use the shared .NET <see cref="ArrayPool{T}"/>.</para>
|
||||
/// <para>Based on nnSdk 15.3.0 (FS 15.0.0)</para></remarks>
|
||||
/// <para>Based on nnSdk 16.2.0 (FS 16.0.0)</para></remarks>
|
||||
file sealed class DefaultAllocatorForPartitionFileSystem : MemoryResource
|
||||
{
|
||||
public static readonly DefaultAllocatorForPartitionFileSystem Instance = new();
|
||||
|
@ -50,7 +50,7 @@ file sealed class DefaultAllocatorForPartitionFileSystem : MemoryResource
|
|||
/// Reads a standard partition file system. These files start with "PFS0" and are typically found inside NCAs
|
||||
/// or as .nsp files.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class PartitionFileSystem : PartitionFileSystemCore<PartitionFileSystemMeta,
|
||||
Impl.PartitionFileSystemFormat,
|
||||
Impl.PartitionFileSystemFormat.PartitionFileSystemHeaderImpl,
|
||||
|
@ -59,7 +59,7 @@ public class PartitionFileSystem : PartitionFileSystemCore<PartitionFileSystemMe
|
|||
/// <summary>
|
||||
/// Reads a hashed partition file system. These files start with "HFS0" and are typically found inside XCIs.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class Sha256PartitionFileSystem : PartitionFileSystemCore<Sha256PartitionFileSystemMeta,
|
||||
Impl.Sha256PartitionFileSystemFormat,
|
||||
Impl.PartitionFileSystemFormat.PartitionFileSystemHeaderImpl,
|
||||
|
@ -74,7 +74,7 @@ public class Sha256PartitionFileSystem : PartitionFileSystemCore<Sha256Partition
|
|||
/// <typeparam name="TFormat">A traits class that provides values used to read and build the metadata.</typeparam>
|
||||
/// <typeparam name="THeader">The type of the header at the beginning of the metadata.</typeparam>
|
||||
/// <typeparam name="TEntry">The type of the entries in the file table in the metadata.</typeparam>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class PartitionFileSystemCore<TMetaData, TFormat, THeader, TEntry> : IFileSystem
|
||||
where TMetaData : PartitionFileSystemMetaCore<TFormat, THeader, TEntry>, new()
|
||||
where TFormat : IPartitionFileSystemFormat
|
||||
|
@ -93,7 +93,7 @@ public class PartitionFileSystemCore<TMetaData, TFormat, THeader, TEntry> : IFil
|
|||
/// <summary>
|
||||
/// Provides access to a file from a <see cref="PartitionFileSystemCore{TMetaData,TFormat,THeader,TEntry}"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
private class PartitionFile : IFile
|
||||
{
|
||||
private TEntry _partitionEntry;
|
||||
|
@ -337,7 +337,7 @@ public class PartitionFileSystemCore<TMetaData, TFormat, THeader, TEntry> : IFil
|
|||
/// </summary>
|
||||
/// <remarks><para>A <see cref="PartitionFileSystemCore{TMetaData,TFormat,THeader,TEntry}"/> cannot contain any
|
||||
/// subdirectories, so a <see cref="PartitionDirectory"/> will only access the root directory.</para>
|
||||
/// <para>Based on nnSdk 15.3.0 (FS 15.0.0)</para></remarks>
|
||||
/// <para>Based on nnSdk 16.2.0 (FS 16.0.0)</para></remarks>
|
||||
private class PartitionDirectory : IDirectory
|
||||
{
|
||||
private int _currentIndex;
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace LibHac.FsSystem
|
|||
/// <typeparam name="TFormat">A traits class that provides values used to read and build the metadata.</typeparam>
|
||||
/// <typeparam name="THeader">The type of the header at the beginning of the metadata.</typeparam>
|
||||
/// <typeparam name="TEntry">The type of the entries in the file table in the metadata.</typeparam>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class PartitionFileSystemMetaCore<TFormat, THeader, TEntry> : IDisposable
|
||||
where TFormat : IPartitionFileSystemFormat
|
||||
where THeader : unmanaged, IPartitionFileSystemHeader
|
||||
|
@ -290,7 +290,7 @@ namespace LibHac.FsSystem
|
|||
/// <summary>
|
||||
/// Reads the metadata for a <see cref="Sha256PartitionFileSystem"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class Sha256PartitionFileSystemMeta : PartitionFileSystemMetaCore<TFormat, THeader, TFormat.PartitionEntry>
|
||||
{
|
||||
public Result Initialize(IStorage baseStorage, MemoryResource allocator, ReadOnlySpan<byte> hash)
|
||||
|
@ -360,7 +360,7 @@ namespace LibHac.FsSystem
|
|||
/// <summary>
|
||||
/// Reads the metadata for a <see cref="PartitionFileSystem"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 15.3.0 (FS 15.0.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 16.2.0 (FS 16.0.0)</remarks>
|
||||
public class PartitionFileSystemMeta : PartitionFileSystemMetaCore<PartitionFileSystemFormat,
|
||||
PartitionFileSystemFormat.PartitionFileSystemHeaderImpl, PartitionFileSystemFormat.PartitionEntry> { }
|
||||
}
|
|
@ -277,7 +277,7 @@ public sealed class GameCardEmulated : IGcApi
|
|||
|
||||
int limArea = (int)_cardHeader.LimAreaPage;
|
||||
bool isNormal = pageAddress < limArea;
|
||||
bool isSecure = (pageAddress + pageCount - 1) >= limArea;
|
||||
bool isSecure = pageAddress + pageCount - 1 >= limArea;
|
||||
|
||||
// Reads cannot span the boundary between the normal area and secure area.
|
||||
if (isNormal && isSecure)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using LibHac.Common.FixedArrays;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common.FixedArrays;
|
||||
|
||||
namespace LibHac.Gc.Impl;
|
||||
|
||||
|
@ -22,9 +23,60 @@ public struct CardId3
|
|||
public Array4<byte> Reserved;
|
||||
}
|
||||
|
||||
public enum DevCardRomSize : byte
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
Size1GB = 3,
|
||||
Size2GB = 4,
|
||||
Size4GB = 5,
|
||||
Size8GB = 6,
|
||||
Size16GB = 7,
|
||||
Size32GB = 8
|
||||
// ReSharper restore InconsistentNaming
|
||||
}
|
||||
|
||||
public enum DevCardNandSize : byte
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
Size16GB = 7,
|
||||
Size32GB = 8,
|
||||
Size64GB = 9
|
||||
// ReSharper restore InconsistentNaming
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct DevCardParameter
|
||||
{
|
||||
public Array512<byte> Data;
|
||||
public CardId1 CardId1;
|
||||
public CardId2 CardId2;
|
||||
public CardId3 CardId3;
|
||||
public uint RomAreaStartAddr;
|
||||
public uint BackupAreaStartAddr;
|
||||
public Array3<byte> ReservedAreaStartAddr;
|
||||
public DevCardRomSize RomSize;
|
||||
public Array2<byte> WaitCycle1ForRead;
|
||||
public Array2<byte> WaitCycle2ForRead;
|
||||
public byte SpeedChangeEmulateWaitCycle1FrequencyForRead;
|
||||
public Array3<byte> SpeedChangeEmulateWaitCycle1ForRead;
|
||||
public byte SpeedChangeEmulateWaitCycle2FrequencyForRead;
|
||||
public Array3<byte> SpeedChangeEmulateWaitCycle2ForRead;
|
||||
public Array3<byte> FirstReadPageWaitCycleForRead;
|
||||
public Array2<byte> WaitCycle1ForWrite;
|
||||
public Array3<byte> WaitCycle2ForWrite;
|
||||
public byte SpeedChangeEmulateWaitCycle1FrequencyForWrite;
|
||||
public Array3<byte> SpeedChangeEmulateWaitCycle1ForWrite;
|
||||
public byte SpeedChangeEmulateWaitCycle2FrequencyForWrite;
|
||||
public Array3<byte> SpeedChangeEmulateWaitCycle2ForWrite;
|
||||
public Array2<byte> WaitCycle1ForSetAccessPattern;
|
||||
public Array3<byte> WaitCycle2ForSetAccessPattern;
|
||||
public Array3<byte> WaitCycleForRefresh;
|
||||
public Array3<byte> WaitCycleForSetKey;
|
||||
public Array3<byte> WaitCycleForIRdInit;
|
||||
public Array3<byte> WaitCycleForISetInit1;
|
||||
public Array3<byte> WaitCycleForISetGen;
|
||||
public Array3<byte> WaitCycleForISetInit2;
|
||||
public DevCardNandSize NandSize;
|
||||
public Array436<byte> Reserved;
|
||||
}
|
||||
|
||||
public struct CardInitialDataPayload
|
||||
|
|
|
@ -101,6 +101,45 @@ public class TypeLayoutTests
|
|||
Assert.Equal(0x30, GetOffset(in s, in s.AuthNonce));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void DevCardParameter_Layout()
|
||||
{
|
||||
var s = new DevCardParameter();
|
||||
|
||||
Assert.Equal(0x200, Unsafe.SizeOf<DevCardParameter>());
|
||||
|
||||
Assert.Equal(0x00, GetOffset(in s, in s.CardId1));
|
||||
Assert.Equal(0x04, GetOffset(in s, in s.CardId2));
|
||||
Assert.Equal(0x08, GetOffset(in s, in s.CardId3));
|
||||
Assert.Equal(0x0C, GetOffset(in s, in s.RomAreaStartAddr));
|
||||
Assert.Equal(0x10, GetOffset(in s, in s.BackupAreaStartAddr));
|
||||
Assert.Equal(0x14, GetOffset(in s, in s.ReservedAreaStartAddr));
|
||||
Assert.Equal(0x17, GetOffset(in s, in s.RomSize));
|
||||
Assert.Equal(0x18, GetOffset(in s, in s.WaitCycle1ForRead));
|
||||
Assert.Equal(0x1A, GetOffset(in s, in s.WaitCycle2ForRead));
|
||||
Assert.Equal(0x1C, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle1FrequencyForRead));
|
||||
Assert.Equal(0x1D, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle1ForRead));
|
||||
Assert.Equal(0x20, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle2FrequencyForRead));
|
||||
Assert.Equal(0x21, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle2ForRead));
|
||||
Assert.Equal(0x24, GetOffset(in s, in s.FirstReadPageWaitCycleForRead));
|
||||
Assert.Equal(0x27, GetOffset(in s, in s.WaitCycle1ForWrite));
|
||||
Assert.Equal(0x29, GetOffset(in s, in s.WaitCycle2ForWrite));
|
||||
Assert.Equal(0x2C, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle1FrequencyForWrite));
|
||||
Assert.Equal(0x2D, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle1ForWrite));
|
||||
Assert.Equal(0x30, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle2FrequencyForWrite));
|
||||
Assert.Equal(0x31, GetOffset(in s, in s.SpeedChangeEmulateWaitCycle2ForWrite));
|
||||
Assert.Equal(0x34, GetOffset(in s, in s.WaitCycle1ForSetAccessPattern));
|
||||
Assert.Equal(0x36, GetOffset(in s, in s.WaitCycle2ForSetAccessPattern));
|
||||
Assert.Equal(0x39, GetOffset(in s, in s.WaitCycleForRefresh));
|
||||
Assert.Equal(0x3C, GetOffset(in s, in s.WaitCycleForSetKey));
|
||||
Assert.Equal(0x3F, GetOffset(in s, in s.WaitCycleForIRdInit));
|
||||
Assert.Equal(0x42, GetOffset(in s, in s.WaitCycleForISetInit1));
|
||||
Assert.Equal(0x45, GetOffset(in s, in s.WaitCycleForISetGen));
|
||||
Assert.Equal(0x48, GetOffset(in s, in s.WaitCycleForISetInit2));
|
||||
Assert.Equal(0x4B, GetOffset(in s, in s.NandSize));
|
||||
Assert.Equal(0x4C, GetOffset(in s, in s.Reserved));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void CardInitialData_Layout()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue