diff options
Diffstat (limited to 'Ryujinx.HLE/FileSystem')
| -rw-r--r-- | Ryujinx.HLE/FileSystem/SaveDataType.cs | 12 | ||||
| -rw-r--r-- | Ryujinx.HLE/FileSystem/SaveHelper.cs | 46 | ||||
| -rw-r--r-- | Ryujinx.HLE/FileSystem/SaveInfo.cs | 28 | ||||
| -rw-r--r-- | Ryujinx.HLE/FileSystem/SaveSpaceId.cs | 10 | ||||
| -rw-r--r-- | Ryujinx.HLE/FileSystem/VirtualFileSystem.cs | 132 |
5 files changed, 228 insertions, 0 deletions
diff --git a/Ryujinx.HLE/FileSystem/SaveDataType.cs b/Ryujinx.HLE/FileSystem/SaveDataType.cs new file mode 100644 index 00000000..edfe8ab1 --- /dev/null +++ b/Ryujinx.HLE/FileSystem/SaveDataType.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.HLE.FileSystem +{ + enum SaveDataType : byte + { + SystemSaveData, + SaveData, + BcatDeliveryCacheStorage, + DeviceSaveData, + TemporaryStorage, + CacheStorage + } +} diff --git a/Ryujinx.HLE/FileSystem/SaveHelper.cs b/Ryujinx.HLE/FileSystem/SaveHelper.cs new file mode 100644 index 00000000..67f01016 --- /dev/null +++ b/Ryujinx.HLE/FileSystem/SaveHelper.cs @@ -0,0 +1,46 @@ +using Ryujinx.HLE.HOS; +using System.IO; + +using static Ryujinx.HLE.FileSystem.VirtualFileSystem; + +namespace Ryujinx.HLE.FileSystem +{ + static class SaveHelper + { + public static string GetSavePath(SaveInfo SaveMetaData, ServiceCtx Context) + { + string BaseSavePath = NandPath; + long CurrentTitleId = SaveMetaData.TitleId; + + switch (SaveMetaData.SaveSpaceId) + { + case SaveSpaceId.NandUser: + BaseSavePath = UserNandPath; + break; + case SaveSpaceId.NandSystem: + BaseSavePath = SystemNandPath; + break; + case SaveSpaceId.SdCard: + BaseSavePath = Path.Combine(SdCardPath, "Nintendo"); + break; + } + + BaseSavePath = Path.Combine(BaseSavePath, "save"); + + if (SaveMetaData.TitleId == 0 && SaveMetaData.SaveDataType == SaveDataType.SaveData) + { + if (Context.Process.MetaData != null) + { + CurrentTitleId = Context.Process.MetaData.ACI0.TitleId; + } + } + + string SavePath = Path.Combine(BaseSavePath, + SaveMetaData.SaveId.ToString("x16"), + SaveMetaData.UserId.ToString(), + SaveMetaData.SaveDataType == SaveDataType.SaveData ? CurrentTitleId.ToString("x16") : string.Empty); + + return SavePath; + } + } +} diff --git a/Ryujinx.HLE/FileSystem/SaveInfo.cs b/Ryujinx.HLE/FileSystem/SaveInfo.cs new file mode 100644 index 00000000..f3790ec7 --- /dev/null +++ b/Ryujinx.HLE/FileSystem/SaveInfo.cs @@ -0,0 +1,28 @@ +using Ryujinx.HLE.HOS.SystemState; + +namespace Ryujinx.HLE.FileSystem +{ + struct SaveInfo + { + public long TitleId { get; private set; } + public long SaveId { get; private set; } + public UserId UserId { get; private set; } + + public SaveDataType SaveDataType { get; private set; } + public SaveSpaceId SaveSpaceId { get; private set; } + + public SaveInfo( + long TitleId, + long SaveId, + SaveDataType SaveDataType, + UserId UserId, + SaveSpaceId SaveSpaceId) + { + this.TitleId = TitleId; + this.UserId = UserId; + this.SaveId = SaveId; + this.SaveDataType = SaveDataType; + this.SaveSpaceId = SaveSpaceId; + } + } +} diff --git a/Ryujinx.HLE/FileSystem/SaveSpaceId.cs b/Ryujinx.HLE/FileSystem/SaveSpaceId.cs new file mode 100644 index 00000000..5a2b32d6 --- /dev/null +++ b/Ryujinx.HLE/FileSystem/SaveSpaceId.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.HLE.FileSystem +{ + enum SaveSpaceId : byte + { + NandSystem, + NandUser, + SdCard, + TemporaryStorage + } +} diff --git a/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs new file mode 100644 index 00000000..e621ec2b --- /dev/null +++ b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs @@ -0,0 +1,132 @@ +using Ryujinx.HLE.HOS; +using System; +using System.IO; + +namespace Ryujinx.HLE.FileSystem +{ + class VirtualFileSystem : IDisposable + { + public const string BasePath = "RyuFs"; + public const string NandPath = "nand"; + public const string SdCardPath = "sdmc"; + public const string SystemPath = "system"; + + public static string SystemNandPath = Path.Combine(NandPath, "system"); + public static string UserNandPath = Path.Combine(NandPath, "user"); + + public Stream RomFs { get; private set; } + + public void LoadRomFs(string FileName) + { + RomFs = new FileStream(FileName, FileMode.Open, FileAccess.Read); + } + + public void SetRomFs(Stream RomfsStream) + { + RomFs?.Close(); + RomFs = RomfsStream; + } + + public string GetFullPath(string BasePath, string FileName) + { + if (FileName.StartsWith("//")) + { + FileName = FileName.Substring(2); + } + else if (FileName.StartsWith('/')) + { + FileName = FileName.Substring(1); + } + else + { + return null; + } + + string FullPath = Path.GetFullPath(Path.Combine(BasePath, FileName)); + + if (!FullPath.StartsWith(GetBasePath())) + { + return null; + } + + return FullPath; + } + + public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath); + + public string GetNandPath() => MakeDirAndGetFullPath(NandPath); + + public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath); + + public string GetGameSavePath(SaveInfo Save, ServiceCtx Context) + { + return MakeDirAndGetFullPath(SaveHelper.GetSavePath(Save, Context)); + } + + public string SwitchPathToSystemPath(string SwitchPath) + { + string[] Parts = SwitchPath.Split(":"); + if (Parts.Length != 2) + { + return null; + } + return GetFullPath(MakeDirAndGetFullPath(Parts[0]), Parts[1]); + } + + public string SystemPathToSwitchPath(string SystemPath) + { + string BaseSystemPath = GetBasePath() + Path.DirectorySeparatorChar; + if (SystemPath.StartsWith(BaseSystemPath)) + { + string RawPath = SystemPath.Replace(BaseSystemPath, ""); + int FirstSeparatorOffset = RawPath.IndexOf(Path.DirectorySeparatorChar); + if (FirstSeparatorOffset == -1) + { + return $"{RawPath}:/"; + } + + string BasePath = RawPath.Substring(0, FirstSeparatorOffset); + string FileName = RawPath.Substring(FirstSeparatorOffset + 1); + return $"{BasePath}:/{FileName}"; + } + return null; + } + + private string MakeDirAndGetFullPath(string Dir) + { + string FullPath = Path.Combine(GetBasePath(), Dir); + + if (!Directory.Exists(FullPath)) + { + Directory.CreateDirectory(FullPath); + } + + return FullPath; + } + + public DriveInfo GetDrive() + { + return new DriveInfo(Path.GetPathRoot(GetBasePath())); + } + + public string GetBasePath() + { + string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + + return Path.Combine(AppDataPath, BasePath); + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + RomFs?.Dispose(); + } + } + } +}
\ No newline at end of file |
