diff --git a/ares/CHANGES b/ares/CHANGES
index f7e04e13f49bd7d26e23ca7110551f8dff8a7ac0..6facb453a82d4ca9b7ba4c17992f0cc0985adf7a 100644
--- a/ares/CHANGES
+++ b/ares/CHANGES
@@ -1,5 +1,23 @@
   Changelog for the c-ares project
 
+* June 10
+- Gisle Vanem's init patch for Windows:
+
+  The init_by_resolv_conf() function fetches the DNS-server(s)
+  from a series of registry branches.
+
+  This can be wrong in the case where DHCP has assigned nameservers, but the
+  user has overridden these servers with other prefered settings. Then it's
+  wrong to use the DHCPNAMESERVER setting in registry.
+
+  In the case of no global DHCP-assigned or fixed servers, but DNS server(s)
+  per adapter, one has to query the adapter branches.  But how can c-ares know
+  which adapter is valid for use? AFAICS it can't. There could be one adapter
+  that is down (e.g. a VPN adapter).
+
+  So it's better to leave this to the IP Helper API (iphlapi) available in
+  Win-98/2000 and later. My patch falls-back to the old way if not available.
+
 * June 8
 - James Bursa fixed an init issue for RISC OS.
 
diff --git a/ares/ares_init.c b/ares/ares_init.c
index 9ac8768ed57e240b06b62094f840c430a1a96037..72ef990fb43e1dea77dd225c9d3c729192687663 100644
--- a/ares/ares_init.c
+++ b/ares/ares_init.c
@@ -17,6 +17,8 @@
 
 #ifdef WIN32
 #include "nameser.h"
+#include <iphlpapi.h>
+#include <malloc.h>
 #else
 #include <sys/param.h>
 #include <sys/time.h>
@@ -231,24 +233,24 @@ static int init_by_environment(ares_channel channel)
 
   return ARES_SUCCESS;
 }
-#ifdef WIN32
-static int get_res_size_nt(HKEY hKey, char *subkey, int *size)
-{
-  return RegQueryValueEx(hKey, subkey, 0, NULL, NULL, size);
-}
 
-/* Warning: returns a dynamically allocated buffer, the user MUST
+#ifdef WIN32
+/*
+ * Warning: returns a dynamically allocated buffer, the user MUST
  * use free() if the function returns 1
  */
-static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
+static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
 {
   /* Test for the size we need */
-  int size = 0;
+  DWORD size = 0;
   int result;
+
   result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
   if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
     return 0;
   *obuf = malloc(size+1);
+  if (!*obuf)
+    return 0;
 
   if (RegQueryValueEx(hKey, subkey, 0, NULL, *obuf, &size) != ERROR_SUCCESS)
   {
@@ -263,29 +265,99 @@ static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
   return 1;
 }
 
-static int get_res_interfaces_nt(HKEY hKey, char *subkey, char **obuf)
+static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
 {
   char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
-  int enum_size = 39;
+  DWORD enum_size = 39;
   int idx = 0;
   HKEY hVal;
+
   while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
                       NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
   {
+    int rc;
+
     enum_size = 39;
     if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
         ERROR_SUCCESS)
       continue;
-    if (!get_res_nt(hVal, subkey, obuf))
-      RegCloseKey(hVal);
-    else
-    {
+    rc = get_res_nt(hVal, subkey, obuf);
       RegCloseKey(hVal);
+    if (rc)
       return 1;
     }
-  }
   return 0;
 }
+
+static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
+{
+  FIXED_INFO    *fi   = alloca (sizeof(*fi));
+  DWORD          size = sizeof (*fi);
+  DWORD WINAPI (*GetNetworkParams) (FIXED_INFO*, DWORD*);  /* available only on Win-98/2000+ */
+  HMODULE        handle;
+  IP_ADDR_STRING *ipAddr;
+  int            i, count = 0;
+  int            debug  = 0;
+  size_t         ip_size = sizeof("255.255.255.255,")-1;
+  size_t         left = ret_size;
+  char          *ret = ret_buf;
+
+  if (!fi)
+     return (0);
+
+  handle = LoadLibrary ("iphlpapi.dll");
+  if (!handle)
+     return (0);
+
+  (void*)GetNetworkParams = GetProcAddress (handle, "GetNetworkParams");
+  if (!GetNetworkParams)
+     goto quit;
+
+  if ((*GetNetworkParams) (fi, &size) != ERROR_BUFFER_OVERFLOW)
+     goto quit;
+
+  fi = alloca (size);
+  if (!fi || (*GetNetworkParams) (fi, &size) != ERROR_SUCCESS)
+     goto quit;
+
+  if (debug)
+  {
+    printf ("Host Name: %s\n", fi->HostName);
+    printf ("Domain Name: %s\n", fi->DomainName);
+    printf ("DNS Servers:\n"
+            "    %s (primary)\n", fi->DnsServerList.IpAddress.String);
+  }
+  if (inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
+      left > ip_size)
+  {
+    ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
+    left -= ret - ret_buf;
+    count++;
+  }
+
+  for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
+       ipAddr = ipAddr->Next, i++)
+  {
+    if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
+    {
+       ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
+       left -= ret - ret_buf;
+       count++;
+    }
+    if (debug)
+       printf ("    %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
+  }
+
+quit:
+  if (handle)
+     FreeLibrary (handle);
+
+  if (debug && left <= ip_size)
+     printf ("Too many nameservers. Truncating to %d addressess", count);
+  if (ret > ret_buf)
+     ret[-1] = '\0';
+  return (count);
+}
 #endif
 
 static int init_by_resolv_conf(ares_channel channel)
@@ -298,6 +370,11 @@ static int init_by_resolv_conf(ares_channel channel)
 #ifdef WIN32
 
     /*
+  NameServer info via IPHLPAPI (IP helper API):
+    GetNetworkParams() should be the trusted source for this.
+    Available in Win-98/2000 and later. If that fail, fall-back to
+    registry information.
+
   NameServer Registry:
 
    On Windows 9X, the DNS server can be found in:
@@ -320,9 +397,17 @@ DhcpNameServer
   DWORD data_type;
   DWORD bytes;
   DWORD result;
-  DWORD keysize = MAX_PATH;
+  char  buf[256];
 
-  status = ARES_EFILE;
+  if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
+     return ARES_SUCCESS;
+
+  if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
+  {
+    status = config_nameserver(&servers, &nservers, buf);
+    if (status == ARES_SUCCESS)
+       goto okay;
+  }
 
   if (IsNT)
   {
@@ -388,15 +473,8 @@ DhcpNameServer
     RegCloseKey(mykey);
   }
 
-  if (status != ARES_EFILE)
-  {
-    /*
-      if (!channel->lookups) {
-      status = config_lookup(channel, "file bind");
-      }
-    */
+  if (status == ARES_SUCCESS)
     status = ARES_EOF;
-  }
 
 #elif defined(riscos)
 
@@ -474,6 +552,7 @@ DhcpNameServer
     }
 
   /* If we got any name server entries, fill them in. */
+okay:
   if (servers)
     {
       channel->servers = servers;