/* * MIT License * * Copyright (c) 2017 Michael VanOverbeek and ShiftOS devs * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static ShiftOS.Objects.ShiftFS.Utils; using ShiftOS.Objects.ShiftFS; using Newtonsoft.Json; using System.Threading; namespace ShiftOS.Engine { /// /// Management class for ShiftFS path variables. /// public static class Paths { /// /// Initiate the path system. /// public static void Init() { Locations = new Dictionary(); Locations.Add("root", "0:"); AddPath("root", "system"); AddPath("root", "home"); AddPath("home", "documents"); AddPath("home", "desktop"); AddPath("home", "pictures"); AddPath("system", "local"); AddPath("local", "english.local"); AddPath("local", "deutsch.local"); AddPath("local", "verbose.local"); AddPath("system", "data"); AddPath("system", "applauncher"); AddPath("data", "save.json"); AddPath("data", "user.dat"); AddPath("data", "notifications.dat"); AddPath("data", "skin"); AddPath("skin", "widgets.dat"); AddPath("system", "programs"); AddPath("system", "kernel.sft"); AddPath("system", "conf.sft"); AddPath("skin", "current"); AddPath("current", "skin.json"); AddPath("current", "images"); CheckPathExistence(); CreateAndMountSharedFolder(); } /// /// Returns all paths in an array of strings. /// /// The array public static string[] GetAll() { List strings = new List(); foreach(var str in Locations) { strings.Add(str.Key + " = " + str.Value); } return strings.ToArray(); } public static string SaveDirectory { get { string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); return System.IO.Path.Combine(appdata, "ShiftOS", "saves"); } } /// /// Gets all full paths without their keynames. /// /// A string array representing all paths. public static string[] GetAllWithoutKey() { List strings = new List(); foreach (var str in Locations) { strings.Add(str.Value); } return strings.ToArray(); } /// /// Get the full path using a path key. /// /// The path key (folder/filename) for the path. /// The full path. public static string GetPath(string id) { return Locations[id]; } /// /// Checks all directories in the path system to see if they exist, and if not, creates them. /// private static void CheckPathExistence() { foreach(var path in Locations) { if (!path.Value.Contains(".") && path.Key != "classic") { if (!DirectoryExists(path.Value)) { Console.WriteLine($"Writing directory: {path.Value.Replace(Locations["root"], "\\")}"); CreateDirectory(path.Value); } } } } /// /// Gets or sets a representing all paths in the system. /// private static Dictionary Locations { get; set; } /// /// Mounts the ShiftOS shared directory to 1:/, creating the directory if it does not exist. /// public static void CreateAndMountSharedFolder() { if (!System.IO.Directory.Exists(SharedFolder)) { System.IO.Directory.CreateDirectory(SharedFolder); } var mount = new Directory(); mount.Name = "Shared"; Utils.Mount(JsonConvert.SerializeObject(mount)); ScanForDirectories(SharedFolder, 1); //This event-based system allows us to sync the ramdisk from ShiftOS to the host OS. Utils.DirectoryCreated += (dir) => { try { if (dir.StartsWith("1:/")) { string real = dir.Replace("/", "\\").Replace("1:", SharedFolder); if (!System.IO.Directory.Exists(real)) System.IO.Directory.CreateDirectory(real); } } catch { } }; Utils.DirectoryDeleted += (dir) => { try { if (dir.StartsWith("1:/")) { string real = dir.Replace("/", "\\").Replace("1:", SharedFolder); if (System.IO.Directory.Exists(real)) System.IO.Directory.Delete(real, true); } } catch { } }; Utils.FileWritten += (dir) => { try { if (dir.StartsWith("1:/")) { string real = dir.Replace("/", "\\").Replace("1:", SharedFolder); System.IO.File.WriteAllBytes(real, ReadAllBytes(dir)); } } catch { } }; Utils.FileDeleted += (dir) => { try { if (dir.StartsWith("1:/")) { string real = dir.Replace("/", "\\").Replace("1:", SharedFolder); if (System.IO.File.Exists(real)) System.IO.File.Delete(real); } } catch { } }; //This thread will sync the ramdisk from the host OS to ShiftOS. var t = new Thread(() => { while (!SaveSystem.ShuttingDown) { Thread.Sleep(15000); ScanForDirectories(SharedFolder, 1); } }); t.IsBackground = true; t.Start(); } private static void ScanForDirectories(string folder, int mount) { foreach (var file in System.IO.Directory.GetFiles(folder)) { string mfsDir = file.Replace(SharedFolder, $"{mount}:").Replace("\\", "/"); if (!FileExists(mfsDir)) WriteAllBytes(mfsDir, System.IO.File.ReadAllBytes(file)); } foreach (var directory in System.IO.Directory.GetDirectories(folder)) { string mfsDir = directory.Replace(SharedFolder, $"{mount}:").Replace("\\", "/"); if(!DirectoryExists(mfsDir)) CreateDirectory(mfsDir); ScanForDirectories(directory, mount); } } /// /// Gets the ShiftOS shared folder. /// public static string SharedFolder { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ShiftOS_Shared"; } } /// /// Gets the location of the ShiftOS.mfs file. /// public static string SaveFile { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ShiftOS.mfs"; } } /// /// Gets the path of the inner save file. /// [Obsolete("Not used.")] public static string SaveFileInner { get { return Locations["save.json"]; } } /// /// Add a path to the system. /// /// The path's parent directory. /// The filename for the path. public static void AddPath(string parent, string path) { Locations.Add(path, Locations[parent] + "/" + path); } public static string Translate(string path) { return Locations["root"] + path.Replace("\\", "/"); } } }