// 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_ = 0;
  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, NULL);
  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, NULL, 0, NULL, NULL);
    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);
  return _lseeki64(handle_->fd(), 0, SEEK_CUR);
}

bool File::SetPosition(int64_t position) {
  ASSERT(handle_->fd() >= 0);
  return _lseeki64(handle_->fd(), position, SEEK_SET) >= 0;
}

bool File::Truncate(int64_t length) {
  ASSERT(handle_->fd() >= 0);
  return _chsize_s(handle_->fd(), length) == 0;
}

bool File::Flush() {
  ASSERT(handle_->fd());
  return _commit(handle_->fd()) != -1;
}

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 NULL;
  }
  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 NULL;
    }
  }
  return new File(new FileHandle(fd));
}

class StringRAII {
 public:
  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)
                                      : 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) {
  Utf8ToWideScope system_name(PrefixLongFilePath(name));
  int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 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 const int kReparseDataHeaderSize = sizeof(ULONG) + 2 * sizeof(USHORT);
static const int kMountPointHeaderSize = 4 * sizeof(USHORT);

// Note: CreateLink used to create junctions on Windows instead of true
// symbolic links. All File::*Link methods now support handling links created
// as junctions and symbolic links.
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::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;
  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;

  // Junction links 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 a link. This step is only
  // necessary for junctions created by the old Link.create implementation.
  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 = NULL;
  if (last_back_slash == NULL && last_forward_slash == NULL) {
    return NULL;
  } else if (last_forward_slash != NULL && last_forward_slash != NULL) {
    // 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 == NULL) ? 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 NULL;
  }
  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 NULL;
    }

    char suffix[8 + 1];
    Utils::SNPrint(suffix, sizeof(suffix), "%x", suffix_bytes);
    Utf8ToWideScope source_path(src);
    if (!buffer.Add(suffix)) {
      return NULL;
    }
    if (CopyFileExW(source_path.wide(), buffer.AsStringW(), NULL, NULL, NULL,
                    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 NULL;
  }
  UUID uuid;
  RPC_STATUS status = UuidCreateSequential(&uuid);
  if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
    return NULL;
  }
  RPC_WSTR uuid_string;
  status = UuidToStringW(&uuid, &uuid_string);
  if (status != RPC_S_OK) {
    return NULL;
  }
  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 NULL;
  }

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

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 == NULL) {
    // 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(), NULL,
                       NULL, NULL, 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, NULL,
      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
      NULL);
  if (dir_handle == INVALID_HANDLE_VALUE) {
    return NULL;
  }

  // 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, NULL, 0,
                               buffer, buffer_size, &received_bytes, NULL);
  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, NULL, 0,
                               buffer, buffer_size, &received_bytes, NULL);
      if (result == 0) {
        // Overwrite the ERROR_MORE_DATA.
        error = GetLastError();
      }
    }
    if (result == 0) {
      CloseHandle(dir_handle);
      SetLastError(error);
      return NULL;
    }
  }
  if (CloseHandle(dir_handle) == 0) {
    return NULL;
  }

  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 NULL;
  }

  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, NULL,
                                        0, NULL, NULL);
  if (dest_size > 0 && dest_size <= utf8_length) {
    return NULL;
  }
  if (dest == NULL) {
    dest = DartUtils::ScopedCString(utf8_length + 1);
  }
  if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, dest,
                               utf8_length, NULL, NULL)) {
    return NULL;
  }
  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 == NULL) 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, NULL, OPEN_EXISTING,
                  FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (file_handle == INVALID_HANDLE_VALUE) {
    return NULL;
  }
  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 NULL;
  }
  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 \\?\ if possible, unless input used it.
  int offset = 0;
  if ((result_size > 4) && (wcsncmp(path.get(), L"\\\\?\\", 4) == 0) &&
      (strncmp(pathname, "\\\\?\\", 4) != 0)) {
    offset = 4;
  }
  int utf8_size = WideCharToMultiByte(CP_UTF8, 0, path.get() + offset, -1,
                                      nullptr, 0, nullptr, nullptr);
  if (dest == NULL) {
    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, NULL, NULL)) {
    return NULL;
  }
  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,
                      NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
      if (target_handle == INVALID_HANDLE_VALUE) {
        result = File::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)
                   ? File::kIsDirectory
                   : File::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, NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
    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)
