// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(DART_HOST_OS_WINDOWS)

#include <functional>
#include <memory>
#include <string>

#include <Shlwapi.h>  // NOLINT
#include <WinIoCtl.h>  // NOLINT
#include <fcntl.h>     // NOLINT
#include <io.h>        // NOLINT
#undef StrDup          // defined in Shlwapi.h as StrDupW
#include <stdio.h>     // NOLINT
#include <string.h>    // NOLINT
#include <sys/stat.h>  // NOLINT
#include <sys/utime.h>  // NOLINT

#include "bin/builtin.h"
#include "bin/crypto.h"
#include "bin/directory.h"
#include "bin/file.h"
#include "bin/file_win.h"
#include "bin/namespace.h"
#include "bin/utils.h"
#include "bin/utils_win.h"
#include "platform/syslog.h"
#include "platform/utils.h"

namespace dart {
namespace bin {

class FileHandle {
 public:
  explicit FileHandle(int fd) : fd_(fd) {}
  ~FileHandle() {}
  int fd() const { return fd_; }
  void set_fd(int fd) { fd_ = fd; }

 private:
  int fd_;

  DISALLOW_COPY_AND_ASSIGN(FileHandle);
};

File::~File() {
  if (!IsClosed() && handle_->fd() != _fileno(stdout) &&
      handle_->fd() != _fileno(stderr)) {
    Close();
  }
  delete handle_;
}

void File::Close() {
  ASSERT(handle_->fd() >= 0);
  int closing_fd = handle_->fd();
  if ((closing_fd == _fileno(stdout)) || (closing_fd == _fileno(stderr))) {
    int fd = _open("NUL", _O_WRONLY);
    ASSERT(fd >= 0);
    _dup2(fd, closing_fd);
    Utils::Close(fd);
  } else {
    int err = Utils::Close(closing_fd);
    if (err != 0) {
      Syslog::PrintErr("%s\n", strerror(errno));
    }
  }
  handle_->set_fd(kClosedFd);
}

intptr_t File::GetFD() {
  return handle_->fd();
}

bool File::IsClosed() {
  return handle_->fd() == kClosedFd;
}

MappedMemory* File::Map(File::MapType type,
                        int64_t position,
                        int64_t length,
                        void* start) {
  DWORD prot_alloc;
  DWORD prot_final;
  switch (type) {
    case File::kReadOnly:
      prot_alloc = PAGE_READWRITE;
      prot_final = PAGE_READONLY;
      break;
    case File::kReadExecute:
      prot_alloc = PAGE_EXECUTE_READWRITE;
      prot_final = PAGE_EXECUTE_READ;
      break;
    case File::kReadWrite:
      prot_alloc = PAGE_READWRITE;
      prot_final = PAGE_READWRITE;
      break;
  }

  void* addr = start;
  if (addr == nullptr) {
    addr = VirtualAlloc(nullptr, length, MEM_COMMIT | MEM_RESERVE, prot_alloc);
    if (addr == nullptr) {
      Syslog::PrintErr("VirtualAlloc failed %d\n", GetLastError());
      return nullptr;
    }
  }

  const int64_t remaining_length = Length() - position;
  SetPosition(position);
  if (!ReadFully(addr, Utils::Minimum(length, remaining_length))) {
    Syslog::PrintErr("ReadFully failed %d\n", GetLastError());
    if (start == nullptr) {
      VirtualFree(addr, 0, MEM_RELEASE);
    }
    return nullptr;
  }

  // If the requested mapping is larger than the file size, we should fill the
  // extra memory with zeros.
  if (length > remaining_length) {
    memset(reinterpret_cast<uint8_t*>(addr) + remaining_length, 0,
           length - remaining_length);
  }

  DWORD old_prot;
  bool result = VirtualProtect(addr, length, prot_final, &old_prot);
  if (!result) {
    Syslog::PrintErr("VirtualProtect failed %d\n", GetLastError());
    if (start == nullptr) {
      VirtualFree(addr, 0, MEM_RELEASE);
    }
    return nullptr;
  }
  return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}

void MappedMemory::Unmap() {
  BOOL result = VirtualFree(address_, 0, MEM_RELEASE);
  ASSERT(result);
  address_ = nullptr;
  size_ = 0;
}

int64_t File::Read(void* buffer, int64_t num_bytes) {
  ASSERT(handle_->fd() >= 0);
  return Utils::Read(handle_->fd(), buffer, num_bytes);
}

int64_t File::Write(const void* buffer, int64_t num_bytes) {
  int fd = handle_->fd();
  // Avoid narrowing conversion
  ASSERT(fd >= 0 && num_bytes <= MAXDWORD && num_bytes >= 0);
  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
  DWORD written = 0;
  BOOL result = WriteFile(handle, buffer, num_bytes, &written, nullptr);
  if (!result) {
    return -1;
  }
  DWORD mode;
  int64_t bytes_written = written;
  if (GetConsoleMode(handle, &mode)) {
    // If `handle` is for a console, then `written` may refer to the number of
    // characters printed to the screen rather than the number of bytes of the
    // buffer that were actually consumed. To compute the number of bytes that
    // were actually consumed, we convert the buffer to a wchar_t using the
    // console's current code page, filling as many characters as were
    // printed, and then convert that many characters back to the encoding for
    // the code page, which gives the number of bytes of `buffer` used to
    // generate the characters that were printed.
    wchar_t* wide = new wchar_t[written];
    int cp = GetConsoleOutputCP();
    MultiByteToWideChar(cp, 0, reinterpret_cast<const char*>(buffer), -1, wide,
                        written);
    int buffer_len =
        WideCharToMultiByte(cp, 0, wide, written, nullptr, 0, nullptr, nullptr);
    delete[] wide;
    bytes_written = buffer_len;
  }
  return bytes_written;
}

bool File::VPrint(const char* format, va_list args) {
  // Measure.
  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = _vscprintf(format, measure_args);
  va_end(measure_args);

  char* buffer = reinterpret_cast<char*>(malloc(len + 1));

  // Print.
  va_list print_args;
  va_copy(print_args, args);
  _vsnprintf(buffer, len + 1, format, print_args);
  va_end(print_args);

  bool result = WriteFully(buffer, len);
  free(buffer);
  return result;
}

int64_t File::Position() {
  ASSERT(handle_->fd() >= 0);
  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd()));
  LARGE_INTEGER zero_offset;
  zero_offset.QuadPart = 0;
  LARGE_INTEGER position;
  if (!SetFilePointerEx(handle, zero_offset, &position, FILE_CURRENT)) {
    return -1L;
  }
  return position.QuadPart;
}

bool File::SetPosition(int64_t position) {
  ASSERT(handle_->fd() >= 0);
  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd()));
  LARGE_INTEGER requested_position;
  requested_position.QuadPart = position;
  return SetFilePointerEx(handle, requested_position,
                          /*lpNewFilePointer=*/nullptr, FILE_BEGIN);
}

bool File::Truncate(int64_t length) {
  if (!SetPosition(length)) {
    return false;
  }
  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd()));
  return SetEndOfFile(handle);
}

bool File::Flush() {
  ASSERT(handle_->fd());
  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd()));
  return FlushFileBuffers(handle);
}

bool File::Lock(File::LockType lock, int64_t start, int64_t end) {
  ASSERT(handle_->fd() >= 0);
  ASSERT((end == -1) || (end > start));
  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd()));
  OVERLAPPED overlapped;
  ZeroMemory(&overlapped, sizeof(OVERLAPPED));

  overlapped.Offset = Utils::Low32Bits(start);
  overlapped.OffsetHigh = Utils::High32Bits(start);

  int64_t length = end == -1 ? 0 : end - start;
  if (length == 0) {
    length = kMaxInt64;
  }
  int32_t length_low = Utils::Low32Bits(length);
  int32_t length_high = Utils::High32Bits(length);

  BOOL rc;
  switch (lock) {
    case File::kLockUnlock:
      rc = UnlockFileEx(handle, 0, length_low, length_high, &overlapped);
      break;
    case File::kLockShared:
    case File::kLockExclusive:
    case File::kLockBlockingShared:
    case File::kLockBlockingExclusive: {
      DWORD flags = 0;
      if ((lock == File::kLockShared) || (lock == File::kLockExclusive)) {
        flags |= LOCKFILE_FAIL_IMMEDIATELY;
      }
      if ((lock == File::kLockExclusive) ||
          (lock == File::kLockBlockingExclusive)) {
        flags |= LOCKFILE_EXCLUSIVE_LOCK;
      }
      rc = LockFileEx(handle, flags, 0, length_low, length_high, &overlapped);
      break;
    }
    default:
      UNREACHABLE();
  }
  return rc;
}

int64_t File::Length() {
  ASSERT(handle_->fd() >= 0);
  struct __stat64 st;
  if (_fstat64(handle_->fd(), &st) == 0) {
    return st.st_size;
  }
  return -1;
}

File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
  int flags = O_RDONLY | O_BINARY | O_NOINHERIT;
  if ((mode & kWrite) != 0) {
    ASSERT((mode & kWriteOnly) == 0);
    flags = (O_RDWR | O_CREAT | O_BINARY | O_NOINHERIT);
  }
  if ((mode & kWriteOnly) != 0) {
    ASSERT((mode & kWrite) == 0);
    flags = (O_WRONLY | O_CREAT | O_BINARY | O_NOINHERIT);
  }
  if ((mode & kTruncate) != 0) {
    flags = flags | O_TRUNC;
  }
  int fd = _wopen(system_name, flags, 0666);
  if (fd < 0) {
    return nullptr;
  }
  if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) ||
      (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) {
    int64_t position = _lseeki64(fd, 0, SEEK_END);
    if (position < 0) {
      return nullptr;
    }
  }
  return OpenFD(fd);
}

File* File::OpenFD(int fd) {
  return new File(new FileHandle(fd));
}

class StringRAII {
 public:
  explicit StringRAII(StringRAII& origin) {  // NOLINT
    own_ = origin.own_;
    s_ = origin.release();
  }

  explicit StringRAII(const char* s) : s_(s), own_(false) {}
  explicit StringRAII(char* s) : s_(s), own_(true) {}
  ~StringRAII() {
    if (own_) {
      free(const_cast<char*>(s_));
    }
  }
  const char* str() const { return s_; }
  const char* release() {
    own_ = false;
    return s_;
  }

 private:
  bool own_;
  const char* s_;
};

class Wchart {
 public:
  explicit Wchart(int size) {
    buf_ = reinterpret_cast<wchar_t*>(malloc(size * sizeof(wchar_t)));
  }
  ~Wchart() { free(buf_); }
  wchar_t* buf() const { return buf_; }

 private:
  wchar_t* buf_;
};

static StringRAII ConvertToAbsolutePath(const char* path,
                                        bool* p_has_converted_successfully) {
  const int kPathLength = 16384;
  Wchart buffer(kPathLength);  // use some reasonably large initial buffer
  Utf8ToWideScope path_utf8_to_wide(path);
  *p_has_converted_successfully = true;
  int full_path_length =
      GetFullPathNameW(path_utf8_to_wide.wide(), kPathLength, buffer.buf(),
                       /*lpFilePart=*/nullptr);
  if (full_path_length == 0) {
    *p_has_converted_successfully = false;
    // GetFullPathNameW failed
    return StringRAII(path);
  }
  if (full_path_length < kPathLength) {
    WideToUtf8Scope scope(buffer.buf());
    return StringRAII(Utils::StrDup(scope.utf8()));
  }

  // Try again with bigger buffer.
  Wchart bigger_buffer(full_path_length);
  if (GetFullPathNameW(path_utf8_to_wide.wide(), full_path_length,
                       bigger_buffer.buf(),
                       /*lpFilePart=*/nullptr) == 0) {
    *p_has_converted_successfully = false;
    // GetFullPathNameW failed
    return StringRAII(path);
  }
  WideToUtf8Scope scope(bigger_buffer.buf());
  return StringRAII(Utils::StrDup(scope.utf8()));
}

static StringRAII PrefixLongPathIfExceedLimit(
    const char* path,
    bool is_file,
    std::function<char*(int)> allocate) {
  // File name and Directory name have different size limit.
  // Reference: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation
  const int path_short_limit = is_file ? MAX_PATH : MAX_DIRECTORY_PATH;

  const char* kLongPathPrefix = "\\\\?\\";
  const int kLongPathPrefixLength = 4;

  // if absolute path is short or already prefixed, just return it.
  if ((File::IsAbsolutePath(path) && strlen(path) < path_short_limit) ||
      strncmp(path, kLongPathPrefix, kLongPathPrefixLength) == 0) {
    return StringRAII(path);
  }

  // Long relative path have to be converted to absolute path before prefixing.
  bool is_ok = true;
  StringRAII absolute_path_raii(
      File::IsAbsolutePath(path)
          ? StringRAII(path)
          : StringRAII(ConvertToAbsolutePath(path, &is_ok)));
  if (!is_ok) {
    return StringRAII(path);
  }
  const char* absolute_path = absolute_path_raii.str();
  int length = strlen(absolute_path);
  if (length < path_short_limit) {
    // No need for a prefix if absolute path is short
    return StringRAII(path);
  }
  if (strncmp(absolute_path, kLongPathPrefix, kLongPathPrefixLength) == 0) {
    // Relative path converted to absolute could get a prefix.
    return StringRAII(absolute_path);
  }

  // Add prefix and replace forward slashes with backward slashes.
  char* result = allocate((kLongPathPrefixLength + length + 1) * sizeof(char));
  strncpy(result, kLongPathPrefix, kLongPathPrefixLength);
  for (int i = 0; i < length; i++) {
    result[kLongPathPrefixLength + i] =
        absolute_path[i] == '/' ? '\\' : absolute_path[i];
  }
  result[length + kLongPathPrefixLength] = '\0';
  return StringRAII(result);
}

static const char* PrefixLongFilePath(const char* path) {
  return PrefixLongPathIfExceedLimit(
             path, /*is_file=*/true,
             [](int size) {
               return reinterpret_cast<char*>(Dart_ScopeAllocate(size));
             })
      .release();
}

static StringRAII PrefixLongFilePathNoScope(const char* path) {
  return PrefixLongPathIfExceedLimit(path, /*is_file=*/true, [](int size) {
    return reinterpret_cast<char*>(malloc(size));
  });
}

const char* PrefixLongDirectoryPath(const char* path) {
  return PrefixLongPathIfExceedLimit(
             path, /*is_file=*/false,
             [](int size) {
               return reinterpret_cast<char*>(Dart_ScopeAllocate(size));
             })
      .release();
}

File* File::Open(Namespace* namespc, const char* path, FileOpenMode mode) {
  // File::Open can be called without scope(when launching isolate),
  // so it mallocs prefixed path
  StringRAII string_raii = PrefixLongFilePathNoScope(path);
  Utf8ToWideScope system_name(string_raii.str());
  File* file = FileOpenW(system_name.wide(), mode);
  return file;
}

Utils::CStringUniquePtr File::UriToPath(const char* uri) {
  UriDecoder uri_decoder(uri);
  if (uri_decoder.decoded() == nullptr) {
    SetLastError(ERROR_INVALID_NAME);
    return Utils::CreateCStringUniquePtr(nullptr);
  }

  Utf8ToWideScope uri_w(uri_decoder.decoded());
  if (!UrlIsFileUrlW(uri_w.wide())) {
    return Utils::CreateCStringUniquePtr(Utils::StrDup(uri_decoder.decoded()));
  }
  wchar_t filename_w[MAX_PATH];
  DWORD filename_len = MAX_PATH;
  HRESULT result = PathCreateFromUrlW(uri_w.wide(), filename_w, &filename_len,
                                      /* dwFlags= */ 0);
  if (result != S_OK) {
    return Utils::CreateCStringUniquePtr(nullptr);
  }

  WideToUtf8Scope utf8_path(filename_w);
  return utf8_path.release();
}

File* File::OpenUri(Namespace* namespc, const char* uri, FileOpenMode mode) {
  auto path = UriToPath(uri);
  if (path == nullptr) {
    return nullptr;
  }
  return Open(namespc, path.get(), mode);
}

File* File::OpenStdio(int fd) {
  int stdio_fd = -1;
  switch (fd) {
    case 1:
      stdio_fd = _fileno(stdout);
      break;
    case 2:
      stdio_fd = _fileno(stderr);
      break;
    default:
      UNREACHABLE();
  }
  _setmode(stdio_fd, _O_BINARY);
  return new File(new FileHandle(stdio_fd));
}

static bool StatHelper(wchar_t* path, struct __stat64* st) {
  int stat_status = _wstat64(path, st);
  if (stat_status != 0) {
    return false;
  }
  if ((st->st_mode & S_IFMT) != S_IFREG) {
    SetLastError(ERROR_NOT_SUPPORTED);
    return false;
  }
  return true;
}

bool File::Exists(Namespace* namespc, const char* name) {
  StringRAII string_raii = PrefixLongFilePathNoScope(name);
  Utf8ToWideScope system_name(string_raii.str());
  struct __stat64 st;
  return StatHelper(system_name.wide(), &st);
}

bool File::ExistsUri(Namespace* namespc, const char* uri) {
  UriDecoder uri_decoder(uri);
  if (uri_decoder.decoded() == nullptr) {
    SetLastError(ERROR_INVALID_NAME);
    return false;
  }
  return File::Exists(namespc, uri_decoder.decoded());
}

bool File::Create(Namespace* namespc, const char* name, bool exclusive) {
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  int flags = O_RDONLY | O_CREAT;
  if (exclusive) {
    flags |= O_EXCL;
  }
  int fd = _wopen(system_name.wide(), flags, 0666);
  if (fd < 0) {
    return false;
  }
  return (Utils::Close(fd) == 0);
}

// This structure is needed for creating and reading Junctions.
typedef struct _REPARSE_DATA_BUFFER {
  ULONG ReparseTag;
  USHORT ReparseDataLength;
  USHORT Reserved;

  union {
    struct {
      USHORT SubstituteNameOffset;
      USHORT SubstituteNameLength;
      USHORT PrintNameOffset;
      USHORT PrintNameLength;
      ULONG Flags;
      WCHAR PathBuffer[1];
    } SymbolicLinkReparseBuffer;

    struct {
      USHORT SubstituteNameOffset;
      USHORT SubstituteNameLength;
      USHORT PrintNameOffset;
      USHORT PrintNameLength;
      WCHAR PathBuffer[1];
    } MountPointReparseBuffer;

    struct {
      UCHAR DataBuffer[1];
    } GenericReparseBuffer;
  };
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

static constexpr int kReparseDataHeaderSize =
    sizeof(ULONG) + 2 * sizeof(USHORT);
static constexpr int kMountPointHeaderSize = 4 * sizeof(USHORT);

bool File::CreateLink(Namespace* namespc,
                      const char* utf8_name,
                      const char* utf8_target) {
  Utf8ToWideScope name(PrefixLongFilePath(utf8_name));
  Utf8ToWideScope target(PrefixLongFilePath(utf8_target));
  DWORD flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;

  File::Type type = File::GetType(namespc, utf8_target, true);
  if (type == kIsDirectory) {
    flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
  }

  int create_status = CreateSymbolicLinkW(name.wide(), target.wide(), flags);

  // If running on a Windows 10 build older than 14972, an invalid parameter
  // error will be returned when trying to use the
  // SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag. Retry without the flag.
  if ((create_status == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)) {
    flags &= ~SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
    create_status = CreateSymbolicLinkW(name.wide(), target.wide(), flags);
  }

  return (create_status != 0);
}

bool File::CreatePipe(Namespace* namespc, File** readPipe, File** writePipe) {
  int pipe_fds[2];
  int status = _pipe(pipe_fds, 4096, _O_BINARY);
  if (status != 0) {
    return false;
  }
  *readPipe = OpenFD(pipe_fds[0]);
  *writePipe = OpenFD(pipe_fds[1]);
  return true;
}

bool File::Delete(Namespace* namespc, const char* name) {
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  int status = _wremove(system_name.wide());
  return status != -1;
}

bool File::DeleteLink(Namespace* namespc, const char* name) {
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  bool result = false;
  DWORD attributes = GetFileAttributesW(system_name.wide());
  if ((attributes == INVALID_FILE_ATTRIBUTES) ||
      ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0)) {
    SetLastError(ERROR_NOT_A_REPARSE_POINT);
    return false;
  }
  if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
    // It's a junction, which is a special type of directory, or a symbolic
    // link to a directory. Remove the directory.
    result = (RemoveDirectoryW(system_name.wide()) != 0);
  } else {
    // Symbolic link to a file. Remove the file.
    result = (DeleteFileW(system_name.wide()) != 0);
  }
  return result;
}

bool File::Rename(Namespace* namespc,
                  const char* old_path,
                  const char* new_path) {
  const char* prefixed_old_path = PrefixLongFilePath(old_path);
  File::Type type = GetType(namespc, prefixed_old_path, false);
  if (type != kIsFile) {
    SetLastError(ERROR_FILE_NOT_FOUND);
    return false;
  }
  const char* prefixed_new_path = PrefixLongFilePath(new_path);
  Utf8ToWideScope system_old_path(prefixed_old_path);
  Utf8ToWideScope system_new_path(prefixed_new_path);
  DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;

  // Symbolic links (e.g. produced by Link.create) to directories on Windows
  // appear as special directories. MoveFileExW's MOVEFILE_REPLACE_EXISTING
  // does not allow for replacement of directories, so we need to remove it
  // before renaming.
  if ((Directory::Exists(namespc, prefixed_new_path) == Directory::EXISTS) &&
      (GetType(namespc, prefixed_new_path, false) == kIsLink)) {
    // Bail out if the DeleteLink call fails.
    if (!DeleteLink(namespc, prefixed_new_path)) {
      return false;
    }
  }
  int move_status =
      MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
  return (move_status != 0);
}

bool File::RenameLink(Namespace* namespc,
                      const char* old_path,
                      const char* new_path) {
  const char* prefixed_old_path = PrefixLongFilePath(old_path);
  File::Type type = GetType(namespc, prefixed_old_path, false);
  if (type != kIsLink) {
    SetLastError(ERROR_FILE_NOT_FOUND);
    return false;
  }
  Utf8ToWideScope system_old_path(prefixed_old_path);
  const char* prefixed_new_path = PrefixLongFilePath(new_path);
  Utf8ToWideScope system_new_path(prefixed_new_path);
  DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;

  // Symbolic links (e.g. produced by Link.create) to directories on Windows
  // appear as special directories. MoveFileExW's MOVEFILE_REPLACE_EXISTING
  // does not allow for replacement of directories, so we need to remove it
  // before renaming.
  if ((Directory::Exists(namespc, prefixed_new_path) == Directory::EXISTS) &&
      (GetType(namespc, prefixed_new_path, false) == kIsLink)) {
    // Bail out if the DeleteLink call fails.
    if (!DeleteLink(namespc, prefixed_new_path)) {
      return false;
    }
  }
  int move_status =
      MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
  return (move_status != 0);
}

static wchar_t* CopyToDartScopeString(wchar_t* string) {
  wchar_t* wide_path = reinterpret_cast<wchar_t*>(
      Dart_ScopeAllocate(MAX_PATH * sizeof(wchar_t) + 1));
  wcscpy(wide_path, string);
  return wide_path;
}

static wchar_t* CopyIntoTempFile(const char* src, const char* dest) {
  // This function will copy the file to a temp file in the destination
  // directory and return the path of temp file.
  // Creating temp file name has the same logic as Directory::CreateTemp(),
  // which tries with the rng and falls back to a uuid if it failed.
  const char* last_back_slash = strrchr(dest, '\\');
  // It is possible the path uses forwardslash as path separator.
  const char* last_forward_slash = strrchr(dest, '/');
  const char* last_path_separator = nullptr;
  if (last_back_slash == nullptr && last_forward_slash == nullptr) {
    return nullptr;
  } else if (last_forward_slash != nullptr && last_forward_slash != nullptr) {
    // If both types occur in the path, use the one closer to the end.
    if (last_back_slash - dest > last_forward_slash - dest) {
      last_path_separator = last_back_slash;
    } else {
      last_path_separator = last_forward_slash;
    }
  } else {
    last_path_separator =
        (last_forward_slash == nullptr) ? last_back_slash : last_forward_slash;
  }
  int length_of_parent_dir = last_path_separator - dest + 1;
  if (length_of_parent_dir + 8 > MAX_PATH) {
    return nullptr;
  }
  uint32_t suffix_bytes = 0;
  const int kSuffixSize = sizeof(suffix_bytes);
  if (Crypto::GetRandomBytes(kSuffixSize,
                             reinterpret_cast<uint8_t*>(&suffix_bytes))) {
    PathBuffer buffer;
    char* dir = reinterpret_cast<char*>(
        Dart_ScopeAllocate(1 + sizeof(char) * length_of_parent_dir));
    memmove(dir, dest, length_of_parent_dir);
    dir[length_of_parent_dir] = '\0';
    if (!buffer.Add(dir)) {
      return nullptr;
    }

    char suffix[8 + 1];
    Utils::SNPrint(suffix, sizeof(suffix), "%x", suffix_bytes);
    Utf8ToWideScope source_path(src);
    if (!buffer.Add(suffix)) {
      return nullptr;
    }
    if (CopyFileExW(source_path.wide(), buffer.AsStringW(), nullptr, nullptr,
                    nullptr, 0) != 0) {
      return CopyToDartScopeString(buffer.AsStringW());
    }
    // If CopyFileExW() fails to copy to a temp file with random hex, fall
    // back to copy to a uuid temp file.
  }
  // UUID has a total of 36 characters in the form of
  // xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx.
  if (length_of_parent_dir + 36 > MAX_PATH) {
    return nullptr;
  }
  UUID uuid;
  RPC_STATUS status = UuidCreateSequential(&uuid);
  if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
    return nullptr;
  }
  RPC_WSTR uuid_string;
  status = UuidToStringW(&uuid, &uuid_string);
  if (status != RPC_S_OK) {
    return nullptr;
  }
  PathBuffer buffer;
  char* dir = reinterpret_cast<char*>(
      Dart_ScopeAllocate(1 + sizeof(char) * length_of_parent_dir));
  memmove(dir, dest, length_of_parent_dir);
  dir[length_of_parent_dir] = '\0';
  Utf8ToWideScope dest_path(dir);
  if (!buffer.AddW(dest_path.wide()) ||
      !buffer.AddW(reinterpret_cast<wchar_t*>(uuid_string))) {
    return nullptr;
  }

  RpcStringFreeW(&uuid_string);
  Utf8ToWideScope source_path(src);
  if (CopyFileExW(source_path.wide(), buffer.AsStringW(), nullptr, nullptr,
                  nullptr, 0) != 0) {
    return CopyToDartScopeString(buffer.AsStringW());
  }
  return nullptr;
}

bool File::Copy(Namespace* namespc,
                const char* old_path,
                const char* new_path) {
  const char* prefixed_old_path = PrefixLongFilePath(old_path);
  const char* prefixed_new_path = PrefixLongFilePath(new_path);
  File::Type type = GetType(namespc, prefixed_old_path, false);
  if (type != kIsFile) {
    SetLastError(ERROR_FILE_NOT_FOUND);
    return false;
  }

  wchar_t* temp_file = CopyIntoTempFile(prefixed_old_path, prefixed_new_path);
  if (temp_file == nullptr) {
    // If temp file creation fails, fall back on doing a direct copy.
    Utf8ToWideScope system_old_path(prefixed_old_path);
    Utf8ToWideScope system_new_path(prefixed_new_path);
    return CopyFileExW(system_old_path.wide(), system_new_path.wide(), nullptr,
                       nullptr, nullptr, 0) != 0;
  }
  Utf8ToWideScope system_new_dest(prefixed_new_path);

  // Remove the existing file. Otherwise, renaming will fail.
  if (Exists(namespc, prefixed_new_path)) {
    DeleteFileW(system_new_dest.wide());
  }

  if (!MoveFileW(temp_file, system_new_dest.wide())) {
    DWORD error = GetLastError();
    DeleteFileW(temp_file);
    SetLastError(error);
    return false;
  }
  return true;
}

int64_t File::LengthFromPath(Namespace* namespc, const char* name) {
  struct __stat64 st;
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  if (!StatHelper(system_name.wide(), &st)) {
    return -1;
  }
  return st.st_size;
}

const char* File::LinkTarget(Namespace* namespc,
                             const char* pathname,
                             char* dest,
                             int dest_size) {
  const wchar_t* name =
      StringUtilsWin::Utf8ToWide(PrefixLongFilePath(pathname));
  HANDLE dir_handle = CreateFileW(
      name, GENERIC_READ,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
      nullptr);
  if (dir_handle == INVALID_HANDLE_VALUE) {
    return nullptr;
  }

  // Allocate a buffer for regular paths (smaller than MAX_PATH). If buffer is
  // too small for a long path, allocate a bigger buffer and try again.
  int buffer_size =
      sizeof(REPARSE_DATA_BUFFER) + (MAX_PATH + 1) * sizeof(WCHAR);
  REPARSE_DATA_BUFFER* buffer =
      reinterpret_cast<REPARSE_DATA_BUFFER*>(Dart_ScopeAllocate(buffer_size));
  DWORD received_bytes;  // Value is not used.
  int result = DeviceIoControl(dir_handle, FSCTL_GET_REPARSE_POINT, nullptr, 0,
                               buffer, buffer_size, &received_bytes, nullptr);
  if (result == 0) {
    DWORD error = GetLastError();
    // If ERROR_MORE_DATA is thrown, the target path exceeds the size limit. A
    // bigger buffer will be required.
    if (error == ERROR_MORE_DATA) {
      // Allocate a bigger buffer with MAX_LONG_PATH
      buffer_size =
          sizeof(REPARSE_DATA_BUFFER) + (MAX_LONG_PATH + 1) * sizeof(WCHAR);
      buffer = reinterpret_cast<REPARSE_DATA_BUFFER*>(
          Dart_ScopeAllocate(buffer_size));
      result = DeviceIoControl(dir_handle, FSCTL_GET_REPARSE_POINT, nullptr, 0,
                               buffer, buffer_size, &received_bytes, nullptr);
      if (result == 0) {
        // Overwrite the ERROR_MORE_DATA.
        error = GetLastError();
      }
    }
    if (result == 0) {
      CloseHandle(dir_handle);
      SetLastError(error);
      return nullptr;
    }
  }
  if (CloseHandle(dir_handle) == 0) {
    return nullptr;
  }

  wchar_t* target;
  size_t target_offset;
  size_t target_length;
  if (buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
    target = buffer->MountPointReparseBuffer.PathBuffer;
    target_offset = buffer->MountPointReparseBuffer.SubstituteNameOffset;
    target_length = buffer->MountPointReparseBuffer.SubstituteNameLength;
  } else if (buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
    target = buffer->SymbolicLinkReparseBuffer.PathBuffer;
    target_offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset;
    target_length = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
  } else {  // Not a junction or a symbolic link.
    SetLastError(ERROR_NOT_A_REPARSE_POINT);
    return nullptr;
  }

  target_offset /= sizeof(wchar_t);  // Offset and length are in bytes.
  target_length /= sizeof(wchar_t);
  target += target_offset;
  // Remove "\??\" from beginning of target.
  if ((target_length > 4) && (wcsncmp(L"\\??\\", target, 4) == 0)) {
    target += 4;
    target_length -= 4;
  }
  int utf8_length = WideCharToMultiByte(CP_UTF8, 0, target, target_length,
                                        nullptr, 0, nullptr, nullptr);
  if (dest_size > 0 && dest_size <= utf8_length) {
    return nullptr;
  }
  if (dest == nullptr) {
    dest = DartUtils::ScopedCString(utf8_length + 1);
  }
  if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, dest,
                               utf8_length, nullptr, nullptr)) {
    return nullptr;
  }
  dest[utf8_length] = '\0';
  return dest;
}

void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
  const char* prefixed_name = PrefixLongFilePath(name);
  File::Type type = GetType(namespc, prefixed_name, true);
  data[kType] = type;
  if (type != kDoesNotExist) {
    struct _stat64 st;
    Utf8ToWideScope system_name(prefixed_name);
    int stat_status = _wstat64(system_name.wide(), &st);
    if (stat_status == 0) {
      data[kCreatedTime] = st.st_ctime * 1000;
      data[kModifiedTime] = st.st_mtime * 1000;
      data[kAccessedTime] = st.st_atime * 1000;
      data[kMode] = st.st_mode;
      data[kSize] = st.st_size;
    } else {
      data[kType] = File::kDoesNotExist;
    }
  }
}

time_t File::LastAccessed(Namespace* namespc, const char* name) {
  struct __stat64 st;
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  if (!StatHelper(system_name.wide(), &st)) {
    return -1;
  }
  return st.st_atime;
}

time_t File::LastModified(Namespace* namespc, const char* name) {
  struct __stat64 st;
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  if (!StatHelper(system_name.wide(), &st)) {
    return -1;
  }
  return st.st_mtime;
}

bool File::SetLastAccessed(Namespace* namespc,
                           const char* name,
                           int64_t millis) {
  struct __stat64 st;
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  if (!StatHelper(system_name.wide(), &st)) {  // Checks that it is a file.
    return false;
  }

  // _utime and related functions set the access and modification times of the
  // affected file. Even if the specified modification time is not changed
  // from the current value, _utime will trigger a file modification event
  // (e.g. ReadDirectoryChangesW will report the file as modified).
  //
  // So set the file access time directly using SetFileTime.
  FILETIME at = GetFiletimeFromMillis(millis);
  HANDLE file_handle =
      CreateFileW(system_name.wide(), FILE_WRITE_ATTRIBUTES,
                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                  nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
  if (file_handle == INVALID_HANDLE_VALUE) {
    return false;
  }
  bool result = SetFileTime(file_handle, nullptr, &at, nullptr);
  CloseHandle(file_handle);
  return result;
}

bool File::SetLastModified(Namespace* namespc,
                           const char* name,
                           int64_t millis) {
  // First get the current times.
  struct __stat64 st;
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  if (!StatHelper(system_name.wide(), &st)) {
    return false;
  }

  // Set the new time:
  struct __utimbuf64 times;
  times.actime = st.st_atime;
  times.modtime = millis / kMillisecondsPerSecond;
  return _wutime64(system_name.wide(), &times) == 0;
}

// Keep this function synchronized with the behavior
// of `FileSystemEntity.isAbsolute` in file_system_entity.dart.
bool File::IsAbsolutePath(const char* pathname) {
  if (pathname == nullptr) return false;
  char first = pathname[0];
  char second = pathname[1];
  if (first == '\\' && second == '\\') return true;
  if (second != ':') return false;
  first |= 0x20;
  char third = pathname[2];
  return (first >= 'a') && (first <= 'z') && (third == '\\' || third == '/');
}

const char* File::GetCanonicalPath(Namespace* namespc,
                                   const char* pathname,
                                   char* dest,
                                   int dest_size) {
  Utf8ToWideScope system_name(PrefixLongFilePath(pathname));
  HANDLE file_handle =
      CreateFileW(system_name.wide(), 0, FILE_SHARE_READ, nullptr,
                  OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
  if (file_handle == INVALID_HANDLE_VALUE) {
    return nullptr;
  }
  wchar_t dummy_buffer[1];
  int required_size =
      GetFinalPathNameByHandle(file_handle, dummy_buffer, 0, VOLUME_NAME_DOS);
  if (required_size == 0) {
    DWORD error = GetLastError();
    CloseHandle(file_handle);
    SetLastError(error);
    return nullptr;
  }
  auto path = std::unique_ptr<wchar_t[]>(new wchar_t[required_size]);
  int result_size = GetFinalPathNameByHandle(file_handle, path.get(),
                                             required_size, VOLUME_NAME_DOS);
  ASSERT(result_size <= required_size - 1);
  CloseHandle(file_handle);

  // Remove leading \\?\ since it is only to overcome MAX_PATH limitation.
  // Leave it if input used it though.
  int offset = 0;
  if ((result_size > 4) && (wcsncmp(path.get(), L"\\\\?\\", 4) == 0) &&
      (strncmp(pathname, "\\\\?\\", 4) != 0)) {
    if ((result_size > 8) && (wcsncmp(path.get(), L"\\\\?\\UNC\\", 8) == 0)) {
      // Leave '\\?\UNC\' prefix intact - stripping it makes invalid UNC name.
    } else {
      offset = 4;
    }
  }
  int utf8_size = WideCharToMultiByte(CP_UTF8, 0, path.get() + offset, -1,
                                      nullptr, 0, nullptr, nullptr);
  if (dest == nullptr) {
    dest = DartUtils::ScopedCString(utf8_size);
    dest_size = utf8_size;
  }
  if (dest_size != 0) {
    ASSERT(utf8_size <= dest_size);
  }
  if (0 == WideCharToMultiByte(CP_UTF8, 0, path.get() + offset, -1, dest,
                               dest_size, nullptr, nullptr)) {
    return nullptr;
  }
  return dest;
}

const char* File::PathSeparator() {
  // This is already UTF-8 encoded.
  return "\\";
}

const char* File::StringEscapedPathSeparator() {
  // This is already UTF-8 encoded.
  return "\\\\";
}

File::StdioHandleType File::GetStdioHandleType(int fd) {
  // Treat all stdio handles as pipes. The Windows event handler and
  // socket code will handle the different handle types.
  return kPipe;
}

File::Type File::GetType(Namespace* namespc,
                         const char* pathname,
                         bool follow_links) {
  // File::GetType can be called without scope(when launching isolate),
  // so it mallocs prefixed path.
  StringRAII string_raii = PrefixLongFilePathNoScope(pathname);
  const char* prefixed_path = string_raii.str();

  // Convert to wchar_t string.
  Utf8ToWideScope name(prefixed_path);
  DWORD attributes = GetFileAttributesW(name.wide());
  File::Type result = kIsFile;
  if (attributes == INVALID_FILE_ATTRIBUTES) {
    result = kDoesNotExist;
  } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
    if (follow_links) {
      HANDLE target_handle = CreateFileW(
          name.wide(), 0,
          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
      if (target_handle == INVALID_HANDLE_VALUE) {
        DWORD last_error = GetLastError();
        if ((last_error == ERROR_FILE_NOT_FOUND) ||
            (last_error == ERROR_PATH_NOT_FOUND)) {
          return kDoesNotExist;
        }
        result = kIsLink;
      } else {
        BY_HANDLE_FILE_INFORMATION info;
        if (!GetFileInformationByHandle(target_handle, &info)) {
          CloseHandle(target_handle);
          return File::kIsLink;
        }
        CloseHandle(target_handle);
        return ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
                   ? kIsDirectory
                   : kIsFile;
      }
    } else {
      result = kIsLink;
    }
  } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
    result = kIsDirectory;
  }
  return result;
}

File::Identical File::AreIdentical(Namespace* namespc_1,
                                   const char* file_1,
                                   Namespace* namespc_2,
                                   const char* file_2) {
  USE(namespc_1);
  USE(namespc_2);
  BY_HANDLE_FILE_INFORMATION file_info[2];
  const char* file_names[2] = {PrefixLongFilePath(file_1),
                               PrefixLongFilePath(file_2)};
  for (int i = 0; i < 2; ++i) {
    Utf8ToWideScope wide_name(file_names[i]);
    HANDLE file_handle = CreateFileW(
        wide_name.wide(), 0,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr);
    if (file_handle == INVALID_HANDLE_VALUE) {
      return File::kError;
    }
    int result = GetFileInformationByHandle(file_handle, &file_info[i]);
    if (result == 0) {
      DWORD error = GetLastError();
      CloseHandle(file_handle);
      SetLastError(error);
      return File::kError;
    }
    if (CloseHandle(file_handle) == 0) {
      return File::kError;
    }
  }
  if ((file_info[0].dwVolumeSerialNumber ==
       file_info[1].dwVolumeSerialNumber) &&
      (file_info[0].nFileIndexHigh == file_info[1].nFileIndexHigh) &&
      (file_info[0].nFileIndexLow == file_info[1].nFileIndexLow)) {
    return kIdentical;
  } else {
    return kDifferent;
  }
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_WINDOWS)
