//===- llvm/Support/Windows/Path.inc - Windows Path Impl --------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the Windows specific implementation of the Path API.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic Windows code that
//===          is guaranteed to work on *all* Windows variants.
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/IOSandbox.h"
#include "llvm/Support/WindowsError.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

// These two headers must be included last, and make sure shlobj is required
// after Windows.h to make sure it picks up our definition of _WIN32_WINNT
#include "llvm/Support/Windows/WindowsSupport.h"
#include <shellapi.h>
#include <shlobj.h>
#include <winioctl.h>

#undef max

// MinGW doesn't define this.
#ifndef _ERRNO_T_DEFINED
#define _ERRNO_T_DEFINED
typedef int errno_t;
#endif

#ifdef _MSC_VER
#pragma comment(lib, "advapi32.lib") // This provides CryptAcquireContextW.
#pragma comment(lib, "ole32.lib")    // This provides CoTaskMemFree
#endif

using namespace llvm;

using llvm::sys::windows::CurCPToUTF16;
using llvm::sys::windows::UTF16ToUTF8;
using llvm::sys::windows::UTF8ToUTF16;
using llvm::sys::windows::widenPath;

static bool is_separator(const wchar_t value) {
  switch (value) {
  case L'\\':
  case L'/':
    return true;
  default:
    return false;
  }
}

// Long path path prefix constants (UTF-8).
static constexpr llvm::StringLiteral LongPathPrefix8 = R"(\\?\)";
static constexpr llvm::StringLiteral LongPathUNCPrefix8 = R"(\\?\UNC\)";

// Long path prefix constants (UTF-16).
static constexpr wchar_t LongPathPrefix16[] = LR"(\\?\)";
static constexpr wchar_t LongPathUNCPrefix16[] = LR"(\\?\UNC\)";

static constexpr DWORD LongPathPrefix16Len =
    static_cast<DWORD>(std::size(LongPathPrefix16) - 1);
static constexpr DWORD LongPathUNCPrefix16Len =
    static_cast<DWORD>(std::size(LongPathUNCPrefix16) - 1);

static void stripLongPathPrefix(wchar_t *&Data, DWORD &CountChars) {
  if (CountChars >= LongPathUNCPrefix16Len &&
      ::wmemcmp(Data, LongPathUNCPrefix16, LongPathUNCPrefix16Len) == 0) {
    // Convert \\?\UNC\foo\bar to \\foo\bar
    CountChars -= 6;
    Data += 6;
    Data[0] = L'\\';
  } else if (CountChars >= LongPathPrefix16Len &&
             ::wmemcmp(Data, LongPathPrefix16, LongPathPrefix16Len) == 0) {
    // Convert \\?\C:\foo to C:\foo
    CountChars -= 4;
    Data += 4;
  }
}

namespace llvm {
namespace sys {
namespace windows {

// Convert a UTF-8 path to UTF-16. Also, if the absolute equivalent of the path
// is longer than the limit that the Win32 Unicode File API can tolerate, make
// it an absolute normalized path prefixed by '\\?\'.
std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
                          size_t MaxPathLen) {
  assert(MaxPathLen <= MAX_PATH);

  // Several operations would convert Path8 to SmallString; more efficient to do
  // it once up front.
  SmallString<MAX_PATH> Path8Str;
  Path8.toVector(Path8Str);

  // If the path is a long path, mangled into forward slashes, normalize
  // back to backslashes here.
  if (Path8Str.starts_with("//?/"))
    llvm::sys::path::native(Path8Str, path::Style::windows_backslash);

  if (std::error_code EC = UTF8ToUTF16(Path8Str, Path16))
    return EC;

  const bool IsAbsolute = llvm::sys::path::is_absolute(Path8);
  size_t CurPathLen;
  if (IsAbsolute)
    CurPathLen = 0; // No contribution from current_path needed.
  else {
    CurPathLen = ::GetCurrentDirectoryW(
        0, NULL); // Returns the size including the null terminator.
    if (CurPathLen == 0)
      return mapWindowsError(::GetLastError());
  }

  if ((Path16.size() + CurPathLen) < MaxPathLen ||
      Path8Str.starts_with(LongPathPrefix8))
    return std::error_code();

  if (!IsAbsolute) {
    if (std::error_code EC = llvm::sys::fs::make_absolute(Path8Str))
      return EC;
  }

  // Remove '.' and '..' because long paths treat these as real path components.
  // Explicitly use the backslash form here, as we're prepending the \\?\
  // prefix.
  llvm::sys::path::native(Path8Str, path::Style::windows);
  llvm::sys::path::remove_dots(Path8Str, true, path::Style::windows);

  const StringRef RootName = llvm::sys::path::root_name(Path8Str);
  assert(!RootName.empty() &&
         "Root name cannot be empty for an absolute path!");

  SmallString<2 * MAX_PATH> FullPath;
  if (RootName[1] != ':') { // Check if UNC.
    FullPath.append(LongPathUNCPrefix8);
    FullPath.append(Path8Str.begin() + 2, Path8Str.end());
  } else {
    FullPath.append(LongPathPrefix8);
    FullPath.append(Path8Str);
  }

  return UTF8ToUTF16(FullPath, Path16);
}

std::error_code makeLongFormPath(const Twine &Path8,
                                 llvm::SmallVectorImpl<char> &Result8) {
  SmallString<128> PathStorage;
  StringRef PathStr = Path8.toStringRef(PathStorage);
  bool HadPrefix = PathStr.starts_with(LongPathPrefix8);

  SmallVector<wchar_t, 128> Path16;
  if (std::error_code EC = widenPath(PathStr, Path16))
    return EC;

  // Start with a buffer equal to input.
  llvm::SmallVector<wchar_t, 128> Long16;
  DWORD Len = static_cast<DWORD>(Path16.size());

  // Loop instead of a double call to be defensive against TOCTOU races.
  do {
    Long16.resize_for_overwrite(Len);

    Len = ::GetLongPathNameW(Path16.data(), Long16.data(), Len);

    // A zero return value indicates a failure other than insufficient space.
    if (Len == 0)
      return mapWindowsError(::GetLastError());

    // If there's insufficient space, the return value is the required size in
    // characters *including* the null terminator, and therefore greater than
    // the buffer size we provided. Equality would imply success with no room
    // for the terminator and should not occur for this API.
    assert(Len != Long16.size());
  } while (Len > Long16.size());

  // On success, GetLongPathNameW returns the number of characters not
  // including the null-terminator.
  Long16.truncate(Len);

  // Strip \\?\ or \\?\UNC\ long length prefix if it wasn't part of the
  // original path.
  wchar_t *Data = Long16.data();
  if (!HadPrefix)
    stripLongPathPrefix(Data, Len);

  return sys::windows::UTF16ToUTF8(Data, Len, Result8);
}

} // end namespace windows

namespace fs {

const file_t kInvalidFile = INVALID_HANDLE_VALUE;

std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
  auto BypassSandbox = sandbox::scopedDisable();

  SmallVector<wchar_t, MAX_PATH> PathName;
  PathName.resize_for_overwrite(PathName.capacity());
  DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.size());

  // A zero return value indicates a failure other than insufficient space.
  if (Size == 0)
    return "";

  // Insufficient space is determined by a return value equal to the size of
  // the buffer passed in.
  if (Size == PathName.capacity())
    return "";

  // On success, GetModuleFileNameW returns the number of characters written to
  // the buffer not including the NULL terminator.
  PathName.truncate(Size);

  // Convert the result from UTF-16 to UTF-8.
  SmallVector<char, MAX_PATH> PathNameUTF8;
  if (UTF16ToUTF8(PathName.data(), PathName.size(), PathNameUTF8))
    return "";

  llvm::sys::path::make_preferred(PathNameUTF8);

  SmallString<256> RealPath;
  sys::fs::real_path(PathNameUTF8, RealPath);
  if (RealPath.size())
    return std::string(RealPath);
  return std::string(PathNameUTF8.data());
}

UniqueID file_status::getUniqueID() const {
  return UniqueID(VolumeSerialNumber, PathHash);
}

ErrorOr<space_info> disk_space(const Twine &Path) {
  ULARGE_INTEGER Avail, Total, Free;
  SmallVector<wchar_t, 128> PathUTF16;

  if (std::error_code EC = widenPath(Path, PathUTF16))
    return EC;

  if (!::GetDiskFreeSpaceExW(PathUTF16.data(), &Avail, &Total, &Free))
    return mapWindowsError(::GetLastError());

  space_info SpaceInfo;
  SpaceInfo.capacity = Total.QuadPart;
  SpaceInfo.free = Free.QuadPart;
  SpaceInfo.available = Avail.QuadPart;

  return SpaceInfo;
}

TimePoint<> basic_file_status::getLastAccessedTime() const {
  FILETIME Time;
  Time.dwLowDateTime = LastAccessedTimeLow;
  Time.dwHighDateTime = LastAccessedTimeHigh;
  return toTimePoint(Time);
}

TimePoint<> basic_file_status::getLastModificationTime() const {
  FILETIME Time;
  Time.dwLowDateTime = LastWriteTimeLow;
  Time.dwHighDateTime = LastWriteTimeHigh;
  return toTimePoint(Time);
}

uint32_t file_status::getLinkCount() const { return NumLinks; }

std::error_code current_path(SmallVectorImpl<char> &result) {
  sandbox::violationIfEnabled();

  SmallVector<wchar_t, MAX_PATH> cur_path;
  DWORD len = MAX_PATH;

  do {
    cur_path.resize_for_overwrite(len);
    len = ::GetCurrentDirectoryW(cur_path.size(), cur_path.data());

    // A zero return value indicates a failure other than insufficient space.
    if (len == 0)
      return mapWindowsError(::GetLastError());

    // If there's insufficient space, the len returned is larger than the len
    // given.
  } while (len > cur_path.size());

  // On success, GetCurrentDirectoryW returns the number of characters not
  // including the null-terminator.
  cur_path.truncate(len);

  if (std::error_code EC =
          UTF16ToUTF8(cur_path.begin(), cur_path.size(), result))
    return EC;

  llvm::sys::path::make_preferred(result);
  return std::error_code();
}

std::error_code set_current_path(const Twine &path) {
  sandbox::violationIfEnabled();

  // Convert to utf-16.
  SmallVector<wchar_t, 128> wide_path;
  if (std::error_code ec = widenPath(path, wide_path))
    return ec;

  if (!::SetCurrentDirectoryW(wide_path.begin()))
    return mapWindowsError(::GetLastError());

  return std::error_code();
}

std::error_code create_directory(const Twine &path, bool IgnoreExisting,
                                 perms Perms) {
  SmallVector<wchar_t, 128> path_utf16;

  // CreateDirectoryW has a lower maximum path length as it must leave room for
  // an 8.3 filename.
  if (std::error_code ec = widenPath(path, path_utf16, MAX_PATH - 12))
    return ec;

  if (!::CreateDirectoryW(path_utf16.begin(), NULL)) {
    DWORD LastError = ::GetLastError();
    if (LastError != ERROR_ALREADY_EXISTS || !IgnoreExisting)
      return mapWindowsError(LastError);
  }

  return std::error_code();
}

std::error_code create_symlink(const Twine &to, const Twine &from) {
  // The Win32 API normally allows forward slashes, but under some cases it does
  // not correctly handle them in the target of a symlink.
  SmallString<128> ToStr;
  llvm::sys::path::native(to, ToStr);

  SmallVector<wchar_t, 128> WideFrom;
  SmallVector<wchar_t, 128> WideTo;
  if (std::error_code ec = widenPath(from, WideFrom))
    return ec;
  if (std::error_code ec = widenPath(ToStr, WideTo))
    return ec;

  // Windows requires SYMBOLIC_LINK_FLAG_DIRECTORY for directory symlinks, so
  // check first what type the target is. Relative symlink targets are relative
  // to the link's parent directory, not the CWD, so resolve accordingly before
  // checking attributes.
  SmallVector<wchar_t, 128> WideResolved;
  const SmallVectorImpl<wchar_t> *AttrPath = &WideTo;

  if (sys::path::is_relative(ToStr)) {
    SmallString<128> FromStr;
    from.toVector(FromStr);
    SmallString<128> Resolved = sys::path::parent_path(FromStr);
    sys::path::append(Resolved, ToStr);
    if (std::error_code ec = widenPath(Resolved, WideResolved))
      return ec;
    AttrPath = &WideResolved;
  }
  DWORD Flags = 0;
  DWORD Attr = ::GetFileAttributesW(AttrPath->begin());
  if (Attr == INVALID_FILE_ATTRIBUTES) {
    DWORD Err = ::GetLastError();
    if (Err != ERROR_FILE_NOT_FOUND && Err != ERROR_PATH_NOT_FOUND)
      return mapWindowsError(Err);
    // Target doesn't exist. Default to a file symlink, matching the Unix
    // behavior of allowing dangling symlinks.
  } else if (Attr & FILE_ATTRIBUTE_DIRECTORY) {
    Flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
  }

  // Try with SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE first, which works
  // in non-UWP programs and when Developer Mode is enabled on Windows 10+.
  if (::CreateSymbolicLinkW(WideFrom.begin(), WideTo.begin(),
                            Flags |
                                SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
    return std::error_code();

  // If the flag is not recognized (older Windows), retry without it.
  DWORD Err = ::GetLastError();
  if (Err == ERROR_INVALID_PARAMETER) {
    if (::CreateSymbolicLinkW(WideFrom.begin(), WideTo.begin(), Flags))
      return std::error_code();
    Err = ::GetLastError();
  }

  return mapWindowsError(Err);
}

std::error_code create_link(const Twine &to, const Twine &from) {
  std::error_code EC = create_symlink(to, from);
  if (EC)
    EC = create_hard_link(to, from);
  return EC;
}

std::error_code create_hard_link(const Twine &to, const Twine &from) {
  // Convert to utf-16.
  SmallVector<wchar_t, 128> wide_from;
  SmallVector<wchar_t, 128> wide_to;
  if (std::error_code ec = widenPath(from, wide_from))
    return ec;
  if (std::error_code ec = widenPath(to, wide_to))
    return ec;

  if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL))
    return mapWindowsError(::GetLastError());

  return std::error_code();
}

std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
  SmallVector<wchar_t, 128> path_utf16;

  if (std::error_code ec = widenPath(path, path_utf16))
    return ec;

  // We don't know whether this is a file or a directory, and remove() can
  // accept both. The usual way to delete a file or directory is to use one of
  // the DeleteFile or RemoveDirectory functions, but that requires you to know
  // which one it is. We could stat() the file to determine that, but that would
  // cost us additional system calls, which can be slow in a directory
  // containing a large number of files. So instead we call CreateFile directly.
  // The important part is the FILE_FLAG_DELETE_ON_CLOSE flag, which causes the
  // file to be deleted once it is closed. We also use the flags
  // FILE_FLAG_BACKUP_SEMANTICS (which allows us to open directories), and
  // FILE_FLAG_OPEN_REPARSE_POINT (don't follow symlinks).
  ScopedFileHandle h(::CreateFileW(
      c_str(path_utf16), DELETE,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS |
          FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE,
      NULL));
  if (!h) {
    std::error_code EC = mapWindowsError(::GetLastError());
    if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
      return EC;
  }

  return std::error_code();
}

static std::error_code is_local_internal(SmallVectorImpl<wchar_t> &Path,
                                         bool &Result) {
  SmallVector<wchar_t, 128> VolumePath;
  size_t Len = 128;
  while (true) {
    VolumePath.resize(Len);
    BOOL Success =
        ::GetVolumePathNameW(Path.data(), VolumePath.data(), VolumePath.size());

    if (Success)
      break;

    DWORD Err = ::GetLastError();
    if (Err != ERROR_INSUFFICIENT_BUFFER)
      return mapWindowsError(Err);

    Len *= 2;
  }
  // If the output buffer has exactly enough space for the path name, but not
  // the null terminator, it will leave the output unterminated.  Push a null
  // terminator onto the end to ensure that this never happens.
  VolumePath.push_back(L'\0');
  VolumePath.truncate(wcslen(VolumePath.data()));
  const wchar_t *P = VolumePath.data();

  UINT Type = ::GetDriveTypeW(P);
  switch (Type) {
  case DRIVE_FIXED:
    Result = true;
    return std::error_code();
  case DRIVE_REMOTE:
  case DRIVE_CDROM:
  case DRIVE_RAMDISK:
  case DRIVE_REMOVABLE:
    Result = false;
    return std::error_code();
  default:
    return make_error_code(errc::no_such_file_or_directory);
  }
  llvm_unreachable("Unreachable!");
}

std::error_code is_local(const Twine &path, bool &result) {
  sandbox::violationIfEnabled();

  if (!llvm::sys::fs::exists(path) || !llvm::sys::path::has_root_path(path))
    return make_error_code(errc::no_such_file_or_directory);

  SmallString<128> Storage;
  StringRef P = path.toStringRef(Storage);

  // Convert to utf-16.
  SmallVector<wchar_t, 128> WidePath;
  if (std::error_code ec = widenPath(P, WidePath))
    return ec;
  return is_local_internal(WidePath, result);
}

static std::error_code realPathFromHandle(HANDLE H,
                                          SmallVectorImpl<wchar_t> &Buffer,
                                          DWORD flags = VOLUME_NAME_DOS) {
  Buffer.resize_for_overwrite(Buffer.capacity());
  DWORD CountChars = ::GetFinalPathNameByHandleW(
      H, Buffer.begin(), Buffer.capacity(), FILE_NAME_NORMALIZED | flags);
  if (CountChars && CountChars >= Buffer.capacity()) {
    // The buffer wasn't big enough, try again.  In this case the return value
    // *does* indicate the size of the null terminator.
    Buffer.resize_for_overwrite(CountChars);
    CountChars = ::GetFinalPathNameByHandleW(H, Buffer.begin(), Buffer.size(),
                                             FILE_NAME_NORMALIZED | flags);
  }
  Buffer.truncate(CountChars);
  if (CountChars == 0)
    return mapWindowsError(GetLastError());
  return std::error_code();
}

static std::error_code realPathFromHandle(HANDLE H,
                                          SmallVectorImpl<char> &RealPath) {
  RealPath.clear();
  SmallVector<wchar_t, MAX_PATH> Buffer;
  if (std::error_code EC = realPathFromHandle(H, Buffer))
    return EC;

  // Strip the \\?\ prefix. We don't want it ending up in output, and such
  // paths don't get canonicalized by file APIs.
  wchar_t *Data = Buffer.data();
  DWORD CountChars = Buffer.size();
  stripLongPathPrefix(Data, CountChars);

  // Convert the result from UTF-16 to UTF-8.
  if (std::error_code EC = UTF16ToUTF8(Data, CountChars, RealPath))
    return EC;

  llvm::sys::path::make_preferred(RealPath);
  return std::error_code();
}

std::error_code is_local(int FD, bool &Result) {
  sandbox::violationIfEnabled();

  SmallVector<wchar_t, 128> FinalPath;
  HANDLE Handle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));

  if (std::error_code EC = realPathFromHandle(Handle, FinalPath))
    return EC;

  return is_local_internal(FinalPath, Result);
}

static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) {
  // Clear the FILE_DISPOSITION_INFO flag first, before checking if it's a
  // network file. On Windows 7 the function realPathFromHandle() below fails
  // if the FILE_DISPOSITION_INFO flag was already set to 'DeleteFile = true' by
  // a prior call.
  FILE_DISPOSITION_INFO Disposition;
  Disposition.DeleteFile = false;
  if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
                                  sizeof(Disposition)))
    return mapWindowsError(::GetLastError());
  if (!Delete)
    return std::error_code();

  // Check if the file is on a network (non-local) drive. If so, don't
  // continue when DeleteFile is true, since it prevents opening the file for
  // writes.
  SmallVector<wchar_t, 128> FinalPath;
  if (std::error_code EC = realPathFromHandle(Handle, FinalPath))
    return EC;

  bool IsLocal;
  if (std::error_code EC = is_local_internal(FinalPath, IsLocal))
    return EC;

  if (!IsLocal)
    return errc::not_supported;

  // The file is on a local drive, we can safely set FILE_DISPOSITION_INFO's
  // flag.
  Disposition.DeleteFile = true;
  if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
                                  sizeof(Disposition)))
    return mapWindowsError(::GetLastError());
  return std::error_code();
}

static std::error_code rename_internal(HANDLE FromHandle, const Twine &To,
                                       bool ReplaceIfExists) {
  SmallVector<wchar_t, 0> ToWide;
  if (auto EC = widenPath(To, ToWide))
    return EC;

  std::vector<char> RenameInfoBuf(sizeof(FILE_RENAME_INFO) - sizeof(wchar_t) +
                                  (ToWide.size() * sizeof(wchar_t)));
  FILE_RENAME_INFO &RenameInfo =
      *reinterpret_cast<FILE_RENAME_INFO *>(RenameInfoBuf.data());
  RenameInfo.ReplaceIfExists = ReplaceIfExists;
  RenameInfo.RootDirectory = 0;
  RenameInfo.FileNameLength = ToWide.size() * sizeof(wchar_t);
  std::copy(ToWide.begin(), ToWide.end(), &RenameInfo.FileName[0]);

  SetLastError(ERROR_SUCCESS);
  if (!SetFileInformationByHandle(FromHandle, FileRenameInfo, &RenameInfo,
                                  RenameInfoBuf.size())) {
    unsigned Error = GetLastError();
    if (Error == ERROR_SUCCESS)
      Error = ERROR_CALL_NOT_IMPLEMENTED; // Wine doesn't always set error code.
    return mapWindowsError(Error);
  }

  return std::error_code();
}

static std::error_code rename_handle(HANDLE FromHandle, const Twine &To) {
  SmallVector<wchar_t, 128> WideTo;
  if (std::error_code EC = widenPath(To, WideTo))
    return EC;

  // We normally expect this loop to succeed after a few iterations. If it
  // requires more than 200 tries, it's more likely that the failures are due to
  // a true error, so stop trying.
  for (unsigned Retry = 0; Retry != 200; ++Retry) {
    auto EC = rename_internal(FromHandle, To, true);

    if (EC ==
        std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category())) {
      // Wine doesn't support SetFileInformationByHandle in rename_internal.
      // Fall back to MoveFileEx.
      SmallVector<wchar_t, MAX_PATH> WideFrom;
      if (std::error_code EC2 = realPathFromHandle(FromHandle, WideFrom))
        return EC2;
      if (::MoveFileExW(WideFrom.begin(), WideTo.begin(),
                        MOVEFILE_REPLACE_EXISTING))
        return std::error_code();
      return mapWindowsError(GetLastError());
    }

    if (!EC || EC != errc::permission_denied)
      return EC;

    // The destination file probably exists and is currently open in another
    // process, either because the file was opened without FILE_SHARE_DELETE or
    // it is mapped into memory (e.g. using MemoryBuffer). Rename it in order to
    // move it out of the way of the source file. Use FILE_FLAG_DELETE_ON_CLOSE
    // to arrange for the destination file to be deleted when the other process
    // closes it.
    ScopedFileHandle ToHandle(
        ::CreateFileW(WideTo.begin(), GENERIC_READ | DELETE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                      NULL, OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL));
    if (!ToHandle) {
      auto EC = mapWindowsError(GetLastError());
      // Another process might have raced with us and moved the existing file
      // out of the way before we had a chance to open it. If that happens, try
      // to rename the source file again.
      if (EC == errc::no_such_file_or_directory)
        continue;
      return EC;
    }

    BY_HANDLE_FILE_INFORMATION FI;
    if (!GetFileInformationByHandle(ToHandle, &FI))
      return mapWindowsError(GetLastError());

    // Try to find a unique new name for the destination file.
    for (unsigned UniqueId = 0; UniqueId != 200; ++UniqueId) {
      std::string TmpFilename = (To + ".tmp" + utostr(UniqueId)).str();
      if (auto EC = rename_internal(ToHandle, TmpFilename, false)) {
        if (EC == errc::file_exists || EC == errc::permission_denied) {
          // Again, another process might have raced with us and moved the file
          // before we could move it. Check whether this is the case, as it
          // might have caused the permission denied error. If that was the
          // case, we don't need to move it ourselves.
          ScopedFileHandle ToHandle2(::CreateFileW(
              WideTo.begin(), 0,
              FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
          if (!ToHandle2) {
            auto EC = mapWindowsError(GetLastError());
            if (EC == errc::no_such_file_or_directory)
              break;
            return EC;
          }
          BY_HANDLE_FILE_INFORMATION FI2;
          if (!GetFileInformationByHandle(ToHandle2, &FI2))
            return mapWindowsError(GetLastError());
          if (FI.nFileIndexHigh != FI2.nFileIndexHigh ||
              FI.nFileIndexLow != FI2.nFileIndexLow ||
              FI.dwVolumeSerialNumber != FI2.dwVolumeSerialNumber)
            break;
          continue;
        }
        return EC;
      }
      break;
    }

    // Okay, the old destination file has probably been moved out of the way at
    // this point, so try to rename the source file again. Still, another
    // process might have raced with us to create and open the destination
    // file, so we need to keep doing this until we succeed.
  }

  // The most likely root cause.
  return errc::permission_denied;
}

std::error_code rename(const Twine &From, const Twine &To) {
  // Convert to utf-16.
  SmallVector<wchar_t, 128> WideFrom;
  if (std::error_code EC = widenPath(From, WideFrom))
    return EC;

  ScopedFileHandle FromHandle;
  // Retry this a few times to defeat badly behaved file system scanners.
  for (unsigned Retry = 0; Retry != 200; ++Retry) {
    if (Retry != 0)
      ::Sleep(10);
    // `FILE_FLAG_BACKUP_SEMANTICS` must be used to create a handle to a
    // directory.
    FromHandle =
        ::CreateFileW(WideFrom.begin(), GENERIC_READ | DELETE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                      NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (FromHandle)
      break;

    // We don't want to loop if the file doesn't exist.
    auto EC = mapWindowsError(GetLastError());
    if (EC == errc::no_such_file_or_directory)
      return EC;
  }
  if (!FromHandle)
    return mapWindowsError(GetLastError());

  return rename_handle(FromHandle, To);
}

std::error_code resize_file(int FD, uint64_t Size) {
#ifdef HAVE__CHSIZE_S
  errno_t error = ::_chsize_s(FD, Size);
#else
  errno_t error = ::_chsize(FD, Size);
#endif
  return std::error_code(error, std::generic_category());
}

std::error_code resize_file_sparse(int FD, uint64_t Size) {
  HANDLE hFile = reinterpret_cast<HANDLE>(::_get_osfhandle(FD));
  DWORD temp;
  if (!DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &temp,
                       NULL)) {
    return mapWindowsError(GetLastError());
  }
  LARGE_INTEGER liSize;
  liSize.QuadPart = Size;
  if (!SetFilePointerEx(hFile, liSize, NULL, FILE_BEGIN) ||
      !SetEndOfFile(hFile)) {
    return mapWindowsError(GetLastError());
  }
  return std::error_code();
}

std::error_code access(const Twine &Path, AccessMode Mode) {
  sandbox::violationIfEnabled();

  SmallVector<wchar_t, 128> PathUtf16;

  if (std::error_code EC = widenPath(Path, PathUtf16))
    return EC;

  DWORD Attributes = ::GetFileAttributesW(PathUtf16.begin());

  if (Attributes == INVALID_FILE_ATTRIBUTES) {
    // Avoid returning unexpected error codes when querying for existence.
    if (Mode == AccessMode::Exist)
      return errc::no_such_file_or_directory;

    // See if the file didn't actually exist.
    DWORD LastError = ::GetLastError();
    if (LastError != ERROR_FILE_NOT_FOUND && LastError != ERROR_PATH_NOT_FOUND)
      return mapWindowsError(LastError);
    return errc::no_such_file_or_directory;
  }

  if (Mode == AccessMode::Write && (Attributes & FILE_ATTRIBUTE_READONLY))
    return errc::permission_denied;

  if (Mode == AccessMode::Execute && (Attributes & FILE_ATTRIBUTE_DIRECTORY))
    return errc::permission_denied;

  return std::error_code();
}

bool can_execute(const Twine &Path) {
  return !access(Path, AccessMode::Execute) ||
         !access(Path + ".exe", AccessMode::Execute);
}

bool equivalent(file_status A, file_status B) {
  assert(status_known(A) && status_known(B));
  return A.getUniqueID() == B.getUniqueID();
}

std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
  sandbox::violationIfEnabled();

  file_status fsA, fsB;
  if (std::error_code ec = status(A, fsA))
    return ec;
  if (std::error_code ec = status(B, fsB))
    return ec;
  result = equivalent(fsA, fsB);
  return std::error_code();
}

static bool isReservedName(StringRef path) {
  // This list of reserved names comes from MSDN, at:
  // http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
  static const char *const sReservedNames[] = {
      "nul",  "con",  "prn",  "aux",  "com1", "com2", "com3", "com4",
      "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
      "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"};

  // First, check to see if this is a device namespace, which always
  // starts with \\.\, since device namespaces are not legal file paths.
  if (path.starts_with("\\\\.\\"))
    return true;

  // Then compare against the list of ancient reserved names.
  for (size_t i = 0; i < std::size(sReservedNames); ++i) {
    if (path.equals_insensitive(sReservedNames[i]))
      return true;
  }

  // The path isn't what we consider reserved.
  return false;
}

static file_type file_type_from_attrs(DWORD Attrs) {
  return (Attrs & FILE_ATTRIBUTE_DIRECTORY) ? file_type::directory_file
                                            : file_type::regular_file;
}

static perms perms_from_attrs(DWORD Attrs) {
  return (Attrs & FILE_ATTRIBUTE_READONLY) ? (all_read | all_exe) : all_all;
}

static std::error_code getStatus(HANDLE FileHandle, file_status &Result) {
  SmallVector<wchar_t, MAX_PATH> ntPath;
  if (FileHandle == INVALID_HANDLE_VALUE)
    goto handle_status_error;

  switch (::GetFileType(FileHandle)) {
  default:
    llvm_unreachable("Don't know anything about this file type");
  case FILE_TYPE_UNKNOWN: {
    DWORD Err = ::GetLastError();
    if (Err != NO_ERROR)
      return mapWindowsError(Err);
    Result = file_status(file_type::type_unknown);
    return std::error_code();
  }
  case FILE_TYPE_DISK:
    break;
  case FILE_TYPE_CHAR:
    Result = file_status(file_type::character_file);
    return std::error_code();
  case FILE_TYPE_PIPE:
    Result = file_status(file_type::fifo_file);
    return std::error_code();
  }

  BY_HANDLE_FILE_INFORMATION Info;
  if (!::GetFileInformationByHandle(FileHandle, &Info))
    goto handle_status_error;

  // File indices aren't necessarily stable after closing the file handle;
  // instead hash a canonicalized path.
  //
  // For getting a canonical path to the file, call GetFinalPathNameByHandleW
  // with VOLUME_NAME_NT. We don't really care exactly what the path looks
  // like here, as long as it is canonical (e.g. doesn't differentiate between
  // whether a file was referred to with upper/lower case names originally).
  // The default format with VOLUME_NAME_DOS doesn't work with all file system
  // drivers, such as ImDisk. (See
  // https://github.com/rust-lang/rust/pull/86447.)
  uint64_t PathHash;
  if (std::error_code EC =
          realPathFromHandle(FileHandle, ntPath, VOLUME_NAME_NT)) {
    // If realPathFromHandle failed, fall back on the fields
    // nFileIndex{High,Low} instead. They're not necessarily stable on all file
    // systems as they're only documented as being unique/stable as long as the
    // file handle is open - but they're a decent fallback if we couldn't get
    // the canonical path.
    PathHash = (static_cast<uint64_t>(Info.nFileIndexHigh) << 32ULL) |
               static_cast<uint64_t>(Info.nFileIndexLow);
  } else {
    PathHash = hash_combine_range(ntPath);
  }

  Result = file_status(
      file_type_from_attrs(Info.dwFileAttributes),
      perms_from_attrs(Info.dwFileAttributes), Info.nNumberOfLinks,
      Info.ftLastAccessTime.dwHighDateTime, Info.ftLastAccessTime.dwLowDateTime,
      Info.ftLastWriteTime.dwHighDateTime, Info.ftLastWriteTime.dwLowDateTime,
      Info.dwVolumeSerialNumber, Info.nFileSizeHigh, Info.nFileSizeLow,
      PathHash);
  return std::error_code();

handle_status_error:
  std::error_code Err = mapLastWindowsError();
  if (Err == std::errc::no_such_file_or_directory)
    Result = file_status(file_type::file_not_found);
  else if (Err == std::errc::permission_denied)
    Result = file_status(file_type::type_unknown);
  else
    Result = file_status(file_type::status_error);
  return Err;
}

std::error_code status(const Twine &path, file_status &result, bool Follow) {
  sandbox::violationIfEnabled();

  SmallString<128> path_storage;
  SmallVector<wchar_t, 128> path_utf16;

  StringRef path8 = path.toStringRef(path_storage);
  if (isReservedName(path8)) {
    result = file_status(file_type::character_file);
    return std::error_code();
  }

  if (std::error_code ec = widenPath(path8, path_utf16))
    return ec;

  DWORD Flags = FILE_FLAG_BACKUP_SEMANTICS;
  if (!Follow) {
    DWORD attr = ::GetFileAttributesW(path_utf16.begin());
    if (attr == INVALID_FILE_ATTRIBUTES)
      return getStatus(INVALID_HANDLE_VALUE, result);

    // Handle reparse points.
    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
      Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
  }

  ScopedFileHandle h(
      ::CreateFileW(path_utf16.begin(), 0, // Attributes only.
                    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                    NULL, OPEN_EXISTING, Flags, 0));
  if (!h)
    return getStatus(INVALID_HANDLE_VALUE, result);

  return getStatus(h, result);
}

std::error_code status(int FD, file_status &Result) {
  sandbox::violationIfEnabled();

  HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
  return getStatus(FileHandle, Result);
}

std::error_code status(file_t FileHandle, file_status &Result) {
  sandbox::violationIfEnabled();

  return getStatus(FileHandle, Result);
}

unsigned getUmask() { return 0; }

std::error_code setPermissions(const Twine &Path, perms Permissions) {
  SmallVector<wchar_t, 128> PathUTF16;
  if (std::error_code EC = widenPath(Path, PathUTF16))
    return EC;

  DWORD Attributes = ::GetFileAttributesW(PathUTF16.begin());
  if (Attributes == INVALID_FILE_ATTRIBUTES)
    return mapWindowsError(GetLastError());

  // There are many Windows file attributes that are not to do with the file
  // permissions (e.g. FILE_ATTRIBUTE_HIDDEN). We need to be careful to preserve
  // them.
  if (Permissions & all_write) {
    Attributes &= ~FILE_ATTRIBUTE_READONLY;
    if (Attributes == 0)
      // FILE_ATTRIBUTE_NORMAL indicates no other attributes are set.
      Attributes |= FILE_ATTRIBUTE_NORMAL;
  } else {
    Attributes |= FILE_ATTRIBUTE_READONLY;
    // FILE_ATTRIBUTE_NORMAL is not compatible with any other attributes, so
    // remove it, if it is present.
    Attributes &= ~FILE_ATTRIBUTE_NORMAL;
  }

  if (!::SetFileAttributesW(PathUTF16.begin(), Attributes))
    return mapWindowsError(GetLastError());

  return std::error_code();
}

std::error_code setPermissions(int FD, perms Permissions) {
  // FIXME Not implemented.
  return std::make_error_code(std::errc::not_supported);
}

std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
                                                 TimePoint<> ModificationTime) {
  FILETIME AccessFT = toFILETIME(AccessTime);
  FILETIME ModifyFT = toFILETIME(ModificationTime);
  HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
  if (!SetFileTime(FileHandle, NULL, &AccessFT, &ModifyFT))
    return mapWindowsError(::GetLastError());
  return std::error_code();
}

std::error_code mapped_file_region::init(sys::fs::file_t OrigFileHandle,
                                         uint64_t Offset, mapmode Mode,
                                         const char *Name) {
  this->Mode = Mode;
  if (OrigFileHandle == INVALID_HANDLE_VALUE)
    return make_error_code(errc::bad_file_descriptor);

  DWORD flprotect;
  switch (Mode) {
  case readonly:
    flprotect = PAGE_READONLY;
    break;
  case readwrite:
    flprotect = PAGE_READWRITE;
    break;
  case priv:
    flprotect = PAGE_WRITECOPY;
    break;
  }

  SmallVector<wchar_t, 128> NameUTF16;
  if (Name)
    if (std::error_code EC = UTF8ToUTF16(Name, NameUTF16))
      return EC;

  HANDLE FileMappingHandle =
      ::CreateFileMappingW(OrigFileHandle, 0, flprotect, Hi_32(Size),
                           Lo_32(Size), Name ? c_str(NameUTF16) : 0);
  if (FileMappingHandle == NULL) {
    std::error_code ec = mapWindowsError(GetLastError());
    return ec;
  }

  DWORD dwDesiredAccess;
  switch (Mode) {
  case readonly:
    dwDesiredAccess = FILE_MAP_READ;
    break;
  case readwrite:
    dwDesiredAccess = FILE_MAP_WRITE;
    break;
  case priv:
    dwDesiredAccess = FILE_MAP_COPY;
    break;
  }
  Mapping = ::MapViewOfFile(FileMappingHandle, dwDesiredAccess, Offset >> 32,
                            Offset & 0xffffffff, Size);
  if (Mapping == NULL) {
    std::error_code ec = mapWindowsError(GetLastError());
    ::CloseHandle(FileMappingHandle);
    return ec;
  }

  if (Size == 0) {
    MEMORY_BASIC_INFORMATION mbi;
    SIZE_T Result = VirtualQuery(Mapping, &mbi, sizeof(mbi));
    if (Result == 0) {
      std::error_code ec = mapWindowsError(GetLastError());
      ::UnmapViewOfFile(Mapping);
      ::CloseHandle(FileMappingHandle);
      return ec;
    }
    Size = mbi.RegionSize;
  }

  // Close the file mapping handle, as it's kept alive by the file mapping. But
  // neither the file mapping nor the file mapping handle keep the file handle
  // alive, so we need to keep a reference to the file in case all other handles
  // are closed and the file is deleted, which may cause invalid data to be read
  // from the file.
  ::CloseHandle(FileMappingHandle);
  if (!::DuplicateHandle(::GetCurrentProcess(), OrigFileHandle,
                         ::GetCurrentProcess(), &FileHandle, 0, 0,
                         DUPLICATE_SAME_ACCESS)) {
    std::error_code ec = mapWindowsError(GetLastError());
    ::UnmapViewOfFile(Mapping);
    return ec;
  }

  return std::error_code();
}

mapped_file_region::mapped_file_region(sys::fs::file_t fd, mapmode mode,
                                       size_t length, uint64_t offset,
                                       std::error_code &ec, const char *name)
    : Size(length) {
  sandbox::violationIfEnabled();

  ec = init(fd, offset, mode, name);
  if (ec)
    copyFrom(mapped_file_region());
}

static bool hasFlushBufferKernelBug() {
  static bool Ret{GetWindowsOSVersion() < llvm::VersionTuple(10, 0, 0, 17763)};
  return Ret;
}

static bool isEXE(StringRef Magic) {
  static const char PEMagic[] = {'P', 'E', '\0', '\0'};
  if (Magic.starts_with(StringRef("MZ")) && Magic.size() >= 0x3c + 4) {
    uint32_t off = read32le(Magic.data() + 0x3c);
    // PE/COFF file, either EXE or DLL.
    if (Magic.substr(off).starts_with(StringRef(PEMagic, sizeof(PEMagic))))
      return true;
  }
  return false;
}

void mapped_file_region::unmapImpl() {
  if (Mapping) {

    bool Exe = isEXE(StringRef((char *)Mapping, Size));

    ::UnmapViewOfFile(Mapping);

    if (Mode == mapmode::readwrite) {
      bool DoFlush = Exe && hasFlushBufferKernelBug();
      // There is a Windows kernel bug, the exact trigger conditions of which
      // are not well understood.  When triggered, dirty pages are not properly
      // flushed and subsequent process's attempts to read a file can return
      // invalid data.  Calling FlushFileBuffers on the write handle is
      // sufficient to ensure that this bug is not triggered.
      // The bug only occurs when writing an executable and executing it right
      // after, under high I/O pressure.
      if (!DoFlush) {
        // Separately, on VirtualBox Shared Folder mounts, writes via memory
        // maps always end up unflushed (regardless of version of Windows),
        // unless flushed with this explicit call, if they are renamed with
        // SetFileInformationByHandle(FileRenameInfo) before closing the output
        // handle.
        //
        // As the flushing is quite expensive, use a heuristic to limit the
        // cases where we do the flushing. Only do the flushing if we aren't
        // sure we are on a local file system.
        bool IsLocal = false;
        SmallVector<wchar_t, 128> FinalPath;
        if (!realPathFromHandle(FileHandle, FinalPath)) {
          // Not checking the return value here - if the check fails, assume the
          // file isn't local.
          is_local_internal(FinalPath, IsLocal);
        }
        DoFlush = !IsLocal;
      }
      if (DoFlush)
        ::FlushFileBuffers(FileHandle);
    }

    ::CloseHandle(FileHandle);
  }
}

void mapped_file_region::dontNeedImpl() {}

void mapped_file_region::willNeedImpl() {
  struct MEMORY_RANGE_ENTRY {
    PVOID VirtualAddress;
    SIZE_T NumberOfBytes;
  };
  // PrefetchVirtualMemory is only available on Windows 8 and later. Since we
  // still support compilation on Windows 7, we load the function dynamically.
  typedef BOOL(WINAPI * PrefetchVirtualMemory_t)(
      HANDLE hProcess, ULONG_PTR NumberOfEntries,
      MEMORY_RANGE_ENTRY * VirtualAddresses, ULONG Flags);

  static auto pfnPrefetchVirtualMemory = []() -> PrefetchVirtualMemory_t {
    HMODULE kernelM =
        llvm::sys::windows::loadSystemModuleSecure(L"kernel32.dll");
    if (!kernelM)
      return nullptr;
    return (PrefetchVirtualMemory_t)(void *)::GetProcAddress(
        kernelM, "PrefetchVirtualMemory");
  }();
  if (pfnPrefetchVirtualMemory) {
    MEMORY_RANGE_ENTRY Range{Mapping, Size};
    pfnPrefetchVirtualMemory(::GetCurrentProcess(), 1, &Range, 0);
  }
}

std::error_code mapped_file_region::sync() const {
  if (!::FlushViewOfFile(Mapping, Size))
    return mapWindowsError(GetLastError());
  if (!::FlushFileBuffers(FileHandle))
    return mapWindowsError(GetLastError());
  return std::error_code();
}

int mapped_file_region::alignment() {
  SYSTEM_INFO SysInfo;
  ::GetSystemInfo(&SysInfo);
  return SysInfo.dwAllocationGranularity;
}

static basic_file_status status_from_find_data(WIN32_FIND_DATAW *FindData) {
  return basic_file_status(file_type_from_attrs(FindData->dwFileAttributes),
                           perms_from_attrs(FindData->dwFileAttributes),
                           FindData->ftLastAccessTime.dwHighDateTime,
                           FindData->ftLastAccessTime.dwLowDateTime,
                           FindData->ftLastWriteTime.dwHighDateTime,
                           FindData->ftLastWriteTime.dwLowDateTime,
                           FindData->nFileSizeHigh, FindData->nFileSizeLow);
}

std::error_code detail::directory_iterator_construct(detail::DirIterState &IT,
                                                     StringRef Path,
                                                     bool FollowSymlinks) {
  sandbox::violationIfEnabled();

  SmallVector<wchar_t, 128> PathUTF16;

  if (std::error_code EC = widenPath(Path, PathUTF16))
    return EC;

  // Convert path to the format that Windows is happy with.
  size_t PathUTF16Len = PathUTF16.size();
  if (PathUTF16Len > 0 && !is_separator(PathUTF16[PathUTF16Len - 1]) &&
      PathUTF16[PathUTF16Len - 1] != L':') {
    PathUTF16.push_back(L'\\');
    PathUTF16.push_back(L'*');
  } else {
    PathUTF16.push_back(L'*');
  }

  //  Get the first directory entry.
  WIN32_FIND_DATAW FirstFind;
  ScopedFindHandle FindHandle(::FindFirstFileExW(
      c_str(PathUTF16), FindExInfoBasic, &FirstFind, FindExSearchNameMatch,
      NULL, FIND_FIRST_EX_LARGE_FETCH));
  if (!FindHandle)
    return mapWindowsError(::GetLastError());

  size_t FilenameLen = ::wcslen(FirstFind.cFileName);
  while ((FilenameLen == 1 && FirstFind.cFileName[0] == L'.') ||
         (FilenameLen == 2 && FirstFind.cFileName[0] == L'.' &&
          FirstFind.cFileName[1] == L'.'))
    if (!::FindNextFileW(FindHandle, &FirstFind)) {
      DWORD LastError = ::GetLastError();
      // Check for end.
      if (LastError == ERROR_NO_MORE_FILES)
        return detail::directory_iterator_destruct(IT);
      return mapWindowsError(LastError);
    } else {
      FilenameLen = ::wcslen(FirstFind.cFileName);
    }

  // Construct the current directory entry.
  SmallString<128> DirectoryEntryNameUTF8;
  if (std::error_code EC =
          UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName),
                      DirectoryEntryNameUTF8))
    return EC;

  IT.IterationHandle = intptr_t(FindHandle.take());
  SmallString<128> DirectoryEntryPath(Path);
  path::append(DirectoryEntryPath, DirectoryEntryNameUTF8);
  IT.CurrentEntry =
      directory_entry(DirectoryEntryPath, FollowSymlinks,
                      file_type_from_attrs(FirstFind.dwFileAttributes),
                      status_from_find_data(&FirstFind));

  return std::error_code();
}

std::error_code detail::directory_iterator_destruct(detail::DirIterState &IT) {
  if (IT.IterationHandle != 0)
    // Closes the handle if it's valid.
    ScopedFindHandle close(HANDLE(IT.IterationHandle));
  IT.IterationHandle = 0;
  IT.CurrentEntry = directory_entry();
  return std::error_code();
}

std::error_code detail::directory_iterator_increment(detail::DirIterState &IT) {
  sandbox::violationIfEnabled();

  WIN32_FIND_DATAW FindData;
  if (!::FindNextFileW(HANDLE(IT.IterationHandle), &FindData)) {
    DWORD LastError = ::GetLastError();
    // Check for end.
    if (LastError == ERROR_NO_MORE_FILES)
      return detail::directory_iterator_destruct(IT);
    return mapWindowsError(LastError);
  }

  size_t FilenameLen = ::wcslen(FindData.cFileName);
  if ((FilenameLen == 1 && FindData.cFileName[0] == L'.') ||
      (FilenameLen == 2 && FindData.cFileName[0] == L'.' &&
       FindData.cFileName[1] == L'.'))
    return directory_iterator_increment(IT);

  SmallString<128> DirectoryEntryPathUTF8;
  if (std::error_code EC =
          UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName),
                      DirectoryEntryPathUTF8))
    return EC;

  IT.CurrentEntry.replace_filename(
      Twine(DirectoryEntryPathUTF8),
      file_type_from_attrs(FindData.dwFileAttributes),
      status_from_find_data(&FindData));
  return std::error_code();
}

ErrorOr<basic_file_status> directory_entry::status() const { return Status; }

static std::error_code nativeFileToFd(Expected<HANDLE> H, int &ResultFD,
                                      OpenFlags Flags) {
  int CrtOpenFlags = 0;
  if (Flags & OF_Append)
    CrtOpenFlags |= _O_APPEND;

  if (Flags & OF_CRLF) {
    assert(Flags & OF_Text && "Flags set OF_CRLF without OF_Text");
    CrtOpenFlags |= _O_TEXT;
  }

  ResultFD = -1;
  if (!H)
    return errorToErrorCode(H.takeError());

  ResultFD = ::_open_osfhandle(intptr_t(*H), CrtOpenFlags);
  if (ResultFD == -1) {
    ::CloseHandle(*H);
    return mapWindowsError(ERROR_INVALID_HANDLE);
  }
  return std::error_code();
}

static DWORD nativeDisposition(CreationDisposition Disp, OpenFlags Flags) {
  // This is a compatibility hack.  Really we should respect the creation
  // disposition, but a lot of old code relied on the implicit assumption that
  // OF_Append implied it would open an existing file.  Since the disposition is
  // now explicit and defaults to CD_CreateAlways, this assumption would cause
  // any usage of OF_Append to append to a new file, even if the file already
  // existed.  A better solution might have two new creation dispositions:
  // CD_AppendAlways and CD_AppendNew.  This would also address the problem of
  // OF_Append being used on a read-only descriptor, which doesn't make sense.
  if (Flags & OF_Append)
    return OPEN_ALWAYS;

  switch (Disp) {
  case CD_CreateAlways:
    return CREATE_ALWAYS;
  case CD_CreateNew:
    return CREATE_NEW;
  case CD_OpenAlways:
    return OPEN_ALWAYS;
  case CD_OpenExisting:
    return OPEN_EXISTING;
  }
  llvm_unreachable("unreachable!");
}

static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) {
  DWORD Result = 0;
  if (Access & FA_Read)
    Result |= GENERIC_READ;
  if (Access & FA_Write)
    Result |= GENERIC_WRITE;
  if (Flags & OF_Delete)
    Result |= DELETE;
  if (Flags & OF_UpdateAtime)
    Result |= FILE_WRITE_ATTRIBUTES;
  return Result;
}

static std::error_code openNativeFileInternal(const Twine &Name,
                                              file_t &ResultFile, DWORD Disp,
                                              DWORD Access, DWORD Flags,
                                              bool Inherit = false) {
  SmallVector<wchar_t, 128> PathUTF16;
  if (std::error_code EC = widenPath(Name, PathUTF16))
    return EC;

  SECURITY_ATTRIBUTES SA;
  SA.nLength = sizeof(SA);
  SA.lpSecurityDescriptor = nullptr;
  SA.bInheritHandle = Inherit;

  HANDLE H =
      ::CreateFileW(PathUTF16.begin(), Access,
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SA,
                    Disp, Flags, NULL);
  if (H == INVALID_HANDLE_VALUE) {
    DWORD LastError = ::GetLastError();
    std::error_code EC = mapWindowsError(LastError);
    // Provide a better error message when trying to open directories.
    // This only runs if we failed to open the file, so there is probably
    // no performances issues.
    if (LastError != ERROR_ACCESS_DENIED)
      return EC;
    if (is_directory(Name))
      return make_error_code(errc::is_a_directory);
    return EC;
  }
  ResultFile = H;
  return std::error_code();
}

Expected<file_t> openNativeFile(const Twine &Name, CreationDisposition Disp,
                                FileAccess Access, OpenFlags Flags,
                                unsigned Mode) {
  sandbox::violationIfEnabled();

  // Verify that we don't have both "append" and "excl".
  assert((!(Disp == CD_CreateNew) || !(Flags & OF_Append)) &&
         "Cannot specify both 'CreateNew' and 'Append' file creation flags!");

  DWORD NativeDisp = nativeDisposition(Disp, Flags);
  DWORD NativeAccess = nativeAccess(Access, Flags);

  bool Inherit = false;
  if (Flags & OF_ChildInherit)
    Inherit = true;

  file_t Result;
  std::error_code EC = openNativeFileInternal(
      Name, Result, NativeDisp, NativeAccess, FILE_ATTRIBUTE_NORMAL, Inherit);
  if (EC)
    return errorCodeToError(EC);

  if (Flags & OF_UpdateAtime) {
    FILETIME FileTime;
    SYSTEMTIME SystemTime;
    GetSystemTime(&SystemTime);
    if (SystemTimeToFileTime(&SystemTime, &FileTime) == 0 ||
        SetFileTime(Result, NULL, &FileTime, NULL) == 0) {
      DWORD LastError = ::GetLastError();
      ::CloseHandle(Result);
      return errorCodeToError(mapWindowsError(LastError));
    }
  }

  return Result;
}

std::error_code openFile(const Twine &Name, int &ResultFD,
                         CreationDisposition Disp, FileAccess Access,
                         OpenFlags Flags, unsigned int Mode) {
  sandbox::violationIfEnabled();

  Expected<file_t> Result = openNativeFile(Name, Disp, Access, Flags);
  if (!Result)
    return errorToErrorCode(Result.takeError());

  return nativeFileToFd(*Result, ResultFD, Flags);
}

static std::error_code directoryRealPath(const Twine &Name,
                                         SmallVectorImpl<char> &RealPath) {
  file_t File;
  std::error_code EC = openNativeFileInternal(
      Name, File, OPEN_EXISTING, GENERIC_READ, FILE_FLAG_BACKUP_SEMANTICS);
  if (EC)
    return EC;

  EC = realPathFromHandle(File, RealPath);
  ::CloseHandle(File);
  return EC;
}

std::error_code openFileForRead(const Twine &Name, int &ResultFD,
                                OpenFlags Flags,
                                SmallVectorImpl<char> *RealPath) {
  sandbox::violationIfEnabled();

  Expected<HANDLE> NativeFile = openNativeFileForRead(Name, Flags, RealPath);
  return nativeFileToFd(std::move(NativeFile), ResultFD, OF_None);
}

Expected<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags,
                                       SmallVectorImpl<char> *RealPath) {
  sandbox::violationIfEnabled();

  Expected<file_t> Result =
      openNativeFile(Name, CD_OpenExisting, FA_Read, Flags);

  // Fetch the real name of the file, if the user asked
  if (Result && RealPath)
    realPathFromHandle(*Result, *RealPath);

  return Result;
}

file_t convertFDToNativeFile(int FD) {
  return reinterpret_cast<HANDLE>(::_get_osfhandle(FD));
}

file_t getStdinHandle() { return ::GetStdHandle(STD_INPUT_HANDLE); }
file_t getStdoutHandle() { return ::GetStdHandle(STD_OUTPUT_HANDLE); }
file_t getStderrHandle() { return ::GetStdHandle(STD_ERROR_HANDLE); }

static Expected<size_t> readNativeFileImpl(file_t FileHandle,
                                           MutableArrayRef<char> Buf,
                                           OVERLAPPED *Overlap) {
  // ReadFile can only read 2GB at a time. The caller should check the number of
  // bytes and read in a loop until termination.
  DWORD BytesToRead =
      std::min(size_t(std::numeric_limits<DWORD>::max()), Buf.size());
  DWORD BytesRead = 0;
  if (::ReadFile(FileHandle, Buf.data(), BytesToRead, &BytesRead, Overlap))
    return BytesRead;
  DWORD Err = ::GetLastError();
  // EOF is not an error.
  if (Err == ERROR_BROKEN_PIPE || Err == ERROR_HANDLE_EOF)
    return BytesRead;
  return errorCodeToError(mapWindowsError(Err));
}

Expected<size_t> readNativeFile(file_t FileHandle, MutableArrayRef<char> Buf) {
  sandbox::violationIfEnabled();

  return readNativeFileImpl(FileHandle, Buf, /*Overlap=*/nullptr);
}

Expected<size_t> readNativeFileSlice(file_t FileHandle,
                                     MutableArrayRef<char> Buf,
                                     uint64_t Offset) {
  sandbox::violationIfEnabled();

  OVERLAPPED Overlapped = {};
  Overlapped.Offset = uint32_t(Offset);
  Overlapped.OffsetHigh = uint32_t(Offset >> 32);
  return readNativeFileImpl(FileHandle, Buf, &Overlapped);
}

std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout,
                            LockKind Kind) {
  DWORD Flags = Kind == LockKind::Exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0;
  Flags |= LOCKFILE_FAIL_IMMEDIATELY;
  OVERLAPPED OV = {};
  file_t File = convertFDToNativeFile(FD);
  auto Start = std::chrono::steady_clock::now();
  auto End = Start + Timeout;
  do {
    if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))
      return std::error_code();
    DWORD Error = ::GetLastError();
    if (Error == ERROR_LOCK_VIOLATION) {
      if (Timeout.count() == 0)
        break;
      ::Sleep(1);
      continue;
    }
    return mapWindowsError(Error);
  } while (std::chrono::steady_clock::now() < End);
  return mapWindowsError(ERROR_LOCK_VIOLATION);
}

std::error_code lockFile(int FD, LockKind Kind) {
  DWORD Flags = Kind == LockKind::Exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0;
  OVERLAPPED OV = {};
  file_t File = convertFDToNativeFile(FD);
  if (::LockFileEx(File, Flags, 0, MAXDWORD, MAXDWORD, &OV))
    return std::error_code();
  DWORD Error = ::GetLastError();
  return mapWindowsError(Error);
}

std::error_code unlockFile(int FD) {
  OVERLAPPED OV = {};
  file_t File = convertFDToNativeFile(FD);
  if (::UnlockFileEx(File, 0, MAXDWORD, MAXDWORD, &OV))
    return std::error_code();
  return mapWindowsError(::GetLastError());
}

std::error_code closeFile(file_t &F) {
  file_t TmpF = F;
  F = kInvalidFile;
  if (!::CloseHandle(TmpF))
    return mapWindowsError(::GetLastError());
  return std::error_code();
}

std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
  SmallString<128> NativePath;
  llvm::sys::path::native(path, NativePath, path::Style::windows_backslash);
  // Convert to utf-16.
  SmallVector<wchar_t, 128> Path16;
  std::error_code EC = widenPath(NativePath, Path16);
  if (EC && !IgnoreErrors)
    return EC;

  // SHFileOperation() accepts a list of paths, and so must be double null-
  // terminated to indicate the end of the list.  The buffer is already null
  // terminated, but since that null character is not considered part of the
  // vector's size, pushing another one will just consume that byte.  So we
  // need to push 2 null terminators.
  Path16.push_back(0);
  Path16.push_back(0);

  HRESULT HR;
  do {
    HR =
        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(HR))
      break;
    llvm::scope_exit Uninitialize([] { CoUninitialize(); });
    IFileOperation *FileOp = NULL;
    HR = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL,
                          IID_PPV_ARGS(&FileOp));
    if (FAILED(HR))
      break;
    llvm::scope_exit FileOpRelease([&FileOp] { FileOp->Release(); });
    HR = FileOp->SetOperationFlags(FOF_NO_UI | FOFX_NOCOPYHOOKS);
    if (FAILED(HR))
      break;
    PIDLIST_ABSOLUTE PIDL = ILCreateFromPathW(Path16.data());
    llvm::scope_exit FreePIDL([&PIDL] { ILFree(PIDL); });
    IShellItem *ShItem = NULL;
    HR = SHCreateItemFromIDList(PIDL, IID_PPV_ARGS(&ShItem));
    if (FAILED(HR))
      break;
    llvm::scope_exit ShItemRelease([&ShItem] { ShItem->Release(); });
    HR = FileOp->DeleteItem(ShItem, NULL);
    if (FAILED(HR))
      break;
    HR = FileOp->PerformOperations();
  } while (false);
  if (FAILED(HR) && !IgnoreErrors)
    return mapWindowsError(HRESULT_CODE(HR));
  return std::error_code();
}

static void expandTildeExpr(SmallVectorImpl<char> &Path) {
  // Path does not begin with a tilde expression.
  if (Path.empty() || Path[0] != '~')
    return;

  StringRef PathStr(Path.begin(), Path.size());
  PathStr = PathStr.drop_front();
  StringRef Expr =
      PathStr.take_until([](char c) { return path::is_separator(c); });

  if (!Expr.empty()) {
    // This is probably a ~username/ expression.  Don't support this on Windows.
    return;
  }

  SmallString<128> HomeDir;
  if (!path::home_directory(HomeDir)) {
    // For some reason we couldn't get the home directory.  Just exit.
    return;
  }

  // Overwrite the first character and insert the rest.
  Path[0] = HomeDir[0];
  Path.insert(Path.begin() + 1, HomeDir.begin() + 1, HomeDir.end());
}

void expand_tilde(const Twine &path, SmallVectorImpl<char> &dest) {
  dest.clear();
  if (path.isTriviallyEmpty())
    return;

  path.toVector(dest);
  expandTildeExpr(dest);

  return;
}

std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest,
                          bool expand_tilde) {
  sandbox::violationIfEnabled();

  dest.clear();
  if (path.isTriviallyEmpty())
    return std::error_code();

  if (expand_tilde) {
    SmallString<128> Storage;
    path.toVector(Storage);
    expandTildeExpr(Storage);
    return real_path(Storage, dest, false);
  }

  if (is_directory(path))
    return directoryRealPath(path, dest);

  int fd;
  if (std::error_code EC =
          llvm::sys::fs::openFileForRead(path, fd, OF_None, &dest))
    return EC;
  ::close(fd);
  return std::error_code();
}

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnested-anon-types"
#endif
// This struct is normally only available in the Windows Driver Kit (WDK)
// headers, not in the standard Windows SDK.
struct LLVM_REPARSE_DATA_BUFFER {
  unsigned long ReparseTag;
  unsigned short ReparseDataLength;
  unsigned short Reserved;
  union {
    struct {
      unsigned short SubstituteNameOffset;
      unsigned short SubstituteNameLength;
      unsigned short PrintNameOffset;
      unsigned short PrintNameLength;
      unsigned long Flags;
      wchar_t PathBuffer[1];
    } SymbolicLinkReparseBuffer;
    struct {
      unsigned short SubstituteNameOffset;
      unsigned short SubstituteNameLength;
      unsigned short PrintNameOffset;
      unsigned short PrintNameLength;
      wchar_t PathBuffer[1];
    } MountPointReparseBuffer;
    struct {
      unsigned char DataBuffer[1];
    } GenericReparseBuffer;
  };
};
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

std::error_code readlink(const Twine &path, SmallVectorImpl<char> &dest) {
  dest.clear();

  SmallVector<wchar_t, 128> PathUTF16;
  if (std::error_code EC = widenPath(path, PathUTF16))
    return EC;

  // Open the symlink without following it.
  ScopedFileHandle H(::CreateFileW(
      c_str(PathUTF16), FILE_READ_ATTRIBUTES,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
      NULL));
  if (!H)
    return mapWindowsError(::GetLastError());

  // Read the reparse point data.
  union {
    LLVM_REPARSE_DATA_BUFFER RDB;
    char Buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
  };
  DWORD BytesReturned;
  if (!::DeviceIoControl(H, FSCTL_GET_REPARSE_POINT, NULL, 0, &RDB,
                         sizeof(Buffer), &BytesReturned, NULL)) {
    DWORD Err = ::GetLastError();
    if (Err == ERROR_NOT_A_REPARSE_POINT)
      return make_error_code(errc::invalid_argument);
    return mapWindowsError(Err);
  }

  if (RDB.ReparseTag != IO_REPARSE_TAG_SYMLINK)
    return make_error_code(errc::invalid_argument);

  const auto &SLB = RDB.SymbolicLinkReparseBuffer;
  size_t PathBufOffset =
      offsetof(LLVM_REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer);

  // Prefer PrintName (user-friendly, e.g. "C:\foo") over SubstituteName
  // (NT-internal, e.g. "\??\C:\foo").
  USHORT NameOffset, NameLength;
  if (SLB.PrintNameLength != 0) {
    NameOffset = SLB.PrintNameOffset;
    NameLength = SLB.PrintNameLength;
  } else {
    NameOffset = SLB.SubstituteNameOffset;
    NameLength = SLB.SubstituteNameLength;
  }

  // Validate that the returned data is large enough to contain the name.
  if (PathBufOffset + NameOffset + NameLength > BytesReturned)
    return make_error_code(errc::invalid_argument);

  const wchar_t *Target = SLB.PathBuffer + NameOffset / sizeof(wchar_t);
  USHORT TargetLen = NameLength / sizeof(wchar_t);

  if (std::error_code EC = UTF16ToUTF8(Target, TargetLen, dest))
    return EC;

  return std::error_code();
}

} // end namespace fs

namespace path {
static bool getKnownFolderPath(KNOWNFOLDERID folderId,
                               SmallVectorImpl<char> &result) {
  wchar_t *path = nullptr;
  if (::SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, nullptr, &path) != S_OK)
    return false;

  bool ok = !UTF16ToUTF8(path, ::wcslen(path), result);
  ::CoTaskMemFree(path);
  if (ok)
    llvm::sys::path::make_preferred(result);
  return ok;
}

bool home_directory(SmallVectorImpl<char> &result) {
  return getKnownFolderPath(FOLDERID_Profile, result);
}

bool user_config_directory(SmallVectorImpl<char> &result) {
  // Either local or roaming appdata may be suitable in some cases, depending
  // on the data. Local is more conservative, Roaming may not always be correct.
  return getKnownFolderPath(FOLDERID_LocalAppData, result);
}

bool cache_directory(SmallVectorImpl<char> &result) {
  return getKnownFolderPath(FOLDERID_LocalAppData, result);
}

static bool getTempDirEnvVar(const wchar_t *Var, SmallVectorImpl<char> &Res) {
  SmallVector<wchar_t, 1024> Buf;
  size_t Size = 1024;
  do {
    Buf.resize_for_overwrite(Size);
    Size = GetEnvironmentVariableW(Var, Buf.data(), Buf.size());
    if (Size == 0)
      return false;

    // Try again with larger buffer.
  } while (Size > Buf.size());
  Buf.truncate(Size);

  return !windows::UTF16ToUTF8(Buf.data(), Size, Res);
}

static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
  const wchar_t *EnvironmentVariables[] = {L"TMP", L"TEMP", L"USERPROFILE"};
  for (auto *Env : EnvironmentVariables) {
    if (getTempDirEnvVar(Env, Res))
      return true;
  }
  return false;
}

void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
  (void)ErasedOnReboot;
  Result.clear();

  // Check whether the temporary directory is specified by an environment var.
  // This matches GetTempPath logic to some degree. GetTempPath is not used
  // directly as it cannot handle evn var longer than 130 chars on Windows 7
  // (fixed on Windows 8).
  if (getTempDirEnvVar(Result)) {
    assert(!Result.empty() && "Unexpected empty path");
    native(Result); // Some Unix-like shells use Unix path separator in $TMP.
    fs::make_absolute(Result); // Make it absolute if not already.
    return;
  }

  // Fall back to a system default.
  const char *DefaultResult = "C:\\Temp";
  Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
  llvm::sys::path::make_preferred(Result);
}
} // end namespace path

namespace windows {
std::error_code CodePageToUTF16(unsigned codepage, llvm::StringRef original,
                                llvm::SmallVectorImpl<wchar_t> &utf16) {
  if (!original.empty()) {
    int len =
        ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.begin(),
                              original.size(), utf16.begin(), 0);

    if (len == 0) {
      return mapWindowsError(::GetLastError());
    }

    utf16.reserve(len + 1);
    utf16.resize_for_overwrite(len);

    len =
        ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.begin(),
                              original.size(), utf16.begin(), utf16.size());

    if (len == 0) {
      return mapWindowsError(::GetLastError());
    }
  }

  // Make utf16 null terminated.
  utf16.push_back(0);
  utf16.pop_back();

  return std::error_code();
}

std::error_code UTF8ToUTF16(llvm::StringRef utf8,
                            llvm::SmallVectorImpl<wchar_t> &utf16) {
  return CodePageToUTF16(CP_UTF8, utf8, utf16);
}

std::error_code CurCPToUTF16(llvm::StringRef curcp,
                             llvm::SmallVectorImpl<wchar_t> &utf16) {
  return CodePageToUTF16(CP_ACP, curcp, utf16);
}

static std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
                                       size_t utf16_len,
                                       llvm::SmallVectorImpl<char> &converted) {
  if (utf16_len) {
    // Get length.
    int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len,
                                    converted.begin(), 0, NULL, NULL);

    if (len == 0) {
      return mapWindowsError(::GetLastError());
    }

    converted.reserve(len + 1);
    converted.resize_for_overwrite(len);

    // Now do the actual conversion.
    len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.data(),
                                converted.size(), NULL, NULL);

    if (len == 0) {
      return mapWindowsError(::GetLastError());
    }
  }

  // Make the new string null terminated.
  converted.push_back(0);
  converted.pop_back();

  return std::error_code();
}

std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
                            llvm::SmallVectorImpl<char> &utf8) {
  return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
}

std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
                             llvm::SmallVectorImpl<char> &curcp) {
  return UTF16ToCodePage(CP_ACP, utf16, utf16_len, curcp);
}

} // end namespace windows
} // end namespace sys
} // end namespace llvm
