IFile.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using ChocolArm64.Memory;
  2. using Ryujinx.OsHle.Ipc;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. namespace Ryujinx.OsHle.Objects.FspSrv
  7. {
  8. class IFile : IIpcInterface, IDisposable
  9. {
  10. private Dictionary<int, ServiceProcessRequest> m_Commands;
  11. public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
  12. private Stream BaseStream;
  13. public IFile(Stream BaseStream)
  14. {
  15. m_Commands = new Dictionary<int, ServiceProcessRequest>()
  16. {
  17. { 0, Read },
  18. { 1, Write }
  19. };
  20. this.BaseStream = BaseStream;
  21. }
  22. public long Read(ServiceCtx Context)
  23. {
  24. long Position = Context.Request.ReceiveBuff[0].Position;
  25. long Zero = Context.RequestData.ReadInt64();
  26. long Offset = Context.RequestData.ReadInt64();
  27. long Size = Context.RequestData.ReadInt64();
  28. byte[] Data = new byte[Size];
  29. int ReadSize = BaseStream.Read(Data, 0, (int)Size);
  30. AMemoryHelper.WriteBytes(Context.Memory, Position, Data);
  31. //TODO: Use ReadSize, we need to return the size that was REALLY read from the file.
  32. //This is a workaround because we are doing something wrong and the game expects to read
  33. //data from a file that doesn't yet exists -- and breaks if it can't read anything.
  34. Context.ResponseData.Write((long)Size);
  35. return 0;
  36. }
  37. public long Write(ServiceCtx Context)
  38. {
  39. long Position = Context.Request.SendBuff[0].Position;
  40. long Zero = Context.RequestData.ReadInt64();
  41. long Offset = Context.RequestData.ReadInt64();
  42. long Size = Context.RequestData.ReadInt64();
  43. byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, (int)Size);
  44. BaseStream.Seek(Offset, SeekOrigin.Begin);
  45. BaseStream.Write(Data, 0, (int)Size);
  46. return 0;
  47. }
  48. public void Dispose()
  49. {
  50. Dispose(true);
  51. }
  52. protected virtual void Dispose(bool disposing)
  53. {
  54. if (disposing && BaseStream != null)
  55. {
  56. BaseStream.Dispose();
  57. }
  58. }
  59. }
  60. }