diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IDirectory.cs index c0ffe767ca..1b41c7cfce 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 482399401b..81051e3c00 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFile.cs @@ -2,6 +2,7 @@ using LibHac.Fs; using Ryujinx.HLE.HOS.Ipc; using System; using System.Collections.Generic; +using LibHac; namespace Ryujinx.HLE.HOS.Services.FspSrv { @@ -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 01a8dc9b42..37a7345e04 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs @@ -1,10 +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; namespace Ryujinx.HLE.HOS.Services.FspSrv @@ -15,9 +13,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 +36,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 +49,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 +66,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 +83,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,31 +100,15 @@ 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); + return ex.ResultValue.Value; } - catch (UnauthorizedAccessException) - { - Logger.PrintError(LogClass.ServiceFs, $"Unable to access {name}"); - - throw; - } - + return 0; } @@ -197,25 +117,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 +135,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 +153,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 +172,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv try { - DirectoryEntryType entryType = _provider.GetEntryType(name); + DirectoryEntryType entryType = _fileSystem.GetEntryType(name); context.ResponseData.Write((int)entryType); } - catch (FileNotFoundException) + catch (HorizonResultException ex) { - context.ResponseData.Write(0); - - return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); + return ex.ResultValue.Value; } return 0; @@ -327,40 +191,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 +214,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 +250,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 +267,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 +284,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 +301,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 +315,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/IStorage.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs index 81bdcdcca6..0f669ae2f1 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IStorage.cs @@ -1,5 +1,6 @@ using Ryujinx.HLE.HOS.Ipc; using System.Collections.Generic; +using LibHac; namespace Ryujinx.HLE.HOS.Services.FspSrv { @@ -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 8c0fa41a8b..e6662c386e 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -64,7 +64,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 50d84c3fd7..848b6d45b2 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -46,7 +46,7 @@ - +