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 )
|
||||
@ stub GetUdpTableFromStack
|
||||
@ stdcall GetUnicastIpAddressEntry( ptr )
|
||||
#@ stub GetUnicastIpAddressTable
|
||||
@ stdcall GetUnicastIpAddressTable(long ptr)
|
||||
@ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
|
||||
@ stdcall Icmp6CreateFile()
|
||||
#@ stub Icmp6ParseReplies
|
||||
|
|
|
@ -2534,6 +2534,84 @@ DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
|
|||
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.@)
|
||||
*
|
||||
|
|
|
@ -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 *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
|
||||
static DWORD (WINAPI *pGetUnicastIpAddressEntry)(MIB_UNICASTIPADDRESS_ROW*);
|
||||
static DWORD (WINAPI *pGetUnicastIpAddressTable)(ADDRESS_FAMILY,MIB_UNICASTIPADDRESS_TABLE**);
|
||||
static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED);
|
||||
static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED);
|
||||
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");
|
||||
pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses");
|
||||
pGetUnicastIpAddressEntry = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressEntry");
|
||||
pGetUnicastIpAddressTable = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressTable");
|
||||
pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange");
|
||||
pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify");
|
||||
pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable");
|
||||
|
@ -2095,6 +2097,59 @@ static void test_GetUnicastIpAddressEntry(void)
|
|||
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)
|
||||
{
|
||||
|
||||
|
@ -2120,6 +2175,7 @@ START_TEST(iphlpapi)
|
|||
test_GetIfEntry2();
|
||||
test_GetIfTable2();
|
||||
test_GetUnicastIpAddressEntry();
|
||||
test_GetUnicastIpAddressTable();
|
||||
freeIPHlpApi();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,6 +145,12 @@ typedef struct _MIB_UNICASTIPADDRESS_ROW
|
|||
LARGE_INTEGER CreationTimeStamp;
|
||||
} 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,
|
||||
MIB_NOTIFICATION_TYPE);
|
||||
typedef VOID (WINAPI *PUNICAST_IPADDRESS_CHANGE_CALLBACK)(PVOID, PMIB_UNICASTIPADDRESS_ROW,
|
||||
|
|
Loading…
Reference in New Issue