From f821d4bc27eafd5d36058fbeaa735586608e295a Mon Sep 17 00:00:00 2001 From: Ezekiel Bethel Date: Sat, 10 Feb 2018 18:23:17 +0000 Subject: [PATCH] Initial pass - fixes IFileSystem OpenFile, implements IFileSystem CreateFile/DeleteFile, fixes IFile Read and implements IFile GetSize/SetSize --- Ryujinx/OsHle/Objects/FspSrv/IFile.cs | 24 ++++++-- Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs | 62 +++++++++++++++++++-- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/Ryujinx/OsHle/Objects/FspSrv/IFile.cs b/Ryujinx/OsHle/Objects/FspSrv/IFile.cs index 1c6cc2e29e..9943c4622a 100644 --- a/Ryujinx/OsHle/Objects/FspSrv/IFile.cs +++ b/Ryujinx/OsHle/Objects/FspSrv/IFile.cs @@ -19,7 +19,10 @@ namespace Ryujinx.OsHle.Objects.FspSrv m_Commands = new Dictionary() { { 0, Read }, - { 1, Write } + { 1, Write }, + // { 2, Flush }, + { 3, GetSize }, + { 4, SetSize } }; this.BaseStream = BaseStream; @@ -35,14 +38,12 @@ namespace Ryujinx.OsHle.Objects.FspSrv byte[] Data = new byte[Size]; + BaseStream.Seek(Offset, SeekOrigin.Begin); int ReadSize = BaseStream.Read(Data, 0, (int)Size); AMemoryHelper.WriteBytes(Context.Memory, Position, Data); - //TODO: Use ReadSize, we need to return the size that was REALLY read from the file. - //This is a workaround because we are doing something wrong and the game expects to read - //data from a file that doesn't yet exists -- and breaks if it can't read anything. - Context.ResponseData.Write((long)Size); + Context.ResponseData.Write((long)ReadSize); return 0; } @@ -63,6 +64,19 @@ namespace Ryujinx.OsHle.Objects.FspSrv return 0; } + public long GetSize(ServiceCtx Context) + { + Context.ResponseData.Write(BaseStream.Length); + return 0; + } + + public long SetSize(ServiceCtx Context) + { + long Size = Context.RequestData.ReadInt64(); + BaseStream.SetLength(Size); + return 0; + } + public void Dispose() { Dispose(true); diff --git a/Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs b/Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs index bf501594f7..29b4242db3 100644 --- a/Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs +++ b/Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs @@ -17,16 +17,65 @@ namespace Ryujinx.OsHle.Objects.FspSrv public IFileSystem(string Path) { + //TODO: implement. m_Commands = new Dictionary() { + { 0, CreateFile }, + { 1, DeleteFile }, + //{ 2, CreateDirectory }, + //{ 3, DeleteDirectory }, + //{ 4, DeleteDirectoryRecursively }, + //{ 5, RenameFile }, + //{ 6, GetEntryType }, { 7, GetEntryType }, { 8, OpenFile }, - { 10, Commit } + //{ 9, OpenDirectory }, + { 10, Commit }, + //{ 11, GetFreeSpaceSize }, + //{ 12, GetTotalSpaceSize }, + //{ 13, CleanDirectoryRecursively }, + //{ 14, GetFileTimeStampRaw } }; this.Path = Path; } + public long CreateFile(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position); + ulong Mode = Context.RequestData.ReadUInt64(); + uint Size = Context.RequestData.ReadUInt32(); + string FileName = Context.Ns.VFs.GetFullPath(Path, Name); + + if (FileName != null) + { + FileStream NewFile = File.Create(FileName); + NewFile.SetLength(Size); + NewFile.Close(); + return 0; + } + + //TODO: Correct error code. + return -1; + } + + public long DeleteFile(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position); + string FileName = Context.Ns.VFs.GetFullPath(Path, Name); + + if (FileName != null) + { + File.Delete(FileName); + return 0; + } + + //TODO: Correct error code. + return -1; + } + public long GetEntryType(ServiceCtx Context) { long Position = Context.Request.PtrBuff[0].Position; @@ -64,11 +113,16 @@ namespace Ryujinx.OsHle.Objects.FspSrv return -1; } - FileStream Stream = new FileStream(FileName, FileMode.OpenOrCreate); + if (File.Exists(FileName)) + { + FileStream Stream = new FileStream(FileName, FileMode.OpenOrCreate); + MakeObject(Context, new IFile(Stream)); - MakeObject(Context, new IFile(Stream)); + return 0; + } - return 0; + //TODO: Correct error code. + return -1; } public long Commit(ServiceCtx Context)