Update to libhac 0.5

This commit is contained in:
Alex Barney 2019-07-05 18:19:40 -05:00
parent 708620252e
commit 8defbed035
6 changed files with 161 additions and 320 deletions

View file

@ -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<LibHac.Fs.DirectoryEntry> _enumerator;
public event EventHandler<EventArgs> 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);
}
}
}
}

View file

@ -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<EventArgs> Disposed;
public string Path { get; private set; }
public IFile(LibHac.Fs.IFile baseFile, string path)
public IFile(LibHac.Fs.IFile baseFile)
{
_commands = new Dictionary<int, ServiceProcessRequest>
{
@ -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<u8, 0x46, 0> 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();
}
}
}

View file

@ -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<int, ServiceProcessRequest> Commands => _commands;
private HashSet<string> _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<string>();
_provider = provider;
_fileSystem = provider;
}
// CreateFile(u32 createOption, u64 size, buffer<bytes<0x301>, 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;
}
}
}

View file

@ -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;
}

View file

@ -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);

View file

@ -46,7 +46,7 @@
<ItemGroup>
<PackageReference Include="Concentus" Version="1.1.7" />
<PackageReference Include="LibHac" Version="0.4.1" />
<PackageReference Include="LibHac" Version="0.4.2--more-results.21" />
<PackageReference Include="TimeZoneConverter.Posix" Version="2.1.0" />
</ItemGroup>