//===-- 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
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#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;
}
