[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