IFileSystem.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. using LibHac;
  2. using LibHac.Fs;
  3. using LibHac.FsSrv.Sf;
  4. namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
  5. {
  6. class IFileSystem : DisposableIpcService
  7. {
  8. private ReferenceCountedDisposable<LibHac.FsSrv.Sf.IFileSystem> _fileSystem;
  9. public IFileSystem(ReferenceCountedDisposable<LibHac.FsSrv.Sf.IFileSystem> provider)
  10. {
  11. _fileSystem = provider;
  12. }
  13. public ReferenceCountedDisposable<LibHac.FsSrv.Sf.IFileSystem> GetBaseFileSystem()
  14. {
  15. return _fileSystem;
  16. }
  17. [CommandHipc(0)]
  18. // CreateFile(u32 createOption, u64 size, buffer<bytes<0x301>, 0x19, 0x301> path)
  19. public ResultCode CreateFile(ServiceCtx context)
  20. {
  21. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  22. int createOption = context.RequestData.ReadInt32();
  23. context.RequestData.BaseStream.Position += 4;
  24. long size = context.RequestData.ReadInt64();
  25. return (ResultCode)_fileSystem.Target.CreateFile(in name, size, createOption).Value;
  26. }
  27. [CommandHipc(1)]
  28. // DeleteFile(buffer<bytes<0x301>, 0x19, 0x301> path)
  29. public ResultCode DeleteFile(ServiceCtx context)
  30. {
  31. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  32. return (ResultCode)_fileSystem.Target.DeleteFile(in name).Value;
  33. }
  34. [CommandHipc(2)]
  35. // CreateDirectory(buffer<bytes<0x301>, 0x19, 0x301> path)
  36. public ResultCode CreateDirectory(ServiceCtx context)
  37. {
  38. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  39. return (ResultCode)_fileSystem.Target.CreateDirectory(in name).Value;
  40. }
  41. [CommandHipc(3)]
  42. // DeleteDirectory(buffer<bytes<0x301>, 0x19, 0x301> path)
  43. public ResultCode DeleteDirectory(ServiceCtx context)
  44. {
  45. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  46. return (ResultCode)_fileSystem.Target.DeleteDirectory(in name).Value;
  47. }
  48. [CommandHipc(4)]
  49. // DeleteDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path)
  50. public ResultCode DeleteDirectoryRecursively(ServiceCtx context)
  51. {
  52. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  53. return (ResultCode)_fileSystem.Target.DeleteDirectoryRecursively(in name).Value;
  54. }
  55. [CommandHipc(5)]
  56. // RenameFile(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath)
  57. public ResultCode RenameFile(ServiceCtx context)
  58. {
  59. ref readonly Path currentName = ref FileSystemProxyHelper.GetSfPath(context, index: 0);
  60. ref readonly Path newName = ref FileSystemProxyHelper.GetSfPath(context, index: 1);
  61. return (ResultCode)_fileSystem.Target.RenameFile(in currentName, in newName).Value;
  62. }
  63. [CommandHipc(6)]
  64. // RenameDirectory(buffer<bytes<0x301>, 0x19, 0x301> oldPath, buffer<bytes<0x301>, 0x19, 0x301> newPath)
  65. public ResultCode RenameDirectory(ServiceCtx context)
  66. {
  67. ref readonly Path currentName = ref FileSystemProxyHelper.GetSfPath(context, index: 0);
  68. ref readonly Path newName = ref FileSystemProxyHelper.GetSfPath(context, index: 1);
  69. return (ResultCode)_fileSystem.Target.RenameDirectory(in currentName, in newName).Value;
  70. }
  71. [CommandHipc(7)]
  72. // GetEntryType(buffer<bytes<0x301>, 0x19, 0x301> path) -> nn::fssrv::sf::DirectoryEntryType
  73. public ResultCode GetEntryType(ServiceCtx context)
  74. {
  75. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  76. Result result = _fileSystem.Target.GetEntryType(out uint entryType, in name);
  77. context.ResponseData.Write((int)entryType);
  78. return (ResultCode)result.Value;
  79. }
  80. [CommandHipc(8)]
  81. // OpenFile(u32 mode, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IFile> file
  82. public ResultCode OpenFile(ServiceCtx context)
  83. {
  84. uint mode = context.RequestData.ReadUInt32();
  85. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  86. Result result = _fileSystem.Target.OpenFile(out ReferenceCountedDisposable<LibHac.FsSrv.Sf.IFile> file, in name, mode);
  87. if (result.IsSuccess())
  88. {
  89. IFile fileInterface = new IFile(file);
  90. MakeObject(context, fileInterface);
  91. }
  92. return (ResultCode)result.Value;
  93. }
  94. [CommandHipc(9)]
  95. // OpenDirectory(u32 filter_flags, buffer<bytes<0x301>, 0x19, 0x301> path) -> object<nn::fssrv::sf::IDirectory> directory
  96. public ResultCode OpenDirectory(ServiceCtx context)
  97. {
  98. uint mode = context.RequestData.ReadUInt32();
  99. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  100. Result result = _fileSystem.Target.OpenDirectory(out ReferenceCountedDisposable<LibHac.FsSrv.Sf.IDirectory> dir, name, mode);
  101. if (result.IsSuccess())
  102. {
  103. IDirectory dirInterface = new IDirectory(dir);
  104. MakeObject(context, dirInterface);
  105. }
  106. return (ResultCode)result.Value;
  107. }
  108. [CommandHipc(10)]
  109. // Commit()
  110. public ResultCode Commit(ServiceCtx context)
  111. {
  112. return (ResultCode)_fileSystem.Target.Commit().Value;
  113. }
  114. [CommandHipc(11)]
  115. // GetFreeSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalFreeSpace
  116. public ResultCode GetFreeSpaceSize(ServiceCtx context)
  117. {
  118. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  119. Result result = _fileSystem.Target.GetFreeSpaceSize(out long size, in name);
  120. context.ResponseData.Write(size);
  121. return (ResultCode)result.Value;
  122. }
  123. [CommandHipc(12)]
  124. // GetTotalSpaceSize(buffer<bytes<0x301>, 0x19, 0x301> path) -> u64 totalSize
  125. public ResultCode GetTotalSpaceSize(ServiceCtx context)
  126. {
  127. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  128. Result result = _fileSystem.Target.GetTotalSpaceSize(out long size, in name);
  129. context.ResponseData.Write(size);
  130. return (ResultCode)result.Value;
  131. }
  132. [CommandHipc(13)]
  133. // CleanDirectoryRecursively(buffer<bytes<0x301>, 0x19, 0x301> path)
  134. public ResultCode CleanDirectoryRecursively(ServiceCtx context)
  135. {
  136. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  137. return (ResultCode)_fileSystem.Target.CleanDirectoryRecursively(in name).Value;
  138. }
  139. [CommandHipc(14)]
  140. // GetFileTimeStampRaw(buffer<bytes<0x301>, 0x19, 0x301> path) -> bytes<0x20> timestamp
  141. public ResultCode GetFileTimeStampRaw(ServiceCtx context)
  142. {
  143. ref readonly Path name = ref FileSystemProxyHelper.GetSfPath(context);
  144. Result result = _fileSystem.Target.GetFileTimeStampRaw(out FileTimeStampRaw timestamp, in name);
  145. context.ResponseData.Write(timestamp.Created);
  146. context.ResponseData.Write(timestamp.Modified);
  147. context.ResponseData.Write(timestamp.Accessed);
  148. byte[] data = new byte[8];
  149. // is valid?
  150. data[0] = 1;
  151. context.ResponseData.Write(data);
  152. return (ResultCode)result.Value;
  153. }
  154. protected override void Dispose(bool isDisposing)
  155. {
  156. if (isDisposing)
  157. {
  158. _fileSystem?.Dispose();
  159. }
  160. }
  161. }
  162. }