From: André Hentschel Subject: [1/2] iphlpapi: Add GetUnicastIpAddressEntry implementation (try 4) Message-Id: <1199daf0-dbde-b16b-aa2c-07dc93bcd58e@dawncrow.de> Date: Wed, 8 Feb 2017 21:58:18 +0100 Signed-off-by: André Hentschel --- 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