Huw Davies : iphlpapi: Implement GetUnicastIpAddressTable() on top of nsi.
Alexandre Julliard
julliard at winehq.org
Tue Jul 20 15:11:04 CDT 2021
Module: wine
Branch: master
Commit: 2f3ab0b242321a044ca68794f811165a8f748a74
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2f3ab0b242321a044ca68794f811165a8f748a74
Author: Huw Davies <huw at codeweavers.com>
Date: Tue Jul 20 08:43:26 2021 +0100
iphlpapi: Implement GetUnicastIpAddressTable() on top of nsi.
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/iphlpapi/iphlpapi_main.c | 132 ++++++++++++++++++++++++------------------
dlls/nsi/tests/nsi.c | 1 -
2 files changed, 76 insertions(+), 57 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 4ff9feb57f2..f4e6ea1a504 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -77,6 +77,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
DWORD WINAPI AllocateAndGetIfTableFromStack( MIB_IFTABLE **table, BOOL sort, HANDLE heap, DWORD flags );
+static const NPI_MODULEID *ip_module_id( USHORT family )
+{
+ if (family == WS_AF_INET) return &NPI_MS_IPV4_MODULEID;
+ if (family == WS_AF_INET6) return &NPI_MS_IPV6_MODULEID;
+ return NULL;
+}
+
DWORD WINAPI ConvertGuidToStringA( const GUID *guid, char *str, DWORD len )
{
if (len < CHARS_IN_GUID) return ERROR_INSUFFICIENT_BUFFER;
@@ -2651,6 +2658,42 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder,
return ret;
}
+static void unicast_row_fill( MIB_UNICASTIPADDRESS_ROW *row, USHORT fam, void *key, struct nsi_ip_unicast_rw *rw,
+ struct nsi_ip_unicast_dynamic *dyn, struct nsi_ip_unicast_static *stat )
+{
+ struct nsi_ipv4_unicast_key *key4 = (struct nsi_ipv4_unicast_key *)key;
+ struct nsi_ipv6_unicast_key *key6 = (struct nsi_ipv6_unicast_key *)key;
+
+ if (fam == WS_AF_INET)
+ {
+ row->Address.Ipv4.sin_family = fam;
+ row->Address.Ipv4.sin_port = 0;
+ row->Address.Ipv4.sin_addr = key4->addr;
+ memset( row->Address.Ipv4.sin_zero, 0, sizeof(row->Address.Ipv4.sin_zero) );
+ row->InterfaceLuid.Value = key4->luid.Value;
+ }
+ else
+ {
+ row->Address.Ipv6.sin6_family = fam;
+ row->Address.Ipv6.sin6_port = 0;
+ row->Address.Ipv6.sin6_flowinfo = 0;
+ row->Address.Ipv6.sin6_addr = key6->addr;
+ row->Address.Ipv6.sin6_scope_id = dyn->scope_id;
+ row->InterfaceLuid.Value = key6->luid.Value;
+ }
+
+ ConvertInterfaceLuidToIndex( &row->InterfaceLuid, &row->InterfaceIndex );
+ row->PrefixOrigin = rw->prefix_origin;
+ row->SuffixOrigin = rw->suffix_origin;
+ row->ValidLifetime = rw->valid_lifetime;
+ row->PreferredLifetime = rw->preferred_lifetime;
+ row->OnLinkPrefixLength = rw->on_link_prefix;
+ row->SkipAsSource = 0;
+ row->DadState = dyn->dad_state;
+ row->ScopeId.u.Value = dyn->scope_id;
+ row->CreationTimeStamp.QuadPart = stat->creation_time;
+}
+
DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
{
IP_ADAPTER_ADDRESSES *aa, *ptr;
@@ -2720,80 +2763,57 @@ DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
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;
+ void *key[2] = { NULL, NULL };
+ struct nsi_ip_unicast_rw *rw[2] = { NULL, NULL };
+ struct nsi_ip_unicast_dynamic *dyn[2] = { NULL, NULL };
+ struct nsi_ip_unicast_static *stat[2] = { NULL, NULL };
+ static const USHORT fam[2] = { WS_AF_INET, WS_AF_INET6 };
+ static const DWORD key_size[2] = { sizeof(struct nsi_ipv4_unicast_key), sizeof(struct nsi_ipv6_unicast_key) };
+ DWORD err, i, size, count[2] = { 0, 0 };
- TRACE("%u, %p\n", family, table);
+ 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)))
+ for (i = 0; i < 2; i++)
{
- HeapFree(GetProcessHeap(), 0, ptr);
- return ret;
+ if (family != WS_AF_UNSPEC && family != fam[i]) continue;
+
+ err = NsiAllocateAndGetTable( 1, ip_module_id( fam[i] ), NSI_IP_UNICAST_TABLE, key + i, key_size[i],
+ (void **)rw + i, sizeof(**rw), (void **)dyn + i, sizeof(**dyn),
+ (void **)stat + i, sizeof(**stat), count + i, 0 );
+ if (err) goto err;
}
- for (aa = ptr; aa; aa = aa->Next)
+ size = FIELD_OFFSET(MIB_UNICASTIPADDRESS_TABLE, Table[ count[0] + count[1] ]);
+ *table = heap_alloc( size );
+ if (!*table)
{
- IP_ADAPTER_UNICAST_ADDRESS *ua = aa->FirstUnicastAddress;
- while (ua)
- {
- count++;
- ua = ua->Next;
- }
+ err = ERROR_NOT_ENOUGH_MEMORY;
+ goto err;
}
- if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) + (count - 1) * sizeof(data->Table[0]))))
+ (*table)->NumEntries = count[0] + count[1];
+ for (i = 0; i < count[0]; i++)
{
- HeapFree(GetProcessHeap(), 0, ptr);
- return ERROR_OUTOFMEMORY;
+ MIB_UNICASTIPADDRESS_ROW *row = (*table)->Table + i;
+ struct nsi_ipv4_unicast_key *key4 = (struct nsi_ipv4_unicast_key *)key[0];
+
+ unicast_row_fill( row, fam[0], (void *)(key4 + i), rw[0] + i, dyn[0] + i, stat[0] + i );
}
- data->NumEntries = 0;
- for (aa = ptr; aa; aa = aa->Next)
+ for (i = 0; i < count[1]; i++)
{
- 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);
+ MIB_UNICASTIPADDRESS_ROW *row = (*table)->Table + count[0] + i;
+ struct nsi_ipv6_unicast_key *key6 = (struct nsi_ipv6_unicast_key *)key[1];
- data->NumEntries++;
- ua = ua->Next;
- }
+ unicast_row_fill( row, fam[1], (void *)(key6 + i), rw[1] + i, dyn[1] + i, stat[1] + i );
}
- HeapFree(GetProcessHeap(), 0, ptr);
-
- *table = data;
- return ret;
+err:
+ for (i = 0; i < 2; i++) NsiFreeTable( key[i], rw[i], dyn[i], stat[i] );
+ return err;
}
/******************************************************************
diff --git a/dlls/nsi/tests/nsi.c b/dlls/nsi/tests/nsi.c
index c07653c2ede..869fa255bb2 100644
--- a/dlls/nsi/tests/nsi.c
+++ b/dlls/nsi/tests/nsi.c
@@ -470,7 +470,6 @@ static void test_ip_unicast( int family )
/* SkipAsSource */
ok( row->DadState == dyn->dad_state, "mismatch\n" );
ok( row->ScopeId.Value == dyn->scope_id, "mismatch\n" );
-todo_wine
ok( row->CreationTimeStamp.QuadPart == stat->creation_time, "mismatch\n" );
winetest_pop_context();
}
More information about the wine-cvs
mailing list