Juan Lang : iphlpapi: Set DNS servers in GetAdaptersAddresses when GAA_FLAG_SKIP_DNS_SERVER isn' t specified.
Alexandre Julliard
julliard at winehq.org
Tue Oct 12 11:26:59 CDT 2010
Module: wine
Branch: master
Commit: 873034c72d46d079bcabd4648599a9aa3561e66c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=873034c72d46d079bcabd4648599a9aa3561e66c
Author: Juan Lang <juan.lang at gmail.com>
Date: Mon Oct 11 09:05:06 2010 -0700
iphlpapi: Set DNS servers in GetAdaptersAddresses when GAA_FLAG_SKIP_DNS_SERVER isn't specified.
---
dlls/iphlpapi/iphlpapi_main.c | 67 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 66 insertions(+), 1 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 52d1c58..ae2dd76 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -924,11 +924,55 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, DWORD index,
return ERROR_SUCCESS;
}
+static ULONG get_dns_server_addresses(PIP_ADAPTER_DNS_SERVER_ADDRESS address, ULONG *len)
+{
+ DWORD size;
+
+ initialise_resolver();
+ /* FIXME: no support for IPv6 DNS server addresses. Doing so requires
+ * sizeof SOCKADDR_STORAGE instead, and using _res._u._ext.nsaddrs when
+ * available.
+ */
+ size = _res.nscount * (sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(SOCKADDR));
+ if (!address || *len < size)
+ {
+ *len = size;
+ return ERROR_BUFFER_OVERFLOW;
+ }
+ *len = size;
+ if (_res.nscount > 0)
+ {
+ PIP_ADAPTER_DNS_SERVER_ADDRESS addr;
+ int i;
+
+ for (i = 0, addr = address; i < _res.nscount && addr;
+ i++, addr = addr->Next)
+ {
+ SOCKADDR_IN *sin;
+
+ addr->Address.iSockaddrLength = sizeof(SOCKADDR);
+ addr->Address.lpSockaddr =
+ (LPSOCKADDR)((PBYTE)addr + sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS));
+ sin = (SOCKADDR_IN *)addr->Address.lpSockaddr;
+ sin->sin_family = WS_AF_INET;
+ sin->sin_port = _res.nsaddr_list[i].sin_port;
+ memcpy(&sin->sin_addr, &_res.nsaddr_list[i].sin_addr, sizeof(sin->sin_addr));
+ if (i == _res.nscount - 1)
+ addr->Next = NULL;
+ else
+ addr->Next =
+ (PIP_ADAPTER_DNS_SERVER_ADDRESS)((PBYTE)addr +
+ sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(SOCKADDR));
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
ULONG WINAPI GetAdaptersAddresses(ULONG family, ULONG flags, PVOID reserved,
PIP_ADAPTER_ADDRESSES aa, PULONG buflen)
{
InterfaceIndexTable *table;
- ULONG i, size, total_size, ret = ERROR_NO_DATA;
+ ULONG i, size, dns_server_size, total_size, ret = ERROR_NO_DATA;
TRACE("(%d, %08x, %p, %p, %p)\n", family, flags, reserved, aa, buflen);
@@ -951,9 +995,20 @@ ULONG WINAPI GetAdaptersAddresses(ULONG family, ULONG flags, PVOID reserved,
}
total_size += size;
}
+ if (!(flags & GAA_FLAG_SKIP_DNS_SERVER))
+ {
+ /* Since DNS servers aren't really per adapter, get enough space for a
+ * single copy of them.
+ */
+ get_dns_server_addresses(NULL, &dns_server_size);
+ total_size += dns_server_size;
+ }
if (aa && *buflen >= total_size)
{
ULONG bytes_left = size = total_size;
+ PIP_ADAPTER_ADDRESSES first_aa = aa;
+ PIP_ADAPTER_DNS_SERVER_ADDRESS firstDns;
+
for (i = 0; i < table->numIndexes; i++)
{
if ((ret = adapterAddressesFromIndex(family, flags, table->indexes[i], aa, &size)))
@@ -968,6 +1023,16 @@ ULONG WINAPI GetAdaptersAddresses(ULONG family, ULONG flags, PVOID reserved,
size = bytes_left -= size;
}
}
+ if (!(flags & GAA_FLAG_SKIP_DNS_SERVER))
+ {
+ firstDns = (PIP_ADAPTER_DNS_SERVER_ADDRESS)((BYTE *)aa + total_size - dns_server_size);
+ get_dns_server_addresses(firstDns, &dns_server_size);
+ for (aa = first_aa; aa; aa = aa->Next)
+ {
+ if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK && aa->OperStatus == IfOperStatusUp)
+ aa->FirstDnsServerAddress = firstDns;
+ }
+ }
ret = ERROR_SUCCESS;
}
if (*buflen < total_size) ret = ERROR_BUFFER_OVERFLOW;
More information about the wine-cvs
mailing list