From f723f6f39aaf7b1cebc0224a055058d62e3b689c Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Wed, 10 Jul 2019 12:20:01 -0500 Subject: [PATCH] Update to LibHac 0.5.0 (#725) * Update to libhac 0.5 * Catch HorizonResultException in IFileSystemProxy * Changes based on feedback --- .../HOS/Services/Acc/IAccountService.cs | 3 +- Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs | 51 ++- Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs | 62 +++- .../HOS/Services/FspSrv/IFileSystem.cs | 351 ++++-------------- .../HOS/Services/FspSrv/IFileSystemProxy.cs | 105 ++++-- Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs | 19 +- .../Ns/IApplicationManagerInterface.cs | 2 +- Ryujinx.HLE/Ryujinx.HLE.csproj | 2 +- 8 files changed, 238 insertions(+), 357 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs b/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs index 3f00ae66a..84b0e0306 100644 --- a/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs +++ b/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs @@ -321,8 +321,7 @@ namespace Ryujinx.HLE.HOS.Services.Acc // Account actually calls nn::arp::detail::IReader::GetApplicationControlProperty() with the current PID and store the result (NACP File) internally. // But since we use LibHac and we load one Application at a time, it's not necessary. - // TODO : Use "context.Device.System.ControlData.UserAccountSwitchLock" when LibHac is updated. - context.ResponseData.Write(false); + context.ResponseData.Write(context.Device.System.ControlData.UserAccountSwitchLock); Logger.PrintStub(LogClass.ServiceAcc); diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs index c0ffe767c..1b41c7cfc 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs @@ -1,11 +1,11 @@ +using LibHac; using Ryujinx.HLE.HOS.Ipc; -using System; using System.Collections.Generic; using System.Text; namespace Ryujinx.HLE.HOS.Services.FspSrv { - class IDirectory : IpcService, IDisposable + class IDirectory : IpcService { private const int DirectoryEntrySize = 0x310; @@ -15,11 +15,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv private IEnumerator _enumerator; - public event EventHandler Disposed; - - public string Path { get; } - - private LibHac.Fs.IDirectory _provider; + private LibHac.Fs.IDirectory _baseDirectory; public IDirectory(LibHac.Fs.IDirectory directory) { @@ -29,9 +25,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { 1, GetEntryCount } }; - _provider = directory; - - Path = directory.FullPath; + _baseDirectory = directory; _enumerator = directory.Read().GetEnumerator(); } @@ -45,13 +39,20 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv int maxReadCount = (int)(bufferLen / DirectoryEntrySize); int readCount = 0; - while (readCount < maxReadCount && _enumerator.MoveNext()) + try { - long position = bufferPosition + readCount * DirectoryEntrySize; + while (readCount < maxReadCount && _enumerator.MoveNext()) + { + long position = bufferPosition + readCount * DirectoryEntrySize; - WriteDirectoryEntry(context, position, _enumerator.Current); + WriteDirectoryEntry(context, position, _enumerator.Current); - readCount++; + readCount++; + } + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; } context.ResponseData.Write((long)readCount); @@ -78,22 +79,16 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv // GetEntryCount() -> u64 public long GetEntryCount(ServiceCtx context) { - context.ResponseData.Write((long)_provider.GetEntryCount()); + try + { + context.ResponseData.Write((long)_baseDirectory.GetEntryCount()); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - Disposed?.Invoke(this, EventArgs.Empty); - } - } } } diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs index 482399401..ac0926c9c 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs @@ -1,3 +1,4 @@ +using LibHac; using LibHac.Fs; using Ryujinx.HLE.HOS.Ipc; using System; @@ -13,11 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv private LibHac.Fs.IFile _baseFile; - public event EventHandler Disposed; - - public string Path { get; private set; } - - public IFile(LibHac.Fs.IFile baseFile, string path) + public IFile(LibHac.Fs.IFile baseFile) { _commands = new Dictionary { @@ -29,7 +26,6 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv }; _baseFile = baseFile; - Path = PathTools.Normalize(path); } // Read(u32 readOption, u64 offset, u64 size) -> (u64 out_size, buffer out_buf) @@ -44,8 +40,16 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv long size = context.RequestData.ReadInt64(); byte[] data = new byte[size]; + int readSize; - int readSize = _baseFile.Read(data, offset, readOption); + try + { + readSize = _baseFile.Read(data, offset, readOption); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } context.Memory.WriteBytes(position, data); @@ -67,7 +71,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv byte[] data = context.Memory.ReadBytes(position, size); - _baseFile.Write(data, offset, writeOption); + try + { + _baseFile.Write(data, offset, writeOption); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -75,7 +86,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv // Flush() public long Flush(ServiceCtx context) { - _baseFile.Flush(); + try + { + _baseFile.Flush(); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -83,9 +101,16 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv // SetSize(u64 size) public long SetSize(ServiceCtx context) { - long size = context.RequestData.ReadInt64(); + try + { + long size = context.RequestData.ReadInt64(); - _baseFile.SetSize(size); + _baseFile.SetSize(size); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -93,7 +118,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv // GetSize() -> u64 fileSize public long GetSize(ServiceCtx context) { - context.ResponseData.Write(_baseFile.GetSize()); + try + { + context.ResponseData.Write(_baseFile.GetSize()); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -105,11 +137,9 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv protected virtual void Dispose(bool disposing) { - if (disposing && _baseFile != null) + if (disposing) { - _baseFile.Dispose(); - - Disposed?.Invoke(this, EventArgs.Empty); + _baseFile?.Dispose(); } } } diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs index 01a8dc9b4..097697c40 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs @@ -1,9 +1,8 @@ +using LibHac; using LibHac.Fs; using Ryujinx.HLE.HOS.Ipc; -using System; using System.Collections.Generic; -using System.IO; -using Ryujinx.Common.Logging; + using static Ryujinx.HLE.HOS.ErrorCode; using static Ryujinx.HLE.Utilities.StringUtils; @@ -15,9 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv public override IReadOnlyDictionary Commands => _commands; - private HashSet _openPaths; - - private LibHac.Fs.IFileSystem _provider; + private LibHac.Fs.IFileSystem _fileSystem; public IFileSystem(LibHac.Fs.IFileSystem provider) { @@ -40,9 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { 14, GetFileTimeStampRaw } }; - _openPaths = new HashSet(); - - _provider = provider; + _fileSystem = provider; } // CreateFile(u32 createOption, u64 size, buffer, 0x19, 0x301> path) @@ -55,34 +50,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv long size = context.RequestData.ReadInt64(); - if (name == null) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (_provider.FileExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.CreateFile(name, size, createOption); + _fileSystem.CreateFile(name, size, createOption); } - catch (DirectoryNotFoundException) + catch (HorizonResultException ex) { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -93,29 +67,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - if (!_provider.FileExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.DeleteFile(name); + _fileSystem.DeleteFile(name); } - catch (FileNotFoundException) + catch (HorizonResultException ex) { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -126,34 +84,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - if (name == null) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (_provider.DirectoryExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.CreateDirectory(name); + _fileSystem.CreateDirectory(name); } - catch (DirectoryNotFoundException) + catch (HorizonResultException ex) { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -164,29 +101,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - if (!_provider.DirectoryExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.DeleteDirectory(name); + _fileSystem.DeleteDirectory(name); } - catch (DirectoryNotFoundException) + catch (HorizonResultException ex) { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -197,25 +118,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - if (!_provider.DirectoryExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.DeleteDirectoryRecursively(name); + _fileSystem.DeleteDirectoryRecursively(name); } - catch (UnauthorizedAccessException) + catch (HorizonResultException ex) { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -227,34 +136,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv string oldName = ReadUtf8String(context, 0); string newName = ReadUtf8String(context, 1); - if (_provider.FileExists(oldName)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (_provider.FileExists(newName)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); - } - - if (IsPathAlreadyInUse(oldName)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.RenameFile(oldName, newName); + _fileSystem.RenameFile(oldName, newName); } - catch (FileNotFoundException) + catch (HorizonResultException ex) { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {oldName} or {newName}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -266,34 +154,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv string oldName = ReadUtf8String(context, 0); string newName = ReadUtf8String(context, 1); - if (!_provider.DirectoryExists(oldName)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (!_provider.DirectoryExists(newName)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); - } - - if (IsPathAlreadyInUse(oldName)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.RenameFile(oldName, newName); + _fileSystem.RenameDirectory(oldName, newName); } - catch (DirectoryNotFoundException) + catch (HorizonResultException ex) { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {oldName} or {newName}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -306,15 +173,20 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv try { - DirectoryEntryType entryType = _provider.GetEntryType(name); + DirectoryEntryType entryType = _fileSystem.GetEntryType(name); - context.ResponseData.Write((int)entryType); + if (entryType == DirectoryEntryType.Directory || entryType == DirectoryEntryType.File) + { + context.ResponseData.Write((int)entryType); + } + else + { + return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); + } } - catch (FileNotFoundException) + catch (HorizonResultException ex) { - context.ResponseData.Write(0); - - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); + return ex.ResultValue.Value; } return 0; @@ -327,40 +199,19 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv string name = ReadUtf8String(context); - if (!_provider.FileExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - - IFile fileInterface; - try { - LibHac.Fs.IFile file = _provider.OpenFile(name, mode); + LibHac.Fs.IFile file = _fileSystem.OpenFile(name, mode); - fileInterface = new IFile(file, name); + IFile fileInterface = new IFile(file); + + MakeObject(context, fileInterface); } - catch (UnauthorizedAccessException) + catch (HorizonResultException ex) { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } - fileInterface.Disposed += RemoveFileInUse; - - lock (_openPaths) - { - _openPaths.Add(fileInterface.Path); - } - - MakeObject(context, fileInterface); - return 0; } @@ -371,47 +222,33 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv string name = ReadUtf8String(context); - if (!_provider.DirectoryExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - - IDirectory dirInterface; - try { - LibHac.Fs.IDirectory dir = _provider.OpenDirectory(name, mode); + LibHac.Fs.IDirectory dir = _fileSystem.OpenDirectory(name, mode); - dirInterface = new IDirectory(dir); + IDirectory dirInterface = new IDirectory(dir); + + MakeObject(context, dirInterface); } - catch (UnauthorizedAccessException) + catch (HorizonResultException ex) { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } - dirInterface.Disposed += RemoveDirectoryInUse; - - lock (_openPaths) - { - _openPaths.Add(dirInterface.Path); - } - - MakeObject(context, dirInterface); - return 0; } // Commit() public long Commit(ServiceCtx context) { - _provider.Commit(); + try + { + _fileSystem.Commit(); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -421,7 +258,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - context.ResponseData.Write(_provider.GetFreeSpaceSize(name)); + try + { + context.ResponseData.Write(_fileSystem.GetFreeSpaceSize(name)); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -431,7 +275,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - context.ResponseData.Write(_provider.GetTotalSpaceSize(name)); + try + { + context.ResponseData.Write(_fileSystem.GetTotalSpaceSize(name)); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -441,25 +292,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - if (!_provider.DirectoryExists(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - if (IsPathAlreadyInUse(name)) - { - return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); - } - try { - _provider.CleanDirectoryRecursively(name); + _fileSystem.CleanDirectoryRecursively(name); } - catch (UnauthorizedAccessException) + catch (HorizonResultException ex) { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; + return ex.ResultValue.Value; } return 0; @@ -470,9 +309,9 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { string name = ReadUtf8String(context); - if (_provider.FileExists(name) || _provider.DirectoryExists(name)) + try { - FileTimeStampRaw timestamp = _provider.GetFileTimeStampRaw(name); + FileTimeStampRaw timestamp = _fileSystem.GetFileTimeStampRaw(name); context.ResponseData.Write(timestamp.Created); context.ResponseData.Write(timestamp.Modified); @@ -484,43 +323,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv data[0] = 1; context.ResponseData.Write(data); - - return 0; } - - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); - } - - private bool IsPathAlreadyInUse(string path) - { - lock (_openPaths) + catch (HorizonResultException ex) { - return _openPaths.Contains(path); + return ex.ResultValue.Value; } - } - private void RemoveFileInUse(object sender, EventArgs e) - { - IFile fileInterface = (IFile)sender; - - lock (_openPaths) - { - fileInterface.Disposed -= RemoveFileInUse; - - _openPaths.Remove(fileInterface.Path); - } - } - - private void RemoveDirectoryInUse(object sender, EventArgs e) - { - IDirectory dirInterface = (IDirectory)sender; - - lock (_openPaths) - { - dirInterface.Disposed -= RemoveDirectoryInUse; - - _openPaths.Remove(dirInterface.Path); - } + return 0; } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs index 84869bf55..1155302fa 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs @@ -127,17 +127,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv // OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object saveDataFs public long OpenSaveDataFileSystem(ServiceCtx context) { - LoadSaveDataFileSystem(context); - - return 0; + return LoadSaveDataFileSystem(context); } // OpenSaveDataFileSystemBySystemSaveDataId(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object systemSaveDataFs public long OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx context) { - LoadSaveDataFileSystem(context); - - return 0; + return LoadSaveDataFileSystem(context); } // OpenDataStorageByCurrentProcess() -> object dataStorage @@ -179,11 +175,18 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv if (File.Exists(ncaPath)) { - LibHac.Fs.IStorage ncaStorage = new LocalStorage(ncaPath, FileAccess.Read, FileMode.Open); - Nca nca = new Nca(context.Device.System.KeySet, ncaStorage); - LibHac.Fs.IStorage romfsStorage = nca.OpenStorage(NcaSectionType.Data, context.Device.System.FsIntegrityCheckLevel); + try + { + LibHac.Fs.IStorage ncaStorage = new LocalStorage(ncaPath, FileAccess.Read, FileMode.Open); + Nca nca = new Nca(context.Device.System.KeySet, ncaStorage); + LibHac.Fs.IStorage romfsStorage = nca.OpenStorage(NcaSectionType.Data, context.Device.System.FsIntegrityCheckLevel); - MakeObject(context, new IStorage(romfsStorage)); + MakeObject(context, new IStorage(romfsStorage)); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } @@ -230,7 +233,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return 0; } - public void LoadSaveDataFileSystem(ServiceCtx context) + public long LoadSaveDataFileSystem(ServiceCtx context) { SaveSpaceId saveSpaceId = (SaveSpaceId)context.RequestData.ReadInt64(); @@ -242,39 +245,62 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv SaveDataType saveDataType = (SaveDataType)context.RequestData.ReadByte(); SaveInfo saveInfo = new SaveInfo(titleId, saveId, saveDataType, userId, saveSpaceId); string savePath = context.Device.FileSystem.GetGameSavePath(saveInfo, context); - LocalFileSystem fileSystem = new LocalFileSystem(savePath); - DirectorySaveDataFileSystem saveFileSystem = new DirectorySaveDataFileSystem(fileSystem); + try + { + LocalFileSystem fileSystem = new LocalFileSystem(savePath); + DirectorySaveDataFileSystem saveFileSystem = new DirectorySaveDataFileSystem(fileSystem); - MakeObject(context, new IFileSystem(saveFileSystem)); + MakeObject(context, new IFileSystem(saveFileSystem)); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } + + return 0; } private long OpenNsp(ServiceCtx context, string pfsPath) { - LocalStorage storage = new LocalStorage(pfsPath, FileAccess.Read, FileMode.Open); - PartitionFileSystem nsp = new PartitionFileSystem(storage); + try + { + LocalStorage storage = new LocalStorage(pfsPath, FileAccess.Read, FileMode.Open); + PartitionFileSystem nsp = new PartitionFileSystem(storage); - ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet); - - IFileSystem nspFileSystem = new IFileSystem(nsp); + ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet); + + IFileSystem nspFileSystem = new IFileSystem(nsp); - MakeObject(context, nspFileSystem); + MakeObject(context, nspFileSystem); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } private long OpenNcaFs(ServiceCtx context, string ncaPath, LibHac.Fs.IStorage ncaStorage) { - Nca nca = new Nca(context.Device.System.KeySet, ncaStorage); - - if (!nca.SectionExists(NcaSectionType.Data)) + try { - return MakeError(ErrorModule.Fs, FsErr.PartitionNotFound); + Nca nca = new Nca(context.Device.System.KeySet, ncaStorage); + + if (!nca.SectionExists(NcaSectionType.Data)) + { + return MakeError(ErrorModule.Fs, FsErr.PartitionNotFound); + } + + LibHac.Fs.IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, context.Device.System.FsIntegrityCheckLevel); + + MakeObject(context, new IFileSystem(fileSystem)); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; } - - LibHac.Fs.IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, context.Device.System.FsIntegrityCheckLevel); - - MakeObject(context, new IFileSystem(fileSystem)); return 0; } @@ -295,15 +321,22 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv FileMode.Open, FileAccess.Read); - 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)) + try { - return OpenNcaFs(context, fullPath, nsp.OpenFile(filename, OpenMode.Read).AsStorage()); + 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)) + { + return OpenNcaFs(context, fullPath, nsp.OpenFile(filename, OpenMode.Read).AsStorage()); + } + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; } } diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs index 81bdcdcca..2ac4d249b 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs @@ -1,3 +1,4 @@ +using LibHac; using Ryujinx.HLE.HOS.Ipc; using System.Collections.Generic; @@ -40,7 +41,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv byte[] data = new byte[size]; - _baseStorage.Read(data, offset); + try + { + _baseStorage.Read(data, offset); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } context.Memory.WriteBytes(buffDesc.Position, data); } @@ -51,7 +59,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv // GetSize() -> u64 size public long GetSize(ServiceCtx context) { - context.ResponseData.Write(_baseStorage.GetSize()); + try + { + context.ResponseData.Write(_baseStorage.GetSize()); + } + catch (HorizonResultException ex) + { + return ex.ResultValue.Value; + } return 0; } diff --git a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs index 88e669642..32c50dcdb 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -65,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns position += isbn.Length; context.Memory.WriteByte(position++, nacp.StartupUserAccount); - context.Memory.WriteByte(position++, nacp.TouchScreenUsageMode); + context.Memory.WriteByte(position++, nacp.UserAccountSwitchLock); context.Memory.WriteByte(position++, nacp.AocRegistrationType); context.Memory.WriteInt32(position, nacp.AttributeFlag); diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index 099a2cd98..78e5c2a3a 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -47,7 +47,7 @@ - +