mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add BCAT storage skeleton
This commit is contained in:
parent
5018bbad6a
commit
da78e7e8ce
23 changed files with 553 additions and 8 deletions
|
@ -3,4 +3,5 @@ Fs,2
|
|||
Loader,9
|
||||
Kvdb,20
|
||||
Sdmmc,24
|
||||
Bcat,122
|
||||
LibHac,428
|
|
|
@ -3,4 +3,5 @@ Fs,LibHac.Fs,LibHac/Fs/ResultFs.cs
|
|||
Loader,LibHac.Loader,LibHac/Loader/ResultLoader.cs
|
||||
Kvdb,LibHac.Kvdb,LibHac/Kvdb/ResultKvdb.cs
|
||||
Sdmmc,LibHac.FsService,LibHac/FsService/ResultSdmmc.cs
|
||||
Bcat,LibHac.Bcat,LibHac/Bcat/ResultBcat.cs
|
||||
LibHac,LibHac.Common,LibHac/Common/ResultLibHac.cs
|
|
|
@ -277,6 +277,19 @@ Module,DescriptionStart,DescriptionEnd,Name,Summary
|
|||
24,1,,DeviceNotFound,
|
||||
24,4,,DeviceAsleep,
|
||||
|
||||
122,1,,InvalidArgument,
|
||||
122,2,,NotFound,
|
||||
122,7,,NotOpen,
|
||||
122,9,,ServiceOpenLimitReached,
|
||||
122,10,,SaveDataNotFount,
|
||||
|
||||
122,31,,NetworkServiceAccountNotAvailable,
|
||||
|
||||
122,90,,PermissionDenied,
|
||||
|
||||
122,204,,InvalidStorageMetaVersion,
|
||||
122,205,,StorageOpenLimitReached,
|
||||
|
||||
123,0,4999,SslService,
|
||||
|
||||
124,0,,Cancelled,
|
||||
|
@ -307,6 +320,8 @@ Module,DescriptionStart,DescriptionEnd,Name,Summary
|
|||
428,3,,ArgumentOutOfRange,
|
||||
428,4,,BufferTooSmall,
|
||||
|
||||
428,51,,ServiceNotInitialized,
|
||||
|
||||
428,1000,1999,InvalidData,
|
||||
428,1001,1019,InvalidKip,
|
||||
428,1002,,InvalidKipFileSize,The size of the KIP file was smaller than expected.
|
||||
|
|
|
93
src/LibHac/Bcat/BcatServer.cs
Normal file
93
src/LibHac/Bcat/BcatServer.cs
Normal file
|
@ -0,0 +1,93 @@
|
|||
using System.Diagnostics;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
using LibHac.Bcat.Detail.Service;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
public class BcatServer
|
||||
{
|
||||
private const int ServiceTypeCount = 4;
|
||||
|
||||
private Horizon ServiceManager { get; }
|
||||
private ServiceCreator[] ServiceCreators { get; } = new ServiceCreator[ServiceTypeCount];
|
||||
|
||||
private readonly object _storageManagerInitLocker = new object();
|
||||
private readonly object _fsInitLocker = new object();
|
||||
|
||||
private DeliveryCacheStorageManager StorageManager { get; set; }
|
||||
private FileSystemClient FsClient { get; set; }
|
||||
|
||||
public BcatServer(Horizon horizon)
|
||||
{
|
||||
ServiceManager = horizon;
|
||||
|
||||
InitServiceCreator(BcatServiceType.BcatU, AccessControl.Bit1);
|
||||
InitServiceCreator(BcatServiceType.BcatS, AccessControl.Bit2);
|
||||
InitServiceCreator(BcatServiceType.BcatM, AccessControl.Bit2 | AccessControl.Bit3);
|
||||
InitServiceCreator(BcatServiceType.BcatA, AccessControl.All);
|
||||
}
|
||||
|
||||
public Result GetServiceCreator(out IServiceCreator serviceCreator, BcatServiceType type)
|
||||
{
|
||||
if ((uint)type < ServiceTypeCount)
|
||||
{
|
||||
serviceCreator = default;
|
||||
return ResultLibHac.ArgumentOutOfRange.Log();
|
||||
}
|
||||
|
||||
serviceCreator = ServiceCreators[(int)type];
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private void InitServiceCreator(BcatServiceType type, AccessControl accessControl)
|
||||
{
|
||||
Debug.Assert((uint)type < ServiceTypeCount);
|
||||
|
||||
ServiceCreators[(int)type] = new ServiceCreator(this, type, accessControl);
|
||||
}
|
||||
|
||||
internal DeliveryCacheStorageManager GetStorageManager()
|
||||
{
|
||||
return StorageManager ?? InitStorageManager();
|
||||
}
|
||||
|
||||
internal FileSystemClient GetFsClient()
|
||||
{
|
||||
return FsClient ?? InitFsClient();
|
||||
}
|
||||
|
||||
private DeliveryCacheStorageManager InitStorageManager()
|
||||
{
|
||||
lock (_storageManagerInitLocker)
|
||||
{
|
||||
if (StorageManager != null)
|
||||
{
|
||||
return StorageManager;
|
||||
}
|
||||
|
||||
StorageManager = new DeliveryCacheStorageManager();
|
||||
return StorageManager;
|
||||
}
|
||||
}
|
||||
|
||||
private FileSystemClient InitFsClient()
|
||||
{
|
||||
lock (_fsInitLocker)
|
||||
{
|
||||
if (FsClient != null)
|
||||
{
|
||||
return FsClient;
|
||||
}
|
||||
|
||||
Result rc = ServiceManager.OpenFileSystemClient(out FileSystemClient fsClient);
|
||||
|
||||
if (!rc.IsSuccess())
|
||||
throw new HorizonResultException(rc, "Abort");
|
||||
|
||||
return fsClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
src/LibHac/Bcat/BcatServiceType.cs
Normal file
10
src/LibHac/Bcat/BcatServiceType.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace LibHac.Bcat
|
||||
{
|
||||
public enum BcatServiceType
|
||||
{
|
||||
BcatU,
|
||||
BcatS,
|
||||
BcatM,
|
||||
BcatA
|
||||
}
|
||||
}
|
12
src/LibHac/Bcat/DeliveryCacheDirectoryEntry.cs
Normal file
12
src/LibHac/Bcat/DeliveryCacheDirectoryEntry.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
11
src/LibHac/Bcat/Detail/Ipc/IDeliveryCacheDirectoryService.cs
Normal file
11
src/LibHac/Bcat/Detail/Ipc/IDeliveryCacheDirectoryService.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Ipc
|
||||
{
|
||||
public interface IDeliveryCacheDirectoryService
|
||||
{
|
||||
Result Open(ref DirectoryName name);
|
||||
Result Read(ref int entriesRead, Span<DeliveryCacheDirectoryEntry> entryBuffer);
|
||||
Result GetCount(ref int count);
|
||||
}
|
||||
}
|
12
src/LibHac/Bcat/Detail/Ipc/IDeliveryCacheFileService.cs
Normal file
12
src/LibHac/Bcat/Detail/Ipc/IDeliveryCacheFileService.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Ipc
|
||||
{
|
||||
public interface IDeliveryCacheFileService
|
||||
{
|
||||
Result Open(ref DirectoryName directoryName, ref FileName fileName);
|
||||
Result Read(out long bytesRead, long offset, Span<byte> destination);
|
||||
Result GetSize(out long size);
|
||||
Result GetDigest(out Digest digest);
|
||||
}
|
||||
}
|
11
src/LibHac/Bcat/Detail/Ipc/IDeliveryCacheStorageService.cs
Normal file
11
src/LibHac/Bcat/Detail/Ipc/IDeliveryCacheStorageService.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Ipc
|
||||
{
|
||||
public interface IDeliveryCacheStorageService
|
||||
{
|
||||
Result CreateFileService(out IDeliveryCacheFileService fileService);
|
||||
Result CreateDirectoryService(out IDeliveryCacheDirectoryService directoryService);
|
||||
Result EnumerateDeliveryCacheDirectory(out int namesRead, Span<DirectoryName> nameBuffer);
|
||||
}
|
||||
}
|
10
src/LibHac/Bcat/Detail/Ipc/IServiceCreator.cs
Normal file
10
src/LibHac/Bcat/Detail/Ipc/IServiceCreator.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using LibHac.Ncm;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Ipc
|
||||
{
|
||||
public interface IServiceCreator
|
||||
{
|
||||
Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service,
|
||||
TitleId applicationId);
|
||||
}
|
||||
}
|
16
src/LibHac/Bcat/Detail/Service/AccessControl.cs
Normal file
16
src/LibHac/Bcat/Detail/Service/AccessControl.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
[Flags]
|
||||
internal enum AccessControl
|
||||
{
|
||||
None = 0,
|
||||
Bit0 = 1 << 0,
|
||||
Bit1 = 1 << 1,
|
||||
Bit2 = 1 << 2,
|
||||
Bit3 = 1 << 3,
|
||||
Bit4 = 1 << 4,
|
||||
All = ~0
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
internal class DeliveryCacheDirectoryService : IDeliveryCacheDirectoryService
|
||||
{
|
||||
public object Locker { get; } = new object();
|
||||
private DeliveryCacheStorageService Parent { get; }
|
||||
private AccessControl Access { get; }
|
||||
private ulong ApplicationId { get; }
|
||||
private DirectoryName _name;
|
||||
private bool IsDirectoryOpen { get; set; }
|
||||
private int Count { get; set; }
|
||||
|
||||
public DeliveryCacheDirectoryService(DeliveryCacheStorageService parent, ulong applicationId,
|
||||
AccessControl accessControl)
|
||||
{
|
||||
Parent = parent;
|
||||
ApplicationId = applicationId;
|
||||
Access = accessControl;
|
||||
}
|
||||
|
||||
public Result Open(ref DirectoryName name)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result Read(ref int entriesRead, Span<DeliveryCacheDirectoryEntry> entryBuffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetCount(ref int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
12
src/LibHac/Bcat/Detail/Service/DeliveryCacheFileEntryMeta.cs
Normal file
12
src/LibHac/Bcat/Detail/Service/DeliveryCacheFileEntryMeta.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x80)]
|
||||
internal struct DeliveryCacheFileEntryMeta
|
||||
{
|
||||
[FieldOffset(0x00)] public FileName Name;
|
||||
[FieldOffset(0x20)] public long Size;
|
||||
[FieldOffset(0x30)] public Digest Digest;
|
||||
}
|
||||
}
|
45
src/LibHac/Bcat/Detail/Service/DeliveryCacheFileService.cs
Normal file
45
src/LibHac/Bcat/Detail/Service/DeliveryCacheFileService.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
internal class DeliveryCacheFileService : IDeliveryCacheFileService
|
||||
{
|
||||
public object Locker { get; } = new object();
|
||||
private DeliveryCacheStorageService Parent { get; }
|
||||
private AccessControl Access { get; }
|
||||
private ulong ApplicationId { get; }
|
||||
private FileHandle Handle { get; set; }
|
||||
private DeliveryCacheFileEntryMeta _metaEntry;
|
||||
private bool IsFileOpen { get; set; }
|
||||
|
||||
public DeliveryCacheFileService(DeliveryCacheStorageService parent, ulong applicationId,
|
||||
AccessControl accessControl)
|
||||
{
|
||||
Parent = parent;
|
||||
ApplicationId = applicationId;
|
||||
Access = accessControl;
|
||||
}
|
||||
|
||||
public Result Open(ref DirectoryName directoryName, ref FileName fileName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result Read(out long bytesRead, long offset, Span<byte> destination)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetSize(out long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result GetDigest(out Digest digest)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
internal class DeliveryCacheStorageManager
|
||||
{
|
||||
private const int MaxEntryCount = 4;
|
||||
|
||||
private readonly object _locker = new object();
|
||||
private Entry[] Entries { get; set; } = new Entry[MaxEntryCount];
|
||||
private bool UseRealStorage { get; set; }
|
||||
|
||||
private struct Entry
|
||||
{
|
||||
public ulong ApplicationId { get; set; }
|
||||
public long RefCount { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
internal class DeliveryCacheStorageService : IDeliveryCacheStorageService
|
||||
{
|
||||
public object Locker { get; } = new object();
|
||||
private AccessControl Access { get; }
|
||||
private ulong ApplicationId { get; }
|
||||
private int OpenFileServiceCount { get; set; }
|
||||
private int OpenDirectoryServiceCount { get; set; }
|
||||
|
||||
public DeliveryCacheStorageService(ulong applicationId, AccessControl accessControl)
|
||||
{
|
||||
ApplicationId = applicationId;
|
||||
Access = accessControl;
|
||||
}
|
||||
|
||||
public Result CreateFileService(out IDeliveryCacheFileService fileService)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result CreateDirectoryService(out IDeliveryCacheDirectoryService directoryService)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result EnumerateDeliveryCacheDirectory(out int namesRead, Span<DirectoryName> nameBuffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
37
src/LibHac/Bcat/Detail/Service/ServiceCreator.cs
Normal file
37
src/LibHac/Bcat/Detail/Service/ServiceCreator.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
using LibHac.Ncm;
|
||||
|
||||
namespace LibHac.Bcat.Detail.Service
|
||||
{
|
||||
internal class ServiceCreator : IServiceCreator
|
||||
{
|
||||
private BcatServer Parent { get; }
|
||||
private BcatServiceType ServiceType { get; }
|
||||
private AccessControl AccessControl { get; }
|
||||
|
||||
public ServiceCreator(BcatServer parentServer, BcatServiceType type, AccessControl accessControl)
|
||||
{
|
||||
Parent = parentServer;
|
||||
ServiceType = type;
|
||||
AccessControl = accessControl;
|
||||
}
|
||||
|
||||
public Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service,
|
||||
TitleId applicationId)
|
||||
{
|
||||
service = default;
|
||||
|
||||
if (!AccessControl.HasFlag(AccessControl.Bit2))
|
||||
return ResultBcat.PermissionDenied.Log();
|
||||
|
||||
return CreateDeliveryCacheStorageServiceImpl(out service, applicationId);
|
||||
}
|
||||
|
||||
private Result CreateDeliveryCacheStorageServiceImpl(out IDeliveryCacheStorageService service,
|
||||
TitleId applicationId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
28
src/LibHac/Bcat/Digest.cs
Normal file
28
src/LibHac/Bcat/Digest.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
|
||||
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 byte this[int i]
|
||||
{
|
||||
get => Bytes[i];
|
||||
set => Bytes[i] = value;
|
||||
}
|
||||
|
||||
public Span<byte> Bytes => SpanHelpers.AsByteSpan(ref this);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Bytes.ToHexString();
|
||||
}
|
||||
}
|
||||
}
|
30
src/LibHac/Bcat/DirectoryName.cs
Normal file
30
src/LibHac/Bcat/DirectoryName.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
[DebuggerDisplay("{ToString()}")]
|
||||
[StructLayout(LayoutKind.Sequential, Size = 32)]
|
||||
public struct DirectoryName
|
||||
{
|
||||
[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 byte this[int i]
|
||||
{
|
||||
get => Bytes[i];
|
||||
set => Bytes[i] = value;
|
||||
}
|
||||
|
||||
public Span<byte> Bytes => SpanHelpers.AsByteSpan(ref this);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return StringUtils.Utf8ZToString(Bytes);
|
||||
}
|
||||
}
|
||||
}
|
30
src/LibHac/Bcat/FileName.cs
Normal file
30
src/LibHac/Bcat/FileName.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
[DebuggerDisplay("{ToString()}")]
|
||||
[StructLayout(LayoutKind.Sequential, Size = 32)]
|
||||
public struct FileName
|
||||
{
|
||||
[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 byte this[int i]
|
||||
{
|
||||
get => Bytes[i];
|
||||
set => Bytes[i] = value;
|
||||
}
|
||||
|
||||
public Span<byte> Bytes => SpanHelpers.AsByteSpan(ref this);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return StringUtils.Utf8ZToString(Bytes);
|
||||
}
|
||||
}
|
||||
}
|
37
src/LibHac/Bcat/ResultBcat.cs
Normal file
37
src/LibHac/Bcat/ResultBcat.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// This file was automatically generated.
|
||||
// Changes to this file will be lost when the file is regenerated.
|
||||
//
|
||||
// To change this file, modify /build/CodeGen/results.csv at the root of this
|
||||
// repo and run the build script.
|
||||
//
|
||||
// The script can be run with the "codegen" option to run only the
|
||||
// code generation portion of the build.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace LibHac.Bcat
|
||||
{
|
||||
public static class ResultBcat
|
||||
{
|
||||
public const int ModuleBcat = 122;
|
||||
|
||||
/// <summary>Error code: 2122-0001; Inner value: 0x27a</summary>
|
||||
public static Result.Base InvalidArgument => new Result.Base(ModuleBcat, 1);
|
||||
/// <summary>Error code: 2122-0002; Inner value: 0x47a</summary>
|
||||
public static Result.Base NotFound => new Result.Base(ModuleBcat, 2);
|
||||
/// <summary>Error code: 2122-0007; Inner value: 0xe7a</summary>
|
||||
public static Result.Base NotOpen => new Result.Base(ModuleBcat, 7);
|
||||
/// <summary>Error code: 2122-0009; Inner value: 0x127a</summary>
|
||||
public static Result.Base ServiceOpenLimitReached => new Result.Base(ModuleBcat, 9);
|
||||
/// <summary>Error code: 2122-0010; Inner value: 0x147a</summary>
|
||||
public static Result.Base SaveDataNotFount => new Result.Base(ModuleBcat, 10);
|
||||
/// <summary>Error code: 2122-0031; Inner value: 0x3e7a</summary>
|
||||
public static Result.Base NetworkServiceAccountNotAvailable => new Result.Base(ModuleBcat, 31);
|
||||
/// <summary>Error code: 2122-0090; Inner value: 0xb47a</summary>
|
||||
public static Result.Base PermissionDenied => new Result.Base(ModuleBcat, 90);
|
||||
/// <summary>Error code: 2122-0204; Inner value: 0x1987a</summary>
|
||||
public static Result.Base InvalidStorageMetaVersion => new Result.Base(ModuleBcat, 204);
|
||||
/// <summary>Error code: 2122-0205; Inner value: 0x19a7a</summary>
|
||||
public static Result.Base StorageOpenLimitReached => new Result.Base(ModuleBcat, 205);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,9 @@ namespace LibHac.Common
|
|||
/// <summary>Error code: 2428-0004; Inner value: 0x9ac</summary>
|
||||
public static Result.Base BufferTooSmall => new Result.Base(ModuleLibHac, 4);
|
||||
|
||||
/// <summary>Error code: 2428-0051; Inner value: 0x67ac</summary>
|
||||
public static Result.Base ServiceNotInitialized => new Result.Base(ModuleLibHac, 51);
|
||||
|
||||
/// <summary>Error code: 2428-1000; Range: 1000-1999; Inner value: 0x7d1ac</summary>
|
||||
public static Result.Base InvalidData { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleLibHac, 1000, 1999); }
|
||||
/// <summary>Error code: 2428-1001; Range: 1001-1019; Inner value: 0x7d3ac</summary>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
using LibHac.Fs;
|
||||
using LibHac.Bcat;
|
||||
using LibHac.Bcat.Detail.Ipc;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsService;
|
||||
using LibHac.FsService.Creators;
|
||||
|
||||
|
@ -7,32 +10,69 @@ namespace LibHac
|
|||
public class Horizon
|
||||
{
|
||||
internal ITimeSpanGenerator Time { get; }
|
||||
|
||||
public FileSystemClient Fs { get; }
|
||||
public FileSystemServer FsSrv { get; private set; }
|
||||
private FileSystemServer FileSystemServer { get; set; }
|
||||
private BcatServer BcatServer { get; set; }
|
||||
|
||||
private readonly object _initLocker = new object();
|
||||
|
||||
public Horizon(ITimeSpanGenerator timer)
|
||||
{
|
||||
Time = timer;
|
||||
}
|
||||
|
||||
Fs = new FileSystemClient(timer);
|
||||
public Result OpenFileSystemProxyService(out IFileSystemProxy service)
|
||||
{
|
||||
if (FileSystemServer is null)
|
||||
{
|
||||
service = default;
|
||||
return ResultLibHac.ServiceNotInitialized.Log();
|
||||
}
|
||||
|
||||
service = FileSystemServer.CreateFileSystemProxyService();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result OpenFileSystemClient(out FileSystemClient client)
|
||||
{
|
||||
if (FileSystemServer is null)
|
||||
{
|
||||
client = default;
|
||||
return ResultLibHac.ServiceNotInitialized.Log();
|
||||
}
|
||||
|
||||
client = FileSystemServer.CreateFileSystemClient();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result OpenBcatUService(out IServiceCreator service) => OpenBcatService(out service, BcatServiceType.BcatU);
|
||||
public Result OpenBcatSService(out IServiceCreator service) => OpenBcatService(out service, BcatServiceType.BcatS);
|
||||
public Result OpenBcatMService(out IServiceCreator service) => OpenBcatService(out service, BcatServiceType.BcatM);
|
||||
public Result OpenBcatAService(out IServiceCreator service) => OpenBcatService(out service, BcatServiceType.BcatA);
|
||||
|
||||
private Result OpenBcatService(out IServiceCreator service, BcatServiceType type)
|
||||
{
|
||||
if (BcatServer is null)
|
||||
{
|
||||
service = default;
|
||||
return ResultLibHac.ServiceNotInitialized.Log();
|
||||
}
|
||||
|
||||
return BcatServer.GetServiceCreator(out service, type);
|
||||
}
|
||||
|
||||
public void InitializeFileSystemServer(FileSystemCreators fsCreators, IDeviceOperator deviceOperator)
|
||||
{
|
||||
if (FsSrv != null) return;
|
||||
if (FileSystemServer != null) return;
|
||||
|
||||
lock (_initLocker)
|
||||
{
|
||||
if (FsSrv != null) return;
|
||||
if (FileSystemServer != null) return;
|
||||
|
||||
var config = new FileSystemServerConfig();
|
||||
config.FsCreators = fsCreators;
|
||||
config.DeviceOperator = deviceOperator;
|
||||
|
||||
FsSrv = new FileSystemServer(config);
|
||||
FileSystemServer = new FileSystemServer(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue