Module: wine Branch: oldstable Commit: a96b43f3850a1eeaa04c9912309994b70366036d URL: http://source.winehq.org/git/wine.git/?a=commit;h=a96b43f3850a1eeaa04c991230...
Author: Bruno Jesus 00cpxxx@gmail.com Date: Thu Dec 1 10:23:36 2016 -0200
iphlpapi: Ensure GetIpAddrTable returns loopback addresses in the end.
Signed-off-by: Bruno Jesus 00cpxxx@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 95298b4442504d9e977fbdb72ce1417273340265) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/iphlpapi/iphlpapi_main.c | 27 +++++++++++++++++++++------ dlls/iphlpapi/tests/iphlpapi.c | 3 +++ 2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 90dcda3..54f7a37 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -134,17 +134,27 @@ DWORD WINAPI AllocateAndGetIfTableFromStack(PMIB_IFTABLE *ppIfTable, }
-static int IpAddrTableSorter(const void *a, const void *b) +static int IpAddrTableNumericSorter(const void *a, const void *b) { - int ret; + int ret = 0;
if (a && b) ret = ((const MIB_IPADDRROW*)a)->dwAddr - ((const MIB_IPADDRROW*)b)->dwAddr; - else - ret = 0; return ret; }
+static int IpAddrTableLoopbackSorter(const void *a, const void *b) +{ + const MIB_IPADDRROW *left = a, *right = b; + int ret = 0; + + if (isIfIndexLoopback(left->dwIndex)) + ret = 1; + else if (isIfIndexLoopback(right->dwIndex)) + ret = -1; + + return ret; +}
/****************************************************************** * AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@) @@ -173,7 +183,7 @@ DWORD WINAPI AllocateAndGetIpAddrTableFromStack(PMIB_IPADDRTABLE *ppIpAddrTable, ret = getIPAddrTable(ppIpAddrTable, heap, flags); if (!ret && bOrder) qsort((*ppIpAddrTable)->table, (*ppIpAddrTable)->dwNumEntries, - sizeof(MIB_IPADDRROW), IpAddrTableSorter); + sizeof(MIB_IPADDRROW), IpAddrTableNumericSorter); TRACE("returning %d\n", ret); return ret; } @@ -1988,9 +1998,14 @@ DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL else { *pdwSize = size; memcpy(pIpAddrTable, table, size); + /* sort by numeric IP value */ if (bOrder) qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries, - sizeof(MIB_IPADDRROW), IpAddrTableSorter); + sizeof(MIB_IPADDRROW), IpAddrTableNumericSorter); + /* sort ensuring loopback interfaces are in the end */ + else + qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries, + sizeof(MIB_IPADDRROW), IpAddrTableLoopbackSorter); ret = NO_ERROR; } HeapFree(GetProcessHeap(), 0, table); diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 92653ed5..2022b70 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -261,6 +261,9 @@ static void testGetIpAddrTable(void) ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i); trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i, ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType); + /* loopback must never be the first when more than one interface is found */ + if (buf->table[i].dwAddr == htonl(INADDR_LOOPBACK)) + ok(buf->dwNumEntries == 1 || i, "Loopback interface in wrong first position\n"); } } HeapFree(GetProcessHeap(), 0, buf);