예제 #1
0
        public void Mount(Configuration config)
        {
            davFs = new DavFS(config);
            davFs.RepositoryActionPerformed      += (s, e) => { RepositoryActionPerformed?.Invoke(s, e); };
            davFs.RepositoryAuthenticationFailed += (s, e) => { RepositoryAuthenticationFailed?.Invoke(s, e); };

            Host = new FileSystemHost(davFs);
            if (Host.Mount($"{config.DriveLetter}:", null, config.SyncOps, 0) < 0)
            {
                throw new IOException("cannot mount file system");
            }
        }
예제 #2
0
        protected override void OnStart(String[] Args)
        {
            try
            {
                String         DebugLogFile   = null;
                UInt32         DebugFlags     = 0;
                String         VolumePrefix   = null;
                String         PassThrough    = null;
                String         MountPoint     = null;
                IntPtr         DebugLogHandle = (IntPtr)(-1);
                FileSystemHost Host           = null;
                Ptfs           Ptfs           = null;
                int            I;

                for (I = 1; Args.Length > I; I++)
                {
                    String Arg = Args[I];
                    if ('-' != Arg[0])
                    {
                        break;
                    }
                    switch (Arg[1])
                    {
                    case '?':
                        throw new CommandLineUsageException();

                    case 'd':
                        argtol(Args, ref I, ref DebugFlags);
                        break;

                    case 'D':
                        argtos(Args, ref I, ref DebugLogFile);
                        break;

                    case 'm':
                        argtos(Args, ref I, ref MountPoint);
                        break;

                    case 'p':
                        argtos(Args, ref I, ref PassThrough);
                        break;

                    case 'u':
                        argtos(Args, ref I, ref VolumePrefix);
                        break;

                    default:
                        throw new CommandLineUsageException();
                    }
                }

                if (Args.Length > I)
                {
                    throw new CommandLineUsageException();
                }

                if (null == PassThrough && null != VolumePrefix)
                {
                    I = VolumePrefix.IndexOf('\\');
                    if (-1 != I && VolumePrefix.Length > I && '\\' != VolumePrefix[I + 1])
                    {
                        I = VolumePrefix.IndexOf('\\', I + 1);
                        if (-1 != I &&
                            VolumePrefix.Length > I + 1 &&
                            (
                                ('A' <= VolumePrefix[I + 1] && VolumePrefix[I + 1] <= 'Z') ||
                                ('a' <= VolumePrefix[I + 1] && VolumePrefix[I + 1] <= 'z')
                            ) &&
                            '$' == VolumePrefix[I + 2])
                        {
                            PassThrough = String.Format("{0}:{1}", VolumePrefix[I + 1], VolumePrefix.Substring(I + 3));
                        }
                    }
                }

                if (null == PassThrough || null == MountPoint)
                {
                    throw new CommandLineUsageException();
                }

                if (null != DebugLogFile)
                {
                    if (0 > FileSystemHost.SetDebugLogFile(DebugLogFile))
                    {
                        throw new CommandLineUsageException("cannot open debug log file");
                    }
                }

                Host        = new FileSystemHost(Ptfs = new Ptfs(PassThrough));
                Host.Prefix = VolumePrefix;
                if (0 > Host.Mount(MountPoint, null, true, DebugFlags))
                {
                    throw new IOException("cannot mount file system");
                }
                MountPoint = Host.MountPoint();
                _Host      = Host;

                Log(EVENTLOG_INFORMATION_TYPE, String.Format("{0}{1}{2} -p {3} -m {4}",
                                                             PROGNAME,
                                                             null != VolumePrefix && 0 < VolumePrefix.Length ? " -u " : "",
                                                             null != VolumePrefix && 0 < VolumePrefix.Length ? VolumePrefix : "",
                                                             PassThrough,
                                                             MountPoint));
            }
            catch (CommandLineUsageException ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format(
                        "{0}" +
                        "usage: {1} OPTIONS\n" +
                        "\n" +
                        "options:\n" +
                        "    -d DebugFlags       [-1: enable all debug logs]\n" +
                        "    -D DebugLogFile     [file path; use - for stderr]\n" +
                        "    -u \\Server\\Share    [UNC prefix (single backslash)]\n" +
                        "    -p Directory        [directory to expose as pass through file system]\n" +
                        "    -m MountPoint       [X:|*|directory]\n",
                        ex.HasMessage ? ex.Message + "\n" : "",
                        PROGNAME));
                throw;
            }
            catch (Exception ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format("{0}", ex.Message));
                throw;
            }
        }
예제 #3
0
파일: Program.cs 프로젝트: pianomanx/winfsp
        protected override void OnStart(String[] Args)
        {
            try
            {
                String         VolumePrefix = null;
                String         MountPoint   = null;
                FileSystemHost Host         = null;
                Notifyfs       Notifyfs     = null;
                int            I;

                for (I = 1; Args.Length > I; I++)
                {
                    String Arg = Args[I];
                    if ('-' != Arg[0])
                    {
                        break;
                    }
                    switch (Arg[1])
                    {
                    case '?':
                        throw new CommandLineUsageException();

                    case 'm':
                        argtos(Args, ref I, ref MountPoint);
                        break;

                    case 'u':
                        argtos(Args, ref I, ref VolumePrefix);
                        break;

                    default:
                        throw new CommandLineUsageException();
                    }
                }

                if (Args.Length > I)
                {
                    throw new CommandLineUsageException();
                }

                if (null == MountPoint)
                {
                    throw new CommandLineUsageException();
                }

                FileSystemHost.SetDebugLogFile("-");

                Host        = new FileSystemHost(Notifyfs = new Notifyfs());
                Host.Prefix = VolumePrefix;
                if (0 > Host.Mount(MountPoint))
                {
                    throw new IOException("cannot mount file system");
                }
                MountPoint = Host.MountPoint();
                _Host      = Host;

                Log(EVENTLOG_INFORMATION_TYPE, String.Format("{0}{1}{2} -m {3}",
                                                             PROGNAME,
                                                             null != VolumePrefix && 0 < VolumePrefix.Length ? " -u " : "",
                                                             null != VolumePrefix && 0 < VolumePrefix.Length ? VolumePrefix : "",
                                                             MountPoint));
            }
            catch (CommandLineUsageException ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format(
                        "{0}" +
                        "usage: {1} OPTIONS\n" +
                        "\n" +
                        "options:\n" +
                        "    -u \\Server\\Share    [UNC prefix (single backslash)]\n" +
                        "    -m MountPoint       [X:|*|directory]\n",
                        ex.HasMessage ? ex.Message + "\n" : "",
                        PROGNAME));
                throw;
            }
            catch (Exception ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format("{0}", ex.Message));
                throw;
            }
        }
예제 #4
0
        protected override void OnStart(String[] Args)
        {
            try
            {
                Boolean        CaseInsensitive = false;
                String         DebugLogFile    = null;
                UInt32         DebugFlags      = 0;
                UInt32         FileInfoTimeout = unchecked ((UInt32)(-1));
                UInt32         MaxFileNodes    = 1024;
                UInt32         MaxFileSize     = 16 * 1024 * 1024;
                String         FileSystemName  = null;
                String         VolumePrefix    = null;
                String         MountPoint      = null;
                String         RootSddl        = null;
                FileSystemHost Host            = null;
                Memfs          Memfs           = null;
                int            I;

                for (I = 1; Args.Length > I; I++)
                {
                    String Arg = Args[I];
                    if ('-' != Arg[0])
                    {
                        break;
                    }
                    switch (Arg[1])
                    {
                    case '?':
                        throw new CommandLineUsageException();

                    case 'D':
                        argtos(Args, ref I, ref DebugLogFile);
                        break;

                    case 'd':
                        argtol(Args, ref I, ref DebugFlags);
                        break;

                    case 'F':
                        argtos(Args, ref I, ref FileSystemName);
                        break;

                    case 'i':
                        CaseInsensitive = true;
                        break;

                    case 'm':
                        argtos(Args, ref I, ref MountPoint);
                        break;

                    case 'n':
                        argtol(Args, ref I, ref MaxFileNodes);
                        break;

                    case 'S':
                        argtos(Args, ref I, ref RootSddl);
                        break;

                    case 's':
                        argtol(Args, ref I, ref MaxFileSize);
                        break;

                    case 't':
                        argtol(Args, ref I, ref FileInfoTimeout);
                        break;

                    case 'u':
                        argtos(Args, ref I, ref VolumePrefix);
                        break;

                    default:
                        throw new CommandLineUsageException();
                    }
                }

                if (Args.Length > I)
                {
                    throw new CommandLineUsageException();
                }

                if ((null == VolumePrefix || 0 == VolumePrefix.Length) && null == MountPoint)
                {
                    throw new CommandLineUsageException();
                }

                if (null != DebugLogFile)
                {
                    if (0 > FileSystemHost.SetDebugLogFile(DebugLogFile))
                    {
                        throw new CommandLineUsageException("cannot open debug log file");
                    }
                }

                Host = new FileSystemHost(Memfs = new Memfs(
                                              CaseInsensitive, MaxFileNodes, MaxFileSize, RootSddl));
                Host.FileInfoTimeout = FileInfoTimeout;
                Host.Prefix          = VolumePrefix;
                Host.FileSystemName  = null != FileSystemName ? FileSystemName : "-MEMFS";
                if (0 > Host.Mount(MountPoint, null, false, DebugFlags))
                {
                    throw new IOException("cannot mount file system");
                }
                MountPoint = Host.MountPoint();
                _Host      = Host;

                Log(EVENTLOG_INFORMATION_TYPE, String.Format("{0} -t {1} -n {2} -s {3}{4}{5}{6}{7}{8}{9}",
                                                             PROGNAME, (Int32)FileInfoTimeout, MaxFileNodes, MaxFileSize,
                                                             null != RootSddl ? " -S " : "", null != RootSddl ? RootSddl : "",
                                                             null != VolumePrefix && 0 < VolumePrefix.Length ? " -u " : "",
                                                             null != VolumePrefix && 0 < VolumePrefix.Length ? VolumePrefix : "",
                                                             null != MountPoint ? " -m " : "", null != MountPoint ? MountPoint : ""));
            }
            catch (CommandLineUsageException ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format(
                        "{0}" +
                        "usage: {1} OPTIONS\n" +
                        "\n" +
                        "options:\n" +
                        "    -d DebugFlags       [-1: enable all debug logs]\n" +
                        "    -D DebugLogFile     [file path; use - for stderr]\n" +
                        "    -i                  [case insensitive file system]\n" +
                        "    -t FileInfoTimeout  [millis]\n" +
                        "    -n MaxFileNodes\n" +
                        "    -s MaxFileSize      [bytes]\n" +
                        "    -F FileSystemName\n" +
                        "    -S RootSddl         [file rights: FA, etc; NO generic rights: GA, etc.]\n" +
                        "    -u \\Server\\Share    [UNC prefix (single backslash)]\n" +
                        "    -m MountPoint       [X:|* (required if no UNC prefix)]\n",
                        ex.HasMessage ? ex.Message + "\n" : "",
                        PROGNAME));
                throw;
            }
            catch (Exception ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format("{0}", ex.Message));
                throw;
            }
        }
예제 #5
0
        public List <FileSystemHost> LoadPartitions(uint DebugLogLevel = 0)
        {
            if (!IsFatxDevice())
            {
                return(null);
            }

            var filesystems = new List <FileSystemHost>();

            // Filter kXboxPartitions to the ones that could fit onto this drive/image
            var partitions = kXboxPartitions.Where(partition => partition.Item2 < DriveSize && partition.Item2 + partition.Item3 <= DriveSize).ToList();

            // Try reading in devkit partition table
            Stream.Position = 0;
            var devkitTable = Stream.ReadStruct <FATX_DEVKIT_PARTITION_TABLE>();

            devkitTable.EndianSwap();
            if (devkitTable.IsValid)
            {
                // Add any non-zero partitions to our partition list
                for (int i = 0; i < devkitTable.Partitions.Length; i++)
                {
                    var partition = devkitTable.Partitions[i];

                    if (partition.Offset != 0 && partition.Size != 0)
                    {
                        var partitionName = kDevkitPartitionNames[i];
                        if (partitionName == "Dump") // Dump can contain multiple partitions, see kDumpPartitions
                        {
                            foreach (var dumpPartition in kDumpPartitions)
                            {
                                partitions.Add(new Tuple <string, long, long>(
                                                   $"DevKit {dumpPartition.Item1}", partition.Offset + dumpPartition.Item2, dumpPartition.Item3));
                            }
                        }
                        else
                        {
                            partitions.Add(new Tuple <string, long, long>(
                                               $"DevKit {kDevkitPartitionNames[i]}", partition.Offset, partition.Size));
                        }
                    }
                }
            }

            // Read in cache partition data
            Stream.Position = 0x800;
            CacheHeader     = Stream.ReadStruct <CACHE_PARTITION_DATA>();
            CacheHeader.EndianSwap();

            // Check partition validity & remove any invalid ones
            var removeList = new List <int>();

            for (int i = 0; i < partitions.Count; i++)
            {
                Stream.Seek(partitions[i].Item2, SeekOrigin.Begin);
                var header = Stream.ReadStruct <FAT_VOLUME_METADATA>();
                if (!header.IsValid)
                {
                    removeList.Add(i);
                }
            }
            removeList.Reverse();
            foreach (var index in removeList)
            {
                partitions.RemoveAt(index);
            }

            // Sort partitions by their offset
            partitions.OrderBy(p => p.Item2).ToList();

            // Work out the retail data partition size
            // (We check all partitions for size == 0 here, because devkit partitions could be added after)
            // (Even though any retail data partition would be invalid/corrupt by devkit partition presence, it's worth trying to salvage it)
            for (int i = 0; i < partitions.Count; i++)
            {
                var  partition = partitions[i];
                long size      = 0x377FFC000;  // 20GB HDD
                if (DriveSize != 0x04AB440C00) // 20GB HDD
                {
                    size = DriveSize - partition.Item2;
                }

                if (partition.Item3 == 0)
                {
                    partitions[i] = new Tuple <string, long, long>(partition.Item1, partition.Item2, size);
                }
            }

            // TODO: check if any partitions interfere with each other (eg. devkit Partition1 located inside retail Partition1 space), and mark the drive label if so ("CORRUPT" or something similar)

            // Load in the filesystems & mount them:
            int stfcIndex  = 0;
            int driveIndex = -1;

            foreach (var partition in partitions)
            {
                if (partition.Item3 == 0)
                {
                    continue; // Couldn't figure out size of it ?
                }
                driveIndex++;

                Stream.Position = partition.Item2;
                var fatx = new FatxFileSystem(Stream, partition.Item1, partition.Item2, partition.Item3);
                fatx.StreamLock = StreamLock;

                var Host = new FileSystemHost(fatx);
                Host.Prefix = null;
                if (Host.Mount(null, null, false, DebugLogLevel) < 0)
                {
                    if (true)
                    {
                        Stream.Position = partition.Item2;
                        var stfs = new StfsFileSystem(Stream, partition.Item1, partition.Item2);
                        stfs.StreamLock     = StreamLock;
                        stfs.SkipHashChecks = true; // TODO!
                        if (stfcIndex < 2 && CacheHeader.IsValid)
                        {
                            stfs.CacheHeader          = CacheHeader;
                            stfs.CachePartitionIndex  = stfcIndex;
                            stfs.StfsVolumeDescriptor = CacheHeader.VolumeDescriptor[stfcIndex];
                        }

                        stfcIndex++;
                        if (stfcIndex >= 2)
                        {
                            stfcIndex = 0; // Reset index for devkit cache partitions
                        }
                        Host        = new FileSystemHost(stfs);
                        Host.Prefix = null;
                        if (Host.Mount(null, null, false, DebugLogLevel) < 0)
                        {
                            continue;
                        }
                    }
                }
                filesystems.Add(Host);
            }

            return(filesystems);
        }
예제 #6
0
파일: Program.cs 프로젝트: saconni/layfs
        protected override void OnStart(String[] Args)
        {
            try
            {
                String         debugLogFile   = null;
                UInt32         debugFlags     = 0;
                String         volumePrefix   = null;
                String         writePath      = null;
                String         readOnlyPath   = null;
                String         mountPoint     = null;
                IntPtr         debugLogHandle = (IntPtr)(-1);
                FileSystemHost host           = null;

                int i;

                for (i = 1; Args.Length > i; i++)
                {
                    String Arg = Args[i];
                    if ('-' != Arg[0])
                    {
                        break;
                    }
                    switch (Arg[1])
                    {
                    case '?':
                        throw new CommandLineUsageException();

                    case 'd':
                        argtol(Args, ref i, ref debugFlags);
                        break;

                    case 'D':
                        argtos(Args, ref i, ref debugLogFile);
                        break;

                    case 'm':
                        argtos(Args, ref i, ref mountPoint);
                        break;

                    case 'r':
                        argtos(Args, ref i, ref readOnlyPath);
                        break;

                    case 'w':
                        argtos(Args, ref i, ref writePath);
                        break;

                    case 'u':
                        argtos(Args, ref i, ref volumePrefix);
                        break;

                    default:
                        throw new CommandLineUsageException();
                    }
                }

                if (Args.Length > i)
                {
                    throw new CommandLineUsageException();
                }

                if (null == readOnlyPath || null == writePath || null == mountPoint)
                {
                    throw new CommandLineUsageException();
                }

                if (null != debugLogFile)
                {
                    if (0 > FileSystemHost.SetDebugLogFile(debugLogFile))
                    {
                        throw new CommandLineUsageException("cannot open debug log file");
                    }
                }

                host        = new FileSystemHost(new LayeredFileSystem(writePath, readOnlyPath));
                host.Prefix = volumePrefix;

                if (0 > host.Mount(mountPoint, null, true, debugFlags))
                {
                    throw new IOException("cannot mount file system");
                }

                mountPoint = host.MountPoint();

                _Host = host;

                Log(EVENTLOG_INFORMATION_TYPE, String.Format("{0}{1}{2} -w {3} -r {5} -m {4}",
                                                             PROGNAME,
                                                             null != volumePrefix && 0 < volumePrefix.Length ? " -u " : "",
                                                             null != volumePrefix && 0 < volumePrefix.Length ? volumePrefix : "",
                                                             writePath,
                                                             mountPoint,
                                                             readOnlyPath));
            }
            catch (CommandLineUsageException ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format(
                        "{0}" +
                        "usage: {1} OPTIONS\n" +
                        "\n" +
                        "options:\n" +
                        "    -d DebugFlags       [-1: enable all debug logs]\n" +
                        "    -D DebugLogFile     [file path; use - for stderr]\n" +
                        "    -u \\Server\\Share    [UNC prefix (single backslash)]\n" +
                        "    -w Directory        [write file system]\n" +
                        "    -r Directory        [read only file system]\n" +
                        "    -m MountPoint       [X:|*|directory]\n",
                        ex.HasMessage ? ex.Message + "\n" : "",
                        PROGNAME));
                throw;
            }
            catch (Exception ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format("{0}", ex.Message));
                throw;
            }
        }
예제 #7
0
        protected override void OnStart(String[] Args)
        {
            try
            {
                String         DebugLogFile   = null;
                UInt32         DebugFlags     = 0;
                String         VolumePrefix   = null;
                String         ImagePath      = null;
                String         MountPoint     = null;
                IntPtr         DebugLogHandle = (IntPtr)(-1);
                bool           SetupFS        = false;
                bool           RemoveFS       = false;
                FileSystemHost Host           = null;
                GdfxFileSystem Gdfx           = null;
                StfsFileSystem Stfs           = null;
                FatxFileSystem Fatx           = null;

                int I;

                for (I = 1; Args.Length > I; I++)
                {
                    String Arg = Args[I];
                    if ('-' != Arg[0])
                    {
                        break;
                    }
                    switch (Arg[1])
                    {
                    case '?':
                        throw new CommandLineUsageException();

                    case 'd':
                        argtol(Args, ref I, ref DebugFlags);
                        break;

                    case 'D':
                        argtos(Args, ref I, ref DebugLogFile);
                        break;

                    case 'm':
                        argtos(Args, ref I, ref MountPoint);
                        break;

                    case 'i':
                        argtos(Args, ref I, ref ImagePath);
                        break;

                    case 'u':
                        argtos(Args, ref I, ref VolumePrefix);
                        break;

                    case 's':
                        SetupFS = true;
                        break;

                    case 'r':
                        RemoveFS = true;
                        break;

                    default:
                        throw new CommandLineUsageException();
                    }
                }

                if (Args.Length > I)
                {
                    throw new CommandLineUsageException();
                }

                if (SetupFS)
                {
                    try
                    {
                        Console.WriteLine("\r\nSetting up Xbox filesystems...\r\n");
                        // Add to WinFsp services list, allows using "net use X: \\xbox-winfps\C$\game.iso"
                        Registry.SetValue(@"HKEY_LOCAL_MACHINE\Software\WinFsp\Services\xbox-winfsp", "CommandLine", "-u %1 -m %2", RegistryValueKind.String);
                        Registry.SetValue(@"HKEY_LOCAL_MACHINE\Software\WinFsp\Services\xbox-winfsp", "Executable", System.Reflection.Assembly.GetEntryAssembly().Location, RegistryValueKind.String);
                        Registry.SetValue(@"HKEY_LOCAL_MACHINE\Software\WinFsp\Services\xbox-winfsp", "Security", "D:P(A;;RPWPLC;;;WD)", RegistryValueKind.String);
                        Registry.SetValue(@"HKEY_LOCAL_MACHINE\Software\WinFsp\Services\xbox-winfsp", "JobControl", 1, RegistryValueKind.DWord);

                        // Context menu item for all files (since STFS has no extension...)
                        Registry.SetValue(@"HKEY_LOCAL_MACHINE\Software\Classes\*\shell\Mount as Xbox STFS/GDF\command", null, $"\"{System.Reflection.Assembly.GetEntryAssembly().Location}\" -i \"%1\" -m *");

                        Console.WriteLine("Successfully setup filesystems, you may need to restart for changes to take effect.\r\n");
                    }
                    catch
                    {
                        Console.WriteLine("Error: Failed to setup filesystems, maybe try running as admin?\r\n");
                    }
                }
                if (RemoveFS)
                {
                    try
                    {
                        bool error = false;
                        Console.WriteLine("\r\nRemoving any Xbox filesystems...\r\n");
                        try
                        {
                            RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\WinFsp\Services", true);
                            if (key != null)
                            {
                                key.DeleteSubKeyTree("xbox-winfsp", true);
                            }
                        }
                        catch
                        {
                            Console.WriteLine("Error: Failed to remove xbox-winfsp key!\r\n");
                            error = true;
                        }

                        try
                        {
                            RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Classes\*\shell", true);
                            if (key != null)
                            {
                                key.DeleteSubKeyTree("Mount as Xbox STFS/GDF");
                            }
                        }
                        catch
                        {
                            Console.WriteLine("Error: Failed to remove context-menu key!\r\n");
                            error = true;
                        }

                        if (error)
                        {
                            throw new Exception();
                        }

                        Console.WriteLine("Removed Xbox filesystems successfully.\r\n");
                    }
                    catch
                    {
                        Console.WriteLine("An error was encountered, maybe try running as admin?\r\n");
                    }
                }

                if (null == ImagePath && null != VolumePrefix)
                {
                    I = VolumePrefix.IndexOf('\\');
                    if (-1 != I && VolumePrefix.Length > I && '\\' != VolumePrefix[I + 1])
                    {
                        I = VolumePrefix.IndexOf('\\', I + 1);
                        if (-1 != I &&
                            VolumePrefix.Length > I + 1 &&
                            (
                                ('A' <= VolumePrefix[I + 1] && VolumePrefix[I + 1] <= 'Z') ||
                                ('a' <= VolumePrefix[I + 1] && VolumePrefix[I + 1] <= 'z')
                            ) &&
                            '$' == VolumePrefix[I + 2])
                        {
                            ImagePath = String.Format("{0}:{1}", VolumePrefix[I + 1], VolumePrefix.Substring(I + 3));
                        }
                    }
                }

                if (null != DebugLogFile)
                {
                    if (0 > FileSystemHost.SetDebugLogFile(DebugLogFile))
                    {
                        throw new CommandLineUsageException("cannot open debug log file");
                    }
                }

                if (!string.IsNullOrEmpty(ImagePath) && !string.IsNullOrEmpty(MountPoint))
                {
                    // For some reason WinFsp needs MountPoint to be null for wildcard to work without elevation...
                    bool openExplorer = false;
                    if (MountPoint == "*")
                    {
                        MountPoint   = null;
                        openExplorer = true; // Open mounted drive in explorer if the mountPoint is wildcard - QoL :)
                    }

                    var fileStream = File.OpenRead(ImagePath);

                    Host        = new FileSystemHost(Fatx = new FatxFileSystem(fileStream, ImagePath));
                    Host.Prefix = VolumePrefix;
                    if (Host.Mount(MountPoint, null, true, DebugFlags) < 0)
                    {
                        Fatx = null;
                        fileStream.Position = 0;
                        Host        = new FileSystemHost(Stfs = new StfsFileSystem(fileStream, ImagePath));
                        Host.Prefix = VolumePrefix;
                        if (Host.Mount(MountPoint, null, true, DebugFlags) < 0)
                        {
                            Stfs = null;
                            fileStream.Position = 0;
                            Host        = new FileSystemHost(Gdfx = new GdfxFileSystem(fileStream, ImagePath));
                            Host.Prefix = VolumePrefix;
                            if (Host.Mount(MountPoint, null, true, DebugFlags) < 0)
                            {
                                throw new IOException("cannot mount file system");
                            }
                        }
                    }

                    MountPoint = Host.MountPoint();
                    _Host      = Host;

                    if (openExplorer)
                    {
                        System.Diagnostics.Process.Start("explorer.exe", MountPoint);
                    }

                    Log(EVENTLOG_INFORMATION_TYPE, String.Format("{0}{1}{2} -p {3} -m {4}",
                                                                 PROGNAME,
                                                                 null != VolumePrefix && 0 < VolumePrefix.Length ? " -u " : "",
                                                                 null != VolumePrefix && 0 < VolumePrefix.Length ? VolumePrefix : "",
                                                                 ImagePath,
                                                                 MountPoint));

                    Console.Title = $"{MountPoint} - xbox-winfsp";
                    Console.WriteLine($"\r\n{ImagePath}:\r\n Mounted to {MountPoint}, hit CTRL+C in this window to unmount.\r\n");
                }
                else
                {
                    _Hosts = new List <FileSystemHost>();
                    string connectedDrives = "";
                    if (Utility.IsAdministrator())
                    {
                        Log(EVENTLOG_INFORMATION_TYPE, "Loading Xbox partitions from physical drives...");
                        for (int i = 1; i < 11; i++)
                        {
                            try
                            {
                                var device = new FatxDevice(i);
                                if (!device.IsFatxDevice())
                                {
                                    continue;
                                }
                                var partitions = device.LoadPartitions(DebugFlags);
                                if (partitions.Count > 0)
                                {
                                    connectedDrives += $"{i} ";
                                }

                                _Hosts.AddRange(partitions);
                            }
                            catch
                            { }
                        }
                        Log(EVENTLOG_INFORMATION_TYPE, $"Loaded {_Hosts.Count} Xbox partitions from drives.");
                    }
                    if (_Hosts.Count <= 0)
                    {
                        throw new CommandLineUsageException();
                    }

                    Console.Title = $"HDD {connectedDrives}- xbox-winfsp";
                    Console.WriteLine("\r\nHit CTRL+C in this window to unmount.");
                }
            }
            catch (CommandLineUsageException ex)
            {
                Log(EVENTLOG_ERROR_TYPE, String.Format(
                        "{0}" +
                        "usage: {1} OPTIONS\n" +
                        "\n" +
                        "options:\n" +
                        "    -d DebugFlags           [-1: enable all debug logs]\n" +
                        "    -D DebugLogFile         [file path; use - for stderr]\n" +
                        "    -i ImagePath            [path to GDFX/STFS image to be mounted]\n" +
                        "    -u \\Server\\ImagePath    [UNC prefix (single backslash)]\n" +
                        "    -m MountPoint           [X:|*|directory]\n" +
                        "    -s                      [installs xbox-winfsp filesystems, may need elevation!]\n" +
                        "    -r                      [removes any xbox-winfsp filesystems, may need elevation!]\n",
                        ex.HasMessage ? ex.Message + "\n" : "",
                        PROGNAME));;
                throw;
            }
            //}
            //catch (Exception ex)
            //{
            //     Log(EVENTLOG_ERROR_TYPE, String.Format("{0}", ex.Message));
            //     throw;
            // }
        }
        protected override void OnStart(string [] args)
        {
            try
            {
                string                     debugLogFile    = null;
                uint                       debugFlags      = 0;
                string                     volumePrefix    = null;
                string                     mountPoint      = null;
                IntPtr                     debugLogHandle  = ( IntPtr )(-1);
                FileSystemHost             host            = null;
                FileSystem.CloudFileSystem cloudFileSystem = null;
                int I;

                for (I = 1; args.Length > I; I++)
                {
                    string arg = args [I];
                    if ('-' != arg [0])
                    {
                        break;
                    }

                    switch (arg [1])
                    {
                    case '?':
                        throw new CommandLineUsageException( );

                    case 'd':
                        SelectArgument(args, ref I, ref debugFlags);
                        break;

                    case 'D':
                        SelectArgument(args, ref I, ref debugLogFile);
                        break;

                    case 'm':
                        SelectArgument(args, ref I, ref mountPoint);
                        break;

                    case 'u':
                        SelectArgument(args, ref I, ref volumePrefix);
                        break;

                    default:
                        throw new CommandLineUsageException( );
                    }
                }

                if (args.Length > I)
                {
                    throw new CommandLineUsageException( );
                }

                if (null != volumePrefix)
                {
                    I = volumePrefix.IndexOf('\\');
                    if (-1 != I &&
                        volumePrefix.Length > I &&
                        '\\' != volumePrefix [I + 1])
                    {
                        I = volumePrefix.IndexOf('\\', I + 1);
                        if (-1 != I &&
                            volumePrefix.Length > I + 1 &&
                            char.IsLetter(volumePrefix [I + 1]) &&
                            '$' == volumePrefix [I + 2])
                        {
                        }
                    }
                }

                if (null == mountPoint)
                {
                    throw new CommandLineUsageException( );
                }

                if (null != debugLogFile)
                {
                    if (0 > FileSystemHost.SetDebugLogFile(debugLogFile))
                    {
                        throw new CommandLineUsageException("cannot open debug log file");
                    }
                }

                host = new FileSystemHost(new FileSystem.CloudFileSystem( ))
                {
                    Prefix = volumePrefix
                };

                if (0 > host.Mount(mountPoint, null, true, debugFlags))
                {
                    throw new IOException("cannot mount file system");
                }

                mountPoint = host.MountPoint( );
                Host       = host;

                Log(
                    EVENTLOG_INFORMATION_TYPE,
                    $"{ProgramName}{( ! string . IsNullOrEmpty ( volumePrefix ) ? " -u ": string . Empty )}{( ! string . IsNullOrEmpty ( volumePrefix ) ? volumePrefix: string . Empty )}  -m {mountPoint}");
            }
            catch (CommandLineUsageException ex)
            {
                Log(
                    EVENTLOG_ERROR_TYPE,
                    $"{( ex . HasMessage ? ex . Message + "\n": "" )}"
                    + $"usage: {ProgramName} OPTIONS\n"
                    + "\n"
                    + "options:\n"
                    + "    -d DebugFlags       [-1: enable all debug logs]\n"
                    + "    -D DebugLogFile     [file path; use - for stderr]\n"
                    + "    -u \\Server\\Share    [UNC prefix (single backslash)]\n"
                    + "    -m MountPoint       [X:|*|directory]\n");
            }
            catch (Exception ex)
            {
                Log(EVENTLOG_ERROR_TYPE, $"{ex . Message}");
                throw;
            }
        }