IStorage.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using LibHac;
  2. using LibHac.Common;
  3. using LibHac.Sf;
  4. using Ryujinx.HLE.HOS.Ipc;
  5. namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
  6. {
  7. class IStorage : DisposableIpcService
  8. {
  9. private SharedRef<LibHac.FsSrv.Sf.IStorage> _baseStorage;
  10. public IStorage(ref SharedRef<LibHac.FsSrv.Sf.IStorage> baseStorage)
  11. {
  12. _baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
  13. }
  14. [CommandHipc(0)]
  15. // Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
  16. public ResultCode Read(ServiceCtx context)
  17. {
  18. ulong offset = context.RequestData.ReadUInt64();
  19. ulong size = context.RequestData.ReadUInt64();
  20. if (context.Request.ReceiveBuff.Count > 0)
  21. {
  22. ulong bufferAddress = context.Request.ReceiveBuff[0].Position;
  23. ulong bufferLen = context.Request.ReceiveBuff[0].Size;
  24. // Use smaller length to avoid overflows.
  25. if (size > bufferLen)
  26. {
  27. size = bufferLen;
  28. }
  29. using (var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true))
  30. {
  31. Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
  32. return (ResultCode)result.Value;
  33. }
  34. }
  35. return ResultCode.Success;
  36. }
  37. [CommandHipc(4)]
  38. // GetSize() -> u64 size
  39. public ResultCode GetSize(ServiceCtx context)
  40. {
  41. Result result = _baseStorage.Get.GetSize(out long size);
  42. context.ResponseData.Write(size);
  43. return (ResultCode)result.Value;
  44. }
  45. protected override void Dispose(bool isDisposing)
  46. {
  47. if (isDisposing)
  48. {
  49. _baseStorage.Destroy();
  50. }
  51. }
  52. }
  53. }