[1/2] iphlpapi: Add GetUnicastIpAddressEntry implementation (try 4)

André Hentschel nerv at dawncrow.de
Wed Feb 8 14:58:18 CST 2017


Signed-off-by: André Hentschel <nerv at dawncrow.de>
---

For https://bugs.winehq.org/show_bug.cgi?id=41753
try 2: Many thanks to Bruno and Hans for the feedback!
try 3: Proper patch numbering
try 4: Also check for the interface, not only the address

 dlls/iphlpapi/iphlpapi.spec   |  2 +-
 dlls/iphlpapi/iphlpapi_main.c | 67 +++++++++++++++++++++++++++++++++++++++++++
 include/netioapi.h            | 17 +++++++++++
 include/ws2def.h              | 13 +++++++++
 include/ws2ipdef.h            |  7 +++++
 5 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec
index 500267c..1a1f8f7 100644
--- a/dlls/iphlpapi/iphlpapi.spec
+++ b/dlls/iphlpapi/iphlpapi.spec
@@ -147,7 +147,7 @@
 @ stub GetUdpStatsFromStack
 @ stdcall GetUdpTable( ptr ptr long )
 @ stub GetUdpTableFromStack
-#@ stub GetUnicastIpAddressEntry
+@ stdcall GetUnicastIpAddressEntry( ptr )
 #@ stub GetUnicastIpAddressTable
 @ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
 @ stdcall Icmp6CreateFile()
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 1daf54d..b0fb973 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -2467,6 +2467,73 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder,
     return ret;
 }
 
+DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
+{
+    IP_ADAPTER_ADDRESSES *aa, *ptr;
+    ULONG size = 0;
+    DWORD ret;
+
+    TRACE("%p\n", row);
+
+    if (!row)
+        return ERROR_INVALID_PARAMETER;
+
+    ret = GetAdaptersAddresses(row->Address.si_family, 0, NULL, NULL, &size);
+    if (ret != ERROR_BUFFER_OVERFLOW)
+        return ret;
+    if (!(ptr = HeapAlloc(GetProcessHeap(), 0, size)))
+        return ERROR_OUTOFMEMORY;
+    if ((ret = GetAdaptersAddresses(row->Address.si_family, 0, NULL, ptr, &size)))
+    {
+        HeapFree(GetProcessHeap(), 0, ptr);
+        return ret;
+    }
+
+    ret = ERROR_FILE_NOT_FOUND;
+    for (aa = ptr; aa; aa = aa->Next)
+    {
+        IP_ADAPTER_UNICAST_ADDRESS *ua;
+
+        if (aa->u.s.IfIndex != row->InterfaceIndex &&
+            memcmp(&aa->Luid, &row->InterfaceLuid, sizeof(row->InterfaceLuid)))
+            continue;
+        ret = ERROR_NOT_FOUND;
+
+        ua = aa->FirstUnicastAddress;
+        while (ua)
+        {
+            SOCKADDR_INET *uaaddr = (SOCKADDR_INET *)ua->Address.lpSockaddr;
+
+            if ((row->Address.si_family == WS_AF_INET6 &&
+                 !memcmp(&row->Address.Ipv6.sin6_addr, &uaaddr->Ipv6.sin6_addr, sizeof(uaaddr->Ipv6.sin6_addr))) ||
+                (row->Address.si_family == WS_AF_INET &&
+                 row->Address.Ipv4.sin_addr.S_un.S_addr == uaaddr->Ipv4.sin_addr.S_un.S_addr))
+            {
+                memcpy(&row->InterfaceLuid, &aa->Luid, sizeof(aa->Luid));
+                row->InterfaceIndex     = aa->u.s.IfIndex;
+                row->PrefixOrigin       = ua->PrefixOrigin;
+                row->SuffixOrigin       = ua->SuffixOrigin;
+                row->ValidLifetime      = ua->ValidLifetime;
+                row->PreferredLifetime  = ua->PreferredLifetime;
+                row->OnLinkPrefixLength = ua->OnLinkPrefixLength;
+                row->SkipAsSource       = 0;
+                row->DadState           = ua->DadState;
+                if (row->Address.si_family == WS_AF_INET6)
+                    row->ScopeId.Value  = row->Address.Ipv6.sin6_scope_id;
+                else
+                    row->ScopeId.Value  = 0;
+                NtQuerySystemTime(&row->CreationTimeStamp);
+                HeapFree(GetProcessHeap(), 0, ptr);
+                return NO_ERROR;
+            }
+            ua = ua->Next;
+        }
+    }
+    HeapFree(GetProcessHeap(), 0, ptr);
+
+    return ret;
+}
+
 /******************************************************************
  *    GetUniDirectionalAdapterInfo (IPHLPAPI.@)
  *
diff --git a/include/netioapi.h b/include/netioapi.h
index 0357431..0e777c7 100644
--- a/include/netioapi.h
+++ b/include/netioapi.h
@@ -82,6 +82,22 @@ typedef struct _MIB_IF_TABLE2
     MIB_IF_ROW2 Table[1];
 } MIB_IF_TABLE2, *PMIB_IF_TABLE2;
 
+typedef struct _MIB_UNICASTIPADDRESS_ROW
+{
+    SOCKADDR_INET       Address;
+    NET_LUID            InterfaceLuid;
+    NET_IFINDEX         InterfaceIndex;
+    NL_PREFIX_ORIGIN    PrefixOrigin;
+    NL_SUFFIX_ORIGIN    SuffixOrigin;
+    ULONG               ValidLifetime;
+    ULONG               PreferredLifetime;
+    UINT8               OnLinkPrefixLength;
+    BOOLEAN             SkipAsSource;
+    NL_DAD_STATE        DadState;
+    SCOPE_ID            ScopeId;
+    LARGE_INTEGER       CreationTimeStamp;
+} MIB_UNICASTIPADDRESS_ROW, *PMIB_UNICASTIPADDRESS_ROW;
+
 DWORD WINAPI ConvertInterfaceGuidToLuid(const GUID*,NET_LUID*);
 DWORD WINAPI ConvertInterfaceIndexToLuid(NET_IFINDEX,NET_LUID*);
 DWORD WINAPI ConvertInterfaceLuidToGuid(const NET_LUID*,GUID*);
@@ -92,5 +108,6 @@ DWORD WINAPI ConvertInterfaceNameToLuidA(const char*,NET_LUID*);
 DWORD WINAPI ConvertInterfaceNameToLuidW(const WCHAR*,NET_LUID*);
 void WINAPI FreeMibTable(void*);
 DWORD WINAPI GetIfEntry2(MIB_IF_ROW2*);
+DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW*);
 
 #endif /* __WINE_NETIOAPI_H */
diff --git a/include/ws2def.h b/include/ws2def.h
index cbd6f74..03468fe 100644
--- a/include/ws2def.h
+++ b/include/ws2def.h
@@ -27,6 +27,8 @@
 #define WS(x)    x
 #endif
 
+typedef USHORT ADDRESS_FAMILY;
+
 #ifndef __CSADDR_DEFINED__
 #define __CSADDR_DEFINED__
 
@@ -78,6 +80,17 @@ typedef enum {
     ScopeLevelGlobal       = 14
 } SCOPE_LEVEL;
 
+typedef struct
+{
+    union {
+        struct {
+            ULONG Zone  : 28;
+            ULONG Level : 4;
+        };
+        ULONG Value;
+    };
+} SCOPE_ID, *PSCOPE_ID;
+
 typedef struct _WSABUF
 {
     ULONG len;
diff --git a/include/ws2ipdef.h b/include/ws2ipdef.h
index ca47caa..e13cf6e 100644
--- a/include/ws2ipdef.h
+++ b/include/ws2ipdef.h
@@ -135,6 +135,13 @@ typedef struct WS(sockaddr_in6_pair)
     PSOCKADDR_IN6 DestinationAddress;
 } SOCKADDR_IN6_PAIR, *PSOCKADDR_IN6_PAIR;
 
+typedef union _SOCKADDR_INET
+{
+    SOCKADDR_IN     Ipv4;
+    SOCKADDR_IN6    Ipv6;
+    ADDRESS_FAMILY  si_family;
+} SOCKADDR_INET, *PSOCKADDR_INET;
+
 /*
  * Multicast group information
  */
-- 
2.7.4





More information about the wine-patches mailing list