[IPHLPAPI] Reduce code duplication and use a single function for TCP and UDP enumerations

Furthermore, memory was improperly allocated before (alignment issues) leading to heap
corruption under certain circumstances
This commit is contained in:
Pierre Schweitzer 2018-11-30 19:42:38 +01:00
parent ed7a78e97a
commit bf052e120b
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
3 changed files with 53 additions and 292 deletions

View file

@ -1040,7 +1040,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
{
case TCP_TABLE_BASIC_ALL:
{
PMIB_TCPTABLE pOurTcpTable = getTcpTable();
PMIB_TCPTABLE pOurTcpTable = getTcpTable(ClassBasic);
PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1066,7 +1066,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_BASIC_CONNECTIONS:
{
PMIB_TCPTABLE pOurTcpTable = getTcpTable();
PMIB_TCPTABLE pOurTcpTable = getTcpTable(ClassBasic);
PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1110,7 +1110,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_BASIC_LISTENER:
{
PMIB_TCPTABLE pOurTcpTable = getTcpTable();
PMIB_TCPTABLE pOurTcpTable = getTcpTable(ClassBasic);
PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1154,7 +1154,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_OWNER_PID_ALL:
{
PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable();
PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getTcpTable(ClassModulePid);
PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1181,7 +1181,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_OWNER_PID_CONNECTIONS:
{
PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable();
PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getTcpTable(ClassModulePid);
PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1226,7 +1226,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_OWNER_PID_LISTENER:
{
PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable();
PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getTcpTable(ClassModulePid);
PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1271,7 +1271,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_OWNER_MODULE_ALL:
{
PMIB_TCPTABLE_OWNER_MODULE pOurTcpTable = getOwnerModTcpTable();
PMIB_TCPTABLE_OWNER_MODULE pOurTcpTable = getTcpTable(ClassModule);
PMIB_TCPTABLE_OWNER_MODULE pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1298,7 +1298,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_OWNER_MODULE_CONNECTIONS:
{
PMIB_TCPTABLE_OWNER_MODULE pOurTcpTable = getOwnerModTcpTable();
PMIB_TCPTABLE_OWNER_MODULE pOurTcpTable = getTcpTable(ClassModule);
PMIB_TCPTABLE_OWNER_MODULE pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1343,7 +1343,7 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U
case TCP_TABLE_OWNER_MODULE_LISTENER:
{
PMIB_TCPTABLE_OWNER_MODULE pOurTcpTable = getOwnerModTcpTable();
PMIB_TCPTABLE_OWNER_MODULE pOurTcpTable = getTcpTable(ClassModule);
PMIB_TCPTABLE_OWNER_MODULE pTheirTcpTable = pTcpTable;
if (pOurTcpTable)
@ -1450,7 +1450,7 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, U
{
case UDP_TABLE_BASIC:
{
PMIB_UDPTABLE pOurUdpTable = getUdpTable();
PMIB_UDPTABLE pOurUdpTable = getUdpTable(ClassBasic);
PMIB_UDPTABLE pTheirUdpTable = pUdpTable;
if (pOurUdpTable)
@ -1476,7 +1476,7 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, U
case UDP_TABLE_OWNER_PID:
{
PMIB_UDPTABLE_OWNER_PID pOurUdpTable = getOwnerUdpTable();
PMIB_UDPTABLE_OWNER_PID pOurUdpTable = getUdpTable(ClassModulePid);
PMIB_UDPTABLE_OWNER_PID pTheirUdpTable = pUdpTable;
if (pOurUdpTable)
@ -1502,7 +1502,7 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, U
case UDP_TABLE_OWNER_MODULE:
{
PMIB_UDPTABLE_OWNER_MODULE pOurUdpTable = getOwnerModUdpTable();
PMIB_UDPTABLE_OWNER_MODULE pOurUdpTable = getUdpTable(ClassModule);
PMIB_UDPTABLE_OWNER_MODULE pTheirUdpTable = pUdpTable;
if (pOurUdpTable)

View file

@ -76,6 +76,12 @@ typedef struct _RouteTable {
RouteEntry routes[1];
} RouteTable;
typedef enum _CLASS_TABLE {
ClassBasic,
ClassModulePid,
ClassModule
} CLASS_TABLE;
/* Allocates and returns to you the route table, or NULL if it can't allocate
* enough memory. free() the returned table.
*/
@ -95,17 +101,7 @@ DWORD getNumUdpEntries(void);
/* Allocates and returns to you the UDP state table, or NULL if it can't
* allocate enough memory. free() the returned table.
*/
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);
/* Allocates and returns to you the UDP state table with module info,
* or NULL if it can't allocate enough memory. free() the returned table.
*/
PMIB_UDPTABLE_OWNER_MODULE getOwnerModUdpTable(void);
PVOID getUdpTable(CLASS_TABLE Class);
/* Returns the number of entries in the TCP state table. */
DWORD getNumTcpEntries(void);
@ -113,16 +109,6 @@ DWORD getNumTcpEntries(void);
/* Allocates and returns to you the TCP state table, or NULL if it can't
* allocate enough memory. free() the returned table.
*/
PMIB_TCPTABLE getTcpTable(void);
/* Allocates and returns to you the TCP state table with owner PID,
* or NULL if it can't allocate enough memory. free() the returned table.
*/
PMIB_TCPTABLE_OWNER_PID getOwnerTcpTable(void);
/* Allocates and returns to you the TCP state table with module info,
* or NULL if it can't allocate enough memory. free() the returned table.
*/
PMIB_TCPTABLE_OWNER_MODULE getOwnerModTcpTable(void);
PVOID getTcpTable(CLASS_TABLE Class);
#endif /* ndef WINE_IPSTATS_H_ */

View file

@ -590,6 +590,21 @@ PMIB_IPNETTABLE getArpTable(void)
return IpArpTable;
}
struct _TABLE_CALL
{
DWORD TOIID;
SIZE_T UdpSize;
SIZE_T TcpSize;
SIZE_T UdpOffset;
SIZE_T TcpOffset;
} UdpTcpTableCall[] = {
{IP_MIB_ARPTABLE_ENTRY_ID, sizeof(MIB_UDPROW), sizeof(MIB_TCPROW), FIELD_OFFSET(MIB_UDPTABLE, table), FIELD_OFFSET(MIB_TCPTABLE, table)},
{IP_MIB_ADDRTABLE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_PID), sizeof(MIB_TCPROW_OWNER_PID), FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table)},
{IP_SPECIFIC_MODULE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_MODULE), sizeof(MIB_TCPROW_OWNER_MODULE), FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table)},
};
#define Add2Ptr(PTR, INC) (PVOID)((ULONG_PTR)(PTR) + (INC))
DWORD getNumUdpEntries(void)
{
DWORD numEntities;
@ -639,7 +654,7 @@ DWORD getNumUdpEntries(void)
return totalNumber;
}
PMIB_UDPTABLE getUdpTable(void)
PVOID getUdpTable(CLASS_TABLE Class)
{
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
@ -647,7 +662,7 @@ PMIB_UDPTABLE getUdpTable(void)
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_UDPTABLE IpUdpTable = NULL;
PMIB_UDPROW AdapterUdpTable = NULL;
PVOID AdapterUdpTable = NULL;
TRACE("called.\n");
@ -661,7 +676,7 @@ PMIB_UDPTABLE getUdpTable(void)
IpUdpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_UDPROW) * totalNumber) );
UdpTcpTableCall[Class].UdpOffset + (UdpTcpTableCall[Class].UdpSize * totalNumber) );
if (!IpUdpTable) {
closeTcpFile(tcpFile);
return NULL;
@ -676,17 +691,19 @@ PMIB_UDPTABLE getUdpTable(void)
status = tdiGetSetOfThings( tcpFile,
INFO_CLASS_PROTOCOL,
INFO_TYPE_PROVIDER,
IP_MIB_ARPTABLE_ENTRY_ID,
UdpTcpTableCall[Class].TOIID,
CL_TL_ENTITY,
entitySet[i].tei_instance,
0,
sizeof(MIB_UDPROW),
(PVOID *)&AdapterUdpTable,
UdpTcpTableCall[Class].UdpSize,
&AdapterUdpTable,
&returnSize );
if( status == STATUS_SUCCESS ) {
for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
IpUdpTable->table[CurrIdx] = AdapterUdpTable[TmpIdx];
CopyMemory(Add2Ptr(IpUdpTable, UdpTcpTableCall[Class].UdpOffset + UdpTcpTableCall[Class].UdpSize * CurrIdx),
Add2Ptr(AdapterUdpTable, UdpTcpTableCall[Class].UdpSize * TmpIdx),
UdpTcpTableCall[Class].UdpSize);
tdiFreeThingSet( AdapterUdpTable );
}
}
@ -700,128 +717,6 @@ PMIB_UDPTABLE getUdpTable(void)
return IpUdpTable;
}
PMIB_UDPTABLE_OWNER_PID getOwnerUdpTable(void)
{
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
HANDLE tcpFile;
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_UDPTABLE_OWNER_PID IpOwnerUdpTable = NULL;
PMIB_UDPROW_OWNER_PID AdapterOwnerUdpTable = NULL;
TRACE("called.\n");
totalNumber = getNumUdpEntries();
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
ERR("openTcpFile returned 0x%08lx\n", status);
return 0;
}
IpOwnerUdpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_UDPROW_OWNER_PID) * totalNumber) );
if (!IpOwnerUdpTable) {
closeTcpFile(tcpFile);
return NULL;
}
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
for( i = 0; i < numEntities; i++ ) {
if( entitySet[i].tei_entity == CL_TL_ENTITY &&
hasArp( tcpFile, &entitySet[i] ) ) {
status = tdiGetSetOfThings( tcpFile,
INFO_CLASS_PROTOCOL,
INFO_TYPE_PROVIDER,
IP_MIB_ADDRTABLE_ENTRY_ID,
CL_TL_ENTITY,
entitySet[i].tei_instance,
0,
sizeof(MIB_UDPROW_OWNER_PID),
(PVOID *)&AdapterOwnerUdpTable,
&returnSize );
if( status == STATUS_SUCCESS ) {
for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
IpOwnerUdpTable->table[CurrIdx] = AdapterOwnerUdpTable[TmpIdx];
tdiFreeThingSet( AdapterOwnerUdpTable );
}
}
}
closeTcpFile( tcpFile );
tdiFreeThingSet( entitySet );
IpOwnerUdpTable->dwNumEntries = CurrIdx;
return IpOwnerUdpTable;
}
PMIB_UDPTABLE_OWNER_MODULE getOwnerModUdpTable(void)
{
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
HANDLE tcpFile;
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_UDPTABLE_OWNER_MODULE IpOwnerModUdpTable = NULL;
PMIB_UDPROW_OWNER_MODULE AdapterOwnerModUdpTable = NULL;
TRACE("called.\n");
totalNumber = getNumUdpEntries();
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
ERR("openTcpFile returned 0x%08lx\n", status);
return 0;
}
IpOwnerModUdpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_UDPROW_OWNER_MODULE) * totalNumber) );
if (!IpOwnerModUdpTable) {
closeTcpFile(tcpFile);
return NULL;
}
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
for( i = 0; i < numEntities; i++ ) {
if( entitySet[i].tei_entity == CL_TL_ENTITY &&
hasArp( tcpFile, &entitySet[i] ) ) {
status = tdiGetSetOfThings( tcpFile,
INFO_CLASS_PROTOCOL,
INFO_TYPE_PROVIDER,
IP_SPECIFIC_MODULE_ENTRY_ID,
CL_TL_ENTITY,
entitySet[i].tei_instance,
0,
sizeof(MIB_UDPROW_OWNER_MODULE),
(PVOID *)&AdapterOwnerModUdpTable,
&returnSize );
if( status == STATUS_SUCCESS ) {
for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
IpOwnerModUdpTable->table[CurrIdx] = AdapterOwnerModUdpTable[TmpIdx];
tdiFreeThingSet( AdapterOwnerModUdpTable );
}
}
}
closeTcpFile( tcpFile );
tdiFreeThingSet( entitySet );
IpOwnerModUdpTable->dwNumEntries = CurrIdx;
return IpOwnerModUdpTable;
}
DWORD getNumTcpEntries(void)
{
DWORD numEntities;
@ -871,7 +766,7 @@ DWORD getNumTcpEntries(void)
return totalNumber;
}
PMIB_TCPTABLE getTcpTable(void)
PVOID getTcpTable(CLASS_TABLE Class)
{
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
@ -879,7 +774,7 @@ PMIB_TCPTABLE getTcpTable(void)
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_TCPTABLE IpTcpTable = NULL;
PMIB_TCPROW AdapterTcpTable = NULL;
PVOID AdapterTcpTable = NULL;
TRACE("called.\n");
@ -893,7 +788,7 @@ PMIB_TCPTABLE getTcpTable(void)
IpTcpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_TCPROW) * totalNumber) );
UdpTcpTableCall[Class].TcpOffset + (UdpTcpTableCall[Class].TcpSize * totalNumber) );
if (!IpTcpTable) {
closeTcpFile(tcpFile);
return NULL;
@ -908,17 +803,19 @@ PMIB_TCPTABLE getTcpTable(void)
status = tdiGetSetOfThings( tcpFile,
INFO_CLASS_PROTOCOL,
INFO_TYPE_PROVIDER,
IP_MIB_ARPTABLE_ENTRY_ID,
UdpTcpTableCall[Class].TOIID,
CO_TL_ENTITY,
entitySet[i].tei_instance,
0,
sizeof(MIB_TCPROW),
(PVOID *)&AdapterTcpTable,
UdpTcpTableCall[Class].TcpSize,
&AdapterTcpTable,
&returnSize );
if( status == STATUS_SUCCESS ) {
for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
IpTcpTable->table[CurrIdx] = AdapterTcpTable[TmpIdx];
CopyMemory(Add2Ptr(IpTcpTable, UdpTcpTableCall[Class].TcpOffset + UdpTcpTableCall[Class].TcpSize * CurrIdx),
Add2Ptr(AdapterTcpTable, UdpTcpTableCall[Class].TcpSize * TmpIdx),
UdpTcpTableCall[Class].TcpSize);
tdiFreeThingSet( AdapterTcpTable );
}
}
@ -931,125 +828,3 @@ PMIB_TCPTABLE getTcpTable(void)
return IpTcpTable;
}
PMIB_TCPTABLE_OWNER_PID getOwnerTcpTable(void)
{
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
HANDLE tcpFile;
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_TCPTABLE_OWNER_PID IpOwnerTcpTable = NULL;
PMIB_TCPROW_OWNER_PID AdapterOwnerTcpTable = NULL;
TRACE("called.\n");
totalNumber = getNumTcpEntries();
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
ERR("openTcpFile returned 0x%08lx\n", status);
return 0;
}
IpOwnerTcpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_TCPROW_OWNER_PID) * totalNumber) );
if (!IpOwnerTcpTable) {
closeTcpFile(tcpFile);
return NULL;
}
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
for( i = 0; i < numEntities; i++ ) {
if( entitySet[i].tei_entity == CO_TL_ENTITY &&
hasArp( tcpFile, &entitySet[i] ) ) {
status = tdiGetSetOfThings( tcpFile,
INFO_CLASS_PROTOCOL,
INFO_TYPE_PROVIDER,
IP_MIB_ADDRTABLE_ENTRY_ID,
CO_TL_ENTITY,
entitySet[i].tei_instance,
0,
sizeof(MIB_TCPROW_OWNER_PID),
(PVOID *)&AdapterOwnerTcpTable,
&returnSize );
if( status == STATUS_SUCCESS ) {
for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
IpOwnerTcpTable->table[CurrIdx] = AdapterOwnerTcpTable[TmpIdx];
tdiFreeThingSet( AdapterOwnerTcpTable );
}
}
}
closeTcpFile( tcpFile );
tdiFreeThingSet( entitySet );
IpOwnerTcpTable->dwNumEntries = CurrIdx;
return IpOwnerTcpTable;
}
PMIB_TCPTABLE_OWNER_MODULE getOwnerModTcpTable(void)
{
DWORD numEntities, returnSize;
TDIEntityID *entitySet;
HANDLE tcpFile;
int i, totalNumber, TmpIdx, CurrIdx = 0;
NTSTATUS status;
PMIB_TCPTABLE_OWNER_MODULE IpOwnerModTcpTable = NULL;
PMIB_TCPROW_OWNER_MODULE AdapterOwnerModTcpTable = NULL;
TRACE("called.\n");
totalNumber = getNumTcpEntries();
status = openTcpFile( &tcpFile, FILE_READ_DATA );
if( !NT_SUCCESS(status) ) {
ERR("openTcpFile returned 0x%08lx\n", status);
return 0;
}
IpOwnerModTcpTable = HeapAlloc
( GetProcessHeap(), 0,
sizeof(DWORD) + (sizeof(MIB_TCPROW_OWNER_MODULE) * totalNumber) );
if (!IpOwnerModTcpTable) {
closeTcpFile(tcpFile);
return NULL;
}
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
for( i = 0; i < numEntities; i++ ) {
if( entitySet[i].tei_entity == CO_TL_ENTITY &&
hasArp( tcpFile, &entitySet[i] ) ) {
status = tdiGetSetOfThings( tcpFile,
INFO_CLASS_PROTOCOL,
INFO_TYPE_PROVIDER,
IP_SPECIFIC_MODULE_ENTRY_ID,
CO_TL_ENTITY,
entitySet[i].tei_instance,
0,
sizeof(MIB_TCPROW_OWNER_MODULE),
(PVOID *)&AdapterOwnerModTcpTable,
&returnSize );
if( status == STATUS_SUCCESS ) {
for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
IpOwnerModTcpTable->table[CurrIdx] = AdapterOwnerModTcpTable[TmpIdx];
tdiFreeThingSet( AdapterOwnerModTcpTable );
}
}
}
closeTcpFile( tcpFile );
tdiFreeThingSet( entitySet );
IpOwnerModTcpTable->dwNumEntries = CurrIdx;
return IpOwnerModTcpTable;
}