Esempio n. 1
0
	void UserInterface::DismountVolume (shared_ptr <VolumeInfo> volume, bool ignoreOpenFiles, bool interactive) const
	{
		VolumeInfoList volumes;
		volumes.push_back (volume);

		DismountVolumes (volumes, ignoreOpenFiles, interactive);
	}
Esempio n. 2
0
	void UserInterface::DisplayVolumeProperties (const VolumeInfoList &volumes) const
	{
		if (volumes.size() < 1)
			throw_err (LangString["NO_VOLUMES_MOUNTED"]);

		wxString prop;

		foreach_ref (const VolumeInfo &volume, volumes)
		{
			prop << _("Slot") << L": " << StringConverter::FromNumber (volume.SlotNumber) << L'\n';
			prop << LangString["VOLUME"] << L": " << wstring (volume.Path) << L'\n';
#ifndef TC_WINDOWS
			prop << LangString["VIRTUAL_DEVICE"] << L": " << wstring (volume.VirtualDevice) << L'\n';
#endif
			prop << LangString["MOUNT_POINT"] << L": " << wstring (volume.MountPoint) << L'\n';
			prop << LangString["SIZE"] << L": " << SizeToString (volume.Size) << L'\n';
			prop << LangString["TYPE"] << L": " << VolumeTypeToString (volume.Type, volume.Protection) << L'\n';

			prop << LangString["READ_ONLY"] << L": " << LangString [volume.Protection == VolumeProtection::ReadOnly ? "UISTR_YES" : "UISTR_NO"] << L'\n';

			wxString protection;
			if (volume.Type == VolumeType::Hidden)
				protection = LangString["NOT_APPLICABLE_OR_NOT_AVAILABLE"];
			else if (volume.HiddenVolumeProtectionTriggered)
				protection = LangString["HID_VOL_DAMAGE_PREVENTED"];
			else
				protection = LangString [volume.Protection == VolumeProtection::HiddenVolumeReadOnly ? "UISTR_YES" : "UISTR_NO"];

			prop << LangString["HIDDEN_VOL_PROTECTION"] << L": " << protection << L'\n';
			prop << LangString["ENCRYPTION_ALGORITHM"] << L": " << volume.EncryptionAlgorithmName << L'\n';
			prop << LangString["KEY_SIZE"] << L": " << StringFormatter (L"{0} {1}", volume.EncryptionAlgorithmKeySize * 8, LangString ["BITS"]) << L'\n';

			if (volume.EncryptionModeName == L"XTS")
				prop << LangString["SECONDARY_KEY_SIZE_XTS"] << L": " << StringFormatter (L"{0} {1}", volume.EncryptionAlgorithmKeySize * 8, LangString ["BITS"]) << L'\n';;

			wstringstream blockSize;
			blockSize << volume.EncryptionAlgorithmBlockSize * 8;
			if (volume.EncryptionAlgorithmBlockSize != volume.EncryptionAlgorithmMinBlockSize)
				blockSize << L"/" << volume.EncryptionAlgorithmMinBlockSize * 8;

			prop << LangString["BLOCK_SIZE"] << L": " << blockSize.str() + L" " + LangString ["BITS"] << L'\n';
			prop << LangString["MODE_OF_OPERATION"] << L": " << volume.EncryptionModeName << L'\n';
			prop << LangString["PKCS5_PRF"] << L": " << volume.Pkcs5PrfName << L'\n';
	
			prop << LangString["VOLUME_FORMAT_VERSION"] << L": " << (volume.MinRequiredProgramVersion < 0x600 ? 1 : 2) << L'\n';
			prop << LangString["BACKUP_HEADER"] << L": " << LangString[volume.MinRequiredProgramVersion >= 0x600 ? "UISTR_YES" : "UISTR_NO"] << L'\n';

#ifdef TC_LINUX
			if (string (volume.VirtualDevice).find ("/dev/mapper/truecrypt") != 0)
			{
#endif
			prop << LangString["TOTAL_DATA_READ"] << L": " << SizeToString (volume.TotalDataRead) << L'\n';
			prop << LangString["TOTAL_DATA_WRITTEN"] << L": " << SizeToString (volume.TotalDataWritten) << L'\n';
#ifdef TC_LINUX
			}
#endif
		
			prop << L'\n';
		}
Esempio n. 3
0
	void UserInterface::DismountAllVolumes (bool ignoreOpenFiles, bool interactive) const
	{
		try
		{
			VolumeInfoList mountedVolumes = Core->GetMountedVolumes();

			if (mountedVolumes.size() < 1)
				ShowInfo (LangString["NO_VOLUMES_MOUNTED"]);

			BusyScope busy (this);
			DismountVolumes (mountedVolumes, ignoreOpenFiles, interactive);
		}
		catch (exception &e)
		{
			ShowError (e);
		}
	}
Esempio n. 4
0
	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;
	}
Esempio n. 5
0
	shared_ptr <VolumeInfo> CoreUnix::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
	{
		if (!mountedVolume->MountPoint.IsEmpty())
		{
			DismountFilesystem (mountedVolume->MountPoint, ignoreOpenFiles);

			// Delete mount directory if a default path has been used
			if (string (mountedVolume->MountPoint).find (GetDefaultMountPointPrefix()) == 0)
				mountedVolume->MountPoint.Delete();
		}

		try
		{
			DismountNativeVolume (mountedVolume);
		}
		catch (NotApplicable &) { }

		if (!mountedVolume->LoopDevice.IsEmpty())
		{
			try
			{
				DetachLoopDevice (mountedVolume->LoopDevice);
			}
			catch (ExecutedProcessFailed&) { }
		}

		if (syncVolumeInfo || mountedVolume->Protection == VolumeProtection::HiddenVolumeReadOnly)
		{
			sync();
			VolumeInfoList ml = GetMountedVolumes (mountedVolume->Path);

			if (ml.size() > 0)
				mountedVolume = ml.front();
		}

		list <string> args;
		args.push_back ("--");
		args.push_back (mountedVolume->AuxMountPoint);

		for (int t = 0; true; t++)
		{
			try
			{
				Process::Execute ("umount", args);
				break;
			}
			catch (ExecutedProcessFailed&)
			{
				if (t > 10)
					throw;
				Thread::Sleep (200);
			}
		}

		try
		{
			mountedVolume->AuxMountPoint.Delete();
		}
		catch (...)	{ }

		VolumeEventArgs eventArgs (mountedVolume);
		VolumeDismountedEvent.Raise (eventArgs);

		return mountedVolume;
	}
Esempio n. 6
0
	shared_ptr <VolumeInfo> CoreUnix::MountVolume (MountOptions &options)
	{
		CoalesceSlotNumberAndMountPoint (options);

		if (IsVolumeMounted (*options.Path))
			throw VolumeAlreadyMounted (SRC_POS);

		Cipher::EnableHwSupport (!options.NoHardwareCrypto);

		shared_ptr <Volume> volume;

		while (true)
		{
			try
			{
				volume = OpenVolume (
					options.Path,
					options.PreserveTimestamps,
					options.Password,
					options.Keyfiles,
					options.Protection,
					options.ProtectionPassword,
					options.ProtectionKeyfiles,
					options.SharedAccessAllowed,
					VolumeType::Unknown,
					options.UseBackupHeaders,
					options.PartitionInSystemEncryptionScope
					);

				options.Password.reset();
			}
			catch (SystemException &e)
			{
				if (options.Protection != VolumeProtection::ReadOnly
					&& (e.GetErrorCode() == EROFS || e.GetErrorCode() == EACCES || e.GetErrorCode() == EPERM))
				{
					// Read-only filesystem
					options.Protection = VolumeProtection::ReadOnly;
					continue;
				}

				throw;
			}

			break;
		}

		if (options.Path->IsDevice())
		{
			if (volume->GetFile()->GetDeviceSectorSize() != volume->GetSectorSize())
				throw ParameterIncorrect (SRC_POS);

#if defined (TC_LINUX)
			if (volume->GetSectorSize() != TC_SECTOR_SIZE_LEGACY)
			{
				if (options.Protection == VolumeProtection::HiddenVolumeReadOnly)
					throw UnsupportedSectorSizeHiddenVolumeProtection();

				if (options.NoKernelCrypto)
					throw UnsupportedSectorSizeNoKernelCrypto();
			}
#endif
		}

		// Find a free mount point for FUSE service
		MountedFilesystemList mountedFilesystems = GetMountedFilesystems ();
		string fuseMountPoint;
		for (int i = 1; true; i++)
		{
			stringstream path;
			path << GetTempDirectory() << "/" << GetFuseMountDirPrefix() << i;
			FilesystemPath fsPath (path.str());

			bool inUse = false;

			foreach_ref (const MountedFilesystem &mf, mountedFilesystems)
			{
				if (mf.MountPoint == path.str())
				{
					inUse = true;
					break;
				}
			}

			if (!inUse)
			{
				try
				{
					if (fsPath.IsDirectory())
						fsPath.Delete();

					throw_sys_sub_if (mkdir (path.str().c_str(), S_IRUSR | S_IXUSR) == -1, path.str());

					fuseMountPoint = fsPath;
					break;
				}
				catch (...)
				{
					if (i > 255)
						throw TemporaryDirectoryFailure (SRC_POS, StringConverter::ToWide (path.str()));
				}
			}
		}

		try
		{
			FuseService::Mount (volume, options.SlotNumber, fuseMountPoint);
		}
		catch (...)
		{
			try
			{
				DirectoryPath (fuseMountPoint).Delete();
			}
			catch (...) { }
			throw;
		}

		try
		{
			// Create a mount directory if a default path has been specified
			bool mountDirCreated = false;
			string mountPoint;
			if (!options.NoFilesystem && options.MountPoint)
			{
				mountPoint = *options.MountPoint;

#ifndef TC_MACOSX
				if (mountPoint.find (GetDefaultMountPointPrefix()) == 0 && !options.MountPoint->IsDirectory())
				{
					Directory::Create (*options.MountPoint);
					try
					{
						throw_sys_sub_if (chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId()) == -1, mountPoint);
					} catch (ParameterIncorrect&) { }

					mountDirCreated = true;
				}
#endif
			}

			try
			{
				try
				{
					MountVolumeNative (volume, options, fuseMountPoint);
				}
				catch (NotApplicable&)
				{
					MountAuxVolumeImage (fuseMountPoint, options);
				}
			}
			catch (...)
			{
				if (mountDirCreated)
					remove (mountPoint.c_str());
				throw;
			}
		}
		catch (...)
		{
			try
			{
				VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path);
				if (mountedVolumes.size() > 0)
				{
					shared_ptr <VolumeInfo> mountedVolume (mountedVolumes.front());
					DismountVolume (mountedVolume);
				}
			}
			catch (...) { }
			throw;
		}

		VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path);
		if (mountedVolumes.size() != 1)
			throw ParameterIncorrect (SRC_POS);

		VolumeEventArgs eventArgs (mountedVolumes.front());
		VolumeMountedEvent.Raise (eventArgs);

		return mountedVolumes.front();
	}
Esempio n. 7
0
	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);
	}
Esempio n. 8
0
	shared_ptr <VolumeInfo> CoreMacOSX::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
	{
		if (!mountedVolume->VirtualDevice.IsEmpty() && mountedVolume->VirtualDevice.IsBlockDevice())
		{
			list <string> args;
			args.push_back ("detach");
			args.push_back (mountedVolume->VirtualDevice);

			if (ignoreOpenFiles)
				args.push_back ("-force");

			try
			{
				Process::Execute ("hdiutil", args);
			}
			catch (ExecutedProcessFailed &e)
			{
				if (!ignoreOpenFiles)
				{
					string err = e.GetErrorOutput();

					if (err.find ("couldn't unmount") != string::npos
						|| err.find ("busy") != string::npos
						|| err.find ("49153") != string::npos)
					{
						throw MountedVolumeInUse (SRC_POS);
					}
				}

				throw;
			}
		}

		if (syncVolumeInfo || mountedVolume->Protection == VolumeProtection::HiddenVolumeReadOnly)
		{
			sync();
			VolumeInfoList ml = GetMountedVolumes (mountedVolume->Path);

			if (ml.size() > 0)
				mountedVolume = ml.front();
		}

		list <string> args;
		args.push_back ("--");
		args.push_back (mountedVolume->AuxMountPoint);

		for (int t = 0; true; t++)
		{
			try
			{
				Process::Execute ("umount", args);
				break;
			}
			catch (ExecutedProcessFailed&)
			{
				if (t > 10)
					throw;
				Thread::Sleep (200);
			}
		}

		try
		{
			mountedVolume->AuxMountPoint.Delete();
		}
		catch (...)	{ }

		return mountedVolume;
	}