IFile.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using LibHac.Fs;
  2. using Ryujinx.HLE.HOS.Ipc;
  3. using System;
  4. using System.Collections.Generic;
  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 LibHac.Fs.IFile _baseFile;
  12. public event EventHandler<EventArgs> Disposed;
  13. public string Path { get; private set; }
  14. public IFile(LibHac.Fs.IFile baseFile, string path)
  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. _baseFile = baseFile;
  25. Path = LibHac.Fs.PathTools.Normalize(path);
  26. }
  27. // Read(u32 readOption, 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. ReadOption readOption = (ReadOption)context.RequestData.ReadInt32();
  32. context.RequestData.BaseStream.Position += 4;
  33. long offset = context.RequestData.ReadInt64();
  34. long size = context.RequestData.ReadInt64();
  35. byte[] data = new byte[size];
  36. int readSize = _baseFile.Read(data, offset, readOption);
  37. context.Memory.WriteBytes(position, data);
  38. context.ResponseData.Write((long)readSize);
  39. return 0;
  40. }
  41. // Write(u32 writeOption, u64 offset, u64 size, buffer<u8, 0x45, 0>)
  42. public long Write(ServiceCtx context)
  43. {
  44. long position = context.Request.SendBuff[0].Position;
  45. WriteOption writeOption = (WriteOption)context.RequestData.ReadInt32();
  46. context.RequestData.BaseStream.Position += 4;
  47. long offset = context.RequestData.ReadInt64();
  48. long size = context.RequestData.ReadInt64();
  49. byte[] data = context.Memory.ReadBytes(position, size);
  50. _baseFile.Write(data, offset, writeOption);
  51. return 0;
  52. }
  53. // Flush()
  54. public long Flush(ServiceCtx context)
  55. {
  56. _baseFile.Flush();
  57. return 0;
  58. }
  59. // SetSize(u64 size)
  60. public long SetSize(ServiceCtx context)
  61. {
  62. long size = context.RequestData.ReadInt64();
  63. _baseFile.SetSize(size);
  64. return 0;
  65. }
  66. // GetSize() -> u64 fileSize
  67. public long GetSize(ServiceCtx context)
  68. {
  69. context.ResponseData.Write(_baseFile.GetSize());
  70. return 0;
  71. }
  72. public void Dispose()
  73. {
  74. Dispose(true);
  75. }
  76. protected virtual void Dispose(bool disposing)
  77. {
  78. if (disposing && _baseFile != null)
  79. {
  80. _baseFile.Dispose();
  81. Disposed?.Invoke(this, EventArgs.Empty);
  82. }
  83. }
  84. }
  85. }