VirtualFileSystem.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using Ryujinx.HLE.FileSystem.Content;
  2. using Ryujinx.HLE.HOS;
  3. using System;
  4. using System.IO;
  5. namespace Ryujinx.HLE.FileSystem
  6. {
  7. class VirtualFileSystem : IDisposable
  8. {
  9. public const string BasePath = "RyuFs";
  10. public const string NandPath = "nand";
  11. public const string SdCardPath = "sdmc";
  12. public const string SystemPath = "system";
  13. public static string SafeNandPath = Path.Combine(NandPath, "safe");
  14. public static string SystemNandPath = Path.Combine(NandPath, "system");
  15. public static string UserNandPath = Path.Combine(NandPath, "user");
  16. public Stream RomFs { get; private set; }
  17. public void LoadRomFs(string fileName)
  18. {
  19. RomFs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
  20. }
  21. public void SetRomFs(Stream romfsStream)
  22. {
  23. RomFs?.Close();
  24. RomFs = romfsStream;
  25. }
  26. public string GetFullPath(string basePath, string fileName)
  27. {
  28. if (fileName.StartsWith("//"))
  29. {
  30. fileName = fileName.Substring(2);
  31. }
  32. else if (fileName.StartsWith('/'))
  33. {
  34. fileName = fileName.Substring(1);
  35. }
  36. else
  37. {
  38. return null;
  39. }
  40. string fullPath = Path.GetFullPath(Path.Combine(basePath, fileName));
  41. if (!fullPath.StartsWith(GetBasePath()))
  42. {
  43. return null;
  44. }
  45. return fullPath;
  46. }
  47. public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
  48. public string GetNandPath() => MakeDirAndGetFullPath(NandPath);
  49. public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);
  50. public string GetGameSavePath(SaveInfo save, ServiceCtx context)
  51. {
  52. return MakeDirAndGetFullPath(SaveHelper.GetSavePath(save, context));
  53. }
  54. public string GetFullPartitionPath(string partitionPath)
  55. {
  56. return MakeDirAndGetFullPath(partitionPath);
  57. }
  58. public string SwitchPathToSystemPath(string switchPath)
  59. {
  60. string[] parts = switchPath.Split(":");
  61. if (parts.Length != 2)
  62. {
  63. return null;
  64. }
  65. return GetFullPath(MakeDirAndGetFullPath(parts[0]), parts[1]);
  66. }
  67. public string SystemPathToSwitchPath(string systemPath)
  68. {
  69. string baseSystemPath = GetBasePath() + Path.DirectorySeparatorChar;
  70. if (systemPath.StartsWith(baseSystemPath))
  71. {
  72. string rawPath = systemPath.Replace(baseSystemPath, "");
  73. int firstSeparatorOffset = rawPath.IndexOf(Path.DirectorySeparatorChar);
  74. if (firstSeparatorOffset == -1)
  75. {
  76. return $"{rawPath}:/";
  77. }
  78. string basePath = rawPath.Substring(0, firstSeparatorOffset);
  79. string fileName = rawPath.Substring(firstSeparatorOffset + 1);
  80. return $"{basePath}:/{fileName}";
  81. }
  82. return null;
  83. }
  84. private string MakeDirAndGetFullPath(string dir)
  85. {
  86. // Handles Common Switch Content Paths
  87. switch (dir)
  88. {
  89. case ContentPath.SdCard:
  90. case "@Sdcard":
  91. dir = SdCardPath;
  92. break;
  93. case ContentPath.User:
  94. dir = UserNandPath;
  95. break;
  96. case ContentPath.System:
  97. dir = SystemNandPath;
  98. break;
  99. case ContentPath.SdCardContent:
  100. dir = Path.Combine(SdCardPath, "Nintendo", "Contents");
  101. break;
  102. case ContentPath.UserContent:
  103. dir = Path.Combine(UserNandPath, "Contents");
  104. break;
  105. case ContentPath.SystemContent:
  106. dir = Path.Combine(SystemNandPath, "Contents");
  107. break;
  108. }
  109. string fullPath = Path.Combine(GetBasePath(), dir);
  110. if (!Directory.Exists(fullPath))
  111. {
  112. Directory.CreateDirectory(fullPath);
  113. }
  114. return fullPath;
  115. }
  116. public DriveInfo GetDrive()
  117. {
  118. return new DriveInfo(Path.GetPathRoot(GetBasePath()));
  119. }
  120. public string GetBasePath()
  121. {
  122. string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
  123. return Path.Combine(appDataPath, BasePath);
  124. }
  125. public void Dispose()
  126. {
  127. Dispose(true);
  128. }
  129. protected virtual void Dispose(bool disposing)
  130. {
  131. if (disposing)
  132. {
  133. RomFs?.Dispose();
  134. }
  135. }
  136. }
  137. }