From d50fbd6a6fe14e7f21bdec43bfa11ceefeb694bc Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Mon, 10 Sep 2018 23:15:36 +0300 Subject: [PATCH] Extract wsl tool to get info from registry * WSLDistributionWithRoot wraps WSLDistribution and uses registry to get basepath * WSL#getWindowsPath capitalizes disk letter * WSLDistributionWithRoot applies "toCanonicalPath" to its argument --- .../execution/wsl/WSLDistribution.java | 1 + .../wsl/WSLDistributionWithRoot.java | 79 +++++++++++++++++++ .../com/intellij/execution/wsl/WSLUtil.java | 2 +- 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionWithRoot.java diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java index f027773f494e..ae3c6b03b9bc 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistribution.java @@ -29,6 +29,7 @@ import java.util.stream.Collectors; * Represents a single linux distribution in WSL, installed after Fall Creators Update * * @see WSLUtil + * @see WSLDistributionWithRoot */ public class WSLDistribution { static final String WSL_MNT_ROOT = "/mnt/"; diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionWithRoot.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionWithRoot.java new file mode 100644 index 000000000000..046d44a03e2a --- /dev/null +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLDistributionWithRoot.java @@ -0,0 +1,79 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.execution.wsl; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.AtomicNotNullLazyValue; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.WindowsRegistryUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Wraps {@link WSLDistribution} and fetches data from registry to find base path of distro on Windows + */ +public class WSLDistributionWithRoot extends WSLDistribution { + private final static Logger LOG = Logger.getInstance(WSLDistributionWithRoot.class); + private static final AtomicNotNullLazyValue> DISTRIBUTION_TO_ROOTFS = + AtomicNotNullLazyValue.createValue(() -> { + final Map result = ContainerUtil.newHashMap(); + + final String lxss = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Lxss"; + final List distributions = WindowsRegistryUtil.readRegistryBranch(lxss); + + LOG.debug("Processing Lxss registry: " + distributions.size()); + for (String distribution : distributions) { + final String name = WindowsRegistryUtil.readRegistryValue(lxss + "\\" + distribution, "DistributionName"); + final String path = WindowsRegistryUtil.readRegistryValue(lxss + "\\" + distribution, "BasePath"); + LOG.debug(name + ": " + path); + + if (path != null) { + result.put(name, path + "\\rootfs"); + } + } + return Collections.unmodifiableMap(result); + }); + @Nullable private final String myWslRootInHost; + + public WSLDistributionWithRoot(@NotNull WSLDistribution wslDistribution) { + super(wslDistribution); + String wslRootInHost = DISTRIBUTION_TO_ROOTFS.getValue().get(wslDistribution.getMsId()); + + if (wslRootInHost == null) { + LOG.warn("WSL rootfs is null"); + } + else if (!FileUtil.exists(wslRootInHost)) { + LOG.warn("WSL rootfs doesn't exist: " + wslRootInHost); + wslRootInHost = null; + } + myWslRootInHost = wslRootInHost; + } + + @Nullable + @Override + public String getWslPath(@NotNull String windowsPath) { + String canonicalPath = FileUtil.toCanonicalPath(windowsPath); + if (myWslRootInHost != null && FileUtil.isAncestor(myWslRootInHost, canonicalPath, true)) { // this is some internal WSL path + return FileUtil.toSystemIndependentName(canonicalPath.substring(myWslRootInHost.length())); + } + return super.getWslPath(canonicalPath); + } + + @Nullable + @Override + public String getWindowsPath(@NotNull String wslPath) { + String windowsPath = super.getWindowsPath(wslPath); + if (windowsPath != null) { + return windowsPath; + } + + if (myWslRootInHost == null) { + return null; + } + return FileUtil.toSystemDependentName(myWslRootInHost + FileUtil.toCanonicalPath(wslPath)); + } +} diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java b/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java index 4582e1668a84..95e6cbddd20e 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java +++ b/platform/platform-impl/src/com/intellij/execution/wsl/WSLUtil.java @@ -150,6 +150,6 @@ public class WSLUtil { if (slashIndex < wslPath.length() && wslPath.charAt(slashIndex) != '/') { return null; } - return FileUtil.toSystemDependentName(wslPath.charAt(driveLetterIndex) + ":" + wslPath.substring(slashIndex)); + return FileUtil.toSystemDependentName(Character.toUpperCase(wslPath.charAt(driveLetterIndex)) + ":" + wslPath.substring(slashIndex)); } }