/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <assert.h>
#include <direct.h>
#include <limits.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <wchar.h>

#include "uv.h"
#include "internal.h"

#include <iphlpapi.h>
#include <psapi.h>
#include <tlhelp32.h>


/*
 * Max title length; the only thing MSDN tells us about the maximum length
 * of the console title is that it is smaller than 64K. However in practice
 * it is much smaller, and there is no way to figure out what the exact length
 * of the title is or can be, at least not on XP. To make it even more
 * annoying, GetConsoleTitle failes when the buffer to be read into is bigger
 * than the actual maximum length. So we make a conservative guess here;
 * just don't put the novel you're writing in the title, unless the plot
 * survives truncation.
 */
#define MAX_TITLE_LENGTH 8192

/* The number of nanoseconds in one second. */
#undef NANOSEC
#define NANOSEC 1000000000


/* Cached copy of the process title, plus a mutex guarding it. */
static char *process_title;
static CRITICAL_SECTION process_title_lock;

/* The tick frequency of the high-resolution clock. */
static uint64_t hrtime_frequency_ = 0;


/*
 * One-time intialization code for functionality defined in util.c.
 */
void uv__util_init() {
  /* Initialize process title access mutex. */
  InitializeCriticalSection(&process_title_lock);

  /* Retrieve high-resolution timer frequency. */
  if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_))
    hrtime_frequency_ = 0;
}


int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
    char* utf8Buffer, size_t utf8Size) {
  return WideCharToMultiByte(CP_UTF8,
                             0,
                             utf16Buffer,
                             utf16Size,
                             utf8Buffer,
                             utf8Size,
                             NULL,
                             NULL);
}


int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
    size_t utf16Size) {
  return MultiByteToWideChar(CP_UTF8,
                             0,
                             utf8Buffer,
                             -1,
                             utf16Buffer,
                             utf16Size);
}


int uv_exepath(char* buffer, size_t* size_ptr) {
  int utf8_len, utf16_buffer_len, utf16_len;
  WCHAR* utf16_buffer;

  if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
    return -1;
  }

  if (*size_ptr > 32768) {
    /* Windows paths can never be longer than this. */
    utf16_buffer_len = 32768;
  } else {
    utf16_buffer_len = (int) *size_ptr;
  }

  utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len);
  if (!utf16_buffer) {
    return -1;
  }

  /* Get the path as UTF-16. */
  utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
  if (utf16_len <= 0) {
    goto error;
  }

  /* utf16_len contains the length, *not* including the terminating null. */
  utf16_buffer[utf16_len] = L'\0';

  /* Convert to UTF-8 */
  utf8_len = WideCharToMultiByte(CP_UTF8,
                                 0,
                                 utf16_buffer,
                                 -1,
                                 buffer,
                                 *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr,
                                 NULL,
                                 NULL);
  if (utf8_len == 0) {
    goto error;
  }

  free(utf16_buffer);

  /* utf8_len *does* include the terminating null at this point, but the */
  /* returned size shouldn't. */
  *size_ptr = utf8_len - 1;
  return 0;

 error:
  free(utf16_buffer);
  return -1;
}


uv_err_t uv_cwd(char* buffer, size_t size) {
  DWORD utf16_len;
  WCHAR utf16_buffer[MAX_PATH];
  int r;

  if (buffer == NULL || size == 0) {
    return uv__new_artificial_error(UV_EINVAL);
  }

  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
  if (utf16_len == 0) {
    return uv__new_sys_error(GetLastError());
  } else if (utf16_len > MAX_PATH) {
    /* This should be impossible;  however the CRT has a code path to deal */
    /* with this scenario, so I added a check anyway. */
    return uv__new_artificial_error(UV_EIO);
  }

  /* utf16_len contains the length, *not* including the terminating null. */
  utf16_buffer[utf16_len] = L'\0';

  /* The returned directory should not have a trailing slash, unless it */
  /* points at a drive root, like c:\. Remove it if needed.*/
  if (utf16_buffer[utf16_len - 1] == L'\\' &&
      !(utf16_len == 3 && utf16_buffer[1] == L':')) {
    utf16_len--;
    utf16_buffer[utf16_len] = L'\0';
  }

  /* Convert to UTF-8 */
  r = WideCharToMultiByte(CP_UTF8,
                          0,
                          utf16_buffer,
                          -1,
                          buffer,
                          size > INT_MAX ? INT_MAX : (int) size,
                          NULL,
                          NULL);
  if (r == 0) {
    return uv__new_sys_error(GetLastError());
  }

  return uv_ok_;
}


uv_err_t uv_chdir(const char* dir) {
  WCHAR utf16_buffer[MAX_PATH];
  size_t utf16_len;
  WCHAR drive_letter, env_var[4];

  if (dir == NULL) {
    return uv__new_artificial_error(UV_EINVAL);
  }

  if (MultiByteToWideChar(CP_UTF8,
                          0,
                          dir,
                          -1,
                          utf16_buffer,
                          MAX_PATH) == 0) {
    DWORD error = GetLastError();
    /* The maximum length of the current working directory is 260 chars, */
    /* including terminating null. If it doesn't fit, the path name must be */
    /* too long. */
    if (error == ERROR_INSUFFICIENT_BUFFER) {
      return uv__new_artificial_error(UV_ENAMETOOLONG);
    } else {
      return uv__new_sys_error(error);
    }
  }

  if (!SetCurrentDirectoryW(utf16_buffer)) {
    return uv__new_sys_error(GetLastError());
  }

  /* Windows stores the drive-local path in an "hidden" environment variable, */
  /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */
  /* update this, so we'll have to do it. */
  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
  if (utf16_len == 0) {
    return uv__new_sys_error(GetLastError());
  } else if (utf16_len > MAX_PATH) {
    return uv__new_artificial_error(UV_EIO);
  }

  /* The returned directory should not have a trailing slash, unless it */
  /* points at a drive root, like c:\. Remove it if needed. */
  if (utf16_buffer[utf16_len - 1] == L'\\' &&
      !(utf16_len == 3 && utf16_buffer[1] == L':')) {
    utf16_len--;
    utf16_buffer[utf16_len] = L'\0';
  }

  if (utf16_len < 2 || utf16_buffer[1] != L':') {
    /* Doesn't look like a drive letter could be there - probably an UNC */
    /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */
    drive_letter = 0;
  } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') {
    drive_letter = utf16_buffer[0];
  } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') {
    /* Convert to uppercase. */
    drive_letter = utf16_buffer[0] - L'a' + L'A';
  } else {
    /* Not valid. */
    drive_letter = 0;
  }

  if (drive_letter != 0) {
    /* Construct the environment variable name and set it. */
    env_var[0] = L'=';
    env_var[1] = drive_letter;
    env_var[2] = L':';
    env_var[3] = L'\0';

    if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
      return uv__new_sys_error(GetLastError());
    }
  }

  return uv_ok_;
}


void uv_loadavg(double avg[3]) {
  /* Can't be implemented */
  avg[0] = avg[1] = avg[2] = 0;
}


uint64_t uv_get_free_memory(void) {
  MEMORYSTATUSEX memory_status;
  memory_status.dwLength = sizeof(memory_status);

  if(!GlobalMemoryStatusEx(&memory_status))
  {
     return -1;
  }

  return (uint64_t)memory_status.ullAvailPhys;
}


uint64_t uv_get_total_memory(void) {
  MEMORYSTATUSEX memory_status;
  memory_status.dwLength = sizeof(memory_status);

  if(!GlobalMemoryStatusEx(&memory_status))
  {
    return -1;
  }

  return (uint64_t)memory_status.ullTotalPhys;
}


int uv_parent_pid() {
  int parent_pid = -1;
  HANDLE handle;
  PROCESSENTRY32 pe;
  int current_pid = GetCurrentProcessId();

  pe.dwSize = sizeof(PROCESSENTRY32);
  handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

  if (Process32First(handle, &pe)) {
    do {
      if (pe.th32ProcessID == current_pid) {
        parent_pid = pe.th32ParentProcessID;
        break;
      }
    } while( Process32Next(handle, &pe));
  }

  CloseHandle(handle);
  return parent_pid;
}


char** uv_setup_args(int argc, char** argv) {
  return argv;
}


uv_err_t uv_set_process_title(const char* title) {
  uv_err_t err;
  int length;
  WCHAR* title_w = NULL;

  uv__once_init();

  /* Find out how big the buffer for the wide-char title must be */
  length = uv_utf8_to_utf16(title, NULL, 0);
  if (!length) {
    err = uv__new_sys_error(GetLastError());
    goto done;
  }

  /* Convert to wide-char string */
  title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
  if (!title_w) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  length = uv_utf8_to_utf16(title, title_w, length);
  if (!length) {
    err = uv__new_sys_error(GetLastError());
    goto done;
  };

  /* If the title must be truncated insert a \0 terminator there */
  if (length > MAX_TITLE_LENGTH) {
    title_w[MAX_TITLE_LENGTH - 1] = L'\0';
  }

  if (!SetConsoleTitleW(title_w)) {
    err = uv__new_sys_error(GetLastError());
    goto done;
  }

  EnterCriticalSection(&process_title_lock);
  free(process_title);
  process_title = strdup(title);
  LeaveCriticalSection(&process_title_lock);

  err = uv_ok_;

done:
  free(title_w);
  return err;
}


static int uv__get_process_title() {
  WCHAR title_w[MAX_TITLE_LENGTH];
  int length;

  if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
    return -1;
  }

  /* Find out what the size of the buffer is that we need */
  length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
  if (!length) {
    return -1;
  }

  assert(!process_title);
  process_title = (char*)malloc(length);
  if (!process_title) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  /* Do utf16 -> utf8 conversion here */
  if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
    free(process_title);
    return -1;
  }

  return 0;
}


uv_err_t uv_get_process_title(char* buffer, size_t size) {
  uv__once_init();

  EnterCriticalSection(&process_title_lock);
  /*
   * If the process_title was never read before nor explicitly set,
   * we must query it with getConsoleTitleW
   */
  if (!process_title && uv__get_process_title() == -1) {
    return uv__new_sys_error(GetLastError());
  }

  assert(process_title);
  strncpy(buffer, process_title, size);
  LeaveCriticalSection(&process_title_lock);

  return uv_ok_;
}


uint64_t uv_hrtime(void) {
  LARGE_INTEGER counter;

  uv__once_init();

  /* If the performance frequency is zero, there's no support. */
  if (!hrtime_frequency_) {
    /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
    return 0;
  }

  if (!QueryPerformanceCounter(&counter)) {
    /* uv__set_sys_error(loop, GetLastError()); */
    return 0;
  }

  /* Because we have no guarantee about the order of magnitude of the */
  /* performance counter frequency, and there may not be much headroom to */
  /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
  return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) +
         (((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_)
         << 32);
}


uv_err_t uv_resident_set_memory(size_t* rss) {
  HANDLE current_process;
  PROCESS_MEMORY_COUNTERS pmc;

  current_process = GetCurrentProcess();

  if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) {
    return uv__new_sys_error(GetLastError());
  }

  *rss = pmc.WorkingSetSize;

  return uv_ok_;
}


uv_err_t uv_uptime(double* uptime) {
  BYTE stack_buffer[4096];
  BYTE* malloced_buffer = NULL;
  BYTE* buffer = (BYTE*) stack_buffer;
  size_t buffer_size = sizeof(stack_buffer);
  DWORD data_size;

  PERF_DATA_BLOCK* data_block;
  PERF_OBJECT_TYPE* object_type;
  PERF_COUNTER_DEFINITION* counter_definition;

  DWORD i;

  for (;;) {
    LONG result;

    data_size = (DWORD) buffer_size;
    result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
                              L"2",
                              NULL,
                              NULL,
                              buffer,
                              &data_size);
    if (result == ERROR_SUCCESS) {
      break;
    } else if (result != ERROR_MORE_DATA) {
      *uptime = 0;
      return uv__new_sys_error(result);
    }

    free(malloced_buffer);

    buffer_size *= 2;
    /* Don't let the buffer grow infinitely. */
    if (buffer_size > 1 << 20) {
      goto internalError;
    }

    buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
    if (malloced_buffer == NULL) {
      *uptime = 0;
      return uv__new_artificial_error(UV_ENOMEM);
    }
  }

  if (data_size < sizeof(*data_block))
    goto internalError;

  data_block = (PERF_DATA_BLOCK*) buffer;

  if (wmemcmp(data_block->Signature, L"PERF", 4) != 0)
    goto internalError;

  if (data_size < data_block->HeaderLength + sizeof(*object_type))
    goto internalError;

  object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength);

  if (object_type->NumInstances != PERF_NO_INSTANCES)
    goto internalError;

  counter_definition = (PERF_COUNTER_DEFINITION*) (buffer +
      data_block->HeaderLength + object_type->HeaderLength);
  for (i = 0; i < object_type->NumCounters; i++) {
    if ((BYTE*) counter_definition + sizeof(*counter_definition) >
        buffer + data_size) {
      break;
    }

    if (counter_definition->CounterNameTitleIndex == 674 &&
        counter_definition->CounterSize == sizeof(uint64_t)) {
      if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size ||
          !(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
        goto internalError;
      } else {
        BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
                        counter_definition->CounterOffset;
        uint64_t value = *((uint64_t*) address);
        *uptime = (double) (object_type->PerfTime.QuadPart - value) /
                  (double) object_type->PerfFreq.QuadPart;
        free(malloced_buffer);
        return uv_ok_;
      }
    }

    counter_definition = (PERF_COUNTER_DEFINITION*)
        ((BYTE*) counter_definition + counter_definition->ByteLength);
  }

  /* If we get here, the uptime value was not found. */
  free(malloced_buffer);
  *uptime = 0;
  return uv__new_artificial_error(UV_ENOSYS);

 internalError:
  free(malloced_buffer);
  *uptime = 0;
  return uv__new_artificial_error(UV_EIO);
}


uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
  uv_cpu_info_t* cpu_infos;
  SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
  DWORD sppi_size;
  SYSTEM_INFO system_info;
  DWORD cpu_count, r, i;
  NTSTATUS status;
  ULONG result_size;
  uv_err_t err;
  uv_cpu_info_t* cpu_info;

  cpu_infos = NULL;
  cpu_count = 0;
  sppi = NULL;

  uv__once_init();

  GetSystemInfo(&system_info);
  cpu_count = system_info.dwNumberOfProcessors;

  cpu_infos = calloc(cpu_count, sizeof *cpu_infos);
  if (cpu_infos == NULL) {
    err = uv__new_artificial_error(UV_ENOMEM);
    goto error;
  }

  sppi_size = cpu_count * sizeof(*sppi);
  sppi = malloc(sppi_size);
  if (sppi == NULL) {
    err = uv__new_artificial_error(UV_ENOMEM);
    goto error;
  }

  status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
                                     sppi,
                                     sppi_size,
                                     &result_size);
  if (!NT_SUCCESS(status)) {
    err = uv__new_sys_error(pRtlNtStatusToDosError(status));
    goto error;
  }

  assert(result_size == sppi_size);

  for (i = 0; i < cpu_count; i++) {
    WCHAR key_name[128];
    HKEY processor_key;
    DWORD cpu_speed;
    DWORD cpu_speed_size = sizeof(cpu_speed);
    WCHAR cpu_brand[256];
    DWORD cpu_brand_size = sizeof(cpu_brand);
    int len;

    len = _snwprintf(key_name,
                     ARRAY_SIZE(key_name),
                     L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
                     i);

    assert(len > 0 && len < ARRAY_SIZE(key_name));

    r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                      key_name,
                      0,
                      KEY_QUERY_VALUE,
                      &processor_key);
    if (r != ERROR_SUCCESS) {
      err = uv__new_sys_error(GetLastError());
      goto error;
    }

    if (RegQueryValueExW(processor_key,
                         L"~MHz",
                         NULL,
                         NULL,
                         (BYTE*) &cpu_speed,
                         &cpu_speed_size) != ERROR_SUCCESS) {
      err = uv__new_sys_error(GetLastError());
      RegCloseKey(processor_key);
      goto error;
    }

    if (RegQueryValueExW(processor_key,
                         L"ProcessorNameString",
                         NULL,
                         NULL,
                         (BYTE*) &cpu_brand,
                         &cpu_brand_size) != ERROR_SUCCESS) {
      err = uv__new_sys_error(GetLastError());
      RegCloseKey(processor_key);
      goto error;
    }

    RegCloseKey(processor_key);

    cpu_info = &cpu_infos[i];
    cpu_info->speed = cpu_speed;
    cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
    cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
        sppi[i].IdleTime.QuadPart) / 10000;
    cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
    cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
    cpu_info->cpu_times.nice = 0;


    len = WideCharToMultiByte(CP_UTF8,
                              0,
                              cpu_brand,
                              cpu_brand_size / sizeof(WCHAR),
                              NULL,
                              0,
                              NULL,
                              NULL);
    if (len == 0) {
      err = uv__new_sys_error(GetLastError());
      goto error;
    }

    assert(len > 0);

    /* Allocate 1 extra byte for the null terminator. */
    cpu_info->model = malloc(len + 1);
    if (cpu_info->model == NULL) {
      err = uv__new_artificial_error(UV_ENOMEM);
      goto error;
    }

    if (WideCharToMultiByte(CP_UTF8,
                            0,
                            cpu_brand,
                            cpu_brand_size / sizeof(WCHAR),
                            cpu_info->model,
                            len,
                            NULL,
                            NULL) == 0) {
      err = uv__new_sys_error(GetLastError());
      goto error;
    }

    /* Ensure that cpu_info->model is null terminated. */
    cpu_info->model[len] = '\0';
  }

  free(sppi);

  *cpu_count_ptr = cpu_count;
  *cpu_infos_ptr = cpu_infos;

  return uv_ok_;

 error:
  /* This is safe because the cpu_infos array is zeroed on allocation. */
  for (i = 0; i < cpu_count; i++)
    free(cpu_infos[i].model);

  free(cpu_infos);
  free(sppi);

  return err;
}


void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
  int i;

  for (i = 0; i < count; i++) {
    free(cpu_infos[i].model);
  }

  free(cpu_infos);
}


uv_err_t uv_interface_addresses(uv_interface_address_t** addresses_ptr,
    int* count_ptr) {
  IP_ADAPTER_ADDRESSES* win_address_buf;
  ULONG win_address_buf_size;
  IP_ADAPTER_ADDRESSES* win_address;

  uv_interface_address_t* uv_address_buf;
  char* name_buf;
  size_t uv_address_buf_size;
  uv_interface_address_t* uv_address;

  int count;

  /* Fetch the size of the adapters reported by windows, and then get the */
  /* list itself. */
  win_address_buf_size = 0;
  win_address_buf = NULL;

  for (;;) {
    ULONG r;

    /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */
    /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */
    /* win_address_buf_size. */
    r = GetAdaptersAddresses(AF_UNSPEC,
                             0,
                             NULL,
                             win_address_buf,
                             &win_address_buf_size);

    if (r == ERROR_SUCCESS)
      break;

    free(win_address_buf);

    switch (r) {
      case ERROR_BUFFER_OVERFLOW:
        /* This happens when win_address_buf is NULL or too small to hold */
        /* all adapters. */
        win_address_buf = malloc(win_address_buf_size);
        if (win_address_buf == NULL)
          return uv__new_artificial_error(UV_ENOMEM);

        continue;

      case ERROR_NO_DATA: {
        /* No adapters were found. */
        uv_address_buf = malloc(1);
        if (uv_address_buf == NULL)
          return uv__new_artificial_error(UV_ENOMEM);

        *count_ptr = 0;
        *addresses_ptr = uv_address_buf;

        return uv_ok_;
      }

      case ERROR_ADDRESS_NOT_ASSOCIATED:
        return uv__new_artificial_error(UV_EAGAIN);

      case ERROR_INVALID_PARAMETER:
        /* MSDN says:
         *   "This error is returned for any of the following conditions: the
         *   SizePointer parameter is NULL, the Address parameter is not
         *   AF_INET, AF_INET6, or AF_UNSPEC, or the address information for
         *   the parameters requested is greater than ULONG_MAX."
         * Since the first two conditions are not met, it must be that the
         * adapter data is too big.
         */
        return uv__new_artificial_error(UV_ENOBUFS);

      default:
        /* Other (unspecified) errors can happen, but we don't have any */
        /* special meaning for them. */
        assert(r != ERROR_SUCCESS);
        return uv__new_sys_error(r);
    }
  }

  /* Count the number of enabled interfaces and compute how much space is */
  /* needed to store their info. */
  count = 0;
  uv_address_buf_size = 0;

  for (win_address = win_address_buf;
       win_address != NULL;
       win_address = win_address->Next) {
    /* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */
    /* with Windows XP */
    IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
    int name_size;

    /* Interfaces that are not 'up' should not be reported. Also skip */
    /* interfaces that have no associated unicast address, as to avoid */
    /* allocating space for the name for this interface. */
    if (win_address->OperStatus != IfOperStatusUp ||
        win_address->FirstUnicastAddress == NULL)
      continue;

    /* Compute the size of the interface name. */
    name_size = WideCharToMultiByte(CP_UTF8,
                                    0,
                                    win_address->FriendlyName,
                                    -1,
                                    NULL,
                                    0,
                                    NULL,
                                    FALSE);
    if (name_size <= 0) {
      free(win_address_buf);
      return uv__new_sys_error(GetLastError());
    }
    uv_address_buf_size += name_size;

    /* Count the number of addresses associated with this interface, and */
    /* compute the size. */
    for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
                           win_address->FirstUnicastAddress;
         unicast_address != NULL;
         unicast_address = unicast_address->Next) {
      count++;
      uv_address_buf_size += sizeof(uv_interface_address_t);
    }
  }

  /* Allocate space to store interface data plus adapter names. */
  uv_address_buf = malloc(uv_address_buf_size);
  if (uv_address_buf == NULL) {
    free(win_address_buf);
    return uv__new_artificial_error(UV_ENOMEM);
  }

  /* Compute the start of the uv_interface_address_t array, and the place in */
  /* the buffer where the interface names will be stored. */
  uv_address = uv_address_buf;
  name_buf = (char*) (uv_address_buf + count);

  /* Fill out the output buffer. */
  for (win_address = win_address_buf;
       win_address != NULL;
       win_address = win_address->Next) {
    IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
    int name_size;
    size_t max_name_size;

    if (win_address->OperStatus != IfOperStatusUp ||
        win_address->FirstUnicastAddress == NULL)
      continue;

    /* Convert the interface name to UTF8. */
    max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf;
    if (max_name_size > (size_t) INT_MAX)
      max_name_size = INT_MAX;
    name_size = WideCharToMultiByte(CP_UTF8,
                                    0,
                                    win_address->FriendlyName,
                                    -1,
                                    name_buf,
                                    (int) max_name_size,
                                    NULL,
                                    FALSE);
    if (name_size <= 0) {
      free(win_address_buf);
      free(uv_address_buf);
      return uv__new_sys_error(GetLastError());
    }

    /* Add an uv_interface_address_t element for every unicast address. */
    for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
                           win_address->FirstUnicastAddress;
         unicast_address != NULL;
         unicast_address = unicast_address->Next) {
      struct sockaddr* sa;

      uv_address->name = name_buf;

      sa = unicast_address->Address.lpSockaddr;
      if (sa->sa_family == AF_INET6)
        uv_address->address.address6 = *((struct sockaddr_in6 *) sa);
      else
        uv_address->address.address4 = *((struct sockaddr_in *) sa);

      uv_address->is_internal =
          (win_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK);

      uv_address++;
    }

    name_buf += name_size;
  }

  free(win_address_buf);

  *addresses_ptr = uv_address_buf;
  *count_ptr = count;

  return uv_ok_;
}


void uv_free_interface_addresses(uv_interface_address_t* addresses,
    int count) {
  free(addresses);
}
