Home | History | Annotate | Download | only in Windows
      1 //===- llvm/Support/Windows/Path.inc - Windows Path Impl --------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the Windows specific implementation of the Path API.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 //===----------------------------------------------------------------------===//
     15 //=== WARNING: Implementation here must contain only generic Windows code that
     16 //===          is guaranteed to work on *all* Windows variants.
     17 //===----------------------------------------------------------------------===//
     18 
     19 #include "llvm/ADT/STLExtras.h"
     20 #include "llvm/Support/ConvertUTF.h"
     21 #include "llvm/Support/WindowsError.h"
     22 #include <fcntl.h>
     23 #include <io.h>
     24 #include <sys/stat.h>
     25 #include <sys/types.h>
     26 
     27 // These two headers must be included last, and make sure shlobj is required
     28 // after Windows.h to make sure it picks up our definition of _WIN32_WINNT
     29 #include "WindowsSupport.h"
     30 #include <shellapi.h>
     31 #include <shlobj.h>
     32 
     33 #undef max
     34 
     35 // MinGW doesn't define this.
     36 #ifndef _ERRNO_T_DEFINED
     37 #define _ERRNO_T_DEFINED
     38 typedef int errno_t;
     39 #endif
     40 
     41 #ifdef _MSC_VER
     42 # pragma comment(lib, "advapi32.lib")  // This provides CryptAcquireContextW.
     43 # pragma comment(lib, "ole32.lib")     // This provides CoTaskMemFree
     44 #endif
     45 
     46 using namespace llvm;
     47 
     48 using llvm::sys::windows::UTF8ToUTF16;
     49 using llvm::sys::windows::CurCPToUTF16;
     50 using llvm::sys::windows::UTF16ToUTF8;
     51 using llvm::sys::path::widenPath;
     52 
     53 static bool is_separator(const wchar_t value) {
     54   switch (value) {
     55   case L'\\':
     56   case L'/':
     57     return true;
     58   default:
     59     return false;
     60   }
     61 }
     62 
     63 namespace llvm {
     64 namespace sys  {
     65 namespace path {
     66 
     67 // Convert a UTF-8 path to UTF-16.  Also, if the absolute equivalent of the
     68 // path is longer than CreateDirectory can tolerate, make it absolute and
     69 // prefixed by '\\?\'.
     70 std::error_code widenPath(const Twine &Path8,
     71                           SmallVectorImpl<wchar_t> &Path16) {
     72   const size_t MaxDirLen = MAX_PATH - 12; // Must leave room for 8.3 filename.
     73 
     74   // Several operations would convert Path8 to SmallString; more efficient to
     75   // do it once up front.
     76   SmallString<128> Path8Str;
     77   Path8.toVector(Path8Str);
     78 
     79   // If we made this path absolute, how much longer would it get?
     80   size_t CurPathLen;
     81   if (llvm::sys::path::is_absolute(Twine(Path8Str)))
     82     CurPathLen = 0; // No contribution from current_path needed.
     83   else {
     84     CurPathLen = ::GetCurrentDirectoryW(0, NULL);
     85     if (CurPathLen == 0)
     86       return mapWindowsError(::GetLastError());
     87   }
     88 
     89   // Would the absolute path be longer than our limit?
     90   if ((Path8Str.size() + CurPathLen) >= MaxDirLen &&
     91       !Path8Str.startswith("\\\\?\\")) {
     92     SmallString<2*MAX_PATH> FullPath("\\\\?\\");
     93     if (CurPathLen) {
     94       SmallString<80> CurPath;
     95       if (std::error_code EC = llvm::sys::fs::current_path(CurPath))
     96         return EC;
     97       FullPath.append(CurPath);
     98     }
     99     // Traverse the requested path, canonicalizing . and .. (because the \\?\
    100     // prefix is documented to treat them as real components).  Ignore
    101     // separators, which can be returned from the iterator if the path has a
    102     // drive name.  We don't need to call native() on the result since append()
    103     // always attaches preferred_separator.
    104     for (llvm::sys::path::const_iterator I = llvm::sys::path::begin(Path8Str),
    105                                          E = llvm::sys::path::end(Path8Str);
    106                                          I != E; ++I) {
    107       if (I->size() == 1 && is_separator((*I)[0]))
    108         continue;
    109       if (I->size() == 1 && *I == ".")
    110         continue;
    111       if (I->size() == 2 && *I == "..")
    112         llvm::sys::path::remove_filename(FullPath);
    113       else
    114         llvm::sys::path::append(FullPath, *I);
    115     }
    116     return UTF8ToUTF16(FullPath, Path16);
    117   }
    118 
    119   // Just use the caller's original path.
    120   return UTF8ToUTF16(Path8Str, Path16);
    121 }
    122 } // end namespace path
    123 
    124 namespace fs {
    125 
    126 const file_t kInvalidFile = INVALID_HANDLE_VALUE;
    127 
    128 std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
    129   SmallVector<wchar_t, MAX_PATH> PathName;
    130   DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.capacity());
    131 
    132   // A zero return value indicates a failure other than insufficient space.
    133   if (Size == 0)
    134     return "";
    135 
    136   // Insufficient space is determined by a return value equal to the size of
    137   // the buffer passed in.
    138   if (Size == PathName.capacity())
    139     return "";
    140 
    141   // On success, GetModuleFileNameW returns the number of characters written to
    142   // the buffer not including the NULL terminator.
    143   PathName.set_size(Size);
    144 
    145   // Convert the result from UTF-16 to UTF-8.
    146   SmallVector<char, MAX_PATH> PathNameUTF8;
    147   if (UTF16ToUTF8(PathName.data(), PathName.size(), PathNameUTF8))
    148     return "";
    149 
    150   return std::string(PathNameUTF8.data());
    151 }
    152 
    153 UniqueID file_status::getUniqueID() const {
    154   // The file is uniquely identified by the volume serial number along
    155   // with the 64-bit file identifier.
    156   uint64_t FileID = (static_cast<uint64_t>(FileIndexHigh) << 32ULL) |
    157                     static_cast<uint64_t>(FileIndexLow);
    158 
    159   return UniqueID(VolumeSerialNumber, FileID);
    160 }
    161 
    162 ErrorOr<space_info> disk_space(const Twine &Path) {
    163   ULARGE_INTEGER Avail, Total, Free;
    164   if (!::GetDiskFreeSpaceExA(Path.str().c_str(), &Avail, &Total, &Free))
    165     return mapWindowsError(::GetLastError());
    166   space_info SpaceInfo;
    167   SpaceInfo.capacity =
    168       (static_cast<uint64_t>(Total.HighPart) << 32) + Total.LowPart;
    169   SpaceInfo.free = (static_cast<uint64_t>(Free.HighPart) << 32) + Free.LowPart;
    170   SpaceInfo.available =
    171       (static_cast<uint64_t>(Avail.HighPart) << 32) + Avail.LowPart;
    172   return SpaceInfo;
    173 }
    174 
    175 TimePoint<> basic_file_status::getLastAccessedTime() const {
    176   FILETIME Time;
    177   Time.dwLowDateTime = LastAccessedTimeLow;
    178   Time.dwHighDateTime = LastAccessedTimeHigh;
    179   return toTimePoint(Time);
    180 }
    181 
    182 TimePoint<> basic_file_status::getLastModificationTime() const {
    183   FILETIME Time;
    184   Time.dwLowDateTime = LastWriteTimeLow;
    185   Time.dwHighDateTime = LastWriteTimeHigh;
    186   return toTimePoint(Time);
    187 }
    188 
    189 uint32_t file_status::getLinkCount() const {
    190   return NumLinks;
    191 }
    192 
    193 std::error_code current_path(SmallVectorImpl<char> &result) {
    194   SmallVector<wchar_t, MAX_PATH> cur_path;
    195   DWORD len = MAX_PATH;
    196 
    197   do {
    198     cur_path.reserve(len);
    199     len = ::GetCurrentDirectoryW(cur_path.capacity(), cur_path.data());
    200 
    201     // A zero return value indicates a failure other than insufficient space.
    202     if (len == 0)
    203       return mapWindowsError(::GetLastError());
    204 
    205     // If there's insufficient space, the len returned is larger than the len
    206     // given.
    207   } while (len > cur_path.capacity());
    208 
    209   // On success, GetCurrentDirectoryW returns the number of characters not
    210   // including the null-terminator.
    211   cur_path.set_size(len);
    212   return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);
    213 }
    214 
    215 std::error_code set_current_path(const Twine &path) {
    216   // Convert to utf-16.
    217   SmallVector<wchar_t, 128> wide_path;
    218   if (std::error_code ec = widenPath(path, wide_path))
    219     return ec;
    220 
    221   if (!::SetCurrentDirectoryW(wide_path.begin()))
    222     return mapWindowsError(::GetLastError());
    223 
    224   return std::error_code();
    225 }
    226 
    227 std::error_code create_directory(const Twine &path, bool IgnoreExisting,
    228                                  perms Perms) {
    229   SmallVector<wchar_t, 128> path_utf16;
    230 
    231   if (std::error_code ec = widenPath(path, path_utf16))
    232     return ec;
    233 
    234   if (!::CreateDirectoryW(path_utf16.begin(), NULL)) {
    235     DWORD LastError = ::GetLastError();
    236     if (LastError != ERROR_ALREADY_EXISTS || !IgnoreExisting)
    237       return mapWindowsError(LastError);
    238   }
    239 
    240   return std::error_code();
    241 }
    242 
    243 // We can't use symbolic links for windows.
    244 std::error_code create_link(const Twine &to, const Twine &from) {
    245   // Convert to utf-16.
    246   SmallVector<wchar_t, 128> wide_from;
    247   SmallVector<wchar_t, 128> wide_to;
    248   if (std::error_code ec = widenPath(from, wide_from))
    249     return ec;
    250   if (std::error_code ec = widenPath(to, wide_to))
    251     return ec;
    252 
    253   if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL))
    254     return mapWindowsError(::GetLastError());
    255 
    256   return std::error_code();
    257 }
    258 
    259 std::error_code create_hard_link(const Twine &to, const Twine &from) {
    260   return create_link(to, from);
    261 }
    262 
    263 std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
    264   SmallVector<wchar_t, 128> path_utf16;
    265 
    266   if (std::error_code ec = widenPath(path, path_utf16))
    267     return ec;
    268 
    269   // We don't know whether this is a file or a directory, and remove() can
    270   // accept both. The usual way to delete a file or directory is to use one of
    271   // the DeleteFile or RemoveDirectory functions, but that requires you to know
    272   // which one it is. We could stat() the file to determine that, but that would
    273   // cost us additional system calls, which can be slow in a directory
    274   // containing a large number of files. So instead we call CreateFile directly.
    275   // The important part is the FILE_FLAG_DELETE_ON_CLOSE flag, which causes the
    276   // file to be deleted once it is closed. We also use the flags
    277   // FILE_FLAG_BACKUP_SEMANTICS (which allows us to open directories), and
    278   // FILE_FLAG_OPEN_REPARSE_POINT (don't follow symlinks).
    279   ScopedFileHandle h(::CreateFileW(
    280       c_str(path_utf16), DELETE,
    281       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
    282       OPEN_EXISTING,
    283       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS |
    284           FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE,
    285       NULL));
    286   if (!h) {
    287     std::error_code EC = mapWindowsError(::GetLastError());
    288     if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
    289       return EC;
    290   }
    291 
    292   return std::error_code();
    293 }
    294 
    295 static std::error_code is_local_internal(SmallVectorImpl<wchar_t> &Path,
    296                                          bool &Result) {
    297   SmallVector<wchar_t, 128> VolumePath;
    298   size_t Len = 128;
    299   while (true) {
    300     VolumePath.resize(Len);
    301     BOOL Success =
    302         ::GetVolumePathNameW(Path.data(), VolumePath.data(), VolumePath.size());
    303 
    304     if (Success)
    305       break;
    306 
    307     DWORD Err = ::GetLastError();
    308     if (Err != ERROR_INSUFFICIENT_BUFFER)
    309       return mapWindowsError(Err);
    310 
    311     Len *= 2;
    312   }
    313   // If the output buffer has exactly enough space for the path name, but not
    314   // the null terminator, it will leave the output unterminated.  Push a null
    315   // terminator onto the end to ensure that this never happens.
    316   VolumePath.push_back(L'\0');
    317   VolumePath.set_size(wcslen(VolumePath.data()));
    318   const wchar_t *P = VolumePath.data();
    319 
    320   UINT Type = ::GetDriveTypeW(P);
    321   switch (Type) {
    322   case DRIVE_FIXED:
    323     Result = true;
    324     return std::error_code();
    325   case DRIVE_REMOTE:
    326   case DRIVE_CDROM:
    327   case DRIVE_RAMDISK:
    328   case DRIVE_REMOVABLE:
    329     Result = false;
    330     return std::error_code();
    331   default:
    332     return make_error_code(errc::no_such_file_or_directory);
    333   }
    334   llvm_unreachable("Unreachable!");
    335 }
    336 
    337 std::error_code is_local(const Twine &path, bool &result) {
    338   if (!llvm::sys::fs::exists(path) || !llvm::sys::path::has_root_path(path))
    339     return make_error_code(errc::no_such_file_or_directory);
    340 
    341   SmallString<128> Storage;
    342   StringRef P = path.toStringRef(Storage);
    343 
    344   // Convert to utf-16.
    345   SmallVector<wchar_t, 128> WidePath;
    346   if (std::error_code ec = widenPath(P, WidePath))
    347     return ec;
    348   return is_local_internal(WidePath, result);
    349 }
    350 
    351 static std::error_code realPathFromHandle(HANDLE H,
    352                                           SmallVectorImpl<wchar_t> &Buffer) {
    353   DWORD CountChars = ::GetFinalPathNameByHandleW(
    354       H, Buffer.begin(), Buffer.capacity() - 1, FILE_NAME_NORMALIZED);
    355   if (CountChars > Buffer.capacity()) {
    356     // The buffer wasn't big enough, try again.  In this case the return value
    357     // *does* indicate the size of the null terminator.
    358     Buffer.reserve(CountChars);
    359     CountChars = ::GetFinalPathNameByHandleW(
    360         H, Buffer.data(), Buffer.capacity() - 1, FILE_NAME_NORMALIZED);
    361   }
    362   if (CountChars == 0)
    363     return mapWindowsError(GetLastError());
    364   Buffer.set_size(CountChars);
    365   return std::error_code();
    366 }
    367 
    368 static std::error_code realPathFromHandle(HANDLE H,
    369                                           SmallVectorImpl<char> &RealPath) {
    370   RealPath.clear();
    371   SmallVector<wchar_t, MAX_PATH> Buffer;
    372   if (std::error_code EC = realPathFromHandle(H, Buffer))
    373     return EC;
    374 
    375   const wchar_t *Data = Buffer.data();
    376   DWORD CountChars = Buffer.size();
    377   if (CountChars >= 4) {
    378     if (0 == ::memcmp(Data, L"\\\\?\\", 8)) {
    379       CountChars -= 4;
    380       Data += 4;
    381     }
    382   }
    383 
    384   // Convert the result from UTF-16 to UTF-8.
    385   return UTF16ToUTF8(Data, CountChars, RealPath);
    386 }
    387 
    388 std::error_code is_local(int FD, bool &Result) {
    389   SmallVector<wchar_t, 128> FinalPath;
    390   HANDLE Handle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
    391 
    392   if (std::error_code EC = realPathFromHandle(Handle, FinalPath))
    393     return EC;
    394 
    395   return is_local_internal(FinalPath, Result);
    396 }
    397 
    398 static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) {
    399   FILE_DISPOSITION_INFO Disposition;
    400   Disposition.DeleteFile = Delete;
    401   if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
    402                                   sizeof(Disposition)))
    403     return mapWindowsError(::GetLastError());
    404   return std::error_code();
    405 }
    406 
    407 static std::error_code rename_internal(HANDLE FromHandle, const Twine &To,
    408                                        bool ReplaceIfExists) {
    409   SmallVector<wchar_t, 0> ToWide;
    410   if (auto EC = widenPath(To, ToWide))
    411     return EC;
    412 
    413   std::vector<char> RenameInfoBuf(sizeof(FILE_RENAME_INFO) - sizeof(wchar_t) +
    414                                   (ToWide.size() * sizeof(wchar_t)));
    415   FILE_RENAME_INFO &RenameInfo =
    416       *reinterpret_cast<FILE_RENAME_INFO *>(RenameInfoBuf.data());
    417   RenameInfo.ReplaceIfExists = ReplaceIfExists;
    418   RenameInfo.RootDirectory = 0;
    419   RenameInfo.FileNameLength = ToWide.size();
    420   std::copy(ToWide.begin(), ToWide.end(), &RenameInfo.FileName[0]);
    421 
    422   SetLastError(ERROR_SUCCESS);
    423   if (!SetFileInformationByHandle(FromHandle, FileRenameInfo, &RenameInfo,
    424                                   RenameInfoBuf.size())) {
    425     unsigned Error = GetLastError();
    426     if (Error == ERROR_SUCCESS)
    427       Error = ERROR_CALL_NOT_IMPLEMENTED; // Wine doesn't always set error code.
    428     return mapWindowsError(Error);
    429   }
    430 
    431   return std::error_code();
    432 }
    433 
    434 static std::error_code rename_handle(HANDLE FromHandle, const Twine &To) {
    435   SmallVector<wchar_t, 128> WideTo;
    436   if (std::error_code EC = widenPath(To, WideTo))
    437     return EC;
    438 
    439   // We normally expect this loop to succeed after a few iterations. If it
    440   // requires more than 200 tries, it's more likely that the failures are due to
    441   // a true error, so stop trying.
    442   for (unsigned Retry = 0; Retry != 200; ++Retry) {
    443     auto EC = rename_internal(FromHandle, To, true);
    444 
    445     if (EC ==
    446         std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category())) {
    447       // Wine doesn't support SetFileInformationByHandle in rename_internal.
    448       // Fall back to MoveFileEx.
    449       SmallVector<wchar_t, MAX_PATH> WideFrom;
    450       if (std::error_code EC2 = realPathFromHandle(FromHandle, WideFrom))
    451         return EC2;
    452       if (::MoveFileExW(WideFrom.begin(), WideTo.begin(),
    453                         MOVEFILE_REPLACE_EXISTING))
    454         return std::error_code();
    455       return mapWindowsError(GetLastError());
    456     }
    457 
    458     if (!EC || EC != errc::permission_denied)
    459       return EC;
    460 
    461     // The destination file probably exists and is currently open in another
    462     // process, either because the file was opened without FILE_SHARE_DELETE or
    463     // it is mapped into memory (e.g. using MemoryBuffer). Rename it in order to
    464     // move it out of the way of the source file. Use FILE_FLAG_DELETE_ON_CLOSE
    465     // to arrange for the destination file to be deleted when the other process
    466     // closes it.
    467     ScopedFileHandle ToHandle(
    468         ::CreateFileW(WideTo.begin(), GENERIC_READ | DELETE,
    469                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    470                       NULL, OPEN_EXISTING,
    471                       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL));
    472     if (!ToHandle) {
    473       auto EC = mapWindowsError(GetLastError());
    474       // Another process might have raced with us and moved the existing file
    475       // out of the way before we had a chance to open it. If that happens, try
    476       // to rename the source file again.
    477       if (EC == errc::no_such_file_or_directory)
    478         continue;
    479       return EC;
    480     }
    481 
    482     BY_HANDLE_FILE_INFORMATION FI;
    483     if (!GetFileInformationByHandle(ToHandle, &FI))
    484       return mapWindowsError(GetLastError());
    485 
    486     // Try to find a unique new name for the destination file.
    487     for (unsigned UniqueId = 0; UniqueId != 200; ++UniqueId) {
    488       std::string TmpFilename = (To + ".tmp" + utostr(UniqueId)).str();
    489       if (auto EC = rename_internal(ToHandle, TmpFilename, false)) {
    490         if (EC == errc::file_exists || EC == errc::permission_denied) {
    491           // Again, another process might have raced with us and moved the file
    492           // before we could move it. Check whether this is the case, as it
    493           // might have caused the permission denied error. If that was the
    494           // case, we don't need to move it ourselves.
    495           ScopedFileHandle ToHandle2(::CreateFileW(
    496               WideTo.begin(), 0,
    497               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
    498               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
    499           if (!ToHandle2) {
    500             auto EC = mapWindowsError(GetLastError());
    501             if (EC == errc::no_such_file_or_directory)
    502               break;
    503             return EC;
    504           }
    505           BY_HANDLE_FILE_INFORMATION FI2;
    506           if (!GetFileInformationByHandle(ToHandle2, &FI2))
    507             return mapWindowsError(GetLastError());
    508           if (FI.nFileIndexHigh != FI2.nFileIndexHigh ||
    509               FI.nFileIndexLow != FI2.nFileIndexLow ||
    510               FI.dwVolumeSerialNumber != FI2.dwVolumeSerialNumber)
    511             break;
    512           continue;
    513         }
    514         return EC;
    515       }
    516       break;
    517     }
    518 
    519     // Okay, the old destination file has probably been moved out of the way at
    520     // this point, so try to rename the source file again. Still, another
    521     // process might have raced with us to create and open the destination
    522     // file, so we need to keep doing this until we succeed.
    523   }
    524 
    525   // The most likely root cause.
    526   return errc::permission_denied;
    527 }
    528 
    529 static std::error_code rename_fd(int FromFD, const Twine &To) {
    530   HANDLE FromHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FromFD));
    531   return rename_handle(FromHandle, To);
    532 }
    533 
    534 std::error_code rename(const Twine &From, const Twine &To) {
    535   // Convert to utf-16.
    536   SmallVector<wchar_t, 128> WideFrom;
    537   if (std::error_code EC = widenPath(From, WideFrom))
    538     return EC;
    539 
    540   ScopedFileHandle FromHandle;
    541   // Retry this a few times to defeat badly behaved file system scanners.
    542   for (unsigned Retry = 0; Retry != 200; ++Retry) {
    543     if (Retry != 0)
    544       ::Sleep(10);
    545     FromHandle =
    546         ::CreateFileW(WideFrom.begin(), GENERIC_READ | DELETE,
    547                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    548                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    549     if (FromHandle)
    550       break;
    551   }
    552   if (!FromHandle)
    553     return mapWindowsError(GetLastError());
    554 
    555   return rename_handle(FromHandle, To);
    556 }
    557 
    558 std::error_code resize_file(int FD, uint64_t Size) {
    559 #ifdef HAVE__CHSIZE_S
    560   errno_t error = ::_chsize_s(FD, Size);
    561 #else
    562   errno_t error = ::_chsize(FD, Size);
    563 #endif
    564   return std::error_code(error, std::generic_category());
    565 }
    566 
    567 std::error_code access(const Twine &Path, AccessMode Mode) {
    568   SmallVector<wchar_t, 128> PathUtf16;
    569 
    570   if (std::error_code EC = widenPath(Path, PathUtf16))
    571     return EC;
    572 
    573   DWORD Attributes = ::GetFileAttributesW(PathUtf16.begin());
    574 
    575   if (Attributes == INVALID_FILE_ATTRIBUTES) {
    576     // See if the file didn't actually exist.
    577     DWORD LastError = ::GetLastError();
    578     if (LastError != ERROR_FILE_NOT_FOUND &&
    579         LastError != ERROR_PATH_NOT_FOUND)
    580       return mapWindowsError(LastError);
    581     return errc::no_such_file_or_directory;
    582   }
    583 
    584   if (Mode == AccessMode::Write && (Attributes & FILE_ATTRIBUTE_READONLY))
    585     return errc::permission_denied;
    586 
    587   return std::error_code();
    588 }
    589 
    590 bool can_execute(const Twine &Path) {
    591   return !access(Path, AccessMode::Execute) ||
    592          !access(Path + ".exe", AccessMode::Execute);
    593 }
    594 
    595 bool equivalent(file_status A, file_status B) {
    596   assert(status_known(A) && status_known(B));
    597   return A.FileIndexHigh         == B.FileIndexHigh &&
    598          A.FileIndexLow          == B.FileIndexLow &&
    599          A.FileSizeHigh          == B.FileSizeHigh &&
    600          A.FileSizeLow           == B.FileSizeLow &&
    601          A.LastAccessedTimeHigh  == B.LastAccessedTimeHigh &&
    602          A.LastAccessedTimeLow   == B.LastAccessedTimeLow &&
    603          A.LastWriteTimeHigh     == B.LastWriteTimeHigh &&
    604          A.LastWriteTimeLow      == B.LastWriteTimeLow &&
    605          A.VolumeSerialNumber    == B.VolumeSerialNumber;
    606 }
    607 
    608 std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
    609   file_status fsA, fsB;
    610   if (std::error_code ec = status(A, fsA))
    611     return ec;
    612   if (std::error_code ec = status(B, fsB))
    613     return ec;
    614   result = equivalent(fsA, fsB);
    615   return std::error_code();
    616 }
    617 
    618 static bool isReservedName(StringRef path) {
    619   // This list of reserved names comes from MSDN, at:
    620   // http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
    621   static const char *const sReservedNames[] = { "nul", "con", "prn", "aux",
    622                                                 "com1", "com2", "com3", "com4",
    623                                                 "com5", "com6", "com7", "com8",
    624                                                 "com9", "lpt1", "lpt2", "lpt3",
    625                                                 "lpt4", "lpt5", "lpt6", "lpt7",
    626                                                 "lpt8", "lpt9" };
    627 
    628   // First, check to see if this is a device namespace, which always
    629   // starts with \\.\, since device namespaces are not legal file paths.
    630   if (path.startswith("\\\\.\\"))
    631     return true;
    632 
    633   // Then compare against the list of ancient reserved names.
    634   for (size_t i = 0; i < array_lengthof(sReservedNames); ++i) {
    635     if (path.equals_lower(sReservedNames[i]))
    636       return true;
    637   }
    638 
    639   // The path isn't what we consider reserved.
    640   return false;
    641 }
    642 
    643 static file_type file_type_from_attrs(DWORD Attrs) {
    644   return (Attrs & FILE_ATTRIBUTE_DIRECTORY) ? file_type::directory_file
    645                                             : file_type::regular_file;
    646 }
    647 
    648 static perms perms_from_attrs(DWORD Attrs) {
    649   return (Attrs & FILE_ATTRIBUTE_READONLY) ? (all_read | all_exe) : all_all;
    650 }
    651 
    652 static std::error_code getStatus(HANDLE FileHandle, file_status &Result) {
    653   if (FileHandle == INVALID_HANDLE_VALUE)
    654     goto handle_status_error;
    655 
    656   switch (::GetFileType(FileHandle)) {
    657   default:
    658     llvm_unreachable("Don't know anything about this file type");
    659   case FILE_TYPE_UNKNOWN: {
    660     DWORD Err = ::GetLastError();
    661     if (Err != NO_ERROR)
    662       return mapWindowsError(Err);
    663     Result = file_status(file_type::type_unknown);
    664     return std::error_code();
    665   }
    666   case FILE_TYPE_DISK:
    667     break;
    668   case FILE_TYPE_CHAR:
    669     Result = file_status(file_type::character_file);
    670     return std::error_code();
    671   case FILE_TYPE_PIPE:
    672     Result = file_status(file_type::fifo_file);
    673     return std::error_code();
    674   }
    675 
    676   BY_HANDLE_FILE_INFORMATION Info;
    677   if (!::GetFileInformationByHandle(FileHandle, &Info))
    678     goto handle_status_error;
    679 
    680   Result = file_status(
    681       file_type_from_attrs(Info.dwFileAttributes),
    682       perms_from_attrs(Info.dwFileAttributes), Info.nNumberOfLinks,
    683       Info.ftLastAccessTime.dwHighDateTime, Info.ftLastAccessTime.dwLowDateTime,
    684       Info.ftLastWriteTime.dwHighDateTime, Info.ftLastWriteTime.dwLowDateTime,
    685       Info.dwVolumeSerialNumber, Info.nFileSizeHigh, Info.nFileSizeLow,
    686       Info.nFileIndexHigh, Info.nFileIndexLow);
    687   return std::error_code();
    688 
    689 handle_status_error:
    690   DWORD LastError = ::GetLastError();
    691   if (LastError == ERROR_FILE_NOT_FOUND ||
    692       LastError == ERROR_PATH_NOT_FOUND)
    693     Result = file_status(file_type::file_not_found);
    694   else if (LastError == ERROR_SHARING_VIOLATION)
    695     Result = file_status(file_type::type_unknown);
    696   else
    697     Result = file_status(file_type::status_error);
    698   return mapWindowsError(LastError);
    699 }
    700 
    701 std::error_code status(const Twine &path, file_status &result, bool Follow) {
    702   SmallString<128> path_storage;
    703   SmallVector<wchar_t, 128> path_utf16;
    704 
    705   StringRef path8 = path.toStringRef(path_storage);
    706   if (isReservedName(path8)) {
    707     result = file_status(file_type::character_file);
    708     return std::error_code();
    709   }
    710 
    711   if (std::error_code ec = widenPath(path8, path_utf16))
    712     return ec;
    713 
    714   DWORD attr = ::GetFileAttributesW(path_utf16.begin());
    715   if (attr == INVALID_FILE_ATTRIBUTES)
    716     return getStatus(INVALID_HANDLE_VALUE, result);
    717 
    718   DWORD Flags = FILE_FLAG_BACKUP_SEMANTICS;
    719   // Handle reparse points.
    720   if (!Follow && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
    721     Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
    722 
    723   ScopedFileHandle h(
    724       ::CreateFileW(path_utf16.begin(), 0, // Attributes only.
    725                     FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
    726                     NULL, OPEN_EXISTING, Flags, 0));
    727   if (!h)
    728     return getStatus(INVALID_HANDLE_VALUE, result);
    729 
    730   return getStatus(h, result);
    731 }
    732 
    733 std::error_code status(int FD, file_status &Result) {
    734   HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
    735   return getStatus(FileHandle, Result);
    736 }
    737 
    738 std::error_code setPermissions(const Twine &Path, perms Permissions) {
    739   SmallVector<wchar_t, 128> PathUTF16;
    740   if (std::error_code EC = widenPath(Path, PathUTF16))
    741     return EC;
    742 
    743   DWORD Attributes = ::GetFileAttributesW(PathUTF16.begin());
    744   if (Attributes == INVALID_FILE_ATTRIBUTES)
    745     return mapWindowsError(GetLastError());
    746 
    747   // There are many Windows file attributes that are not to do with the file
    748   // permissions (e.g. FILE_ATTRIBUTE_HIDDEN). We need to be careful to preserve
    749   // them.
    750   if (Permissions & all_write) {
    751     Attributes &= ~FILE_ATTRIBUTE_READONLY;
    752     if (Attributes == 0)
    753       // FILE_ATTRIBUTE_NORMAL indicates no other attributes are set.
    754       Attributes |= FILE_ATTRIBUTE_NORMAL;
    755   }
    756   else {
    757     Attributes |= FILE_ATTRIBUTE_READONLY;
    758     // FILE_ATTRIBUTE_NORMAL is not compatible with any other attributes, so
    759     // remove it, if it is present.
    760     Attributes &= ~FILE_ATTRIBUTE_NORMAL;
    761   }
    762 
    763   if (!::SetFileAttributesW(PathUTF16.begin(), Attributes))
    764     return mapWindowsError(GetLastError());
    765 
    766   return std::error_code();
    767 }
    768 
    769 std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
    770   FILETIME FT = toFILETIME(Time);
    771   HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
    772   if (!SetFileTime(FileHandle, NULL, &FT, &FT))
    773     return mapWindowsError(::GetLastError());
    774   return std::error_code();
    775 }
    776 
    777 std::error_code mapped_file_region::init(int FD, uint64_t Offset,
    778                                          mapmode Mode) {
    779   this->Mode = Mode;
    780   HANDLE OrigFileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
    781   if (OrigFileHandle == INVALID_HANDLE_VALUE)
    782     return make_error_code(errc::bad_file_descriptor);
    783 
    784   DWORD flprotect;
    785   switch (Mode) {
    786   case readonly:  flprotect = PAGE_READONLY; break;
    787   case readwrite: flprotect = PAGE_READWRITE; break;
    788   case priv:      flprotect = PAGE_WRITECOPY; break;
    789   }
    790 
    791   HANDLE FileMappingHandle =
    792       ::CreateFileMappingW(OrigFileHandle, 0, flprotect,
    793                            Hi_32(Size),
    794                            Lo_32(Size),
    795                            0);
    796   if (FileMappingHandle == NULL) {
    797     std::error_code ec = mapWindowsError(GetLastError());
    798     return ec;
    799   }
    800 
    801   DWORD dwDesiredAccess;
    802   switch (Mode) {
    803   case readonly:  dwDesiredAccess = FILE_MAP_READ; break;
    804   case readwrite: dwDesiredAccess = FILE_MAP_WRITE; break;
    805   case priv:      dwDesiredAccess = FILE_MAP_COPY; break;
    806   }
    807   Mapping = ::MapViewOfFile(FileMappingHandle,
    808                             dwDesiredAccess,
    809                             Offset >> 32,
    810                             Offset & 0xffffffff,
    811                             Size);
    812   if (Mapping == NULL) {
    813     std::error_code ec = mapWindowsError(GetLastError());
    814     ::CloseHandle(FileMappingHandle);
    815     return ec;
    816   }
    817 
    818   if (Size == 0) {
    819     MEMORY_BASIC_INFORMATION mbi;
    820     SIZE_T Result = VirtualQuery(Mapping, &mbi, sizeof(mbi));
    821     if (Result == 0) {
    822       std::error_code ec = mapWindowsError(GetLastError());
    823       ::UnmapViewOfFile(Mapping);
    824       ::CloseHandle(FileMappingHandle);
    825       return ec;
    826     }
    827     Size = mbi.RegionSize;
    828   }
    829 
    830   // Close the file mapping handle, as it's kept alive by the file mapping. But
    831   // neither the file mapping nor the file mapping handle keep the file handle
    832   // alive, so we need to keep a reference to the file in case all other handles
    833   // are closed and the file is deleted, which may cause invalid data to be read
    834   // from the file.
    835   ::CloseHandle(FileMappingHandle);
    836   if (!::DuplicateHandle(::GetCurrentProcess(), OrigFileHandle,
    837                          ::GetCurrentProcess(), &FileHandle, 0, 0,
    838                          DUPLICATE_SAME_ACCESS)) {
    839     std::error_code ec = mapWindowsError(GetLastError());
    840     ::UnmapViewOfFile(Mapping);
    841     return ec;
    842   }
    843 
    844   return std::error_code();
    845 }
    846 
    847 mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length,
    848                                        uint64_t offset, std::error_code &ec)
    849     : Size(length), Mapping() {
    850   ec = init(fd, offset, mode);
    851   if (ec)
    852     Mapping = 0;
    853 }
    854 
    855 mapped_file_region::~mapped_file_region() {
    856   if (Mapping) {
    857     ::UnmapViewOfFile(Mapping);
    858 
    859     if (Mode == mapmode::readwrite) {
    860       // There is a Windows kernel bug, the exact trigger conditions of which
    861       // are not well understood.  When triggered, dirty pages are not properly
    862       // flushed and subsequent process's attempts to read a file can return
    863       // invalid data.  Calling FlushFileBuffers on the write handle is
    864       // sufficient to ensure that this bug is not triggered.
    865       ::FlushFileBuffers(FileHandle);
    866     }
    867 
    868     ::CloseHandle(FileHandle);
    869   }
    870 }
    871 
    872 size_t mapped_file_region::size() const {
    873   assert(Mapping && "Mapping failed but used anyway!");
    874   return Size;
    875 }
    876 
    877 char *mapped_file_region::data() const {
    878   assert(Mapping && "Mapping failed but used anyway!");
    879   return reinterpret_cast<char*>(Mapping);
    880 }
    881 
    882 const char *mapped_file_region::const_data() const {
    883   assert(Mapping && "Mapping failed but used anyway!");
    884   return reinterpret_cast<const char*>(Mapping);
    885 }
    886 
    887 int mapped_file_region::alignment() {
    888   SYSTEM_INFO SysInfo;
    889   ::GetSystemInfo(&SysInfo);
    890   return SysInfo.dwAllocationGranularity;
    891 }
    892 
    893 static basic_file_status status_from_find_data(WIN32_FIND_DATAW *FindData) {
    894   return basic_file_status(file_type_from_attrs(FindData->dwFileAttributes),
    895                            perms_from_attrs(FindData->dwFileAttributes),
    896                            FindData->ftLastAccessTime.dwHighDateTime,
    897                            FindData->ftLastAccessTime.dwLowDateTime,
    898                            FindData->ftLastWriteTime.dwHighDateTime,
    899                            FindData->ftLastWriteTime.dwLowDateTime,
    900                            FindData->nFileSizeHigh, FindData->nFileSizeLow);
    901 }
    902 
    903 std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
    904                                                      StringRef path,
    905                                                      bool follow_symlinks) {
    906   SmallVector<wchar_t, 128> path_utf16;
    907 
    908   if (std::error_code ec = widenPath(path, path_utf16))
    909     return ec;
    910 
    911   // Convert path to the format that Windows is happy with.
    912   if (path_utf16.size() > 0 &&
    913       !is_separator(path_utf16[path.size() - 1]) &&
    914       path_utf16[path.size() - 1] != L':') {
    915     path_utf16.push_back(L'\\');
    916     path_utf16.push_back(L'*');
    917   } else {
    918     path_utf16.push_back(L'*');
    919   }
    920 
    921   //  Get the first directory entry.
    922   WIN32_FIND_DATAW FirstFind;
    923   ScopedFindHandle FindHandle(::FindFirstFileExW(
    924       c_str(path_utf16), FindExInfoBasic, &FirstFind, FindExSearchNameMatch,
    925       NULL, FIND_FIRST_EX_LARGE_FETCH));
    926   if (!FindHandle)
    927     return mapWindowsError(::GetLastError());
    928 
    929   size_t FilenameLen = ::wcslen(FirstFind.cFileName);
    930   while ((FilenameLen == 1 && FirstFind.cFileName[0] == L'.') ||
    931          (FilenameLen == 2 && FirstFind.cFileName[0] == L'.' &&
    932                               FirstFind.cFileName[1] == L'.'))
    933     if (!::FindNextFileW(FindHandle, &FirstFind)) {
    934       DWORD LastError = ::GetLastError();
    935       // Check for end.
    936       if (LastError == ERROR_NO_MORE_FILES)
    937         return detail::directory_iterator_destruct(it);
    938       return mapWindowsError(LastError);
    939     } else
    940       FilenameLen = ::wcslen(FirstFind.cFileName);
    941 
    942   // Construct the current directory entry.
    943   SmallString<128> directory_entry_name_utf8;
    944   if (std::error_code ec =
    945           UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName),
    946                       directory_entry_name_utf8))
    947     return ec;
    948 
    949   it.IterationHandle = intptr_t(FindHandle.take());
    950   SmallString<128> directory_entry_path(path);
    951   path::append(directory_entry_path, directory_entry_name_utf8);
    952   it.CurrentEntry = directory_entry(directory_entry_path, follow_symlinks,
    953                                     status_from_find_data(&FirstFind));
    954 
    955   return std::error_code();
    956 }
    957 
    958 std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
    959   if (it.IterationHandle != 0)
    960     // Closes the handle if it's valid.
    961     ScopedFindHandle close(HANDLE(it.IterationHandle));
    962   it.IterationHandle = 0;
    963   it.CurrentEntry = directory_entry();
    964   return std::error_code();
    965 }
    966 
    967 std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
    968   WIN32_FIND_DATAW FindData;
    969   if (!::FindNextFileW(HANDLE(it.IterationHandle), &FindData)) {
    970     DWORD LastError = ::GetLastError();
    971     // Check for end.
    972     if (LastError == ERROR_NO_MORE_FILES)
    973       return detail::directory_iterator_destruct(it);
    974     return mapWindowsError(LastError);
    975   }
    976 
    977   size_t FilenameLen = ::wcslen(FindData.cFileName);
    978   if ((FilenameLen == 1 && FindData.cFileName[0] == L'.') ||
    979       (FilenameLen == 2 && FindData.cFileName[0] == L'.' &&
    980                            FindData.cFileName[1] == L'.'))
    981     return directory_iterator_increment(it);
    982 
    983   SmallString<128> directory_entry_path_utf8;
    984   if (std::error_code ec =
    985           UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName),
    986                       directory_entry_path_utf8))
    987     return ec;
    988 
    989   it.CurrentEntry.replace_filename(Twine(directory_entry_path_utf8),
    990                                    status_from_find_data(&FindData));
    991   return std::error_code();
    992 }
    993 
    994 ErrorOr<basic_file_status> directory_entry::status() const {
    995   return Status;
    996 }
    997 
    998 static std::error_code nativeFileToFd(Expected<HANDLE> H, int &ResultFD,
    999                                       OpenFlags Flags) {
   1000   int CrtOpenFlags = 0;
   1001   if (Flags & OF_Append)
   1002     CrtOpenFlags |= _O_APPEND;
   1003 
   1004   if (Flags & OF_Text)
   1005     CrtOpenFlags |= _O_TEXT;
   1006 
   1007   ResultFD = -1;
   1008   if (!H)
   1009     return errorToErrorCode(H.takeError());
   1010 
   1011   ResultFD = ::_open_osfhandle(intptr_t(*H), CrtOpenFlags);
   1012   if (ResultFD == -1) {
   1013     ::CloseHandle(*H);
   1014     return mapWindowsError(ERROR_INVALID_HANDLE);
   1015   }
   1016   return std::error_code();
   1017 }
   1018 
   1019 static DWORD nativeDisposition(CreationDisposition Disp, OpenFlags Flags) {
   1020   // This is a compatibility hack.  Really we should respect the creation
   1021   // disposition, but a lot of old code relied on the implicit assumption that
   1022   // OF_Append implied it would open an existing file.  Since the disposition is
   1023   // now explicit and defaults to CD_CreateAlways, this assumption would cause
   1024   // any usage of OF_Append to append to a new file, even if the file already
   1025   // existed.  A better solution might have two new creation dispositions:
   1026   // CD_AppendAlways and CD_AppendNew.  This would also address the problem of
   1027   // OF_Append being used on a read-only descriptor, which doesn't make sense.
   1028   if (Flags & OF_Append)
   1029     return OPEN_ALWAYS;
   1030 
   1031   switch (Disp) {
   1032   case CD_CreateAlways:
   1033     return CREATE_ALWAYS;
   1034   case CD_CreateNew:
   1035     return CREATE_NEW;
   1036   case CD_OpenAlways:
   1037     return OPEN_ALWAYS;
   1038   case CD_OpenExisting:
   1039     return OPEN_EXISTING;
   1040   }
   1041   llvm_unreachable("unreachable!");
   1042 }
   1043 
   1044 static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) {
   1045   DWORD Result = 0;
   1046   if (Access & FA_Read)
   1047     Result |= GENERIC_READ;
   1048   if (Access & FA_Write)
   1049     Result |= GENERIC_WRITE;
   1050   if (Flags & OF_Delete)
   1051     Result |= DELETE;
   1052   if (Flags & OF_UpdateAtime)
   1053     Result |= FILE_WRITE_ATTRIBUTES;
   1054   return Result;
   1055 }
   1056 
   1057 static std::error_code openNativeFileInternal(const Twine &Name,
   1058                                               file_t &ResultFile, DWORD Disp,
   1059                                               DWORD Access, DWORD Flags,
   1060                                               bool Inherit = false) {
   1061   SmallVector<wchar_t, 128> PathUTF16;
   1062   if (std::error_code EC = widenPath(Name, PathUTF16))
   1063     return EC;
   1064 
   1065   SECURITY_ATTRIBUTES SA;
   1066   SA.nLength = sizeof(SA);
   1067   SA.lpSecurityDescriptor = nullptr;
   1068   SA.bInheritHandle = Inherit;
   1069 
   1070   HANDLE H =
   1071       ::CreateFileW(PathUTF16.begin(), Access,
   1072                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SA,
   1073                     Disp, Flags, NULL);
   1074   if (H == INVALID_HANDLE_VALUE) {
   1075     DWORD LastError = ::GetLastError();
   1076     std::error_code EC = mapWindowsError(LastError);
   1077     // Provide a better error message when trying to open directories.
   1078     // This only runs if we failed to open the file, so there is probably
   1079     // no performances issues.
   1080     if (LastError != ERROR_ACCESS_DENIED)
   1081       return EC;
   1082     if (is_directory(Name))
   1083       return make_error_code(errc::is_a_directory);
   1084     return EC;
   1085   }
   1086   ResultFile = H;
   1087   return std::error_code();
   1088 }
   1089 
   1090 Expected<file_t> openNativeFile(const Twine &Name, CreationDisposition Disp,
   1091                                 FileAccess Access, OpenFlags Flags,
   1092                                 unsigned Mode) {
   1093   // Verify that we don't have both "append" and "excl".
   1094   assert((!(Disp == CD_CreateNew) || !(Flags & OF_Append)) &&
   1095          "Cannot specify both 'CreateNew' and 'Append' file creation flags!");
   1096 
   1097   DWORD NativeDisp = nativeDisposition(Disp, Flags);
   1098   DWORD NativeAccess = nativeAccess(Access, Flags);
   1099 
   1100   bool Inherit = false;
   1101   if (Flags & OF_ChildInherit)
   1102     Inherit = true;
   1103 
   1104   file_t Result;
   1105   std::error_code EC = openNativeFileInternal(
   1106       Name, Result, NativeDisp, NativeAccess, FILE_ATTRIBUTE_NORMAL, Inherit);
   1107   if (EC)
   1108     return errorCodeToError(EC);
   1109 
   1110   if (Flags & OF_UpdateAtime) {
   1111     FILETIME FileTime;
   1112     SYSTEMTIME SystemTime;
   1113     GetSystemTime(&SystemTime);
   1114     if (SystemTimeToFileTime(&SystemTime, &FileTime) == 0 ||
   1115         SetFileTime(Result, NULL, &FileTime, NULL) == 0) {
   1116       DWORD LastError = ::GetLastError();
   1117       ::CloseHandle(Result);
   1118       return errorCodeToError(mapWindowsError(LastError));
   1119     }
   1120   }
   1121 
   1122   if (Flags & OF_Delete) {
   1123     if ((EC = setDeleteDisposition(Result, true))) {
   1124       ::CloseHandle(Result);
   1125       return errorCodeToError(EC);
   1126     }
   1127   }
   1128   return Result;
   1129 }
   1130 
   1131 std::error_code openFile(const Twine &Name, int &ResultFD,
   1132                          CreationDisposition Disp, FileAccess Access,
   1133                          OpenFlags Flags, unsigned int Mode) {
   1134   Expected<file_t> Result = openNativeFile(Name, Disp, Access, Flags);
   1135   if (!Result)
   1136     return errorToErrorCode(Result.takeError());
   1137 
   1138   return nativeFileToFd(*Result, ResultFD, Flags);
   1139 }
   1140 
   1141 static std::error_code directoryRealPath(const Twine &Name,
   1142                                          SmallVectorImpl<char> &RealPath) {
   1143   file_t File;
   1144   std::error_code EC = openNativeFileInternal(
   1145       Name, File, OPEN_EXISTING, GENERIC_READ, FILE_FLAG_BACKUP_SEMANTICS);
   1146   if (EC)
   1147     return EC;
   1148 
   1149   EC = realPathFromHandle(File, RealPath);
   1150   ::CloseHandle(File);
   1151   return EC;
   1152 }
   1153 
   1154 std::error_code openFileForRead(const Twine &Name, int &ResultFD,
   1155                                 OpenFlags Flags,
   1156                                 SmallVectorImpl<char> *RealPath) {
   1157   Expected<HANDLE> NativeFile = openNativeFileForRead(Name, Flags, RealPath);
   1158   return nativeFileToFd(std::move(NativeFile), ResultFD, OF_None);
   1159 }
   1160 
   1161 Expected<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags,
   1162                                        SmallVectorImpl<char> *RealPath) {
   1163   Expected<file_t> Result =
   1164       openNativeFile(Name, CD_OpenExisting, FA_Read, Flags);
   1165 
   1166   // Fetch the real name of the file, if the user asked
   1167   if (Result && RealPath)
   1168     realPathFromHandle(*Result, *RealPath);
   1169 
   1170   return Result;
   1171 }
   1172 
   1173 void closeFile(file_t &F) {
   1174   ::CloseHandle(F);
   1175   F = kInvalidFile;
   1176 }
   1177 
   1178 std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
   1179   // Convert to utf-16.
   1180   SmallVector<wchar_t, 128> Path16;
   1181   std::error_code EC = widenPath(path, Path16);
   1182   if (EC && !IgnoreErrors)
   1183     return EC;
   1184 
   1185   // SHFileOperation() accepts a list of paths, and so must be double null-
   1186   // terminated to indicate the end of the list.  The buffer is already null
   1187   // terminated, but since that null character is not considered part of the
   1188   // vector's size, pushing another one will just consume that byte.  So we
   1189   // need to push 2 null terminators.
   1190   Path16.push_back(0);
   1191   Path16.push_back(0);
   1192 
   1193   SHFILEOPSTRUCTW shfos = {};
   1194   shfos.wFunc = FO_DELETE;
   1195   shfos.pFrom = Path16.data();
   1196   shfos.fFlags = FOF_NO_UI;
   1197 
   1198   int result = ::SHFileOperationW(&shfos);
   1199   if (result != 0 && !IgnoreErrors)
   1200     return mapWindowsError(result);
   1201   return std::error_code();
   1202 }
   1203 
   1204 static void expandTildeExpr(SmallVectorImpl<char> &Path) {
   1205   // Path does not begin with a tilde expression.
   1206   if (Path.empty() || Path[0] != '~')
   1207     return;
   1208 
   1209   StringRef PathStr(Path.begin(), Path.size());
   1210   PathStr = PathStr.drop_front();
   1211   StringRef Expr = PathStr.take_until([](char c) { return path::is_separator(c); });
   1212 
   1213   if (!Expr.empty()) {
   1214     // This is probably a ~username/ expression.  Don't support this on Windows.
   1215     return;
   1216   }
   1217 
   1218   SmallString<128> HomeDir;
   1219   if (!path::home_directory(HomeDir)) {
   1220     // For some reason we couldn't get the home directory.  Just exit.
   1221     return;
   1222   }
   1223 
   1224   // Overwrite the first character and insert the rest.
   1225   Path[0] = HomeDir[0];
   1226   Path.insert(Path.begin() + 1, HomeDir.begin() + 1, HomeDir.end());
   1227 }
   1228 
   1229 std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest,
   1230                           bool expand_tilde) {
   1231   dest.clear();
   1232   if (path.isTriviallyEmpty())
   1233     return std::error_code();
   1234 
   1235   if (expand_tilde) {
   1236     SmallString<128> Storage;
   1237     path.toVector(Storage);
   1238     expandTildeExpr(Storage);
   1239     return real_path(Storage, dest, false);
   1240   }
   1241 
   1242   if (is_directory(path))
   1243     return directoryRealPath(path, dest);
   1244 
   1245   int fd;
   1246   if (std::error_code EC =
   1247           llvm::sys::fs::openFileForRead(path, fd, OF_None, &dest))
   1248     return EC;
   1249   ::close(fd);
   1250   return std::error_code();
   1251 }
   1252 
   1253 } // end namespace fs
   1254 
   1255 namespace path {
   1256 static bool getKnownFolderPath(KNOWNFOLDERID folderId,
   1257                                SmallVectorImpl<char> &result) {
   1258   wchar_t *path = nullptr;
   1259   if (::SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, nullptr, &path) != S_OK)
   1260     return false;
   1261 
   1262   bool ok = !UTF16ToUTF8(path, ::wcslen(path), result);
   1263   ::CoTaskMemFree(path);
   1264   return ok;
   1265 }
   1266 
   1267 bool getUserCacheDir(SmallVectorImpl<char> &Result) {
   1268   return getKnownFolderPath(FOLDERID_LocalAppData, Result);
   1269 }
   1270 
   1271 bool home_directory(SmallVectorImpl<char> &result) {
   1272   return getKnownFolderPath(FOLDERID_Profile, result);
   1273 }
   1274 
   1275 static bool getTempDirEnvVar(const wchar_t *Var, SmallVectorImpl<char> &Res) {
   1276   SmallVector<wchar_t, 1024> Buf;
   1277   size_t Size = 1024;
   1278   do {
   1279     Buf.reserve(Size);
   1280     Size = GetEnvironmentVariableW(Var, Buf.data(), Buf.capacity());
   1281     if (Size == 0)
   1282       return false;
   1283 
   1284     // Try again with larger buffer.
   1285   } while (Size > Buf.capacity());
   1286   Buf.set_size(Size);
   1287 
   1288   return !windows::UTF16ToUTF8(Buf.data(), Size, Res);
   1289 }
   1290 
   1291 static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
   1292   const wchar_t *EnvironmentVariables[] = {L"TMP", L"TEMP", L"USERPROFILE"};
   1293   for (auto *Env : EnvironmentVariables) {
   1294     if (getTempDirEnvVar(Env, Res))
   1295       return true;
   1296   }
   1297   return false;
   1298 }
   1299 
   1300 void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
   1301   (void)ErasedOnReboot;
   1302   Result.clear();
   1303 
   1304   // Check whether the temporary directory is specified by an environment var.
   1305   // This matches GetTempPath logic to some degree. GetTempPath is not used
   1306   // directly as it cannot handle evn var longer than 130 chars on Windows 7
   1307   // (fixed on Windows 8).
   1308   if (getTempDirEnvVar(Result)) {
   1309     assert(!Result.empty() && "Unexpected empty path");
   1310     native(Result); // Some Unix-like shells use Unix path separator in $TMP.
   1311     fs::make_absolute(Result); // Make it absolute if not already.
   1312     return;
   1313   }
   1314 
   1315   // Fall back to a system default.
   1316   const char *DefaultResult = "C:\\Temp";
   1317   Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
   1318 }
   1319 } // end namespace path
   1320 
   1321 namespace windows {
   1322 std::error_code CodePageToUTF16(unsigned codepage,
   1323                                 llvm::StringRef original,
   1324                                 llvm::SmallVectorImpl<wchar_t> &utf16) {
   1325   if (!original.empty()) {
   1326     int len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.begin(),
   1327                                     original.size(), utf16.begin(), 0);
   1328 
   1329     if (len == 0) {
   1330       return mapWindowsError(::GetLastError());
   1331     }
   1332 
   1333     utf16.reserve(len + 1);
   1334     utf16.set_size(len);
   1335 
   1336     len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.begin(),
   1337                                 original.size(), utf16.begin(), utf16.size());
   1338 
   1339     if (len == 0) {
   1340       return mapWindowsError(::GetLastError());
   1341     }
   1342   }
   1343 
   1344   // Make utf16 null terminated.
   1345   utf16.push_back(0);
   1346   utf16.pop_back();
   1347 
   1348   return std::error_code();
   1349 }
   1350 
   1351 std::error_code UTF8ToUTF16(llvm::StringRef utf8,
   1352                             llvm::SmallVectorImpl<wchar_t> &utf16) {
   1353   return CodePageToUTF16(CP_UTF8, utf8, utf16);
   1354 }
   1355 
   1356 std::error_code CurCPToUTF16(llvm::StringRef curcp,
   1357                             llvm::SmallVectorImpl<wchar_t> &utf16) {
   1358   return CodePageToUTF16(CP_ACP, curcp, utf16);
   1359 }
   1360 
   1361 static
   1362 std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
   1363                                 size_t utf16_len,
   1364                                 llvm::SmallVectorImpl<char> &converted) {
   1365   if (utf16_len) {
   1366     // Get length.
   1367     int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.begin(),
   1368                                     0, NULL, NULL);
   1369 
   1370     if (len == 0) {
   1371       return mapWindowsError(::GetLastError());
   1372     }
   1373 
   1374     converted.reserve(len);
   1375     converted.set_size(len);
   1376 
   1377     // Now do the actual conversion.
   1378     len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.data(),
   1379                                 converted.size(), NULL, NULL);
   1380 
   1381     if (len == 0) {
   1382       return mapWindowsError(::GetLastError());
   1383     }
   1384   }
   1385 
   1386   // Make the new string null terminated.
   1387   converted.push_back(0);
   1388   converted.pop_back();
   1389 
   1390   return std::error_code();
   1391 }
   1392 
   1393 std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
   1394                             llvm::SmallVectorImpl<char> &utf8) {
   1395   return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
   1396 }
   1397 
   1398 std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
   1399                              llvm::SmallVectorImpl<char> &curcp) {
   1400   return UTF16ToCodePage(CP_ACP, utf16, utf16_len, curcp);
   1401 }
   1402 
   1403 } // end namespace windows
   1404 } // end namespace sys
   1405 } // end namespace llvm
   1406