public void AddCloud(AvailableCloud selectedItem) { var name = selectedItem.Name; var letters = VirtualDriveWrapper.GetFreeDriveLettes(); if (letters.Count == 0) { throw new InvalidOperationException("No free letters"); } if (Clouds.Any(c => c.CloudInfo.Name == name)) { int i = 1; while (Clouds.Any(c => c.CloudInfo.Name == name + " " + i)) { i++; } name = name + " " + i; } var info = new CloudInfo { Id = Guid.NewGuid().ToString(), Name = name, ClassName = selectedItem.ClassName, AssemblyFileName = selectedItem.AssemblyFileName, DriveLetter = letters[0] }; var mount = new CloudMount(info, this); Clouds.Add(mount); SaveClouds(); }
internal async Task <char?> Mount(char driveLetter, bool readOnly, CancellationToken cs, bool interactiveAuth = true) { if (Interlocked.CompareExchange(ref mounted, 1, 0) != 0) { return(null); } var mountedEvent = new TaskCompletionSource <char>(); mountTask = Task.Factory.StartNew( async() => { try { lock (mountLock) { if (mountedLetter != null) { return; } mountedLetter = driveLetter; } AmazonDrive amazon = await Authenticate(cs, interactiveAuth); if (amazon == null) { Log.Error("Authentication failed"); mountedEvent.SetException(new InvalidOperationException("Authentication failed")); return; } provider = new FSProvider(amazon); provider.CachePath = Environment.ExpandEnvironmentVariables(Gui.Properties.Settings.Default.CacheFolder); provider.SmallFilesCacheSize = Gui.Properties.Settings.Default.SmallFilesCacheLimit * (1 << 20); provider.SmallFileSizeLimit = Gui.Properties.Settings.Default.SmallFileSizeLimit * (1 << 20); provider.OnStatisticsUpdated = ProviderStatisticsUpdated; cloudDrive = new VirtualDriveWrapper(provider); cloudDrive.Mounted = () => { mountedEvent.SetResult((char)mountedLetter); }; OnMountChanged?.Invoke(); try { cloudDrive.Mount(mountedLetter + ":\\", readOnly); mountedLetter = null; } catch (InvalidOperationException) { Log.Warn($"Drive letter {mountedLetter} is already used"); Exception lastException = null; foreach (char letter in VirtualDriveWrapper.GetFreeDriveLettes()) { try { mountedLetter = letter; cloudDrive.Mount(mountedLetter + ":\\", readOnly); break; } catch (InvalidOperationException ex) { lastException = ex; Log.Warn($"Drive letter {letter} is already used"); } } if (mountedLetter != null) { var message = "Could not find free letter"; if (lastException != null && lastException.InnerException != null) { message = lastException.InnerException.Message; } mountedEvent.SetException(new InvalidOperationException(message)); } } } catch (Exception ex) { mountedEvent.SetException(ex); } finally { mountedLetter = null; mounted = 0; OnMountChanged?.Invoke(); } }, TaskCreationOptions.LongRunning).Unwrap(); return(await mountedEvent.Task); }
private async Task <char> Mount(bool interactiveAuth = true) { try { Instance.OnAuthUpdated = this; var authenticated = await Authenticate(Instance, MountCancellation.Token, interactiveAuth); if (!authenticated) { Log.ErrorTrace("Authentication failed"); throw new InvalidOperationException("Authentication failed"); } var origProv = new FSProvider(instance, ProviderStatisticsUpdated) { VolumeName = CloudInfo.Name, CachePath = Environment.ExpandEnvironmentVariables(Properties.Settings.Default.CacheFolder), SmallFilesCacheSize = Properties.Settings.Default.SmallFilesCacheLimit * (1 << 20), SmallFileSizeLimit = Properties.Settings.Default.SmallFileSizeLimit * (1 << 20) }; var rfProv = new RootFolderFSProvider(origProv); await rfProv.SetRootFolder(CloudInfo.RootFolder); Provider = rfProv; var cloudDrive = new VirtualDriveWrapper(Provider); var mountedEvent = new TaskCompletionSource <char>(); cloudDrive.Mounted = letter => { mountedEvent.SetResult(letter); }; NotifyMount(); var task = Task.Factory.StartNew( () => { try { cloudDrive.Mount(CloudInfo.DriveLetter, CloudInfo.ReadOnly); unmountingEvent.Set(); } catch (InvalidOperationException) { Log.Warn($"Drive letter {CloudInfo.DriveLetter} is already used"); Exception lastException = null; var wasMounted = false; foreach (var letter in VirtualDriveWrapper.GetFreeDriveLettes()) { try { cloudDrive.Mount(letter, CloudInfo.ReadOnly); unmountingEvent.Set(); Instance.Dispose(); instance = null; wasMounted = true; break; } catch (InvalidOperationException ex) { lastException = ex; Log.Warn($"Drive letter {letter} is already used"); } } if (!wasMounted) { var message = "Could not find free letter"; if (lastException?.InnerException != null) { message = lastException.InnerException.Message; } mountedEvent.SetException(new InvalidOperationException(message)); } } catch (Exception ex) { mountedEvent.SetException(ex); } }, TaskCreationOptions.LongRunning); return(await mountedEvent.Task); } finally { NotifyMount(); } }