[IPHLPAPI] Implement GetExtendedUdpTable()

We only support IPv4 and UDP_TABLE_BASIC, UDP_TABLE_OWNER_PID
for now

CORE-5126
This commit is contained in:
Pierre Schweitzer 2018-11-24 21:22:42 +01:00
parent 6fb6c7b50b
commit 58cef01422
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
3 changed files with 108 additions and 2 deletions

View file

@ -33,7 +33,7 @@
@ stdcall GetBestRoute( long long long )
@ stub GetBestRouteFromStack
@ stdcall GetExtendedTcpTable( ptr ptr long long long long )
@ stdcall -stub GetExtendedUdpTable( ptr ptr long long long long )
@ stdcall GetExtendedUdpTable( ptr ptr long long long long )
@ stdcall GetFriendlyIfIndex( long )
@ stdcall GetIcmpStatistics( ptr )
@ stdcall GetIcmpStatisticsEx(ptr long)

View file

@ -1091,7 +1091,108 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
break;
}
return ret;
return ret;
}
static int UdpTableSorter(const void *a, const void *b);
/******************************************************************
* GetExtendedUdpTable (IPHLPAPI.@)
*
* Get the table of UDP endpoints available to the application.
*
* PARAMS
* pUdpTable [Out] table struct with the filtered UDP endpoints available to application
* pdwSize [In/Out] estimated size of the structure returned in pUdpTable, in bytes
* bOrder [In] whether to order the table
* ulAf [in] version of IP used by the UDP endpoints
* TableClass [in] type of the UDP table structure from UDP_TABLE_CLASS
* Reserved [in] reserved - this value must be zero
*
* RETURNS
* Success: NO_ERROR
* Failure: either ERROR_INSUFFICIENT_BUFFER or ERROR_INVALID_PARAMETER
*
* NOTES
*/
DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved)
{
DWORD ret = NO_ERROR;
if (!pdwSize)
{
return ERROR_INVALID_PARAMETER;
}
if (ulAf != AF_INET)
{
UNIMPLEMENTED;
return ERROR_INVALID_PARAMETER;
}
switch (TableClass)
{
case UDP_TABLE_BASIC:
{
PMIB_UDPTABLE pOurUdpTable = getUdpTable();
PMIB_UDPTABLE pTheirUdpTable = pUdpTable;
if (pOurUdpTable)
{
if (sizeof(DWORD) + pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW) > *pdwSize || !pTheirUdpTable)
{
*pdwSize = sizeof(DWORD) + pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW);
ret = ERROR_INSUFFICIENT_BUFFER;
}
else
{
memcpy(pTheirUdpTable, pOurUdpTable, sizeof(DWORD) + pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW_OWNER_PID));
if (bOrder)
qsort(pTheirUdpTable->table, pTheirUdpTable->dwNumEntries,
sizeof(MIB_UDPROW), UdpTableSorter);
}
free(pOurUdpTable);
}
}
break;
case UDP_TABLE_OWNER_PID:
{
PMIB_UDPTABLE_OWNER_PID pOurUdpTable = getOwnerUdpTable();
PMIB_UDPTABLE_OWNER_PID pTheirUdpTable = pUdpTable;
if (pOurUdpTable)
{
if (sizeof(DWORD) + pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW_OWNER_PID) > *pdwSize || !pTheirUdpTable)
{
*pdwSize = sizeof(DWORD) + pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW_OWNER_PID);
ret = ERROR_INSUFFICIENT_BUFFER;
}
else
{
memcpy(pTheirUdpTable, pOurUdpTable, sizeof(DWORD) + pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW_OWNER_PID));
if (bOrder)
qsort(pTheirUdpTable->table, pTheirUdpTable->dwNumEntries,
sizeof(MIB_UDPROW_OWNER_PID), UdpTableSorter);
}
free(pOurUdpTable);
}
}
break;
default:
UNIMPLEMENTED;
ret = ERROR_INVALID_PARAMETER;
break;
}
return ret;
}

View file

@ -97,6 +97,11 @@ DWORD getNumUdpEntries(void);
*/
PMIB_UDPTABLE getUdpTable(void);
/* Allocates and returns to you the UDP state table with owner PID,
* or NULL if it can't allocate enough memory. free() the returned table.
*/
PMIB_UDPTABLE_OWNER_PID getOwnerUdpTable(void);
/* Returns the number of entries in the TCP state table. */
DWORD getNumTcpEntries(void);