Commit d95103c4 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

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

parent fc28de99
MODULE = iphlpapi.dll MODULE = iphlpapi.dll
IMPORTLIB = iphlpapi IMPORTLIB = iphlpapi
IMPORTS = advapi32 nsi uuid IMPORTS = advapi32 dnsapi nsi uuid
EXTRALIBS = $(RESOLV_LIBS) $(KSTAT_LIBS) $(PROCSTAT_LIBS) EXTRALIBS = $(RESOLV_LIBS) $(KSTAT_LIBS) $(PROCSTAT_LIBS)
C_SRCS = \ C_SRCS = \
......
...@@ -1395,41 +1395,65 @@ static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only ) ...@@ -1395,41 +1395,65 @@ static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only )
} }
#endif #endif
static ULONG get_dns_server_addresses(PIP_ADAPTER_DNS_SERVER_ADDRESS address, ULONG *len) static DWORD dns_servers_query_code( ULONG family )
{ {
int num = get_dns_servers( NULL, 0, FALSE ); if (family == WS_AF_INET) return DnsConfigDnsServersIpv4;
DWORD size; if (family == WS_AF_INET6) return DnsConfigDnsServersIpv6;
return DnsConfigDnsServersUnspec;
}
size = num * (sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(SOCKADDR_STORAGE)); static ULONG get_dns_server_addresses( ULONG family, IP_ADAPTER_DNS_SERVER_ADDRESS *address, ULONG *len )
if (!address || *len < size) {
{ char buf[FIELD_OFFSET(DNS_ADDR_ARRAY, AddrArray[3])];
*len = size; DNS_ADDR_ARRAY *servers = (DNS_ADDR_ARRAY *)buf;
return ERROR_BUFFER_OVERFLOW; DWORD err, num, i, needed, array_len = sizeof(buf);
} DWORD query = dns_servers_query_code( family );
*len = size; SOCKADDR_INET *out_addrs;
if (num > 0)
{
PIP_ADAPTER_DNS_SERVER_ADDRESS addr = address;
SOCKADDR_STORAGE *sock_addrs = (SOCKADDR_STORAGE *)(address + num);
int i;
get_dns_servers( sock_addrs, num, FALSE ); for (;;)
{
err = DnsQueryConfig( query, 0, NULL, NULL, servers, &array_len );
if (err != ERROR_SUCCESS && err != ERROR_MORE_DATA) goto err;
num = (array_len - FIELD_OFFSET(DNS_ADDR_ARRAY, AddrArray[0])) / sizeof(DNS_ADDR);
needed = num * (sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(*out_addrs));
if (!address || *len < needed)
{
*len = needed;
err = ERROR_BUFFER_OVERFLOW;
goto err;
}
if (!err) break;
for (i = 0; i < num; i++, addr = addr->Next) if ((char *)servers != buf) heap_free( servers );
servers = heap_alloc( array_len );
if (!servers)
{ {
addr->u.s.Length = sizeof(*addr); err = ERROR_NOT_ENOUGH_MEMORY;
if (sock_addrs[i].ss_family == WS_AF_INET6) goto err;
addr->Address.iSockaddrLength = sizeof(SOCKADDR_IN6);
else
addr->Address.iSockaddrLength = sizeof(SOCKADDR_IN);
addr->Address.lpSockaddr = (SOCKADDR *)(sock_addrs + i);
if (i == num - 1)
addr->Next = NULL;
else
addr->Next = addr + 1;
} }
} }
return ERROR_SUCCESS;
*len = needed;
out_addrs = (SOCKADDR_INET *)(address + num);
for (i = 0; i < num; i++)
{
address[i].u.s.Length = sizeof(*address);
address[i].u.s.Reserved = 0;
address[i].Next = NULL;
address[i].Address.iSockaddrLength = servers->AddrArray[i].Data.DnsAddrUserDword[0];
if (address[i].Address.iSockaddrLength > sizeof(*out_addrs))
address[i].Address.iSockaddrLength = 0;
address[i].Address.lpSockaddr = (SOCKADDR *)(out_addrs + i);
memcpy( out_addrs + i, servers->AddrArray[i].MaxSa, address[i].Address.iSockaddrLength );
memset( (BYTE *)(out_addrs + i) + address[i].Address.iSockaddrLength, 0,
sizeof(*out_addrs) - address[i].Address.iSockaddrLength );
if (i) address[i - 1].Next = address + i;
}
err = ERROR_SUCCESS;
err:
if ((char *)servers != buf) heap_free( servers );
return err;
} }
#ifdef HAVE_STRUCT___RES_STATE #ifdef HAVE_STRUCT___RES_STATE
...@@ -1506,7 +1530,7 @@ ULONG WINAPI DECLSPEC_HOTPATCH GetAdaptersAddresses(ULONG family, ULONG flags, P ...@@ -1506,7 +1530,7 @@ ULONG WINAPI DECLSPEC_HOTPATCH GetAdaptersAddresses(ULONG family, ULONG flags, P
/* Since DNS servers aren't really per adapter, get enough space for a /* Since DNS servers aren't really per adapter, get enough space for a
* single copy of them. * single copy of them.
*/ */
get_dns_server_addresses(NULL, &dns_server_size); get_dns_server_addresses( family, NULL, &dns_server_size );
total_size += dns_server_size; total_size += dns_server_size;
} }
/* Since DNS suffix also isn't really per adapter, get enough space for a /* Since DNS suffix also isn't really per adapter, get enough space for a
...@@ -1538,7 +1562,7 @@ ULONG WINAPI DECLSPEC_HOTPATCH GetAdaptersAddresses(ULONG family, ULONG flags, P ...@@ -1538,7 +1562,7 @@ ULONG WINAPI DECLSPEC_HOTPATCH GetAdaptersAddresses(ULONG family, ULONG flags, P
if (dns_server_size) if (dns_server_size)
{ {
firstDns = (PIP_ADAPTER_DNS_SERVER_ADDRESS)((BYTE *)first_aa + total_size - dns_server_size - dns_suffix_size); firstDns = (PIP_ADAPTER_DNS_SERVER_ADDRESS)((BYTE *)first_aa + total_size - dns_server_size - dns_suffix_size);
get_dns_server_addresses(firstDns, &dns_server_size); get_dns_server_addresses( family, firstDns, &dns_server_size );
for (aa = first_aa; aa; aa = aa->Next) for (aa = first_aa; aa; aa = aa->Next)
{ {
if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK && aa->OperStatus == IfOperStatusUp) if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK && aa->OperStatus == IfOperStatusUp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment