//===-- MSVCPaths.cpp - MSVC path-parsing helpers -------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/WindowsDriver/MSVCPaths.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"
#include <optional>
#include <string>

#ifdef _WIN32
#include "llvm/Support/ConvertUTF.h"
#endif

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#endif

#ifdef _MSC_VER
// Don't support SetupApi on MinGW.
#define USE_MSVC_SETUP_API

// Make sure this comes before MSVCSetupApi.h
#include <comdef.h>

#include "llvm/Support/COM.h"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#endif
#include "llvm/WindowsDriver/MSVCSetupApi.h"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
_COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
_COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
_COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
_COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
_COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
_COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
#endif

static std::string
getHighestNumericTupleInDirectory(llvm::vfs::FileSystem &VFS,
                                  llvm::StringRef Directory) {
  std::string Highest;
  llvm::VersionTuple HighestTuple;

  std::error_code EC;
  for (llvm::vfs::directory_iterator DirIt = VFS.dir_begin(Directory, EC),
                                     DirEnd;
       !EC && DirIt != DirEnd; DirIt.increment(EC)) {
    auto Status = VFS.status(DirIt->path());
    if (!Status || !Status->isDirectory())
      continue;
    llvm::StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
    llvm::VersionTuple Tuple;
    if (Tuple.tryParse(CandidateName)) // tryParse() returns true on error.
      continue;
    if (Tuple > HighestTuple) {
      HighestTuple = Tuple;
      Highest = CandidateName.str();
    }
  }

  return Highest;
}

static bool getWindows10SDKVersionFromPath(llvm::vfs::FileSystem &VFS,
                                           const std::string &SDKPath,
                                           std::string &SDKVersion) {
  llvm::SmallString<128> IncludePath(SDKPath);
  llvm::sys::path::append(IncludePath, "Include");
  SDKVersion = getHighestNumericTupleInDirectory(VFS, IncludePath);
  return !SDKVersion.empty();
}

static bool getWindowsSDKDirViaCommandLine(
    llvm::vfs::FileSystem &VFS, std::optional<llvm::StringRef> WinSdkDir,
    std::optional<llvm::StringRef> WinSdkVersion,
    std::optional<llvm::StringRef> WinSysRoot, std::string &Path, int &Major,
    std::string &Version) {
  if (WinSdkDir || WinSysRoot) {
    // Don't validate the input; trust the value supplied by the user.
    // The motivation is to prevent unnecessary file and registry access.
    llvm::VersionTuple SDKVersion;
    if (WinSdkVersion)
      SDKVersion.tryParse(*WinSdkVersion);

    if (WinSysRoot) {
      llvm::SmallString<128> SDKPath(*WinSysRoot);
      llvm::sys::path::append(SDKPath, "Windows Kits");
      if (!SDKVersion.empty())
        llvm::sys::path::append(SDKPath, llvm::Twine(SDKVersion.getMajor()));
      else
        llvm::sys::path::append(
            SDKPath, getHighestNumericTupleInDirectory(VFS, SDKPath));
      Path = std::string(SDKPath);
    } else {
      Path = WinSdkDir->str();
    }

    if (!SDKVersion.empty()) {
      Major = SDKVersion.getMajor();
      Version = SDKVersion.getAsString();
    } else if (getWindows10SDKVersionFromPath(VFS, Path, Version)) {
      Major = 10;
    }
    return true;
  }
  return false;
}

#ifdef _WIN32
static bool readFullStringValue(HKEY hkey, const char *valueName,
                                std::string &value) {
  std::wstring WideValueName;
  if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
    return false;

  DWORD result = 0;
  DWORD valueSize = 0;
  DWORD type = 0;
  // First just query for the required size.
  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
                            &valueSize);
  if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
    return false;
  std::vector<BYTE> buffer(valueSize);
  result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
                            &valueSize);
  if (result == ERROR_SUCCESS) {
    std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
                           valueSize / sizeof(wchar_t));
    if (valueSize && WideValue.back() == L'\0') {
      WideValue.pop_back();
    }
    // The destination buffer must be empty as an invariant of the conversion
    // function; but this function is sometimes called in a loop that passes in
    // the same buffer, however. Simply clear it out so we can overwrite it.
    value.clear();
    return llvm::convertWideToUTF8(WideValue, value);
  }
  return false;
}
#endif

/// Read registry string.
/// This also supports a means to look for high-versioned keys by use
/// of a $VERSION placeholder in the key path.
/// $VERSION in the key path is a placeholder for the version number,
/// causing the highest value path to be searched for and used.
/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
/// There can be additional characters in the component.  Only the numeric
/// characters are compared.  This function only searches HKLM.
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
                                    std::string &value, std::string *phValue) {
#ifndef _WIN32
  return false;
#else
  HKEY hRootKey = HKEY_LOCAL_MACHINE;
  HKEY hKey = NULL;
  long lResult;
  bool returnValue = false;

  const char *placeHolder = strstr(keyPath, "$VERSION");
  std::string bestName;
  // If we have a $VERSION placeholder, do the highest-version search.
  if (placeHolder) {
    const char *keyEnd = placeHolder - 1;
    const char *nextKey = placeHolder;
    // Find end of previous key.
    while ((keyEnd > keyPath) && (*keyEnd != '\\'))
      keyEnd--;
    // Find end of key containing $VERSION.
    while (*nextKey && (*nextKey != '\\'))
      nextKey++;
    size_t partialKeyLength = keyEnd - keyPath;
    char partialKey[256];
    if (partialKeyLength >= sizeof(partialKey))
      partialKeyLength = sizeof(partialKey) - 1;
    strncpy(partialKey, keyPath, partialKeyLength);
    partialKey[partialKeyLength] = '\0';
    HKEY hTopKey = NULL;
    lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
                            &hTopKey);
    if (lResult == ERROR_SUCCESS) {
      char keyName[256];
      double bestValue = 0.0;
      DWORD index, size = sizeof(keyName) - 1;
      for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
                                    NULL, NULL) == ERROR_SUCCESS;
           index++) {
        const char *sp = keyName;
        while (*sp && !llvm::isDigit(*sp))
          sp++;
        if (!*sp)
          continue;
        const char *ep = sp + 1;
        while (*ep && (llvm::isDigit(*ep) || (*ep == '.')))
          ep++;
        char numBuf[32];
        strncpy(numBuf, sp, sizeof(numBuf) - 1);
        numBuf[sizeof(numBuf) - 1] = '\0';
        double dvalue = strtod(numBuf, NULL);
        if (dvalue > bestValue) {
          // Test that InstallDir is indeed there before keeping this index.
          // Open the chosen key path remainder.
          bestName = keyName;
          // Append rest of key.
          bestName.append(nextKey);
          lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
                                  KEY_READ | KEY_WOW64_32KEY, &hKey);
          if (lResult == ERROR_SUCCESS) {
            if (readFullStringValue(hKey, valueName, value)) {
              bestValue = dvalue;
              if (phValue)
                *phValue = bestName;
              returnValue = true;
            }
            RegCloseKey(hKey);
          }
        }
        size = sizeof(keyName) - 1;
      }
      RegCloseKey(hTopKey);
    }
  } else {
    lResult =
        RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
    if (lResult == ERROR_SUCCESS) {
      if (readFullStringValue(hKey, valueName, value))
        returnValue = true;
      if (phValue)
        phValue->clear();
      RegCloseKey(hKey);
    }
  }
  return returnValue;
#endif // _WIN32
}

const char *llvm::archToWindowsSDKArch(Triple::ArchType Arch) {
  switch (Arch) {
  case Triple::ArchType::x86:
    return "x86";
  case Triple::ArchType::x86_64:
    return "x64";
  case Triple::ArchType::arm:
  case Triple::ArchType::thumb:
    return "arm";
  case Triple::ArchType::aarch64:
    return "arm64";
  default:
    return "";
  }
}

const char *llvm::archToLegacyVCArch(Triple::ArchType Arch) {
  switch (Arch) {
  case Triple::ArchType::x86:
    // x86 is default in legacy VC toolchains.
    // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
    return "";
  case Triple::ArchType::x86_64:
    return "amd64";
  case Triple::ArchType::arm:
  case Triple::ArchType::thumb:
    return "arm";
  case Triple::ArchType::aarch64:
    return "arm64";
  default:
    return "";
  }
}

const char *llvm::archToDevDivInternalArch(Triple::ArchType Arch) {
  switch (Arch) {
  case Triple::ArchType::x86:
    return "i386";
  case Triple::ArchType::x86_64:
    return "amd64";
  case Triple::ArchType::arm:
  case Triple::ArchType::thumb:
    return "arm";
  case Triple::ArchType::aarch64:
    return "arm64";
  default:
    return "";
  }
}

bool llvm::appendArchToWindowsSDKLibPath(int SDKMajor, SmallString<128> LibPath,
                                         Triple::ArchType Arch,
                                         std::string &path) {
  if (SDKMajor >= 8) {
    sys::path::append(LibPath, archToWindowsSDKArch(Arch));
  } else {
    switch (Arch) {
    // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
    case Triple::x86:
      break;
    case Triple::x86_64:
      sys::path::append(LibPath, "x64");
      break;
    case Triple::arm:
    case Triple::thumb:
      // It is not necessary to link against Windows SDK 7.x when targeting ARM.
      return false;
    default:
      return false;
    }
  }

  path = std::string(LibPath);
  return true;
}

std::string llvm::getSubDirectoryPath(SubDirectoryType Type,
                                      ToolsetLayout VSLayout,
                                      const std::string &VCToolChainPath,
                                      Triple::ArchType TargetArch,
                                      StringRef SubdirParent) {
  const char *SubdirName;
  const char *IncludeName;
  switch (VSLayout) {
  case ToolsetLayout::OlderVS:
    SubdirName = archToLegacyVCArch(TargetArch);
    IncludeName = "include";
    break;
  case ToolsetLayout::VS2017OrNewer:
    SubdirName = archToWindowsSDKArch(TargetArch);
    IncludeName = "include";
    break;
  case ToolsetLayout::DevDivInternal:
    SubdirName = archToDevDivInternalArch(TargetArch);
    IncludeName = "inc";
    break;
  }

  SmallString<256> Path(VCToolChainPath);
  if (!SubdirParent.empty())
    sys::path::append(Path, SubdirParent);

  switch (Type) {
  case SubDirectoryType::Bin:
    if (VSLayout == ToolsetLayout::VS2017OrNewer) {
      // MSVC ships with two linkers: a 32-bit x86 and 64-bit x86 linker.
      // On x86, pick the linker that corresponds to the current process.
      // On ARM64, pick the 32-bit x86 linker; the 64-bit one doesn't run
      // on Windows 10.
      //
      // FIXME: Consider using IsWow64GuestMachineSupported to figure out
      // if we can invoke the 64-bit linker. It's generally preferable
      // because it won't run out of address-space.
      const bool HostIsX64 =
          Triple(sys::getProcessTriple()).getArch() == Triple::x86_64;
      const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86";
      sys::path::append(Path, "bin", HostName, SubdirName);
    } else { // OlderVS or DevDivInternal
      sys::path::append(Path, "bin", SubdirName);
    }
    break;
  case SubDirectoryType::Include:
    sys::path::append(Path, IncludeName);
    break;
  case SubDirectoryType::Lib:
    sys::path::append(Path, "lib", SubdirName);
    break;
  }
  return std::string(Path);
}

bool llvm::useUniversalCRT(ToolsetLayout VSLayout,
                           const std::string &VCToolChainPath,
                           Triple::ArchType TargetArch, vfs::FileSystem &VFS) {
  SmallString<128> TestPath(getSubDirectoryPath(
      SubDirectoryType::Include, VSLayout, VCToolChainPath, TargetArch));
  sys::path::append(TestPath, "stdlib.h");
  return !VFS.exists(TestPath);
}

bool llvm::getWindowsSDKDir(vfs::FileSystem &VFS,
                            std::optional<StringRef> WinSdkDir,
                            std::optional<StringRef> WinSdkVersion,
                            std::optional<StringRef> WinSysRoot,
                            std::string &Path, int &Major,
                            std::string &WindowsSDKIncludeVersion,
                            std::string &WindowsSDKLibVersion) {
  // Trust /winsdkdir and /winsdkversion if present.
  if (getWindowsSDKDirViaCommandLine(VFS, WinSdkDir, WinSdkVersion, WinSysRoot,
                                     Path, Major, WindowsSDKIncludeVersion)) {
    WindowsSDKLibVersion = WindowsSDKIncludeVersion;
    return true;
  }

  // FIXME: Try env vars (%WindowsSdkDir%, %UCRTVersion%) before going to
  // registry.

  // Try the Windows registry.
  std::string RegistrySDKVersion;
  if (!getSystemRegistryString(
          "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
          "InstallationFolder", Path, &RegistrySDKVersion))
    return false;
  if (Path.empty() || RegistrySDKVersion.empty())
    return false;

  WindowsSDKIncludeVersion.clear();
  WindowsSDKLibVersion.clear();
  Major = 0;
  std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
  if (Major <= 7)
    return true;
  if (Major == 8) {
    // Windows SDK 8.x installs libraries in a folder whose names depend on the
    // version of the OS you're targeting.  By default choose the newest, which
    // usually corresponds to the version of the OS you've installed the SDK on.
    const char *Tests[] = {"winv6.3", "win8", "win7"};
    for (const char *Test : Tests) {
      SmallString<128> TestPath(Path);
      sys::path::append(TestPath, "Lib", Test);
      if (VFS.exists(TestPath)) {
        WindowsSDKLibVersion = Test;
        break;
      }
    }
    return !WindowsSDKLibVersion.empty();
  }
  if (Major == 10) {
    if (WinSdkVersion) {
      // Use the user-provided version as-is.
      WindowsSDKIncludeVersion = WinSdkVersion->str();
      WindowsSDKLibVersion = WindowsSDKIncludeVersion;
      return true;
    }

    if (!getWindows10SDKVersionFromPath(VFS, Path, WindowsSDKIncludeVersion))
      return false;
    WindowsSDKLibVersion = WindowsSDKIncludeVersion;
    return true;
  }
  // Unsupported SDK version
  return false;
}

bool llvm::getUniversalCRTSdkDir(vfs::FileSystem &VFS,
                                 std::optional<StringRef> WinSdkDir,
                                 std::optional<StringRef> WinSdkVersion,
                                 std::optional<StringRef> WinSysRoot,
                                 std::string &Path, std::string &UCRTVersion) {
  // If /winsdkdir is passed, use it as location for the UCRT too.
  // FIXME: Should there be a dedicated /ucrtdir to override /winsdkdir?
  int Major;
  if (getWindowsSDKDirViaCommandLine(VFS, WinSdkDir, WinSdkVersion, WinSysRoot,
                                     Path, Major, UCRTVersion))
    return true;

  // FIXME: Try env vars (%UniversalCRTSdkDir%, %UCRTVersion%) before going to
  // registry.

  // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
  // for the specific key "KitsRoot10". So do we.
  if (!getSystemRegistryString(
          "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
          Path, nullptr))
    return false;

  if (WinSdkVersion) {
    // Use the user-provided version as-is.
    UCRTVersion = WinSdkVersion->str();
    return true;
  }

  return getWindows10SDKVersionFromPath(VFS, Path, UCRTVersion);
}

bool llvm::findVCToolChainViaCommandLine(
    vfs::FileSystem &VFS, std::optional<StringRef> VCToolsDir,
    std::optional<StringRef> VCToolsVersion,
    std::optional<StringRef> WinSysRoot, std::string &Path,
    ToolsetLayout &VSLayout) {
  // Don't validate the input; trust the value supplied by the user.
  // The primary motivation is to prevent unnecessary file and registry access.
  if (VCToolsDir || WinSysRoot) {
    if (WinSysRoot) {
      SmallString<128> ToolsPath(*WinSysRoot);
      sys::path::append(ToolsPath, "VC", "Tools", "MSVC");
      std::string ToolsVersion;
      if (VCToolsVersion)
        ToolsVersion = VCToolsVersion->str();
      else
        ToolsVersion = getHighestNumericTupleInDirectory(VFS, ToolsPath);
      sys::path::append(ToolsPath, ToolsVersion);
      Path = std::string(ToolsPath);
    } else {
      Path = VCToolsDir->str();
    }
    VSLayout = ToolsetLayout::VS2017OrNewer;
    return true;
  }
  return false;
}

bool llvm::findVCToolChainViaEnvironment(vfs::FileSystem &VFS,
                                         std::string &Path,
                                         ToolsetLayout &VSLayout) {
  // These variables are typically set by vcvarsall.bat
  // when launching a developer command prompt.
  if (std::optional<std::string> VCToolsInstallDir =
          sys::Process::GetEnv("VCToolsInstallDir")) {
    // This is only set by newer Visual Studios, and it leads straight to
    // the toolchain directory.
    Path = std::move(*VCToolsInstallDir);
    VSLayout = ToolsetLayout::VS2017OrNewer;
    return true;
  }
  if (std::optional<std::string> VCInstallDir =
          sys::Process::GetEnv("VCINSTALLDIR")) {
    // If the previous variable isn't set but this one is, then we've found
    // an older Visual Studio. This variable is set by newer Visual Studios too,
    // so this check has to appear second.
    // In older Visual Studios, the VC directory is the toolchain.
    Path = std::move(*VCInstallDir);
    VSLayout = ToolsetLayout::OlderVS;
    return true;
  }

  // We couldn't find any VC environment variables. Let's walk through PATH and
  // see if it leads us to a VC toolchain bin directory. If it does, pick the
  // first one that we find.
  if (std::optional<std::string> PathEnv = sys::Process::GetEnv("PATH")) {
    SmallVector<StringRef, 8> PathEntries;
    StringRef(*PathEnv).split(PathEntries, sys::EnvPathSeparator);
    for (StringRef PathEntry : PathEntries) {
      if (PathEntry.empty())
        continue;

      SmallString<256> ExeTestPath;

      // If cl.exe doesn't exist, then this definitely isn't a VC toolchain.
      ExeTestPath = PathEntry;
      sys::path::append(ExeTestPath, "cl.exe");
      if (!VFS.exists(ExeTestPath))
        continue;

      // cl.exe existing isn't a conclusive test for a VC toolchain; clang also
      // has a cl.exe. So let's check for link.exe too.
      ExeTestPath = PathEntry;
      sys::path::append(ExeTestPath, "link.exe");
      if (!VFS.exists(ExeTestPath))
        continue;

      // whatever/VC/bin --> old toolchain, VC dir is toolchain dir.
      StringRef TestPath = PathEntry;
      bool IsBin = sys::path::filename(TestPath).equals_insensitive("bin");
      if (!IsBin) {
        // Strip any architecture subdir like "amd64".
        TestPath = sys::path::parent_path(TestPath);
        IsBin = sys::path::filename(TestPath).equals_insensitive("bin");
      }
      if (IsBin) {
        StringRef ParentPath = sys::path::parent_path(TestPath);
        StringRef ParentFilename = sys::path::filename(ParentPath);
        if (ParentFilename.equals_insensitive("VC")) {
          Path = std::string(ParentPath);
          VSLayout = ToolsetLayout::OlderVS;
          return true;
        }
        if (ParentFilename.equals_insensitive("x86ret") ||
            ParentFilename.equals_insensitive("x86chk") ||
            ParentFilename.equals_insensitive("amd64ret") ||
            ParentFilename.equals_insensitive("amd64chk")) {
          Path = std::string(ParentPath);
          VSLayout = ToolsetLayout::DevDivInternal;
          return true;
        }

      } else {
        // This could be a new (>=VS2017) toolchain. If it is, we should find
        // path components with these prefixes when walking backwards through
        // the path.
        // Note: empty strings match anything.
        StringRef ExpectedPrefixes[] = {"",     "Host",  "bin", "",
                                        "MSVC", "Tools", "VC"};

        auto It = sys::path::rbegin(PathEntry);
        auto End = sys::path::rend(PathEntry);
        for (StringRef Prefix : ExpectedPrefixes) {
          if (It == End)
            goto NotAToolChain;
          if (!It->starts_with_insensitive(Prefix))
            goto NotAToolChain;
          ++It;
        }

        // We've found a new toolchain!
        // Back up 3 times (/bin/Host/arch) to get the root path.
        StringRef ToolChainPath(PathEntry);
        for (int i = 0; i < 3; ++i)
          ToolChainPath = sys::path::parent_path(ToolChainPath);

        Path = std::string(ToolChainPath);
        VSLayout = ToolsetLayout::VS2017OrNewer;
        return true;
      }

    NotAToolChain:
      continue;
    }
  }
  return false;
}

bool llvm::findVCToolChainViaSetupConfig(
    vfs::FileSystem &VFS, std::optional<StringRef> VCToolsVersion,
    std::string &Path, ToolsetLayout &VSLayout) {
#if !defined(USE_MSVC_SETUP_API)
  return false;
#else
  // FIXME: This really should be done once in the top-level program's main
  // function, as it may have already been initialized with a different
  // threading model otherwise.
  sys::InitializeCOMRAII COM(sys::COMThreadingMode::SingleThreaded);
  HRESULT HR;

  // _com_ptr_t will throw a _com_error if a COM calls fail.
  // The LLVM coding standards forbid exception handling, so we'll have to
  // stop them from being thrown in the first place.
  // The destructor will put the regular error handler back when we leave
  // this scope.
  struct SuppressCOMErrorsRAII {
    static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}

    SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }

    ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }

  } COMErrorSuppressor;

  ISetupConfigurationPtr Query;
  HR = Query.CreateInstance(__uuidof(SetupConfiguration));
  if (FAILED(HR))
    return false;

  IEnumSetupInstancesPtr EnumInstances;
  HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
  if (FAILED(HR))
    return false;

  ISetupInstancePtr Instance;
  HR = EnumInstances->Next(1, &Instance, nullptr);
  if (HR != S_OK)
    return false;

  ISetupInstancePtr NewestInstance;
  std::optional<uint64_t> NewestVersionNum;
  do {
    bstr_t VersionString;
    uint64_t VersionNum;
    HR = Instance->GetInstallationVersion(VersionString.GetAddress());
    if (FAILED(HR))
      continue;
    HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
    if (FAILED(HR))
      continue;
    if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
      NewestInstance = Instance;
      NewestVersionNum = VersionNum;
    }
  } while ((HR = EnumInstances->Next(1, &Instance, nullptr)) == S_OK);

  if (!NewestInstance)
    return false;

  bstr_t VCPathWide;
  HR = NewestInstance->ResolvePath(L"VC", VCPathWide.GetAddress());
  if (FAILED(HR))
    return false;

  std::string VCRootPath;
  convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);

  std::string ToolsVersion;
  if (VCToolsVersion.has_value()) {
    ToolsVersion = *VCToolsVersion;
  } else {
    SmallString<256> ToolsVersionFilePath(VCRootPath);
    sys::path::append(ToolsVersionFilePath, "Auxiliary", "Build",
                      "Microsoft.VCToolsVersion.default.txt");

    auto ToolsVersionFile = MemoryBuffer::getFile(ToolsVersionFilePath);
    if (!ToolsVersionFile)
      return false;

    ToolsVersion = ToolsVersionFile->get()->getBuffer().rtrim();
  }


  SmallString<256> ToolchainPath(VCRootPath);
  sys::path::append(ToolchainPath, "Tools", "MSVC", ToolsVersion);
  auto Status = VFS.status(ToolchainPath);
  if (!Status || !Status->isDirectory())
    return false;

  Path = std::string(ToolchainPath.str());
  VSLayout = ToolsetLayout::VS2017OrNewer;
  return true;
#endif
}

bool llvm::findVCToolChainViaRegistry(std::string &Path,
                                      ToolsetLayout &VSLayout) {
  std::string VSInstallPath;
  if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
                              "InstallDir", VSInstallPath, nullptr) ||
      getSystemRegistryString(R"(SOFTWARE\Microsoft\VCExpress\$VERSION)",
                              "InstallDir", VSInstallPath, nullptr)) {
    if (!VSInstallPath.empty()) {
      auto pos = VSInstallPath.find(R"(\Common7\IDE)");
      if (pos == std::string::npos)
        return false;
      SmallString<256> VCPath(StringRef(VSInstallPath.c_str(), pos));
      sys::path::append(VCPath, "VC");

      Path = std::string(VCPath);
      VSLayout = ToolsetLayout::OlderVS;
      return true;
    }
  }
  return false;
}
