diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs | 180 |
1 files changed, 88 insertions, 92 deletions
diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs index bd249e50..edcdfa58 100644 --- a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs +++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystem.cs @@ -1,10 +1,11 @@ +using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Ipc; using System; using System.Collections.Generic; using System.IO; -using System.Text; using static Ryujinx.HLE.HOS.ErrorCode; +using static Ryujinx.HLE.Utilities.StringUtils; namespace Ryujinx.HLE.HOS.Services.FspSrv { @@ -18,7 +19,9 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv private string Path; - public IFileSystem(string Path) + private IFileSystemProvider Provider; + + public IFileSystem(string Path, IFileSystemProvider Provider) { m_Commands = new Dictionary<int, ServiceProcessRequest>() { @@ -41,9 +44,11 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv OpenPaths = new HashSet<string>(); - this.Path = Path; + this.Path = Path; + this.Provider = Provider; } + // CreateFile(u32 mode, u64 size, buffer<bytes<0x301>, 0x19, 0x301> path) public long CreateFile(ServiceCtx Context) { string Name = ReadUtf8String(Context); @@ -51,14 +56,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv long Mode = Context.RequestData.ReadInt64(); int Size = Context.RequestData.ReadInt32(); - string FileName = Context.Device.FileSystem.GetFullPath(Path, Name); + string FileName = Provider.GetFullPath(Name); if (FileName == null) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } - if (File.Exists(FileName)) + if (Provider.FileExists(FileName)) { return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); } @@ -68,21 +73,17 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - using (FileStream NewFile = File.Create(FileName)) - { - NewFile.SetLength(Size); - } - - return 0; + return Provider.CreateFile(FileName, Size); } + // DeleteFile(buffer<bytes<0x301>, 0x19, 0x301> path) public long DeleteFile(ServiceCtx Context) { string Name = ReadUtf8String(Context); - string FileName = Context.Device.FileSystem.GetFullPath(Path, Name); + string FileName = Provider.GetFullPath(Name); - if (!File.Exists(FileName)) + if (!Provider.FileExists(FileName)) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } @@ -92,23 +93,22 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - File.Delete(FileName); - - return 0; + return Provider.DeleteFile(FileName); } + // CreateDirectory(buffer<bytes<0x301>, 0x19, 0x301> path) public long CreateDirectory(ServiceCtx Context) { string Name = ReadUtf8String(Context); - string DirName = Context.Device.FileSystem.GetFullPath(Path, Name); + string DirName = Provider.GetFullPath(Name); if (DirName == null) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } - if (Directory.Exists(DirName)) + if (Provider.DirectoryExists(DirName)) { return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); } @@ -118,26 +118,28 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - Directory.CreateDirectory(DirName); + Provider.CreateDirectory(DirName); return 0; } + // DeleteDirectory(buffer<bytes<0x301>, 0x19, 0x301> path) public long DeleteDirectory(ServiceCtx Context) { return DeleteDirectory(Context, false); } + // DeleteDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path) public long DeleteDirectoryRecursively(ServiceCtx Context) { return DeleteDirectory(Context, true); } - + private long DeleteDirectory(ServiceCtx Context, bool Recursive) { string Name = ReadUtf8String(Context); - string DirName = Context.Device.FileSystem.GetFullPath(Path, Name); + string DirName = Provider.GetFullPath(Name); if (!Directory.Exists(DirName)) { @@ -149,25 +151,26 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - Directory.Delete(DirName, Recursive); + Provider.DeleteDirectory(DirName, Recursive); return 0; } + // RenameFile(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath) public long RenameFile(ServiceCtx Context) { string OldName = ReadUtf8String(Context, 0); string NewName = ReadUtf8String(Context, 1); - string OldFileName = Context.Device.FileSystem.GetFullPath(Path, OldName); - string NewFileName = Context.Device.FileSystem.GetFullPath(Path, NewName); + string OldFileName = Provider.GetFullPath(OldName); + string NewFileName = Provider.GetFullPath(NewName); - if (!File.Exists(OldFileName)) + if (Provider.FileExists(OldFileName)) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } - if (File.Exists(NewFileName)) + if (Provider.FileExists(NewFileName)) { return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); } @@ -177,25 +180,24 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - File.Move(OldFileName, NewFileName); - - return 0; + return Provider.RenameFile(OldFileName, NewFileName); } + // RenameDirectory(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath) public long RenameDirectory(ServiceCtx Context) { string OldName = ReadUtf8String(Context, 0); string NewName = ReadUtf8String(Context, 1); - string OldDirName = Context.Device.FileSystem.GetFullPath(Path, OldName); - string NewDirName = Context.Device.FileSystem.GetFullPath(Path, NewName); + string OldDirName = Provider.GetFullPath(OldName); + string NewDirName = Provider.GetFullPath(NewName); - if (!Directory.Exists(OldDirName)) + if (!Provider.DirectoryExists(OldDirName)) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } - if (Directory.Exists(NewDirName)) + if (!Provider.DirectoryExists(NewDirName)) { return MakeError(ErrorModule.Fs, FsErr.PathAlreadyExists); } @@ -205,22 +207,21 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - Directory.Move(OldDirName, NewDirName); - - return 0; + return Provider.RenameDirectory(OldDirName, NewDirName); } + // GetEntryType(buffer<bytes<0x301>, 0x19, 0x301> path) -> nn::fssrv::sf::DirectoryEntryType public long GetEntryType(ServiceCtx Context) { string Name = ReadUtf8String(Context); - string FileName = Context.Device.FileSystem.GetFullPath(Path, Name); + string FileName = Provider.GetFullPath(Name); - if (File.Exists(FileName)) + if (Provider.FileExists(FileName)) { Context.ResponseData.Write(1); } - else if (Directory.Exists(FileName)) + else if (Provider.DirectoryExists(FileName)) { Context.ResponseData.Write(0); } @@ -234,15 +235,16 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return 0; } + // OpenFile(u32 mode, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFile> file public long OpenFile(ServiceCtx Context) { int FilterFlags = Context.RequestData.ReadInt32(); string Name = ReadUtf8String(Context); - string FileName = Context.Device.FileSystem.GetFullPath(Path, Name); + string FileName = Provider.GetFullPath(Name); - if (!File.Exists(FileName)) + if (!Provider.FileExists(FileName)) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } @@ -252,79 +254,96 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - FileStream Stream = new FileStream(FileName, FileMode.Open); - IFile FileInterface = new IFile(Stream, FileName); + long Error = Provider.OpenFile(FileName, out IFile FileInterface); - FileInterface.Disposed += RemoveFileInUse; - - lock (OpenPaths) + if (Error == 0) { - OpenPaths.Add(FileName); - } + FileInterface.Disposed += RemoveFileInUse; - MakeObject(Context, FileInterface); + lock (OpenPaths) + { + OpenPaths.Add(FileName); + } - return 0; + MakeObject(Context, FileInterface); + + return 0; + } + + return Error; } + // OpenDirectory(u32 filter_flags, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IDirectory> directory public long OpenDirectory(ServiceCtx Context) { int FilterFlags = Context.RequestData.ReadInt32(); string Name = ReadUtf8String(Context); - string DirName = Context.Device.FileSystem.GetFullPath(Path, Name); + string DirName = Provider.GetFullPath(Name); - if (!Directory.Exists(DirName)) + if (!Provider.DirectoryExists(DirName)) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } - IDirectory DirInterface = new IDirectory(DirName, FilterFlags); + if (IsPathAlreadyInUse(DirName)) + { + return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); + } - DirInterface.Disposed += RemoveDirectoryInUse; + long Error = Provider.OpenDirectory(DirName, FilterFlags, out IDirectory DirInterface); - lock (OpenPaths) + if (Error == 0) { - OpenPaths.Add(DirName); - } + DirInterface.Disposed += RemoveDirectoryInUse; - MakeObject(Context, DirInterface); + lock (OpenPaths) + { + OpenPaths.Add(DirName); + } - return 0; + MakeObject(Context, DirInterface); + } + + return Error; } + // Commit() public long Commit(ServiceCtx Context) { return 0; } + // GetFreeSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalFreeSpace public long GetFreeSpaceSize(ServiceCtx Context) { string Name = ReadUtf8String(Context); - Context.ResponseData.Write(Context.Device.FileSystem.GetDrive().AvailableFreeSpace); + Context.ResponseData.Write(Provider.GetFreeSpace(Context)); return 0; } + // GetTotalSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalSize public long GetTotalSpaceSize(ServiceCtx Context) { string Name = ReadUtf8String(Context); - Context.ResponseData.Write(Context.Device.FileSystem.GetDrive().TotalSize); + Context.ResponseData.Write(Provider.GetFreeSpace(Context)); return 0; } + // CleanDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path) public long CleanDirectoryRecursively(ServiceCtx Context) { string Name = ReadUtf8String(Context); - string DirName = Context.Device.FileSystem.GetFullPath(Path, Name); + string DirName = Provider.GetFullPath(Name); - if (!Directory.Exists(DirName)) + if (!Provider.DirectoryExists(DirName)) { return MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist); } @@ -334,15 +353,15 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv return MakeError(ErrorModule.Fs, FsErr.PathAlreadyInUse); } - foreach (string Entry in Directory.EnumerateFileSystemEntries(DirName)) + foreach (DirectoryEntry Entry in Provider.GetEntries(DirName)) { - if (Directory.Exists(Entry)) + if (Provider.DirectoryExists(Entry.Path)) { - Directory.Delete(Entry, true); + Provider.DeleteDirectory(Entry.Path, true); } - else if (File.Exists(Entry)) + else if (Provider.FileExists(Entry.Path)) { - File.Delete(Entry); + Provider.DeleteFile(Entry.Path); } } @@ -377,30 +396,7 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv { DirInterface.Disposed -= RemoveDirectoryInUse; - OpenPaths.Remove(DirInterface.HostPath); - } - } - - private string ReadUtf8String(ServiceCtx Context, int Index = 0) - { - long Position = Context.Request.PtrBuff[Index].Position; - long Size = Context.Request.PtrBuff[Index].Size; - - using (MemoryStream MS = new MemoryStream()) - { - while (Size-- > 0) - { - byte Value = Context.Memory.ReadByte(Position++); - - if (Value == 0) - { - break; - } - - MS.WriteByte(Value); - } - - return Encoding.UTF8.GetString(MS.ToArray()); + OpenPaths.Remove(DirInterface.DirectoryPath); } } } |
