iphlpapi: Implement GetIpAddrTable() on top of nsi.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3ef3166b5c
commit
beb8444487
|
@ -148,19 +148,6 @@ static int IpAddrTableNumericSorter(const void *a, const void *b)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int IpAddrTableLoopbackSorter(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const MIB_IPADDRROW *left = a, *right = b;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (isIfIndexLoopback(left->dwIndex))
|
|
||||||
ret = 1;
|
|
||||||
else if (isIfIndexLoopback(right->dwIndex))
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@)
|
* AllocateAndGetIpAddrTableFromStack (IPHLPAPI.@)
|
||||||
*
|
*
|
||||||
|
@ -2131,6 +2118,10 @@ DWORD WINAPI GetInterfaceInfo( IP_INTERFACE_INFO *table, ULONG *size )
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ipaddrrow_cmp( const void *a, const void *b )
|
||||||
|
{
|
||||||
|
return ((const MIB_IPADDRROW*)a)->dwAddr - ((const MIB_IPADDRROW*)b)->dwAddr;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* GetIpAddrTable (IPHLPAPI.@)
|
* GetIpAddrTable (IPHLPAPI.@)
|
||||||
|
@ -2138,59 +2129,63 @@ DWORD WINAPI GetInterfaceInfo( IP_INTERFACE_INFO *table, ULONG *size )
|
||||||
* Get interface-to-IP address mapping table.
|
* Get interface-to-IP address mapping table.
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* pIpAddrTable [Out] buffer for mapping table
|
* table [Out] buffer for mapping table
|
||||||
* pdwSize [In/Out] length of output buffer
|
* size [In/Out] length of output buffer
|
||||||
* bOrder [In] whether to sort the table
|
* sort [In] whether to sort the table
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Success: NO_ERROR
|
* Success: NO_ERROR
|
||||||
* Failure: error code from winerror.h
|
* Failure: error code from winerror.h
|
||||||
*
|
*
|
||||||
* NOTES
|
|
||||||
* If pdwSize is less than required, the function will return
|
|
||||||
* ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to the required byte
|
|
||||||
* size.
|
|
||||||
* If bOrder is true, the returned table will be sorted by the next hop and
|
|
||||||
* an assortment of arbitrary parameters.
|
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder)
|
DWORD WINAPI GetIpAddrTable( MIB_IPADDRTABLE *table, ULONG *size, BOOL sort )
|
||||||
{
|
{
|
||||||
DWORD ret;
|
DWORD err, count, needed, i, loopback, row_num = 0;
|
||||||
|
struct nsi_ipv4_unicast_key *keys;
|
||||||
|
struct nsi_ip_unicast_rw *rw;
|
||||||
|
|
||||||
TRACE("pIpAddrTable %p, pdwSize %p, bOrder %d\n", pIpAddrTable, pdwSize,
|
TRACE( "table %p, size %p, sort %d\n", table, size, sort );
|
||||||
(DWORD)bOrder);
|
if (!size) return ERROR_INVALID_PARAMETER;
|
||||||
if (!pdwSize)
|
|
||||||
ret = ERROR_INVALID_PARAMETER;
|
|
||||||
else {
|
|
||||||
PMIB_IPADDRTABLE table;
|
|
||||||
|
|
||||||
ret = getIPAddrTable(&table, GetProcessHeap(), 0);
|
err = NsiAllocateAndGetTable( 1, &NPI_MS_IPV4_MODULEID, NSI_IP_UNICAST_TABLE, (void **)&keys, sizeof(*keys),
|
||||||
if (ret == NO_ERROR)
|
(void **)&rw, sizeof(*rw), NULL, 0, NULL, 0, &count, 0 );
|
||||||
|
if (err) return err;
|
||||||
|
|
||||||
|
needed = FIELD_OFFSET( MIB_IPADDRTABLE, table[count] );
|
||||||
|
|
||||||
|
if (!table || *size < needed)
|
||||||
{
|
{
|
||||||
ULONG size = FIELD_OFFSET(MIB_IPADDRTABLE, table[table->dwNumEntries]);
|
*size = needed;
|
||||||
|
err = ERROR_INSUFFICIENT_BUFFER;
|
||||||
if (!pIpAddrTable || *pdwSize < size) {
|
goto err;
|
||||||
*pdwSize = size;
|
|
||||||
ret = ERROR_INSUFFICIENT_BUFFER;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*pdwSize = size;
|
|
||||||
memcpy(pIpAddrTable, table, size);
|
|
||||||
/* sort by numeric IP value */
|
|
||||||
if (bOrder)
|
|
||||||
qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries,
|
|
||||||
sizeof(MIB_IPADDRROW), IpAddrTableNumericSorter);
|
|
||||||
/* sort ensuring loopback interfaces are in the end */
|
|
||||||
else
|
|
||||||
qsort(pIpAddrTable->table, pIpAddrTable->dwNumEntries,
|
|
||||||
sizeof(MIB_IPADDRROW), IpAddrTableLoopbackSorter);
|
|
||||||
ret = NO_ERROR;
|
|
||||||
}
|
|
||||||
HeapFree(GetProcessHeap(), 0, table);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
TRACE("returning %d\n", ret);
|
table->dwNumEntries = count;
|
||||||
return ret;
|
|
||||||
|
for (loopback = 0; loopback < 2; loopback++) /* Move the loopback addresses to the end */
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
MIB_IPADDRROW *row = table->table + row_num;
|
||||||
|
|
||||||
|
if (!!loopback != (keys[i].luid.Info.IfType == MIB_IF_TYPE_LOOPBACK)) continue;
|
||||||
|
|
||||||
|
row->dwAddr = keys[i].addr.WS_s_addr;
|
||||||
|
ConvertInterfaceLuidToIndex( &keys[i].luid, &row->dwIndex );
|
||||||
|
ConvertLengthToIpv4Mask( rw[i].on_link_prefix, &row->dwMask );
|
||||||
|
row->dwBCastAddr = 1;
|
||||||
|
row->dwReasmSize = 0xffff;
|
||||||
|
row->unused1 = 0;
|
||||||
|
row->wType = MIB_IPADDR_PRIMARY;
|
||||||
|
row_num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sort) qsort( table->table, count, sizeof(MIB_IPADDRROW), ipaddrrow_cmp );
|
||||||
|
err:
|
||||||
|
NsiFreeTable( keys, rw, NULL, NULL );
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,8 @@ static void testGetIpAddrTable(void)
|
||||||
for (i = 0; i < buf->dwNumEntries; i++)
|
for (i = 0; i < buf->dwNumEntries; i++)
|
||||||
{
|
{
|
||||||
ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
|
ok (buf->table[i].wType != 0, "Test[%d]: expected wType > 0\n", i);
|
||||||
|
ok (buf->table[i].dwBCastAddr == 1, "Test[%d]: got %08x\n", i, buf->table[i].dwBCastAddr);
|
||||||
|
ok (buf->table[i].dwReasmSize == 0xffff, "Test[%d]: got %08x\n", i, buf->table[i].dwReasmSize);
|
||||||
trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
|
trace("Entry[%d]: addr %s, dwIndex %u, wType 0x%x\n", i,
|
||||||
ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
|
ntoa(buf->table[i].dwAddr), buf->table[i].dwIndex, buf->table[i].wType);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue