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"); } }
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; } }
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; } }
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; } }
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); }
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; } }
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; } }