Huw Davies : iphlpapi: Use DnsQueryConfig() to retrieve the dns servers for the remaining functions.

Alexandre Julliard julliard at winehq.org
Fri Aug 6 16:10:39 CDT 2021


Module: wine
Branch: master
Commit: 769952df5fe64013b056d157e826624dfaade41a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=769952df5fe64013b056d157e826624dfaade41a

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Aug  5 09:56:43 2021 +0100

iphlpapi: Use DnsQueryConfig() to retrieve the dns servers for the remaining functions.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/iphlpapi/iphlpapi_main.c | 217 ++++++++----------------------------------
 1 file changed, 38 insertions(+), 179 deletions(-)

diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 2c8c1644b78..40cf358d73f 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -1223,34 +1223,6 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index
     return ERROR_SUCCESS;
 }
 
-static void sockaddr_in_to_WS_storage( SOCKADDR_STORAGE *dst, const struct sockaddr_in *src )
-{
-    SOCKADDR_IN *s = (SOCKADDR_IN *)dst;
-
-    s->sin_family = WS_AF_INET;
-    s->sin_port = src->sin_port;
-    memcpy( &s->sin_addr, &src->sin_addr, sizeof(IN_ADDR) );
-    memset( (char *)s + FIELD_OFFSET( SOCKADDR_IN, sin_zero ), 0,
-            sizeof(SOCKADDR_STORAGE) - FIELD_OFFSET( SOCKADDR_IN, sin_zero) );
-}
-
-#if defined(HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6) || \
-    (defined(HAVE___RES_GET_STATE) && defined(HAVE___RES_GETSERVERS)) || \
-    defined(HAVE_RES_GETSERVERS)
-static void sockaddr_in6_to_WS_storage( SOCKADDR_STORAGE *dst, const struct sockaddr_in6 *src )
-{
-    SOCKADDR_IN6 *s = (SOCKADDR_IN6 *)dst;
-
-    s->sin6_family = WS_AF_INET6;
-    s->sin6_port = src->sin6_port;
-    s->sin6_flowinfo = src->sin6_flowinfo;
-    memcpy( &s->sin6_addr, &src->sin6_addr, sizeof(IN6_ADDR) );
-    s->sin6_scope_id = src->sin6_scope_id;
-    memset( (char *)s + sizeof(SOCKADDR_IN6), 0,
-                    sizeof(SOCKADDR_STORAGE) - sizeof(SOCKADDR_IN6) );
-}
-#endif
-
 #ifdef HAVE_STRUCT___RES_STATE
 /* call res_init() just once because of a bug in Mac OS X 10.4 */
 /* Call once per thread on systems that have per-thread _res. */
@@ -1270,129 +1242,6 @@ static void initialise_resolver(void)
         res_init();
     LeaveCriticalSection(&res_init_cs);
 }
-
-#ifdef HAVE_RES_GETSERVERS
-static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
-{
-    struct __res_state *state = &_res;
-    int i, found = 0, total;
-    SOCKADDR_STORAGE *addr = servers;
-    union res_sockaddr_union *buf;
-
-    initialise_resolver();
-
-    total = res_getservers( state, NULL, 0 );
-
-    if ((!servers || !num) && !ip4_only) return total;
-
-    buf = HeapAlloc( GetProcessHeap(), 0, total * sizeof(union res_sockaddr_union) );
-    total = res_getservers( state, buf, total );
-
-    for (i = 0; i < total; i++)
-    {
-        if (buf[i].sin6.sin6_family == AF_INET6 && ip4_only) continue;
-        if (buf[i].sin.sin_family != AF_INET && buf[i].sin6.sin6_family != AF_INET6) continue;
-
-        found++;
-        if (!servers || !num) continue;
-
-        if (buf[i].sin6.sin6_family == AF_INET6)
-        {
-            sockaddr_in6_to_WS_storage( addr, &buf[i].sin6 );
-        }
-        else
-        {
-            sockaddr_in_to_WS_storage( addr, &buf[i].sin );
-        }
-        if (++addr >= servers + num) break;
-    }
-
-    HeapFree( GetProcessHeap(), 0, buf );
-    return found;
-}
-#else
-
-static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
-{
-    int i, ip6_count = 0;
-    SOCKADDR_STORAGE *addr;
-
-    initialise_resolver();
-
-#ifdef HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6
-    ip6_count = _res._u._ext.nscount6;
-#endif
-
-    if (!servers || !num)
-    {
-        num = _res.nscount;
-        if (ip4_only) num -= ip6_count;
-        return num;
-    }
-
-    for (i = 0, addr = servers; addr < (servers + num) && i < _res.nscount; i++)
-    {
-#ifdef HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6
-        if (_res._u._ext.nsaddrs[i] && _res._u._ext.nsaddrs[i]->sin6_family == AF_INET6)
-        {
-            if (ip4_only) continue;
-            sockaddr_in6_to_WS_storage( addr, _res._u._ext.nsaddrs[i] );
-        }
-        else
-#endif
-        {
-            sockaddr_in_to_WS_storage( addr, _res.nsaddr_list + i );
-        }
-        addr++;
-    }
-    return addr - servers;
-}
-#endif
-#elif defined(HAVE___RES_GET_STATE) && defined(HAVE___RES_GETSERVERS)
-
-static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
-{
-    extern struct res_state *__res_get_state( void );
-    extern int __res_getservers( struct res_state *, struct sockaddr_storage *, int );
-    struct res_state *state = __res_get_state();
-    int i, found = 0, total = __res_getservers( state, NULL, 0 );
-    SOCKADDR_STORAGE *addr = servers;
-    struct sockaddr_storage *buf;
-
-    if ((!servers || !num) && !ip4_only) return total;
-
-    buf = HeapAlloc( GetProcessHeap(), 0, total * sizeof(struct sockaddr_storage) );
-    total = __res_getservers( state, buf, total );
-
-    for (i = 0; i < total; i++)
-    {
-        if (buf[i].ss_family == AF_INET6 && ip4_only) continue;
-        if (buf[i].ss_family != AF_INET && buf[i].ss_family != AF_INET6) continue;
-
-        found++;
-        if (!servers || !num) continue;
-
-        if (buf[i].ss_family == AF_INET6)
-        {
-            sockaddr_in6_to_WS_storage( addr, (struct sockaddr_in6 *)(buf + i) );
-        }
-        else
-        {
-            sockaddr_in_to_WS_storage( addr, (struct sockaddr_in *)(buf + i) );
-        }
-        if (++addr >= servers + num) break;
-    }
-
-    HeapFree( GetProcessHeap(), 0, buf );
-    return found;
-}
-#else
-
-static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
-{
-    FIXME("Unimplemented on this system\n");
-    return 0;
-}
 #endif
 
 static DWORD dns_servers_query_code( ULONG family )
@@ -2528,45 +2377,55 @@ DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOr
  * a single server address may be placed at list if *len is at least
  * sizeof(IP_ADDR_STRING) long.  Otherwise, list->Next is set to firstDynamic,
  * and assumes that all remaining DNS servers are contiguously located
- * beginning at firstDynamic.  On input, *len is assumed to be the total number
+ * beginning at second.  On input, *len is assumed to be the total number
  * of bytes available for all DNS servers, and is ignored if list is NULL.
  * On return, *len is set to the total number of bytes required for all DNS
  * servers.
  * Returns ERROR_BUFFER_OVERFLOW if *len is insufficient,
  * ERROR_SUCCESS otherwise.
  */
-static DWORD get_dns_server_list(PIP_ADDR_STRING list,
- PIP_ADDR_STRING firstDynamic, DWORD *len)
+static DWORD get_dns_server_list( IP_ADDR_STRING *list, IP_ADDR_STRING *second, DWORD *len )
 {
-  DWORD size;
-  int num = get_dns_servers( NULL, 0, TRUE );
+    char buf[FIELD_OFFSET(IP4_ARRAY, AddrArray[3])];
+    IP4_ARRAY *servers = (IP4_ARRAY *)buf;
+    DWORD needed, num, err, i, array_len = sizeof(buf);
+    IP_ADDR_STRING *ptr;
 
-  size = num * sizeof(IP_ADDR_STRING);
-  if (!list || *len < size) {
-    *len = size;
-    return ERROR_BUFFER_OVERFLOW;
-  }
-  *len = size;
-  if (num > 0) {
-    PIP_ADDR_STRING ptr;
-    int i;
-    SOCKADDR_STORAGE *addr = HeapAlloc( GetProcessHeap(), 0, num * sizeof(SOCKADDR_STORAGE) );
+    for (;;)
+    {
+        err = DnsQueryConfig( DnsConfigDnsServerList, 0, NULL, NULL, servers, &array_len );
+        num = (array_len - FIELD_OFFSET(IP4_ARRAY, AddrArray[0])) / sizeof(IP4_ADDRESS);
+        needed = num * sizeof(IP_ADDR_STRING);
+        if (!list || *len < needed)
+        {
+            *len = needed;
+            err = ERROR_BUFFER_OVERFLOW;
+            goto err;
+        }
+        if (!err) break;
 
-    get_dns_servers( addr, num, TRUE );
+        if ((char *)servers != buf) heap_free( servers );
+        servers = heap_alloc( array_len );
+        if (!servers)
+        {
+            err = ERROR_NOT_ENOUGH_MEMORY;
+            goto err;
+        }
+    }
 
-    for (i = 0, ptr = list; i < num; i++, ptr = ptr->Next) {
-        RtlIpv4AddressToStringA((IN_ADDR *)&((struct sockaddr_in *)(addr + i))->sin_addr.s_addr,
-       ptr->IpAddress.String);
-      if (i == num - 1)
-        ptr->Next = NULL;
-      else if (i == 0)
-        ptr->Next = firstDynamic;
-      else
-        ptr->Next = (PIP_ADDR_STRING)((PBYTE)ptr + sizeof(IP_ADDR_STRING));
+    *len = needed;
+
+    for (i = 0, ptr = list; i < num; i++, ptr = ptr->Next)
+    {
+        RtlIpv4AddressToStringA( (IN_ADDR *)&servers->AddrArray[i], ptr->IpAddress.String );
+        if (i == num - 1) ptr->Next = NULL;
+        else if (i == 0) ptr->Next = second;
+        else ptr->Next = ptr + 1;
     }
-    HeapFree( GetProcessHeap(), 0, addr );
-  }
-  return ERROR_SUCCESS;
+
+err:
+    if ((char *)servers != buf) heap_free( servers );
+    return err;
 }
 
 /******************************************************************




More information about the wine-cvs mailing list