void UserInterface::DismountVolume (shared_ptr <VolumeInfo> volume, bool ignoreOpenFiles, bool interactive) const { VolumeInfoList volumes; volumes.push_back (volume); DismountVolumes (volumes, ignoreOpenFiles, interactive); }
VolumeInfoList CoreUnix::GetMountedVolumes (const VolumePath &volumePath) const { VolumeInfoList volumes; foreach_ref (const MountedFilesystem &mf, GetMountedFilesystems ()) { if (string (mf.MountPoint).find (GetFuseMountDirPrefix()) == string::npos) continue; shared_ptr <VolumeInfo> mountedVol; try { shared_ptr <File> controlFile (new File); controlFile->Open (string (mf.MountPoint) + FuseService::GetControlPath()); shared_ptr <Stream> controlFileStream (new FileStream (controlFile)); mountedVol = Serializable::DeserializeNew <VolumeInfo> (controlFileStream); } catch (...) { continue; } if (!volumePath.IsEmpty() && wstring (mountedVol->Path).compare (volumePath) != 0) continue; mountedVol->AuxMountPoint = mf.MountPoint; if (!mountedVol->VirtualDevice.IsEmpty()) { MountedFilesystemList mpl = GetMountedFilesystems (mountedVol->VirtualDevice); if (mpl.size() > 0) mountedVol->MountPoint = mpl.front()->MountPoint; } volumes.push_back (mountedVol); if (!volumePath.IsEmpty()) break; } return volumes; }
void UserInterface::DismountVolumes (VolumeInfoList volumes, bool ignoreOpenFiles, bool interactive) const { BusyScope busy (this); volumes.sort (VolumeInfo::FirstVolumeMountedAfterSecond); wxString message; bool twoPassMode = volumes.size() > 1; bool volumesInUse = false; bool firstPass = true; #ifdef TC_WINDOWS if (Preferences.CloseExplorerWindowsOnDismount) { foreach (shared_ptr <VolumeInfo> volume, volumes) CloseExplorerWindows (volume); } #endif while (!volumes.empty()) { VolumeInfoList volumesLeft; foreach (shared_ptr <VolumeInfo> volume, volumes) { try { BusyScope busy (this); volume = Core->DismountVolume (volume, ignoreOpenFiles); } catch (MountedVolumeInUse&) { if (!firstPass) throw; if (twoPassMode || !interactive) { volumesInUse = true; volumesLeft.push_back (volume); continue; } else { if (AskYesNo (StringFormatter (LangString["UNMOUNT_LOCK_FAILED"], wstring (volume->Path)), true, true)) { BusyScope busy (this); volume = Core->DismountVolume (volume, true); } else throw UserAbort (SRC_POS); } } catch (...) { if (twoPassMode && firstPass) volumesLeft.push_back (volume); else throw; } if (volume->HiddenVolumeProtectionTriggered) ShowWarning (StringFormatter (LangString["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"], wstring (volume->Path))); if (Preferences.Verbose) { if (!message.IsEmpty()) message += L'\n'; message += StringFormatter (_("Volume \"{0}\" has been dismounted."), wstring (volume->Path)); } } if (twoPassMode && firstPass) { volumes = volumesLeft; if (volumesInUse && interactive) { if (AskYesNo (LangString["UNMOUNTALL_LOCK_FAILED"], true, true)) ignoreOpenFiles = true; else throw UserAbort (SRC_POS); } } else break; firstPass = false; } if (Preferences.Verbose && !message.IsEmpty()) ShowInfo (message); }