iphlpapi: Implement GetUnicastIpAddressTable.
Signed-off-by: André Hentschel <nerv@dawncrow.de> Signed-off-by: Bruno Jesus <bjesus@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
12a7b2b41c
commit
eda35423f4
@ -148,7 +148,7 @@
|
|||||||
@ stdcall GetUdpTable( ptr ptr long )
|
@ stdcall GetUdpTable( ptr ptr long )
|
||||||
@ stub GetUdpTableFromStack
|
@ stub GetUdpTableFromStack
|
||||||
@ stdcall GetUnicastIpAddressEntry( ptr )
|
@ stdcall GetUnicastIpAddressEntry( ptr )
|
||||||
#@ stub GetUnicastIpAddressTable
|
@ stdcall GetUnicastIpAddressTable(long ptr)
|
||||||
@ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
|
@ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
|
||||||
@ stdcall Icmp6CreateFile()
|
@ stdcall Icmp6CreateFile()
|
||||||
#@ stub Icmp6ParseReplies
|
#@ stub Icmp6ParseReplies
|
||||||
|
@ -2534,6 +2534,84 @@ DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI GetUnicastIpAddressTable(ADDRESS_FAMILY family, MIB_UNICASTIPADDRESS_TABLE **table)
|
||||||
|
{
|
||||||
|
IP_ADAPTER_ADDRESSES *aa, *ptr;
|
||||||
|
MIB_UNICASTIPADDRESS_TABLE *data;
|
||||||
|
DWORD ret, count = 0;
|
||||||
|
ULONG size, flags;
|
||||||
|
|
||||||
|
TRACE("%u, %p\n", family, table);
|
||||||
|
|
||||||
|
if (!table || (family != WS_AF_INET && family != WS_AF_INET6 && family != WS_AF_UNSPEC))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
flags = GAA_FLAG_SKIP_ANYCAST |
|
||||||
|
GAA_FLAG_SKIP_MULTICAST |
|
||||||
|
GAA_FLAG_SKIP_DNS_SERVER |
|
||||||
|
GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||||
|
|
||||||
|
ret = GetAdaptersAddresses(family, flags, NULL, NULL, &size);
|
||||||
|
if (ret != ERROR_BUFFER_OVERFLOW)
|
||||||
|
return ret;
|
||||||
|
if (!(ptr = HeapAlloc(GetProcessHeap(), 0, size)))
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
if ((ret = GetAdaptersAddresses(family, flags, NULL, ptr, &size)))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (aa = ptr; aa; aa = aa->Next)
|
||||||
|
{
|
||||||
|
IP_ADAPTER_UNICAST_ADDRESS *ua = aa->FirstUnicastAddress;
|
||||||
|
while (ua)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
ua = ua->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) + (count - 1) * sizeof(data->Table[0]))))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->NumEntries = 0;
|
||||||
|
for (aa = ptr; aa; aa = aa->Next)
|
||||||
|
{
|
||||||
|
IP_ADAPTER_UNICAST_ADDRESS *ua = aa->FirstUnicastAddress;
|
||||||
|
while (ua)
|
||||||
|
{
|
||||||
|
MIB_UNICASTIPADDRESS_ROW *row = &data->Table[data->NumEntries];
|
||||||
|
memcpy(&row->Address, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
|
||||||
|
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.u.Value = row->Address.Ipv6.sin6_scope_id;
|
||||||
|
else
|
||||||
|
row->ScopeId.u.Value = 0;
|
||||||
|
NtQuerySystemTime(&row->CreationTimeStamp);
|
||||||
|
|
||||||
|
data->NumEntries++;
|
||||||
|
ua = ua->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
|
||||||
|
*table = data;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* GetUniDirectionalAdapterInfo (IPHLPAPI.@)
|
* GetUniDirectionalAdapterInfo (IPHLPAPI.@)
|
||||||
*
|
*
|
||||||
|
@ -76,6 +76,7 @@ static DWORD (WINAPI *pGetUdpTable)(PMIB_UDPTABLE,PDWORD,BOOL);
|
|||||||
static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
|
static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
|
||||||
static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
|
static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
|
||||||
static DWORD (WINAPI *pGetUnicastIpAddressEntry)(MIB_UNICASTIPADDRESS_ROW*);
|
static DWORD (WINAPI *pGetUnicastIpAddressEntry)(MIB_UNICASTIPADDRESS_ROW*);
|
||||||
|
static DWORD (WINAPI *pGetUnicastIpAddressTable)(ADDRESS_FAMILY,MIB_UNICASTIPADDRESS_TABLE**);
|
||||||
static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
|
static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
|
||||||
static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
|
static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
|
||||||
static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
|
static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG);
|
||||||
@ -125,6 +126,7 @@ static void loadIPHlpApi(void)
|
|||||||
pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo");
|
pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo");
|
||||||
pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
|
pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
|
||||||
pGetUnicastIpAddressEntry = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressEntry");
|
pGetUnicastIpAddressEntry = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressEntry");
|
||||||
|
pGetUnicastIpAddressTable = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressTable");
|
||||||
pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
|
pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
|
||||||
pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
|
pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
|
||||||
pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
|
pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
|
||||||
@ -2095,6 +2097,59 @@ static void test_GetUnicastIpAddressEntry(void)
|
|||||||
HeapFree(GetProcessHeap(), 0, ptr);
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_GetUnicastIpAddressTable(void)
|
||||||
|
{
|
||||||
|
MIB_UNICASTIPADDRESS_TABLE *table;
|
||||||
|
DWORD ret;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
if (!pGetUnicastIpAddressTable)
|
||||||
|
{
|
||||||
|
win_skip( "GetUnicastIpAddressTable not available\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pGetUnicastIpAddressTable(AF_UNSPEC, NULL);
|
||||||
|
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
|
||||||
|
|
||||||
|
ret = pGetUnicastIpAddressTable(AF_BAN, &table);
|
||||||
|
ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret );
|
||||||
|
|
||||||
|
ret = pGetUnicastIpAddressTable(AF_INET, &table);
|
||||||
|
ok( ret == NO_ERROR, "got %u\n", ret );
|
||||||
|
trace("GetUnicastIpAddressTable(AF_INET): NumEntries %u\n", table->NumEntries);
|
||||||
|
pFreeMibTable(table);
|
||||||
|
|
||||||
|
ret = pGetUnicastIpAddressTable(AF_INET6, &table);
|
||||||
|
ok( ret == NO_ERROR, "got %u\n", ret );
|
||||||
|
trace("GetUnicastIpAddressTable(AF_INET6): NumEntries %u\n", table->NumEntries);
|
||||||
|
pFreeMibTable(table);
|
||||||
|
|
||||||
|
ret = pGetUnicastIpAddressTable(AF_UNSPEC, &table);
|
||||||
|
ok( ret == NO_ERROR, "got %u\n", ret );
|
||||||
|
trace("GetUnicastIpAddressTable(AF_UNSPEC): NumEntries %u\n", table->NumEntries);
|
||||||
|
for (i = 0; i < table->NumEntries && winetest_debug > 1; i++)
|
||||||
|
{
|
||||||
|
trace("Index %u:\n", i);
|
||||||
|
trace("Address.si_family: %u\n", table->Table[i].Address.si_family);
|
||||||
|
trace("InterfaceLuid.Info.Reserved: %u\n", table->Table[i].InterfaceLuid.Info.Reserved);
|
||||||
|
trace("InterfaceLuid.Info.NetLuidIndex: %u\n", table->Table[i].InterfaceLuid.Info.NetLuidIndex);
|
||||||
|
trace("InterfaceLuid.Info.IfType: %u\n", table->Table[i].InterfaceLuid.Info.IfType);
|
||||||
|
trace("InterfaceIndex: %u\n", table->Table[i].InterfaceIndex);
|
||||||
|
trace("PrefixOrigin: %u\n", table->Table[i].PrefixOrigin);
|
||||||
|
trace("SuffixOrigin: %u\n", table->Table[i].SuffixOrigin);
|
||||||
|
trace("ValidLifetime: %u seconds\n", table->Table[i].ValidLifetime);
|
||||||
|
trace("PreferredLifetime: %u seconds\n", table->Table[i].PreferredLifetime);
|
||||||
|
trace("OnLinkPrefixLength: %u\n", table->Table[i].OnLinkPrefixLength);
|
||||||
|
trace("SkipAsSource: %u\n", table->Table[i].SkipAsSource);
|
||||||
|
trace("DadState: %u\n", table->Table[i].DadState);
|
||||||
|
trace("ScopeId.Value: %u\n", table->Table[i].ScopeId.Value);
|
||||||
|
trace("CreationTimeStamp: %08x%08x\n", table->Table[i].CreationTimeStamp.HighPart, table->Table[i].CreationTimeStamp.LowPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
pFreeMibTable(table);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(iphlpapi)
|
START_TEST(iphlpapi)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -2120,6 +2175,7 @@ START_TEST(iphlpapi)
|
|||||||
test_GetIfEntry2();
|
test_GetIfEntry2();
|
||||||
test_GetIfTable2();
|
test_GetIfTable2();
|
||||||
test_GetUnicastIpAddressEntry();
|
test_GetUnicastIpAddressEntry();
|
||||||
|
test_GetUnicastIpAddressTable();
|
||||||
freeIPHlpApi();
|
freeIPHlpApi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,12 @@ typedef struct _MIB_UNICASTIPADDRESS_ROW
|
|||||||
LARGE_INTEGER CreationTimeStamp;
|
LARGE_INTEGER CreationTimeStamp;
|
||||||
} MIB_UNICASTIPADDRESS_ROW, *PMIB_UNICASTIPADDRESS_ROW;
|
} MIB_UNICASTIPADDRESS_ROW, *PMIB_UNICASTIPADDRESS_ROW;
|
||||||
|
|
||||||
|
typedef struct _MIB_UNICASTIPADDRESS_TABLE
|
||||||
|
{
|
||||||
|
ULONG NumEntries;
|
||||||
|
MIB_UNICASTIPADDRESS_ROW Table[1];
|
||||||
|
} MIB_UNICASTIPADDRESS_TABLE, *PMIB_UNICASTIPADDRESS_TABLE;
|
||||||
|
|
||||||
typedef VOID (WINAPI *PIPINTERFACE_CHANGE_CALLBACK)(PVOID, PMIB_IPINTERFACE_ROW,
|
typedef VOID (WINAPI *PIPINTERFACE_CHANGE_CALLBACK)(PVOID, PMIB_IPINTERFACE_ROW,
|
||||||
MIB_NOTIFICATION_TYPE);
|
MIB_NOTIFICATION_TYPE);
|
||||||
typedef VOID (WINAPI *PUNICAST_IPADDRESS_CHANGE_CALLBACK)(PVOID, PMIB_UNICASTIPADDRESS_ROW,
|
typedef VOID (WINAPI *PUNICAST_IPADDRESS_CHANGE_CALLBACK)(PVOID, PMIB_UNICASTIPADDRESS_ROW,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user