aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/FileSystem/Content/ContentManager.cs32
-rw-r--r--Ryujinx.HLE/FileSystem/Content/LocationEntry.cs12
-rw-r--r--Ryujinx.HLE/FileSystem/SaveHelper.cs5
-rw-r--r--Ryujinx.HLE/HOS/Font/SharedFontManager.cs10
-rw-r--r--Ryujinx.HLE/HOS/Horizon.cs104
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs34
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs64
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs62
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs196
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs24
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs37
-rw-r--r--Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs46
-rw-r--r--Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs42
-rw-r--r--Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs26
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs19
-rw-r--r--Ryujinx.HLE/Ryujinx.HLE.csproj2
-rw-r--r--Ryujinx/Configuration.cs2
-rw-r--r--Ryujinx/Ui/ApplicationLibrary.cs38
18 files changed, 352 insertions, 403 deletions
diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
index 9ed2e142..17faa19f 100644
--- a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
+++ b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs
@@ -1,5 +1,5 @@
-using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
using Ryujinx.HLE.HOS.Services.Time;
using Ryujinx.HLE.Utilities;
using System;
@@ -16,13 +16,13 @@ namespace Ryujinx.HLE.FileSystem.Content
private Dictionary<string, long> _sharedFontTitleDictionary;
private Dictionary<string, string> _sharedFontFilenameDictionary;
- private SortedDictionary<(ulong, ContentType), string> _contentDictionary;
+ private SortedDictionary<(ulong, NcaContentType), string> _contentDictionary;
private Switch _device;
public ContentManager(Switch device)
{
- _contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
+ _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_sharedFontTitleDictionary = new Dictionary<string, long>
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.FileSystem.Content
public void LoadEntries()
{
- _contentDictionary = new SortedDictionary<(ulong, ContentType), string>();
+ _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
foreach (StorageId storageId in Enum.GetValues(typeof(StorageId)))
{
@@ -146,7 +146,7 @@ namespace Ryujinx.HLE.FileSystem.Content
TimeManager.Instance.InitializeTimeZone(_device);
}
- public void ClearEntry(long titleId, ContentType contentType, StorageId storageId)
+ public void ClearEntry(long titleId, NcaContentType contentType, StorageId storageId)
{
RemoveLocationEntry(titleId, contentType, storageId);
}
@@ -173,10 +173,10 @@ namespace Ryujinx.HLE.FileSystem.Content
{
if (_contentDictionary.ContainsValue(ncaId))
{
- var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
- long titleId = (long)content.Key.Item1;
- ContentType contentType = content.Key.Item2;
- StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
+ var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
+ long titleId = (long)content.Key.Item1;
+ NcaContentType contentType = content.Key.Item2;
+ StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
return storage == storageId;
}
@@ -184,7 +184,7 @@ namespace Ryujinx.HLE.FileSystem.Content
return false;
}
- public UInt128 GetInstalledNcaId(long titleId, ContentType contentType)
+ public UInt128 GetInstalledNcaId(long titleId, NcaContentType contentType)
{
if (_contentDictionary.ContainsKey(((ulong)titleId,contentType)))
{
@@ -194,7 +194,7 @@ namespace Ryujinx.HLE.FileSystem.Content
return new UInt128();
}
- public StorageId GetInstalledStorage(long titleId, ContentType contentType, StorageId storageId)
+ public StorageId GetInstalledStorage(long titleId, NcaContentType contentType, StorageId storageId)
{
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
@@ -202,7 +202,7 @@ namespace Ryujinx.HLE.FileSystem.Content
LocationHelper.GetStorageId(locationEntry.ContentPath) : StorageId.None;
}
- public string GetInstalledContentPath(long titleId, StorageId storageId, ContentType contentType)
+ public string GetInstalledContentPath(long titleId, StorageId storageId, NcaContentType contentType)
{
LocationEntry locationEntry = GetLocation(titleId, contentType, storageId);
@@ -226,7 +226,7 @@ namespace Ryujinx.HLE.FileSystem.Content
AddLocationEntry(newEntry, storageId);
}
- private bool VerifyContentType(LocationEntry locationEntry, ContentType contentType)
+ private bool VerifyContentType(LocationEntry locationEntry, NcaContentType contentType)
{
if (locationEntry.ContentPath == null)
{
@@ -273,7 +273,7 @@ namespace Ryujinx.HLE.FileSystem.Content
}
}
- private void RemoveLocationEntry(long titleId, ContentType contentType, StorageId storageId)
+ private void RemoveLocationEntry(long titleId, NcaContentType contentType, StorageId storageId)
{
LinkedList<LocationEntry> locationList = null;
@@ -304,7 +304,7 @@ namespace Ryujinx.HLE.FileSystem.Content
return _sharedFontFilenameDictionary.TryGetValue(fontName, out filename);
}
- private LocationEntry GetLocation(long titleId, ContentType contentType, StorageId storageId)
+ private LocationEntry GetLocation(long titleId, NcaContentType contentType, StorageId storageId)
{
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
diff --git a/Ryujinx.HLE/FileSystem/Content/LocationEntry.cs b/Ryujinx.HLE/FileSystem/Content/LocationEntry.cs
index 2ab7ea80..15485148 100644
--- a/Ryujinx.HLE/FileSystem/Content/LocationEntry.cs
+++ b/Ryujinx.HLE/FileSystem/Content/LocationEntry.cs
@@ -1,15 +1,15 @@
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem.NcaUtils;
namespace Ryujinx.HLE.FileSystem.Content
{
public struct LocationEntry
{
- public string ContentPath { get; private set; }
- public int Flag { get; private set; }
- public long TitleId { get; private set; }
- public ContentType ContentType { get; private set; }
+ public string ContentPath { get; private set; }
+ public int Flag { get; private set; }
+ public long TitleId { get; private set; }
+ public NcaContentType ContentType { get; private set; }
- public LocationEntry(string contentPath, int flag, long titleId, ContentType contentType)
+ public LocationEntry(string contentPath, int flag, long titleId, NcaContentType contentType)
{
ContentPath = contentPath;
Flag = flag;
diff --git a/Ryujinx.HLE/FileSystem/SaveHelper.cs b/Ryujinx.HLE/FileSystem/SaveHelper.cs
index a1072498..b9abcb85 100644
--- a/Ryujinx.HLE/FileSystem/SaveHelper.cs
+++ b/Ryujinx.HLE/FileSystem/SaveHelper.cs
@@ -1,4 +1,5 @@
using LibHac.Fs;
+using LibHac.FsSystem;
using Ryujinx.HLE.HOS;
using System.IO;
@@ -21,9 +22,9 @@ namespace Ryujinx.HLE.FileSystem
using (LocalStorage systemSaveData = new LocalStorage(savePath, FileAccess.Read, FileMode.Open))
{
- IFileSystem saveFs = new LibHac.Fs.Save.SaveDataFileSystem(context.Device.System.KeySet, systemSaveData, IntegrityCheckLevel.None, false);
+ IFileSystem saveFs = new LibHac.FsSystem.Save.SaveDataFileSystem(context.Device.System.KeySet, systemSaveData, IntegrityCheckLevel.None, false);
- saveFs.CopyFileSystem(outputFolder);
+ saveFs.CopyDirectory(outputFolder, "/", "/");
}
File.Delete(savePath);
diff --git a/Ryujinx.HLE/HOS/Font/SharedFontManager.cs b/Ryujinx.HLE/HOS/Font/SharedFontManager.cs
index 11ba1ab4..40a81b86 100644
--- a/Ryujinx.HLE/HOS/Font/SharedFontManager.cs
+++ b/Ryujinx.HLE/HOS/Font/SharedFontManager.cs
@@ -1,5 +1,6 @@
using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
using Ryujinx.Common;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.FileSystem;
@@ -55,7 +56,7 @@ namespace Ryujinx.HLE.HOS.Font
if (contentManager.TryGetFontTitle(name, out long fontTitle) &&
contentManager.TryGetFontFilename(name, out string fontFilename))
{
- string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, ContentType.Data);
+ string contentPath = contentManager.GetInstalledContentPath(fontTitle, StorageId.NandSystem, NcaContentType.Data);
string fontPath = _device.FileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(fontPath))
@@ -66,9 +67,10 @@ namespace Ryujinx.HLE.HOS.Font
{
Nca nca = new Nca(_device.System.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
- Stream fontFile = romfs.OpenFile(fontFilename, OpenMode.Read).AsStream();
- data = DecryptFont(fontFile);
+ romfs.OpenFile(out IFile fontFile, "/" + fontFilename, OpenMode.Read).ThrowIfFailure();
+
+ data = DecryptFont(fontFile.AsStream());
}
FontInfo info = new FontInfo((int)fontOffset, data.Length);
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index 80c9ef0c..0deb7ac1 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -1,6 +1,9 @@
using LibHac;
using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsService;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
+using LibHac.Spl;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Font;
@@ -116,6 +119,9 @@ namespace Ryujinx.HLE.HOS
internal long HidBaseAddress { get; private set; }
+ internal FileSystemServer FsServer { get; private set; }
+ internal EmulatedGameCard GameCard { get; private set; }
+
public Horizon(Switch device)
{
ControlData = new Nacp();
@@ -228,6 +234,21 @@ namespace Ryujinx.HLE.HOS
// FIXME: TimeZone shoud be init here but it's actually done in ContentManager
TimeServiceManager.Instance.SetupEphemeralNetworkSystemClock();
+
+ LocalFileSystem serverBaseFs = new LocalFileSystem(device.FileSystem.GetBasePath());
+
+ DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(serverBaseFs, KeySet);
+
+ GameCard = fsServerObjects.GameCard;
+
+ FileSystemServerConfig fsServerConfig = new FileSystemServerConfig
+ {
+ FsCreators = fsServerObjects.FsCreators,
+ DeviceOperator = fsServerObjects.DeviceOperator,
+ ExternalKeySet = KeySet.ExternalKeySet
+ };
+
+ FsServer = new FileSystemServer(fsServerConfig);
}
public void LoadCart(string exeFsDir, string romFsFile = null)
@@ -283,25 +304,31 @@ namespace Ryujinx.HLE.HOS
XciPartition securePartition = xci.OpenPartition(XciPartitionType.Secure);
- foreach (DirectoryEntry ticketEntry in securePartition.EnumerateEntries("*.tik"))
+ foreach (DirectoryEntryEx ticketEntry in securePartition.EnumerateEntries("/", "*.tik"))
{
- Ticket ticket = new Ticket(securePartition.OpenFile(ticketEntry.FullPath, OpenMode.Read).AsStream());
+ Result result = securePartition.OpenFile(out IFile ticketFile, ticketEntry.FullPath, OpenMode.Read);
- if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
+ if (result.IsSuccess())
{
- KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet));
+ Ticket ticket = new Ticket(ticketFile.AsStream());
+
+ KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
- foreach (DirectoryEntry fileEntry in securePartition.EnumerateEntries("*.nca"))
+ foreach (DirectoryEntryEx fileEntry in securePartition.EnumerateEntries("/", "*.nca"))
{
- IStorage ncaStorage = securePartition.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage();
+ Result result = securePartition.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read);
+ if (result.IsFailure())
+ {
+ continue;
+ }
- Nca nca = new Nca(KeySet, ncaStorage);
+ Nca nca = new Nca(KeySet, ncaFile.AsStorage());
- if (nca.Header.ContentType == ContentType.Program)
+ if (nca.Header.ContentType == NcaContentType.Program)
{
- int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, ContentType.Program);
+ int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.Header.GetFsHeader(dataIndex).IsPatchSection())
{
@@ -312,7 +339,7 @@ namespace Ryujinx.HLE.HOS
mainNca = nca;
}
}
- else if (nca.Header.ContentType == ContentType.Control)
+ else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
@@ -335,11 +362,14 @@ namespace Ryujinx.HLE.HOS
{
IFileSystem controlFs = controlNca.OpenFileSystem(NcaSectionType.Data, FsIntegrityCheckLevel);
- IFile controlFile = controlFs.OpenFile("/control.nacp", OpenMode.Read);
+ Result result = controlFs.OpenFile(out IFile controlFile, "/control.nacp", OpenMode.Read);
- ControlData = new Nacp(controlFile.AsStream());
+ if (result.IsSuccess())
+ {
+ ControlData = new Nacp(controlFile.AsStream());
- TitleName = CurrentTitle = ControlData.Descriptions[(int)State.DesiredTitleLanguage].Title;
+ TitleName = CurrentTitle = ControlData.Descriptions[(int) State.DesiredTitleLanguage].Title;
+ }
}
public void LoadNca(string ncaFile)
@@ -357,13 +387,15 @@ namespace Ryujinx.HLE.HOS
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
- foreach (DirectoryEntry ticketEntry in nsp.EnumerateEntries("*.tik"))
+ foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
{
- Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry.FullPath, OpenMode.Read).AsStream());
+ Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath, OpenMode.Read);
- if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
+ if (result.IsSuccess())
{
- KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet));
+ Ticket ticket = new Ticket(ticketFile.AsStream());
+
+ KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
@@ -371,15 +403,15 @@ namespace Ryujinx.HLE.HOS
Nca patchNca = null;
Nca controlNca = null;
- foreach (DirectoryEntry fileEntry in nsp.EnumerateEntries("*.nca"))
+ foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
{
- IStorage ncaStorage = nsp.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage();
+ nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure();
- Nca nca = new Nca(KeySet, ncaStorage);
+ Nca nca = new Nca(KeySet, ncaFile.AsStorage());
- if (nca.Header.ContentType == ContentType.Program)
+ if (nca.Header.ContentType == NcaContentType.Program)
{
- int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, ContentType.Program);
+ int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.Header.GetFsHeader(dataIndex).IsPatchSection())
{
@@ -390,7 +422,7 @@ namespace Ryujinx.HLE.HOS
mainNca = nca;
}
}
- else if (nca.Header.ContentType == ContentType.Control)
+ else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
@@ -409,7 +441,7 @@ namespace Ryujinx.HLE.HOS
public void LoadNca(Nca mainNca, Nca patchNca, Nca controlNca)
{
- if (mainNca.Header.ContentType != ContentType.Program)
+ if (mainNca.Header.ContentType != NcaContentType.Program)
{
Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");
@@ -466,7 +498,7 @@ namespace Ryujinx.HLE.HOS
{
IFileSystem controlRomfs = controlNca.OpenFileSystem(NcaSectionType.Data, FsIntegrityCheckLevel);
- IFile controlFile = controlRomfs.OpenFile("/control.nacp", OpenMode.Read);
+ controlRomfs.OpenFile(out IFile controlFile, "/control.nacp", OpenMode.Read).ThrowIfFailure();
Nacp controlData = new Nacp(controlFile.AsStream());
@@ -493,24 +525,24 @@ namespace Ryujinx.HLE.HOS
private void LoadExeFs(IFileSystem codeFs, out Npdm metaData)
{
- if (codeFs.FileExists("/main.npdm"))
- {
- Logger.PrintInfo(LogClass.Loader, "Loading main.npdm...");
+ Result result = codeFs.OpenFile(out IFile npdmFile, "/main.npdm", OpenMode.Read);
- metaData = new Npdm(codeFs.OpenFile("/main.npdm", OpenMode.Read).AsStream());
- }
- else
+ if (result == ResultFs.PathNotFound)
{
Logger.PrintWarning(LogClass.Loader, "NPDM file not found, using default values!");
metaData = GetDefaultNpdm();
}
+ else
+ {
+ metaData = new Npdm(npdmFile.AsStream());
+ }
List<IExecutable> staticObjects = new List<IExecutable>();
void LoadNso(string filename)
{
- foreach (DirectoryEntry file in codeFs.EnumerateEntries($"{filename}*"))
+ foreach (DirectoryEntryEx file in codeFs.EnumerateEntries("/", $"{filename}*"))
{
if (Path.GetExtension(file.Name) != string.Empty)
{
@@ -519,7 +551,9 @@ namespace Ryujinx.HLE.HOS
Logger.PrintInfo(LogClass.Loader, $"Loading {file.Name}...");
- NxStaticObject staticObject = new NxStaticObject(codeFs.OpenFile(file.FullPath, OpenMode.Read).AsStream());
+ codeFs.OpenFile(out IFile nsoFile, file.FullPath, OpenMode.Read).ThrowIfFailure();
+
+ NxStaticObject staticObject = new NxStaticObject(nsoFile.AsStream());
staticObjects.Add(staticObject);
}
@@ -654,7 +688,7 @@ namespace Ryujinx.HLE.HOS
LoadSetAtPath(Path.Combine(home, ".switch"));
LoadSetAtPath(Device.FileSystem.GetSystemPath());
- KeySet = ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile);
+ KeySet = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile);
void LoadSetAtPath(string basePath)
{
diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs
index 04b87b57..2b0f06dd 100644
--- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs
+++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs
@@ -1,6 +1,8 @@
using LibHac;
using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
+using LibHac.Spl;
using Ryujinx.Common;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Utilities;
@@ -25,7 +27,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
try
{
LocalFileSystem fileSystem = new LocalFileSystem(savePath);
- LibHac.Fs.IFileSystem saveFileSystem = new DirectorySaveDataFileSystem(fileSystem);
+
+ Result result = DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem dirFileSystem, fileSystem);
+ if (result.IsFailure())
+ {
+ return (ResultCode)result.Value;
+ }
+
+ LibHac.Fs.IFileSystem saveFileSystem = dirFileSystem;
if (readOnly)
{
@@ -111,13 +120,16 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
PartitionFileSystem nsp = new PartitionFileSystem(pfsFile.AsStorage());
ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet);
-
+
string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\');
- if (nsp.FileExists(filename))
+ Result result = nsp.OpenFile(out LibHac.Fs.IFile ncaFile, filename, OpenMode.Read);
+ if (result.IsFailure())
{
- return OpenNcaFs(context, fullPath, nsp.OpenFile(filename, OpenMode.Read).AsStorage(), out openedFileSystem);
+ return (ResultCode)result.Value;
}
+
+ return OpenNcaFs(context, fullPath, ncaFile.AsStorage(), out openedFileSystem);
}
catch (HorizonResultException ex)
{
@@ -130,15 +142,17 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
public static void ImportTitleKeysFromNsp(LibHac.Fs.IFileSystem nsp, Keyset keySet)
{
- foreach (DirectoryEntry ticketEntry in nsp.EnumerateEntries("*.tik"))
+ foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
{
- Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry.FullPath, OpenMode.Read).AsStream());
+ Result result = nsp.OpenFile(out LibHac.Fs.IFile ticketFile, ticketEntry.FullPath, OpenMode.Read);
- if (!keySet.TitleKeys.ContainsKey(ticket.RightsId))
+ if (result.IsSuccess())
{
- keySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(keySet));
+ Ticket ticket = new Ticket(ticketFile.AsStream());
+
+ keySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(keySet)));
}
}
}
}
-} \ No newline at end of file
+}
diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs
index 4fc8a687..c042ed8e 100644
--- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs
+++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IDirectory.cs
@@ -1,21 +1,17 @@
using LibHac;
-using System.Collections.Generic;
-using System.Text;
+using LibHac.Fs;
+using System;
+using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IDirectory : IpcService
{
- private const int DirectoryEntrySize = 0x310;
-
- private IEnumerator<LibHac.Fs.DirectoryEntry> _enumerator;
-
private LibHac.Fs.IDirectory _baseDirectory;
public IDirectory(LibHac.Fs.IDirectory directory)
{
_baseDirectory = directory;
- _enumerator = directory.Read().GetEnumerator();
}
[Command(0)]
@@ -25,60 +21,26 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
long bufferPosition = context.Request.ReceiveBuff[0].Position;
long bufferLen = context.Request.ReceiveBuff[0].Size;
- int maxReadCount = (int)(bufferLen / DirectoryEntrySize);
- int readCount = 0;
-
- try
- {
- while (readCount < maxReadCount && _enumerator.MoveNext())
- {
- long position = bufferPosition + readCount * DirectoryEntrySize;
+ byte[] entriesBytes = new byte[bufferLen];
+ Span<DirectoryEntry> entries = MemoryMarshal.Cast<byte, DirectoryEntry>(entriesBytes);
- WriteDirectoryEntry(context, position, _enumerator.Current);
+ Result result = _baseDirectory.Read(out long entriesRead, entries);
- readCount++;
- }
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ context.Memory.WriteBytes(bufferPosition, entriesBytes);
+ context.ResponseData.Write(entriesRead);
- context.ResponseData.Write((long)readCount);
-
- return ResultCode.Success;
- }
-
- private void WriteDirectoryEntry(ServiceCtx context, long position, LibHac.Fs.DirectoryEntry entry)
- {
- for (int offset = 0; offset < 0x300; offset += 8)
- {
- context.Memory.WriteInt64(position + offset, 0);
- }
-
- byte[] nameBuffer = Encoding.UTF8.GetBytes(entry.Name);
-
- context.Memory.WriteBytes(position, nameBuffer);
-
- context.Memory.WriteInt32(position + 0x300, (int)entry.Attributes);
- context.Memory.WriteInt32(position + 0x304, (byte)entry.Type);
- context.Memory.WriteInt64(position + 0x308, entry.Size);
+ return (ResultCode)result.Value;
}
[Command(1)]
// GetEntryCount() -> u64
public ResultCode GetEntryCount(ServiceCtx context)
{
- try
- {
- context.ResponseData.Write((long)_baseDirectory.GetEntryCount());
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _baseDirectory.GetEntryCount(out long entryCount);
+
+ context.ResponseData.Write(entryCount);
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs
index df9209e6..f09624f8 100644
--- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFile.cs
@@ -26,22 +26,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
long size = context.RequestData.ReadInt64();
byte[] data = new byte[size];
- int readSize;
- try
- {
- readSize = _baseFile.Read(data, offset, readOption);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _baseFile.Read(out long bytesRead, offset, data, readOption);
context.Memory.WriteBytes(position, data);
- context.ResponseData.Write((long)readSize);
+ context.ResponseData.Write(bytesRead);
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
[Command(1)]
@@ -58,66 +50,34 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
byte[] data = context.Memory.ReadBytes(position, size);
- try
- {
- _baseFile.Write(data, offset, writeOption);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_baseFile.Write(offset, data, writeOption).Value;
}
[Command(2)]
// Flush()
public ResultCode Flush(ServiceCtx context)
{
- try
- {
- _baseFile.Flush();
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_baseFile.Flush().Value;
}
[Command(3)]
// SetSize(u64 size)
public ResultCode SetSize(ServiceCtx context)
{
- try
- {
- long size = context.RequestData.ReadInt64();
-
- _baseFile.SetSize(size);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ long size = context.RequestData.ReadInt64();
- return ResultCode.Success;
+ return (ResultCode)_baseFile.SetSize(size).Value;
}
[Command(4)]
// GetSize() -> u64 fileSize
public ResultCode GetSize(ServiceCtx context)
{
- try
- {
- context.ResponseData.Write(_baseFile.GetSize());
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _baseFile.GetSize(out long size);
+
+ context.ResponseData.Write(size);
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
public void Dispose()
diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs
index 7a7fdbaf..ed7ae0c1 100644
--- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs
+++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IFileSystem.cs
@@ -25,16 +25,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
long size = context.RequestData.ReadInt64();
- try
- {
- _fileSystem.CreateFile(name, size, createOption);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.CreateFile(name, size, createOption).Value;
}
[Command(1)]
@@ -43,16 +34,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- _fileSystem.DeleteFile(name);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.DeleteFile(name).Value;
}
[Command(2)]
@@ -61,16 +43,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- _fileSystem.CreateDirectory(name);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.CreateDirectory(name).Value;
}
[Command(3)]
@@ -79,16 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- _fileSystem.DeleteDirectory(name);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.DeleteDirectory(name).Value;
}
[Command(4)]
@@ -97,16 +61,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- _fileSystem.DeleteDirectoryRecursively(name);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.DeleteDirectoryRecursively(name).Value;
}
[Command(5)]
@@ -116,16 +71,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
string oldName = ReadUtf8String(context, 0);
string newName = ReadUtf8String(context, 1);
- try
- {
- _fileSystem.RenameFile(oldName, newName);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.RenameFile(oldName, newName).Value;
}
[Command(6)]
@@ -135,16 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
string oldName = ReadUtf8String(context, 0);
string newName = ReadUtf8String(context, 1);
- try
- {
- _fileSystem.RenameDirectory(oldName, newName);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.RenameDirectory(oldName, newName).Value;
}
[Command(7)]
@@ -153,25 +90,11 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- DirectoryEntryType entryType = _fileSystem.GetEntryType(name);
-
- if (entryType == DirectoryEntryType.Directory || entryType == DirectoryEntryType.File)
- {
- context.ResponseData.Write((int)entryType);
- }
- else
- {
- return ResultCode.PathDoesNotExist;
- }
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _fileSystem.GetEntryType(out DirectoryEntryType entryType, name);
- return ResultCode.Success;
+ context.ResponseData.Write((int)entryType);
+
+ return (ResultCode)result.Value;
}
[Command(8)]
@@ -182,20 +105,16 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
string name = ReadUtf8String(context);
- try
- {
- LibHac.Fs.IFile file = _fileSystem.OpenFile(name, mode);
+ Result result = _fileSystem.OpenFile(out LibHac.Fs.IFile file, name, mode);
+ if (result.IsSuccess())
+ {
IFile fileInterface = new IFile(file);
MakeObject(context, fileInterface);
}
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
[Command(9)]
@@ -206,36 +125,23 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
string name = ReadUtf8String(context);
- try
- {
- LibHac.Fs.IDirectory dir = _fileSystem.OpenDirectory(name, mode);
+ Result result = _fileSystem.OpenDirectory(out LibHac.Fs.IDirectory dir, name, mode);
+ if (result.IsSuccess())
+ {
IDirectory dirInterface = new IDirectory(dir);
MakeObject(context, dirInterface);
}
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
[Command(10)]
// Commit()
public ResultCode Commit(ServiceCtx context)
{
- try
- {
- _fileSystem.Commit();
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.Commit().Value;
}
[Command(11)]
@@ -244,16 +150,11 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- context.ResponseData.Write(_fileSystem.GetFreeSpaceSize(name));
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _fileSystem.GetFreeSpaceSize(out long size, name);
- return ResultCode.Success;
+ context.ResponseData.Write(size);
+
+ return (ResultCode)result.Value;
}
[Command(12)]
@@ -262,16 +163,11 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- context.ResponseData.Write(_fileSystem.GetTotalSpaceSize(name));
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _fileSystem.GetTotalSpaceSize(out long size, name);
+
+ context.ResponseData.Write(size);
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
[Command(13)]
@@ -280,16 +176,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- _fileSystem.CleanDirectoryRecursively(name);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
-
- return ResultCode.Success;
+ return (ResultCode)_fileSystem.CleanDirectoryRecursively(name).Value;
}
[Command(14)]
@@ -298,27 +185,20 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
string name = ReadUtf8String(context);
- try
- {
- FileTimeStampRaw timestamp = _fileSystem.GetFileTimeStampRaw(name);
+ Result result = _fileSystem.GetFileTimeStampRaw(out FileTimeStampRaw timestamp, name);
- context.ResponseData.Write(timestamp.Created);
- context.ResponseData.Write(timestamp.Modified);
- context.ResponseData.Write(timestamp.Accessed);
+ context.ResponseData.Write(timestamp.Created);
+ context.ResponseData.Write(timestamp.Modified);
+ context.ResponseData.Write(timestamp.Accessed);
- byte[] data = new byte[8];
+ byte[] data = new byte[8];
- // is valid?
- data[0] = 1;
+ // is valid?
+ data[0] = 1;
- context.ResponseData.Write(data);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ context.ResponseData.Write(data);
- return ResultCode.Success;
+ return (ResultCode)result.Value;
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs
index 107599a4..cc407039 100644
--- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs
+++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/IStorage.cs
@@ -31,16 +31,11 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
byte[] data = new byte[size];
- try
- {
- _baseStorage.Read(data, offset);
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _baseStorage.Read(offset, data);
context.Memory.WriteBytes(buffDesc.Position, data);
+
+ return (ResultCode)result.Value;
}
return ResultCode.Success;
@@ -50,16 +45,11 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
// GetSize() -> u64 size
public ResultCode GetSize(ServiceCtx context)
{
- try
- {
- context.ResponseData.Write(_baseStorage.GetSize());
- }
- catch (HorizonResultException ex)
- {
- return (ResultCode)ex.ResultValue.Value;
- }
+ Result result = _baseStorage.GetSize(out long size);
- return ResultCode.Success;
+ context.ResponseData.Write(size);
+
+ return (ResultCode)result.Value;
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs
new file mode 100644
index 00000000..426b50ed
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs
@@ -0,0 +1,37 @@
+using LibHac;
+using LibHac.FsService;
+
+namespace Ryujinx.HLE.HOS.Services.Fs
+{
+ class IDeviceOperator : IpcService
+ {
+ private LibHac.FsService.IDeviceOperator _baseOperator;
+
+ public IDeviceOperator(LibHac.FsService.IDeviceOperator baseOperator)
+ {
+ _baseOperator = baseOperator;
+ }
+
+ [Command(200)]
+ // IsGameCardInserted() -> b8 is_inserted
+ public ResultCode IsGameCardInserted(ServiceCtx context)
+ {
+ Result result = _baseOperator.IsGameCardInserted(out bool isInserted);
+
+ context.ResponseData.Write(isInserted);
+
+ return (ResultCode)result.Value;
+ }
+
+ [Command(202)]
+ // GetGameCardHandle() -> u32 gamecard_handle
+ public ResultCode GetGameCardHandle(ServiceCtx context)
+ {
+ Result result = _baseOperator.GetGameCardHandle(out GameCardHandle handle);
+
+ context.ResponseData.Write(handle.Value);
+
+ return (ResultCode)result.Value;
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs
index a0d22595..38111019 100644
--- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs
+++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs
@@ -1,6 +1,8 @@
using LibHac;
using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsService;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy;
@@ -14,7 +16,12 @@ namespace Ryujinx.HLE.HOS.Services.Fs
[Service("fsp-srv")]
class IFileSystemProxy : IpcService
{
- public IFileSystemProxy(ServiceCtx context) { }
+ private LibHac.FsService.IFileSystemProxy _baseFileSystemProxy;
+
+ public IFileSystemProxy(ServiceCtx context)
+ {
+ _baseFileSystemProxy = context.Device.System.FsServer.CreateFileSystemProxyService();
+ }
[Command(1)]
// Initialize(u64, pid)
@@ -125,6 +132,23 @@ namespace Ryujinx.HLE.HOS.Services.Fs
return ResultCode.Success;
}
+ [Command(30)]
+ // OpenGameCardStorage(u32, u32) -> object<nn::fssrv::sf::IStorage>
+ public ResultCode OpenGameCardStorage(ServiceCtx context)
+ {
+ GameCardHandle handle = new GameCardHandle(context.RequestData.ReadInt32());
+ GameCardPartitionRaw partitionId = (GameCardPartitionRaw)context.RequestData.ReadInt32();
+
+ Result result = _baseFileSystemProxy.OpenGameCardStorage(out LibHac.Fs.IStorage storage, handle, partitionId);
+
+ if (result.IsSuccess())
+ {
+ MakeObject(context, new FileSystemProxy.IStorage(storage));
+ }
+
+ return (ResultCode)result.Value;
+ }
+
[Command(51)]
// OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> saveDataFs
public ResultCode OpenSaveDataFileSystem(ServiceCtx context)
@@ -184,14 +208,14 @@ namespace Ryujinx.HLE.HOS.Services.Fs
byte[] padding = context.RequestData.ReadBytes(7);
long titleId = context.RequestData.ReadInt64();
- ContentType contentType = ContentType.Data;
+ NcaContentType contentType = NcaContentType.Data;
StorageId installedStorage =
context.Device.System.ContentManager.GetInstalledStorage(titleId, contentType, storageId);
if (installedStorage == StorageId.None)
{
- contentType = ContentType.PublicData;
+ contentType = NcaContentType.PublicData;
installedStorage =
context.Device.System.ContentManager.GetInstalledStorage(titleId, contentType, storageId);
@@ -246,6 +270,20 @@ namespace Ryujinx.HLE.HOS.Services.Fs
return ResultCode.Success;
}
+ [Command(400)]
+ // OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
+ public ResultCode OpenDeviceOperator(ServiceCtx context)
+ {
+ Result result = _baseFileSystemProxy.OpenDeviceOperator(out LibHac.FsService.IDeviceOperator deviceOperator);
+
+ if (result.IsSuccess())
+ {
+ MakeObject(context, new IDeviceOperator(deviceOperator));
+ }
+
+ return (ResultCode)result.Value;
+ }
+
[Command(1005)]
// GetGlobalAccessLogMode() -> u32 logMode
public ResultCode GetGlobalAccessLogMode(ServiceCtx context)
diff --git a/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs b/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs
index d77bac73..88ba45e0 100644
--- a/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs
+++ b/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs
@@ -1,4 +1,4 @@
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem.NcaUtils;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using System.Text;
@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- if (ResolvePath(context, titleId, ContentType.Program))
+ if (ResolvePath(context, titleId, NcaContentType.Program))
{
return ResultCode.Success;
}
@@ -38,7 +38,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- RedirectPath(context, titleId, 0, ContentType.Program);
+ RedirectPath(context, titleId, 0, NcaContentType.Program);
return ResultCode.Success;
}
@@ -49,7 +49,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- if (ResolvePath(context, titleId, ContentType.Control))
+ if (ResolvePath(context, titleId, NcaContentType.Control))
{
return ResultCode.Success;
}
@@ -65,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- if (ResolvePath(context, titleId, ContentType.Manual))
+ if (ResolvePath(context, titleId, NcaContentType.Manual))
{
return ResultCode.Success;
}
@@ -81,7 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- if (ResolvePath(context, titleId, ContentType.Data) || ResolvePath(context, titleId, ContentType.PublicData))
+ if (ResolvePath(context, titleId, NcaContentType.Data) || ResolvePath(context, titleId, NcaContentType.PublicData))
{
return ResultCode.Success;
}
@@ -97,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- RedirectPath(context, titleId, 1, ContentType.Control);
+ RedirectPath(context, titleId, 1, NcaContentType.Control);
return ResultCode.Success;
}
@@ -108,7 +108,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- RedirectPath(context, titleId, 1, ContentType.Manual);
+ RedirectPath(context, titleId, 1, NcaContentType.Manual);
return ResultCode.Success;
}
@@ -119,7 +119,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- if (ResolvePath(context, titleId, ContentType.Manual))
+ if (ResolvePath(context, titleId, NcaContentType.Manual))
{
return ResultCode.Success;
}
@@ -135,7 +135,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- RedirectPath(context, titleId, 1, ContentType.Manual);
+ RedirectPath(context, titleId, 1, NcaContentType.Manual);
return ResultCode.Success;
}
@@ -155,7 +155,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- RedirectPath(context, titleId, 1, ContentType.Program);
+ RedirectPath(context, titleId, 1, NcaContentType.Program);
return ResultCode.Success;
}
@@ -175,7 +175,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- DeleteContentPath(context, titleId, ContentType.Program);
+ DeleteContentPath(context, titleId, NcaContentType.Program);
return ResultCode.Success;
}
@@ -186,7 +186,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- DeleteContentPath(context, titleId, ContentType.Control);
+ DeleteContentPath(context, titleId, NcaContentType.Control);
return ResultCode.Success;
}
@@ -197,7 +197,7 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- DeleteContentPath(context, titleId, ContentType.Manual);
+ DeleteContentPath(context, titleId, NcaContentType.Manual);
return ResultCode.Success;
}
@@ -208,12 +208,12 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
long titleId = context.RequestData.ReadInt64();
- DeleteContentPath(context, titleId, ContentType.Manual);
+ DeleteContentPath(context, titleId, NcaContentType.Manual);
return ResultCode.Success;
}
- private void RedirectPath(ServiceCtx context, long titleId, int flag, ContentType contentType)
+ private void RedirectPath(ServiceCtx context, long titleId, int flag, NcaContentType contentType)
{
string contentPath = ReadUtf8String(context);
LocationEntry newLocation = new LocationEntry(contentPath, flag, titleId, contentType);
@@ -221,10 +221,10 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
context.Device.System.ContentManager.RedirectLocation(newLocation, _storageId);
}
- private bool ResolvePath(ServiceCtx context, long titleId,ContentType contentType)
+ private bool ResolvePath(ServiceCtx context, long titleId, NcaContentType contentType)
{
ContentManager contentManager = context.Device.System.ContentManager;
- string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, ContentType.Program);
+ string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, NcaContentType.Program);
if (!string.IsNullOrWhiteSpace(contentPath))
{
@@ -243,12 +243,12 @@ namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
return true;
}
- private void DeleteContentPath(ServiceCtx context, long titleId, ContentType contentType)
+ private void DeleteContentPath(ServiceCtx context, long titleId, NcaContentType contentType)
{
ContentManager contentManager = context.Device.System.ContentManager;
- string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, ContentType.Manual);
+ string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, NcaContentType.Manual);
- contentManager.ClearEntry(titleId, ContentType.Manual, _storageId);
+ contentManager.ClearEntry(titleId, NcaContentType.Manual, _storageId);
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs b/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs
index 7af78dbf..490d0e8e 100644
--- a/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs
+++ b/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs
@@ -1,5 +1,7 @@
+using LibHac;
using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.SystemState;
@@ -165,7 +167,7 @@ namespace Ryujinx.HLE.HOS.Services.Settings
public byte[] GetFirmwareData(Switch device)
{
long titleId = 0x0100000000000809;
- string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, ContentType.Data);
+ string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, NcaContentType.Data);
if (string.IsNullOrWhiteSpace(contentPath))
{
@@ -185,11 +187,25 @@ namespace Ryujinx.HLE.HOS.Services.Settings
IFileSystem firmwareRomFs = firmwareContent.OpenFileSystem(NcaSectionType.Data, device.System.FsIntegrityCheckLevel);
- IFile firmwareFile = firmwareRomFs.OpenFile("/file", OpenMode.Read);
+ Result result = firmwareRomFs.OpenFile(out IFile firmwareFile, "/file", OpenMode.Read);
+ if (result.IsFailure())
+ {
+ return null;
+ }
+
+ result = firmwareFile.GetSize(out long fileSize);
+ if (result.IsFailure())
+ {
+ return null;
+ }
- byte[] data = new byte[firmwareFile.GetSize()];
+ byte[] data = new byte[fileSize];
- firmwareFile.Read(data, 0);
+ result = firmwareFile.Read(out _, 0, data);
+ if (result.IsFailure())
+ {
+ return null;
+ }
return data;
}
diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs
index e9ec654b..f48452f3 100644
--- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs
@@ -1,5 +1,7 @@
-using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac;
+using LibHac.Fs;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.FileSystem;
@@ -58,9 +60,10 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
{
Nca nca = new Nca(_device.System.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
- Stream binaryListStream = romfs.OpenFile("binaryList.txt", OpenMode.Read).AsStream();
- StreamReader reader = new StreamReader(binaryListStream);
+ romfs.OpenFile(out IFile binaryListFile, "/binaryList.txt", OpenMode.Read).ThrowIfFailure();
+
+ StreamReader reader = new StreamReader(binaryListFile.AsStream());
List<string> locationNameList = new List<string>();
@@ -139,7 +142,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
public string GetTimeZoneBinaryTitleContentPath()
{
- return _device.System.ContentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.NandSystem, ContentType.Data);
+ return _device.System.ContentManager.GetInstalledContentPath(TimeZoneBinaryTitleId, StorageId.NandSystem, NcaContentType.Data);
}
public bool HasTimeZoneBinaryTitle()
@@ -162,9 +165,11 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
Nca nca = new Nca(_device.System.KeySet, ncaFile);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
- timeZoneBinaryStream = romfs.OpenFile($"/zoneinfo/{locationName}", OpenMode.Read).AsStream();
+ Result result = romfs.OpenFile(out IFile timeZoneBinaryFile, $"/zoneinfo/{locationName}", OpenMode.Read);
- return ResultCode.Success;
+ timeZoneBinaryStream = timeZoneBinaryFile.AsStream();
+
+ return (ResultCode)result.Value;
}
internal ResultCode LoadTimeZoneRule(out TimeZoneRule outRules, string locationName)
diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj
index 38a6f5ae..0f36843e 100644
--- a/Ryujinx.HLE/Ryujinx.HLE.csproj
+++ b/Ryujinx.HLE/Ryujinx.HLE.csproj
@@ -48,7 +48,7 @@
<ItemGroup>
<PackageReference Include="Concentus" Version="1.1.7" />
- <PackageReference Include="LibHac" Version="0.5.1" />
+ <PackageReference Include="LibHac" Version="0.6.0" />
<PackageReference Include="System.Runtime.Intrinsics.Experimental" Version="4.5.0-rc1" />
<PackageReference Include="TimeZoneConverter.Posix" Version="2.1.0" />
</ItemGroup>
diff --git a/Ryujinx/Configuration.cs b/Ryujinx/Configuration.cs
index 53560521..57980c50 100644
--- a/Ryujinx/Configuration.cs
+++ b/Ryujinx/Configuration.cs
@@ -1,5 +1,5 @@
using JsonPrettyPrinterPlus;
-using LibHac.Fs;
+using LibHac.FsSystem;
using OpenTK.Input;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
diff --git a/Ryujinx/Ui/ApplicationLibrary.cs b/Ryujinx/Ui/ApplicationLibrary.cs
index 7e731f79..1b697e42 100644
--- a/Ryujinx/Ui/ApplicationLibrary.cs
+++ b/Ryujinx/Ui/ApplicationLibrary.cs
@@ -1,6 +1,8 @@
using LibHac;
using LibHac.Fs;
-using LibHac.Fs.NcaUtils;
+using LibHac.FsSystem;
+using LibHac.FsSystem.NcaUtils;
+using LibHac.Spl;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
@@ -8,6 +10,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
+
using SystemState = Ryujinx.HLE.HOS.SystemState;
namespace Ryujinx.UI
@@ -115,8 +118,9 @@ namespace Ryujinx.UI
}
// Creates NACP class from the NACP file
- IFile controlNacp = controlFs.OpenFile("/control.nacp", OpenMode.Read);
- Nacp controlData = new Nacp(controlNacp.AsStream());
+ controlFs.OpenFile(out IFile controlNacpFile, "/control.nacp", OpenMode.Read).ThrowIfFailure();
+
+ Nacp controlData = new Nacp(controlNacpFile.AsStream());
// Get the title name, title ID, developer name and version number from the NACP
version = controlData.DisplayVersion;
@@ -150,7 +154,8 @@ namespace Ryujinx.UI
// Read the icon from the ControlFS and store it as a byte array
try
{
- IFile icon = controlFs.OpenFile($"/icon_{DesiredTitleLanguage}.dat", OpenMode.Read);
+ controlFs.OpenFile(out IFile icon, $"/icon_{DesiredTitleLanguage}.dat", OpenMode.Read).ThrowIfFailure();
+
using (MemoryStream stream = new MemoryStream())
{
icon.AsStream().CopyTo(stream);
@@ -159,15 +164,15 @@ namespace Ryujinx.UI
}
catch (HorizonResultException)
{
- IDirectory controlDir = controlFs.OpenDirectory("./", OpenDirectoryMode.All);
- foreach (DirectoryEntry entry in controlDir.Read())
+ foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
{
if (entry.Name == "control.nacp")
{
continue;
}
- IFile icon = controlFs.OpenFile(entry.FullPath, OpenMode.Read);
+ controlFs.OpenFile(out IFile icon, entry.FullPath, OpenMode.Read).ThrowIfFailure();
+
using (MemoryStream stream = new MemoryStream())
{
icon.AsStream().CopyTo(stream);
@@ -346,21 +351,26 @@ namespace Ryujinx.UI
Nca controlNca = null;
// Add keys to keyset if needed
- foreach (DirectoryEntry ticketEntry in Pfs.EnumerateEntries("*.tik"))
+ foreach (DirectoryEntryEx ticketEntry in Pfs.EnumerateEntries("/", "*.tik"))
{
- Ticket ticket = new Ticket(Pfs.OpenFile(ticketEntry.FullPath, OpenMode.Read).AsStream());
+ Result result = Pfs.OpenFile(out IFile ticketFile, ticketEntry.FullPath, OpenMode.Read);
- if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
+ if (result.IsSuccess())
{
- KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet));
+ Ticket ticket = new Ticket(ticketFile.AsStream());
+
+ KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
// Find the Control NCA and store it in variable called controlNca
- foreach (DirectoryEntry fileEntry in Pfs.EnumerateEntries("*.nca"))
+ foreach (DirectoryEntryEx fileEntry in Pfs.EnumerateEntries("/", "*.nca"))
{
- Nca nca = new Nca(KeySet, Pfs.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage());
- if (nca.Header.ContentType == ContentType.Control)
+ Pfs.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure();
+
+ Nca nca = new Nca(KeySet, ncaFile.AsStorage());
+
+ if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}