From fc77b089a6ab600ac6f954cb193d26239008975f Mon Sep 17 00:00:00 2001
From: emmauss <emmausssss@gmail.com>
Date: Sun, 9 Sep 2018 01:04:26 +0300
Subject: Implements proper save path (#386)

* initial save path implementation

* fix savedatatype offset, remove incomplete createsavedata implimentation

* address nits

* fix crash if npdm is not found

* made saveinfo readonly, other stuff

* remove context param from saveinfo contructor

* fix style

* remove whitespace
---
 Ryujinx.HLE/FileSystem/VirtualFileSystem.cs | 132 ++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 Ryujinx.HLE/FileSystem/VirtualFileSystem.cs

(limited to 'Ryujinx.HLE/FileSystem/VirtualFileSystem.cs')

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
-- 
cgit v1.2.3-70-g09d2