// 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.

#if !defined(DART_IO_DISABLED)

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

#include "bin/process.h"

#include <process.h>  // NOLINT

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/lockers.h"
#include "bin/log.h"
#include "bin/socket.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "bin/utils_win.h"

namespace dart {
namespace bin {

static const int kReadHandle = 0;
static const int kWriteHandle = 1;

int Process::global_exit_code_ = 0;
Mutex* Process::global_exit_code_mutex_ = new Mutex();

// ProcessInfo is used to map a process id to the process handle,
// wait handle for registered exit code event and the pipe used to
// communicate the exit code of the process to Dart.
// ProcessInfo objects are kept in the static singly-linked
// ProcessInfoList.
class ProcessInfo {
 public:
  ProcessInfo(DWORD process_id,
              HANDLE process_handle,
              HANDLE wait_handle,
              HANDLE exit_pipe)
      : process_id_(process_id),
        process_handle_(process_handle),
        wait_handle_(wait_handle),
        exit_pipe_(exit_pipe) { }

  ~ProcessInfo() {
    BOOL success = CloseHandle(process_handle_);
    if (!success) {
      FATAL("Failed to close process handle");
    }
    success = CloseHandle(exit_pipe_);
    if (!success) {
      FATAL("Failed to close process exit code pipe");
    }
  }

  DWORD pid() { return process_id_; }
  HANDLE process_handle() { return process_handle_; }
  HANDLE wait_handle() { return wait_handle_; }
  HANDLE exit_pipe() { return exit_pipe_; }
  ProcessInfo* next() { return next_; }
  void set_next(ProcessInfo* next) { next_ = next; }

 private:
  // Process id.
  DWORD process_id_;
  // Process handle.
  HANDLE process_handle_;
  // Wait handle identifying the exit-code wait operation registered
  // with RegisterWaitForSingleObject.
  HANDLE wait_handle_;
  // File descriptor for pipe to report exit code.
  HANDLE exit_pipe_;
  // Link to next ProcessInfo object in the singly-linked list.
  ProcessInfo* next_;

  DISALLOW_COPY_AND_ASSIGN(ProcessInfo);
};


// Singly-linked list of ProcessInfo objects for all active processes
// started from Dart.
class ProcessInfoList {
 public:
  static void AddProcess(DWORD pid, HANDLE handle, HANDLE pipe) {
    // Register a callback to extract the exit code, when the process
    // is signaled.  The callback runs in a independent thread from the OS pool.
    // Because the callback depends on the process list containing
    // the process, lock the mutex until the process is added to the list.
    MutexLocker locker(mutex_);
    HANDLE wait_handle = INVALID_HANDLE_VALUE;
    BOOL success = RegisterWaitForSingleObject(
        &wait_handle,
        handle,
        &ExitCodeCallback,
        reinterpret_cast<void*>(pid),
        INFINITE,
        WT_EXECUTEONLYONCE);
    if (!success) {
      FATAL("Failed to register exit code wait operation.");
    }
    ProcessInfo* info = new ProcessInfo(pid, handle, wait_handle, pipe);
    // Mutate the process list under the mutex.
    info->set_next(active_processes_);
    active_processes_ = info;
  }

  static bool LookupProcess(DWORD pid,
                            HANDLE* handle,
                            HANDLE* wait_handle,
                            HANDLE* pipe) {
    MutexLocker locker(mutex_);
    ProcessInfo* current = active_processes_;
    while (current != NULL) {
      if (current->pid() == pid) {
        *handle = current->process_handle();
        *wait_handle = current->wait_handle();
        *pipe = current->exit_pipe();
        return true;
      }
      current = current->next();
    }
    return false;
  }

  static void RemoveProcess(DWORD pid) {
    MutexLocker locker(mutex_);
    ProcessInfo* prev = NULL;
    ProcessInfo* current = active_processes_;
    while (current != NULL) {
      if (current->pid() == pid) {
        if (prev == NULL) {
          active_processes_ = current->next();
        } else {
          prev->set_next(current->next());
        }
        delete current;
        return;
      }
      prev = current;
      current = current->next();
    }
  }

 private:
  // Callback called when an exit code is available from one of the
  // processes in the list.
  static void CALLBACK ExitCodeCallback(PVOID data, BOOLEAN timed_out) {
    if (timed_out) {
      return;
    }
    DWORD pid = reinterpret_cast<DWORD>(data);
    HANDLE handle;
    HANDLE wait_handle;
    HANDLE exit_pipe;
    bool success = LookupProcess(pid, &handle, &wait_handle, &exit_pipe);
    if (!success) {
      FATAL("Failed to lookup process in list of active processes");
    }
    // Unregister the event in a non-blocking way.
    BOOL ok = UnregisterWait(wait_handle);
    if (!ok && (GetLastError() != ERROR_IO_PENDING)) {
      FATAL("Failed unregistering wait operation");
    }
    // Get and report the exit code to Dart.
    int exit_code;
    ok = GetExitCodeProcess(handle, reinterpret_cast<DWORD*>(&exit_code));
    if (!ok) {
      FATAL1("GetExitCodeProcess failed %d\n", GetLastError());
    }
    int negative = 0;
    if (exit_code < 0) {
      exit_code = abs(exit_code);
      negative = 1;
    }
    int message[2] = { exit_code, negative };
    DWORD written;
    ok = WriteFile(exit_pipe, message, sizeof(message), &written, NULL);
    // If the process has been closed, the read end of the exit
    // pipe has been closed. It is therefore not a problem that
    // WriteFile fails with a closed pipe error
    // (ERROR_NO_DATA). Other errors should not happen.
    if (ok && (written != sizeof(message))) {
      FATAL("Failed to write entire process exit message");
    } else if (!ok && (GetLastError() != ERROR_NO_DATA)) {
      FATAL1("Failed to write exit code: %d", GetLastError());
    }
    // Remove the process from the list of active processes.
    RemoveProcess(pid);
  }

  // Linked list of ProcessInfo objects for all active processes
  // started from Dart code.
  static ProcessInfo* active_processes_;
  // Mutex protecting all accesses to the linked list of active
  // processes.
  static Mutex* mutex_;

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList);
};


ProcessInfo* ProcessInfoList::active_processes_ = NULL;
Mutex* ProcessInfoList::mutex_ = new Mutex();


// Types of pipes to create.
enum NamedPipeType {
  kInheritRead,
  kInheritWrite,
  kInheritNone
};


// Create a pipe for communicating with a new process. The handles array
// will contain the read and write ends of the pipe. Based on the type
// one of the handles will be inheritable.
// NOTE: If this function returns false the handles might have been allocated
// and the caller should make sure to close them in case of an error.
static bool CreateProcessPipe(HANDLE handles[2],
                              wchar_t* pipe_name,
                              NamedPipeType type) {
  // Security attributes describing an inheritable handle.
  SECURITY_ATTRIBUTES inherit_handle;
  inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES);
  inherit_handle.bInheritHandle = TRUE;
  inherit_handle.lpSecurityDescriptor = NULL;

  if (type == kInheritRead) {
    handles[kWriteHandle] =
        CreateNamedPipeW(pipe_name,
                         PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
                         PIPE_TYPE_BYTE | PIPE_WAIT,
                         1,             // Number of pipes
                         1024,          // Out buffer size
                         1024,          // In buffer size
                         0,             // Timeout in ms
                         NULL);

    if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) {
      Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError());
      return false;
    }

    handles[kReadHandle] =
        CreateFileW(pipe_name,
                    GENERIC_READ,
                    0,
                    &inherit_handle,
                    OPEN_EXISTING,
                    FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
                    NULL);
    if (handles[kReadHandle] == INVALID_HANDLE_VALUE) {
      Log::PrintErr("CreateFile failed %d\n", GetLastError());
      return false;
    }
  } else {
    ASSERT((type == kInheritWrite) || (type == kInheritNone));
    handles[kReadHandle] =
        CreateNamedPipeW(pipe_name,
                         PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
                         PIPE_TYPE_BYTE | PIPE_WAIT,
                         1,             // Number of pipes
                         1024,          // Out buffer size
                         1024,          // In buffer size
                         0,             // Timeout in ms
                         NULL);

    if (handles[kReadHandle] == INVALID_HANDLE_VALUE) {
      Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError());
      return false;
    }

    handles[kWriteHandle] =
        CreateFileW(pipe_name,
                    GENERIC_WRITE,
                    0,
                    (type == kInheritWrite) ? &inherit_handle : NULL,
                    OPEN_EXISTING,
                    FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
                    NULL);
    if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) {
      Log::PrintErr("CreateFile failed %d\n", GetLastError());
      return false;
    }
  }
  return true;
}


static void CloseProcessPipe(HANDLE handles[2]) {
  for (int i = kReadHandle; i < kWriteHandle; i++) {
    if (handles[i] != INVALID_HANDLE_VALUE) {
      if (!CloseHandle(handles[i])) {
        Log::PrintErr("CloseHandle failed %d\n", GetLastError());
      }
      handles[i] = INVALID_HANDLE_VALUE;
    }
  }
}


static void CloseProcessPipes(HANDLE handles1[2],
                              HANDLE handles2[2],
                              HANDLE handles3[2],
                              HANDLE handles4[2]) {
  CloseProcessPipe(handles1);
  CloseProcessPipe(handles2);
  CloseProcessPipe(handles3);
  CloseProcessPipe(handles4);
}


static int SetOsErrorMessage(char** os_error_message) {
  int error_code = GetLastError();
  const int kMaxMessageLength = 256;
  wchar_t message[kMaxMessageLength];
  FormatMessageIntoBuffer(error_code, message, kMaxMessageLength);
  *os_error_message = StringUtilsWin::WideToUtf8(message);
  return error_code;
}


// Open an inheritable handle to NUL.
static HANDLE OpenNul() {
  SECURITY_ATTRIBUTES inherit_handle;
  inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES);
  inherit_handle.bInheritHandle = TRUE;
  inherit_handle.lpSecurityDescriptor = NULL;
  HANDLE nul = CreateFile(L"NUL",
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          &inherit_handle,
                          OPEN_EXISTING,
                          0,
                          NULL);
  if (nul == INVALID_HANDLE_VALUE) {
    Log::PrintErr("CloseHandle failed %d\n", GetLastError());
  }
  return nul;
}


typedef BOOL (WINAPI *InitProcThreadAttrListFn)(
    LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T);

typedef BOOL (WINAPI *UpdateProcThreadAttrFn)(
    LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR,
    PVOID, SIZE_T, PVOID, PSIZE_T);

typedef VOID (WINAPI *DeleteProcThreadAttrListFn)(
     LPPROC_THREAD_ATTRIBUTE_LIST);


static InitProcThreadAttrListFn init_proc_thread_attr_list = NULL;
static UpdateProcThreadAttrFn update_proc_thread_attr = NULL;
static DeleteProcThreadAttrListFn delete_proc_thread_attr_list = NULL;


static bool EnsureInitialized() {
  static bool load_attempted = false;
  static Mutex* mutex = new Mutex();
  HMODULE kernel32_module = GetModuleHandleW(L"kernel32.dll");
  if (!load_attempted) {
    MutexLocker locker(mutex);
    if (load_attempted) {
      return (delete_proc_thread_attr_list != NULL);
    }
    init_proc_thread_attr_list = reinterpret_cast<InitProcThreadAttrListFn>(
        GetProcAddress(kernel32_module, "InitializeProcThreadAttributeList"));
    update_proc_thread_attr = reinterpret_cast<UpdateProcThreadAttrFn>(
        GetProcAddress(kernel32_module, "UpdateProcThreadAttribute"));
    delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>(
        GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList"));
    load_attempted = true;
    return (delete_proc_thread_attr_list != NULL);
  }
  return (delete_proc_thread_attr_list != NULL);
}


const int kMaxPipeNameSize = 80;
template<int Count>
static int GenerateNames(wchar_t pipe_names[Count][kMaxPipeNameSize]) {
  UUID uuid;
  RPC_STATUS status = UuidCreateSequential(&uuid);
  if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
    return status;
  }
  RPC_WSTR uuid_string;
  status = UuidToStringW(&uuid, &uuid_string);
  if (status != RPC_S_OK) {
    return status;
  }
  for (int i = 0; i < Count; i++) {
    static const wchar_t* prefix = L"\\\\.\\Pipe\\dart";
    _snwprintf(pipe_names[i],
               kMaxPipeNameSize,
               L"%s_%s_%d", prefix, uuid_string, i + 1);
  }
  status = RpcStringFreeW(&uuid_string);
  if (status != RPC_S_OK) {
    return status;
  }
  return 0;
}


class ProcessStarter {
 public:
  ProcessStarter(const char* path,
                 char* arguments[],
                 intptr_t arguments_length,
                 const char* working_directory,
                 char* environment[],
                 intptr_t environment_length,
                 ProcessStartMode mode,
                 intptr_t* in,
                 intptr_t* out,
                 intptr_t* err,
                 intptr_t* id,
                 intptr_t* exit_handler,
                 char** os_error_message)
      : path_(path),
        working_directory_(working_directory),
        mode_(mode),
        in_(in),
        out_(out),
        err_(err),
        id_(id),
        exit_handler_(exit_handler),
        os_error_message_(os_error_message) {
    stdin_handles_[kReadHandle] = INVALID_HANDLE_VALUE;
    stdin_handles_[kWriteHandle] = INVALID_HANDLE_VALUE;
    stdout_handles_[kReadHandle] = INVALID_HANDLE_VALUE;
    stdout_handles_[kWriteHandle] = INVALID_HANDLE_VALUE;
    stderr_handles_[kReadHandle] = INVALID_HANDLE_VALUE;
    stderr_handles_[kWriteHandle] = INVALID_HANDLE_VALUE;
    exit_handles_[kReadHandle] = INVALID_HANDLE_VALUE;
    exit_handles_[kWriteHandle] = INVALID_HANDLE_VALUE;

    // Transform input strings to system format.
    const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path_);
    wchar_t** system_arguments;
    system_arguments = reinterpret_cast<wchar_t**>(
        Dart_ScopeAllocate(arguments_length * sizeof(*system_arguments)));
    for (int i = 0; i < arguments_length; i++) {
       system_arguments[i] = StringUtilsWin::Utf8ToWide(arguments[i]);
    }

    // Compute command-line length.
    int command_line_length = wcslen(system_path);
    for (int i = 0; i < arguments_length; i++) {
      command_line_length += wcslen(system_arguments[i]);
    }
    // Account for null termination and one space per argument.
    command_line_length += arguments_length + 1;

    // Put together command-line string.
    command_line_ = reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(
        command_line_length * sizeof(*command_line_)));
    int len = 0;
    int remaining = command_line_length;
    int written =
        _snwprintf(command_line_ + len, remaining, L"%s", system_path);
    len += written;
    remaining -= written;
    ASSERT(remaining >= 0);
    for (int i = 0; i < arguments_length; i++) {
      written = _snwprintf(
          command_line_ + len, remaining, L" %s", system_arguments[i]);
      len += written;
      remaining -= written;
      ASSERT(remaining >= 0);
    }

    // Create environment block if an environment is supplied.
    environment_block_ = NULL;
    if (environment != NULL) {
      wchar_t** system_environment;
      system_environment = reinterpret_cast<wchar_t**>(
          Dart_ScopeAllocate(environment_length * sizeof(*system_environment)));
      // Convert environment strings to system strings.
      for (intptr_t i = 0; i < environment_length; i++) {
        system_environment[i] = StringUtilsWin::Utf8ToWide(environment[i]);
      }

      // An environment block is a sequence of zero-terminated strings
      // followed by a block-terminating zero char.
      intptr_t block_size = 1;
      for (intptr_t i = 0; i < environment_length; i++) {
        block_size += wcslen(system_environment[i]) + 1;
      }
      environment_block_ = reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(
          block_size * sizeof(*environment_block_)));
      intptr_t block_index = 0;
      for (intptr_t i = 0; i < environment_length; i++) {
        intptr_t len = wcslen(system_environment[i]);
        intptr_t result = _snwprintf(environment_block_ + block_index,
                                     len,
                                     L"%s",
                                     system_environment[i]);
        ASSERT(result == len);
        block_index += len;
        environment_block_[block_index++] = '\0';
      }
      // Block-terminating zero char.
      environment_block_[block_index++] = '\0';
      ASSERT(block_index == block_size);
    }

    system_working_directory_ = NULL;
    if (working_directory_ != NULL) {
      system_working_directory_ =
          StringUtilsWin::Utf8ToWide(working_directory_);
    }

    attribute_list_ = NULL;
  }


  ~ProcessStarter() {
    if (attribute_list_ != NULL) {
      delete_proc_thread_attr_list(attribute_list_);
    }
  }


  int Start() {
    // Create pipes required.
    int err = CreatePipes();
    if (err != 0) {
      return err;
    }

    // Setup info structures.
    STARTUPINFOEXW startup_info;
    ZeroMemory(&startup_info, sizeof(startup_info));
    startup_info.StartupInfo.cb = sizeof(startup_info);
    startup_info.StartupInfo.hStdInput = stdin_handles_[kReadHandle];
    startup_info.StartupInfo.hStdOutput = stdout_handles_[kWriteHandle];
    startup_info.StartupInfo.hStdError = stderr_handles_[kWriteHandle];
    startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;

    bool supports_proc_thread_attr_lists = EnsureInitialized();
    if (supports_proc_thread_attr_lists) {
      // Setup the handles to inherit. We only want to inherit the three handles
      // for stdin, stdout and stderr.
      SIZE_T size = 0;
      // The call to determine the size of an attribute list always fails with
      // ERROR_INSUFFICIENT_BUFFER and that error should be ignored.
      if (!init_proc_thread_attr_list(NULL, 1, 0, &size) &&
          (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
        return CleanupAndReturnError();
      }
      attribute_list_ = reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(
          Dart_ScopeAllocate(size));
      ZeroMemory(attribute_list_, size);
      if (!init_proc_thread_attr_list(attribute_list_, 1, 0, &size)) {
        return CleanupAndReturnError();
      }
      static const int kNumInheritedHandles = 3;
      HANDLE inherited_handles[kNumInheritedHandles] =
          { stdin_handles_[kReadHandle],
            stdout_handles_[kWriteHandle],
            stderr_handles_[kWriteHandle] };
      if (!update_proc_thread_attr(attribute_list_,
                                   0,
                                   PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
                                   inherited_handles,
                                   kNumInheritedHandles * sizeof(HANDLE),
                                   NULL,
                                   NULL)) {
        return CleanupAndReturnError();
      }
      startup_info.lpAttributeList = attribute_list_;
    }

    PROCESS_INFORMATION process_info;
    ZeroMemory(&process_info, sizeof(process_info));

    // Create process.
    DWORD creation_flags =
        EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT;
    if (mode_ != kNormal) {
      creation_flags |= DETACHED_PROCESS;
    }
    BOOL result = CreateProcessW(NULL,   // ApplicationName
                                 command_line_,
                                 NULL,   // ProcessAttributes
                                 NULL,   // ThreadAttributes
                                 TRUE,   // InheritHandles
                                 creation_flags,
                                 environment_block_,
                                 system_working_directory_,
                                 reinterpret_cast<STARTUPINFOW*>(&startup_info),
                                 &process_info);

    if (result == 0) {
      return CleanupAndReturnError();
    }

    CloseHandle(stdin_handles_[kReadHandle]);
    CloseHandle(stdout_handles_[kWriteHandle]);
    CloseHandle(stderr_handles_[kWriteHandle]);
    if (mode_ == kNormal) {
      ProcessInfoList::AddProcess(process_info.dwProcessId,
                                  process_info.hProcess,
                                  exit_handles_[kWriteHandle]);
    }
    if (mode_ != kDetached) {
      // Connect the three stdio streams.
      FileHandle* stdin_handle = new FileHandle(stdin_handles_[kWriteHandle]);
      FileHandle* stdout_handle = new FileHandle(stdout_handles_[kReadHandle]);
      FileHandle* stderr_handle = new FileHandle(stderr_handles_[kReadHandle]);
      *in_ = reinterpret_cast<intptr_t>(stdout_handle);
      *out_ = reinterpret_cast<intptr_t>(stdin_handle);
      *err_ = reinterpret_cast<intptr_t>(stderr_handle);
      if (mode_ == kNormal) {
        FileHandle* exit_handle = new FileHandle(exit_handles_[kReadHandle]);
        *exit_handler_ = reinterpret_cast<intptr_t>(exit_handle);
      }
    }

    CloseHandle(process_info.hThread);

    // Return process id.
    *id_ = process_info.dwProcessId;
    return 0;
  }


  int CreatePipes() {
    // Generate unique pipe names for the four named pipes needed.
    wchar_t pipe_names[4][kMaxPipeNameSize];
    int status = GenerateNames<4>(pipe_names);
    if (status != 0) {
      SetOsErrorMessage(os_error_message_);
      Log::PrintErr("UuidCreateSequential failed %d\n", status);
      return status;
    }

    if (mode_ != kDetached) {
      // Open pipes for stdin, stdout, stderr and for communicating the exit
      // code.
      if (!CreateProcessPipe(stdin_handles_, pipe_names[0], kInheritRead) ||
          !CreateProcessPipe(stdout_handles_, pipe_names[1], kInheritWrite) ||
          !CreateProcessPipe(stderr_handles_, pipe_names[2], kInheritWrite)) {
        return CleanupAndReturnError();
      }
      // Only open exit code pipe for non detached processes.
      if (mode_ == kNormal) {
        if (!CreateProcessPipe(exit_handles_, pipe_names[3], kInheritNone)) {
          return CleanupAndReturnError();
        }
      }
    } else {
      // Open NUL for stdin, stdout, and stderr.
      stdin_handles_[kReadHandle] = OpenNul();
      if (stdin_handles_[kReadHandle] == INVALID_HANDLE_VALUE) {
        return CleanupAndReturnError();
      }

      stdout_handles_[kWriteHandle] = OpenNul();
      if (stdout_handles_[kWriteHandle] == INVALID_HANDLE_VALUE) {
        return CleanupAndReturnError();
      }

      stderr_handles_[kWriteHandle] = OpenNul();
      if (stderr_handles_[kWriteHandle] == INVALID_HANDLE_VALUE) {
        return CleanupAndReturnError();
      }
    }
    return 0;
  }


  int CleanupAndReturnError() {
    int error_code = SetOsErrorMessage(os_error_message_);
    CloseProcessPipes(
        stdin_handles_, stdout_handles_, stderr_handles_, exit_handles_);
    return error_code;
  }


  HANDLE stdin_handles_[2];
  HANDLE stdout_handles_[2];
  HANDLE stderr_handles_[2];
  HANDLE exit_handles_[2];

  const wchar_t* system_working_directory_;
  wchar_t* command_line_;
  wchar_t* environment_block_;
  LPPROC_THREAD_ATTRIBUTE_LIST attribute_list_;

  const char* path_;
  const char* working_directory_;
  ProcessStartMode mode_;
  intptr_t* in_;
  intptr_t* out_;
  intptr_t* err_;
  intptr_t* id_;
  intptr_t* exit_handler_;
  char** os_error_message_;

 private:
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
};


int Process::Start(const char* path,
                   char* arguments[],
                   intptr_t arguments_length,
                   const char* working_directory,
                   char* environment[],
                   intptr_t environment_length,
                   ProcessStartMode mode,
                   intptr_t* in,
                   intptr_t* out,
                   intptr_t* err,
                   intptr_t* id,
                   intptr_t* exit_handler,
                   char** os_error_message) {
  ProcessStarter starter(path,
                         arguments,
                         arguments_length,
                         working_directory,
                         environment,
                         environment_length,
                         mode,
                         in,
                         out,
                         err,
                         id,
                         exit_handler,
                         os_error_message);
  return starter.Start();
}


class BufferList: public BufferListBase {
 public:
  BufferList() : read_pending_(true) { }

  // Indicate that data has been read into the buffer provided to
  // overlapped read.
  void DataIsRead(intptr_t size) {
    ASSERT(read_pending_ == true);
    data_size_ += size;
    free_size_ -= size;
    ASSERT(free_size_ >= 0);
    read_pending_ = false;
  }

  // The access to the read buffer for overlapped read.
  void GetReadBuffer(uint8_t** buffer, intptr_t* size) {
    ASSERT(!read_pending_);
    if (free_size_ == 0) {
      Allocate();
    }
    ASSERT(free_size_ > 0);
    ASSERT(free_size_ <= kBufferSize);
    *buffer = FreeSpaceAddress();
    *size = free_size_;
    read_pending_ = true;
  }

  intptr_t GetDataSize() {
    return data_size_;
  }

  uint8_t* GetFirstDataBuffer() {
    ASSERT(head_ != NULL);
    ASSERT(head_ == tail_);
    ASSERT(data_size_ <= kBufferSize);
    return head_->data_;
  }

  void FreeDataBuffer() {
    Free();
  }

 private:
  bool read_pending_;

  DISALLOW_COPY_AND_ASSIGN(BufferList);
};


class OverlappedHandle {
 public:
  OverlappedHandle() {}

  void Init(HANDLE handle, HANDLE event) {
    handle_ = handle;
    event_ = event;
    ClearOverlapped();
  }

  bool HasEvent(HANDLE event) {
    return (event_ == event);
  }

  bool Read() {
    // Get the data read as a result of a completed overlapped operation.
    if (overlapped_.InternalHigh > 0) {
      buffer_.DataIsRead(overlapped_.InternalHigh);
    } else {
      buffer_.DataIsRead(0);
    }

    // Keep reading until error or pending operation.
    while (true) {
      ClearOverlapped();
      uint8_t* buffer;
      intptr_t buffer_size;
      buffer_.GetReadBuffer(&buffer, &buffer_size);
      BOOL ok = ReadFile(handle_, buffer, buffer_size, NULL, &overlapped_);
      if (!ok) {
        return (GetLastError() == ERROR_IO_PENDING);
      }
      buffer_.DataIsRead(overlapped_.InternalHigh);
    }
  }

  Dart_Handle GetData() {
    return buffer_.GetData();
  }

  intptr_t GetDataSize() {
    return buffer_.GetDataSize();
  }

  uint8_t* GetFirstDataBuffer() {
    return buffer_.GetFirstDataBuffer();
  }

  void FreeDataBuffer() {
    return buffer_.FreeDataBuffer();
  }

  void Close() {
    CloseHandle(handle_);
    CloseHandle(event_);
    handle_ = INVALID_HANDLE_VALUE;
    overlapped_.hEvent = INVALID_HANDLE_VALUE;
  }

 private:
  void ClearOverlapped() {
    memset(&overlapped_, 0, sizeof(overlapped_));
    overlapped_.hEvent = event_;
  }

  OVERLAPPED overlapped_;
  HANDLE handle_;
  HANDLE event_;
  BufferList buffer_;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(OverlappedHandle);
};


bool Process::Wait(intptr_t pid,
                   intptr_t in,
                   intptr_t out,
                   intptr_t err,
                   intptr_t exit_event,
                   ProcessResult* result) {
  // Close input to the process right away.
  reinterpret_cast<FileHandle*>(in)->Close();

  // All pipes created to the sub-process support overlapped IO.
  FileHandle* stdout_handle = reinterpret_cast<FileHandle*>(out);
  ASSERT(stdout_handle->SupportsOverlappedIO());
  FileHandle* stderr_handle = reinterpret_cast<FileHandle*>(err);
  ASSERT(stderr_handle->SupportsOverlappedIO());
  FileHandle* exit_handle = reinterpret_cast<FileHandle*>(exit_event);
  ASSERT(exit_handle->SupportsOverlappedIO());

  // Create three events for overlapped IO. These are created as already
  // signalled to ensure they have read called at least once.
  static const int kHandles = 3;
  HANDLE events[kHandles];
  for (int i = 0; i < kHandles; i++) {
    events[i] = CreateEvent(NULL, FALSE, TRUE, NULL);
  }

  // Setup the structure for handling overlapped IO.
  OverlappedHandle oh[kHandles];
  oh[0].Init(stdout_handle->handle(), events[0]);
  oh[1].Init(stderr_handle->handle(), events[1]);
  oh[2].Init(exit_handle->handle(), events[2]);

  // Continue until all handles are closed.
  int alive = kHandles;
  while (alive > 0) {
    // Blocking call waiting for events from the child process.
    DWORD wait_result = WaitForMultipleObjects(alive, events, FALSE, INFINITE);

    // Find the handle signalled.
    int index = wait_result - WAIT_OBJECT_0;
    for (int i = 0; i < kHandles; i++) {
      if (oh[i].HasEvent(events[index])) {
        bool ok = oh[i].Read();
        if (!ok) {
          if (GetLastError() == ERROR_BROKEN_PIPE) {
            oh[i].Close();
            alive--;
            if (index < alive) {
              events[index] = events[alive];
            }
          } else if (err != ERROR_IO_PENDING) {
            DWORD e = GetLastError();
            oh[0].Close();
            oh[1].Close();
            oh[2].Close();
            SetLastError(e);
            return false;
          }
        }
        break;
      }
    }
  }

  // All handles closed and all data read.
  result->set_stdout_data(oh[0].GetData());
  result->set_stderr_data(oh[1].GetData());

  // Calculate the exit code.
  ASSERT(oh[2].GetDataSize() == 8);
  uint32_t exit_codes[2];
  memmove(&exit_codes, oh[2].GetFirstDataBuffer(), sizeof(exit_codes));
  oh[2].FreeDataBuffer();
  intptr_t exit_code = exit_codes[0];
  intptr_t negative = exit_codes[1];
  if (negative != 0) {
    exit_code = -exit_code;
  }
  result->set_exit_code(exit_code);
  return true;
}


bool Process::Kill(intptr_t id, int signal) {
  USE(signal);  // signal is not used on Windows.
  HANDLE process_handle;
  HANDLE wait_handle;
  HANDLE exit_pipe;
  // First check the process info list for the process to get a handle to it.
  bool success = ProcessInfoList::LookupProcess(id,
                                                &process_handle,
                                                &wait_handle,
                                                &exit_pipe);
  // For detached processes we don't have the process registered in the
  // process info list. Try to look it up through the OS.
  if (!success) {
    process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, id);
    // The process is already dead.
    if (process_handle == INVALID_HANDLE_VALUE) {
      return false;
    }
  }
  BOOL result = TerminateProcess(process_handle, -1);
  return result ? true : false;
}


void Process::TerminateExitCodeHandler() {
  // Nothing needs to be done on Windows.
}


intptr_t Process::CurrentProcessId() {
  return static_cast<intptr_t>(GetCurrentProcessId());
}


static SignalInfo* signal_handlers = NULL;
static Mutex* signal_mutex = new Mutex();


SignalInfo::~SignalInfo() {
  reinterpret_cast<FileHandle*>(fd_)->Close();
}


BOOL WINAPI SignalHandler(DWORD signal) {
  MutexLocker lock(signal_mutex);
  const SignalInfo* handler = signal_handlers;
  bool handled = false;
  while (handler != NULL) {
    if (handler->signal() == signal) {
      int value = 0;
      Socket::Write(handler->fd(), &value, 1);
      handled = true;
    }
    handler = handler->next();
  }
  return handled;
}


intptr_t GetWinSignal(intptr_t signal) {
  switch (signal) {
    case kSighup: return CTRL_CLOSE_EVENT;
    case kSigint: return CTRL_C_EVENT;
    default:
      return -1;
  }
}


intptr_t Process::SetSignalHandler(intptr_t signal) {
  signal = GetWinSignal(signal);
  if (signal == -1) {
    return -1;
  }

  // Generate a unique pipe name for the named pipe.
  wchar_t pipe_name[kMaxPipeNameSize];
  int status = GenerateNames<1>(&pipe_name);
  if (status != 0) {
    return status;
  }

  HANDLE fds[2];
  if (!CreateProcessPipe(fds, pipe_name, kInheritNone)) {
    int error_code = GetLastError();
    CloseProcessPipe(fds);
    SetLastError(error_code);
    return -1;
  }
  MutexLocker lock(signal_mutex);
  FileHandle* write_handle = new FileHandle(fds[kWriteHandle]);
  write_handle->EnsureInitialized(EventHandler::delegate());
  intptr_t write_fd = reinterpret_cast<intptr_t>(write_handle);
  if (signal_handlers == NULL) {
    if (SetConsoleCtrlHandler(SignalHandler, true) == 0) {
      int error_code = GetLastError();
      delete write_handle;
      CloseProcessPipe(fds);
      SetLastError(error_code);
      return -1;
    }
  }
  signal_handlers = new SignalInfo(write_fd, signal, signal_handlers);
  return reinterpret_cast<intptr_t>(new FileHandle(fds[kReadHandle]));
}


void Process::ClearSignalHandler(intptr_t signal) {
  signal = GetWinSignal(signal);
  if (signal == -1) {
    return;
  }
  MutexLocker lock(signal_mutex);
  SignalInfo* handler = signal_handlers;
  while (handler != NULL) {
    if ((handler->port() == Dart_GetMainPortId()) &&
        (handler->signal() == signal)) {
      handler->Unlink();
      break;
    }
    handler = handler->next();
  }
  if (handler != NULL) {
    if (signal_handlers == handler) {
      signal_handlers = handler->next();
    }
    if (signal_handlers == NULL) {
      USE(SetConsoleCtrlHandler(SignalHandler, false));
    }
  }
  delete handler;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(TARGET_OS_WINDOWS)

#endif  // !defined(DART_IO_DISABLED)
