IFile.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using Ryujinx.HLE.HOS.Ipc;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. namespace Ryujinx.HLE.HOS.Services.FspSrv
  6. {
  7. class IFile : IpcService, IDisposable
  8. {
  9. private Dictionary<int, ServiceProcessRequest> _commands;
  10. public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
  11. private Stream _baseStream;
  12. public event EventHandler<EventArgs> Disposed;
  13. public string HostPath { get; private set; }
  14. public IFile(Stream baseStream, string hostPath)
  15. {
  16. _commands = new Dictionary<int, ServiceProcessRequest>
  17. {
  18. { 0, Read },
  19. { 1, Write },
  20. { 2, Flush },
  21. { 3, SetSize },
  22. { 4, GetSize }
  23. };
  24. _baseStream = baseStream;
  25. HostPath = hostPath;
  26. }
  27. // Read(u32, u64 offset, u64 size) -> (u64 out_size, buffer<u8, 0x46, 0> out_buf)
  28. public long Read(ServiceCtx context)
  29. {
  30. long position = context.Request.ReceiveBuff[0].Position;
  31. long zero = context.RequestData.ReadInt64();
  32. long offset = context.RequestData.ReadInt64();
  33. long size = context.RequestData.ReadInt64();
  34. byte[] data = new byte[size];
  35. _baseStream.Seek(offset, SeekOrigin.Begin);
  36. int readSize = _baseStream.Read(data, 0, (int)size);
  37. context.Memory.WriteBytes(position, data);
  38. context.ResponseData.Write((long)readSize);
  39. return 0;
  40. }
  41. // Write(u32, u64 offset, u64 size, buffer<u8, 0x45, 0>)
  42. public long Write(ServiceCtx context)
  43. {
  44. long position = context.Request.SendBuff[0].Position;
  45. long zero = context.RequestData.ReadInt64();
  46. long offset = context.RequestData.ReadInt64();
  47. long size = context.RequestData.ReadInt64();
  48. byte[] data = context.Memory.ReadBytes(position, size);
  49. _baseStream.Seek(offset, SeekOrigin.Begin);
  50. _baseStream.Write(data, 0, (int)size);
  51. return 0;
  52. }
  53. // Flush()
  54. public long Flush(ServiceCtx context)
  55. {
  56. _baseStream.Flush();
  57. return 0;
  58. }
  59. // SetSize(u64 size)
  60. public long SetSize(ServiceCtx context)
  61. {
  62. long size = context.RequestData.ReadInt64();
  63. _baseStream.SetLength(size);
  64. return 0;
  65. }
  66. // GetSize() -> u64 fileSize
  67. public long GetSize(ServiceCtx context)
  68. {
  69. context.ResponseData.Write(_baseStream.Length);
  70. return 0;
  71. }
  72. public void Dispose()
  73. {
  74. Dispose(true);
  75. }
  76. protected virtual void Dispose(bool disposing)
  77. {
  78. if (disposing && _baseStream != null)
  79. {
  80. _baseStream.Dispose();
  81. Disposed?.Invoke(this, EventArgs.Empty);
  82. }
  83. }
  84. }
  85. }