Browse Source

custom mount flag support for Dokany (#802)
[ci skip]

Sebastian Stenzel 6 years ago
parent
commit
0da567613d

+ 1 - 1
main/pom.xml

@@ -28,7 +28,7 @@
 		<cryptomator.cryptofs.version>1.8.5</cryptomator.cryptofs.version>
 		<cryptomator.jni.version>2.0.0</cryptomator.jni.version>
 		<cryptomator.fuse.version>1.2.0-SNAPSHOT</cryptomator.fuse.version>
-		<cryptomator.dokany.version>1.1.8</cryptomator.dokany.version>
+		<cryptomator.dokany.version>1.2.0-SNAPSHOT</cryptomator.dokany.version>
 		<cryptomator.webdav.version>1.0.10</cryptomator.webdav.version>
 
 		<javafx.version>12</javafx.version>

+ 10 - 10
main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java

@@ -162,6 +162,7 @@ public class UnlockController implements ViewController {
 		unlockButton.disableProperty().bind(unlocking.or(passwordField.textProperty().isEmpty()));
 		mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents);
 		mountName.textProperty().addListener(this::mountNameDidChange);
+		useReadOnlyMode.selectedProperty().addListener(this::useReadOnlyDidChange);
 		useCustomMountFlags.selectedProperty().addListener(this::useCustomMountFlagsDidChange);
 		mountFlags.disableProperty().bind(useCustomMountFlags.selectedProperty().not());
 		mountFlags.textProperty().addListener(this::mountFlagsDidChange);
@@ -226,6 +227,7 @@ public class UnlockController implements ViewController {
 		VaultSettings vaultSettings = vault.getVaultSettings();
 		unlockAfterStartup.setSelected(savePassword.isSelected() && vaultSettings.unlockAfterStartup().get());
 		revealAfterMount.setSelected(vaultSettings.revealAfterMount().get());
+		useReadOnlyMode.setSelected(vaultSettings.usesReadOnlyMode().get());
 
 		// WEBDAV-dependent controls:
 		if (VolumeImpl.WEBDAV.equals(settings.preferredVolumeImpl().get())) {
@@ -241,15 +243,6 @@ public class UnlockController implements ViewController {
 			}
 		}
 
-		// DOKANY-dependent controls:
-		if (VolumeImpl.DOKANY.equals(settings.preferredVolumeImpl().get())) {
-			// readonly not yet supported by dokany
-			useReadOnlyMode.setSelected(false);
-			useReadOnlyMode.setVisible(false);
-			useReadOnlyMode.setManaged(false);
-		} else {
-			useReadOnlyMode.setSelected(vaultSettings.usesReadOnlyMode().get());
-		}
 
 		// OS-dependent controls:
 		if (SystemUtils.IS_OS_WINDOWS) {
@@ -324,7 +317,14 @@ public class UnlockController implements ViewController {
 			vault.setMountName(newValue);
 		}
 		if (!useCustomMountFlags.isSelected()) {
-			mountFlags.setText(vault.getMountFlags()); // flags might depend on the volume name
+			mountFlags.setText(vault.getMountFlags()); // update default flags
+		}
+	}
+
+	private void useReadOnlyDidChange(@SuppressWarnings("unused") ObservableValue<? extends Boolean> property, @SuppressWarnings("unused")Boolean oldValue, Boolean newValue) {
+		vault.getVaultSettings().usesReadOnlyMode().setValue(newValue);
+		if (!useCustomMountFlags.isSelected()) {
+			mountFlags.setText(vault.getMountFlags()); // update default flags
 		}
 	}
 

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java

@@ -48,7 +48,7 @@ public class DokanyVolume implements Volume {
 		Path mountPath = getMountPoint();
 		String mountName = vaultSettings.mountName().get();
 		try {
-			this.mount = mountFactory.mount(fs.getPath("/"), mountPath, mountName, FS_TYPE_NAME);
+			this.mount = mountFactory.mount(fs.getPath("/"), mountPath, mountName, FS_TYPE_NAME, mountFlags);
 		} catch (MountFailedException e) {
 			if (vaultSettings.getIndividualMountPath().isPresent()) {
 				LOG.warn("Failed to mount vault into {}. Is this directory currently accessed by another process (e.g. Windows Explorer)?", mountPath);

+ 43 - 17
main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java

@@ -60,46 +60,72 @@ public class VaultModule {
 		}
 	}
 
+	// see: https://github.com/osxfuse/osxfuse/wiki/Mount-options
 	private String getMacFuseDefaultMountFlags(Settings settings, VaultSettings vaultSettings) {
 		assert SystemUtils.IS_OS_MAC_OSX;
-		// see: https://github.com/osxfuse/osxfuse/wiki/Mount-options
+
+		StringBuilder flags = new StringBuilder();
+		if (vaultSettings.usesReadOnlyMode().get()) {
+			flags.append(" -ordonly");
+		}
+		flags.append(" -ovolname=").append(vaultSettings.mountName().get());
+		flags.append(" -oatomic_o_trunc");
+		flags.append(" -oauto_xattr");
+		flags.append(" -oauto_cache");
+		flags.append(" -omodules=iconv,from_code=UTF-8,to_code=UTF-8-MAC"); // show files names in Unicode NFD encoding
+		flags.append(" -onoappledouble"); // vastly impacts performance for some reason...
+		flags.append(" -odefault_permissions"); // let the kernel assume permissions based on file attributes etc
+
 		try {
 			Path userHome = Paths.get(System.getProperty("user.home"));
 			int uid = (int) Files.getAttribute(userHome, "unix:uid");
 			int gid = (int) Files.getAttribute(userHome, "unix:gid");
-			return "-ovolname=" + vaultSettings.mountName().get() // volume name
-					+ " -ouid=" + uid //
-					+ " -ogid=" + gid //
-					+ " -oatomic_o_trunc" //
-					+ " -oauto_xattr" //
-					+ " -oauto_cache" //
-					+ " -omodules=iconv,from_code=UTF-8,to_code=UTF-8-MAC" // show files names in Unicode NFD encoding
-					+ " -onoappledouble" // vastly impacts performance for some reason...
-					+ " -odefault_permissions"; // let the kernel assume permissions based on file attributes etc
+			flags.append(" -ouid=").append(uid);
+			flags.append(" -ogid=").append(gid);
 		} catch (IOException e) {
 			LOG.error("Could not read uid/gid from USER_HOME", e);
-			return "";
 		}
+
+		return flags.toString();
 	}
 
+	// see https://manpages.debian.org/testing/fuse/mount.fuse.8.en.html
 	private String getLinuxFuseDefaultMountFlags(Settings settings, VaultSettings vaultSettings) {
 		assert SystemUtils.IS_OS_LINUX;
+
+		StringBuilder flags = new StringBuilder();
+		if (vaultSettings.usesReadOnlyMode().get()) {
+			flags.append(" -oro");
+		}
+		flags.append(" -oauto_unmount");
+
 		try {
 			Path userHome = Paths.get(System.getProperty("user.home"));
 			int uid = (int) Files.getAttribute(userHome, "unix:uid");
 			int gid = (int) Files.getAttribute(userHome, "unix:gid");
-			return "-oauto_unmount" //
-					+ " -ouid=" + uid //
-					+ " -ogid=" + gid;
+			flags.append(" -ouid=").append(uid);
+			flags.append(" -ogid=").append(gid);
 		} catch (IOException e) {
 			LOG.error("Could not read uid/gid from USER_HOME", e);
-			return "";
 		}
+
+		return flags.toString();
 	}
 
+	// see https://github.com/cryptomator/dokany-nio-adapter/blob/develop/src/main/java/org/cryptomator/frontend/dokany/MountUtil.java#L30-L34
 	private String getDokanyDefaultMountFlags(Settings settings, VaultSettings vaultSettings) {
-		// TODO
-		return "--not-yet-supported";
+		assert SystemUtils.IS_OS_WINDOWS;
+
+		StringBuilder flags = new StringBuilder();
+		flags.append(" --options CURRENT_SESSION");
+		if (vaultSettings.usesReadOnlyMode().get()) {
+			flags.append(",WRITE_PROTECTION");
+		}
+		flags.append(" --threadCount 5");
+		flags.append(" --timeout 10000");
+		flags.append(" --allocation-unit-size 4096");
+		flags.append(" --sector-size 4096");
+		return flags.toString();
 	}
 
 }