From c949a12506046b0aa9bc74e6a8fa1dabefcecba7 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 24 Nov 2018 20:32:55 +0100 Subject: [PATCH] [IPHLPAPI] Implement the IPv4 TCP_TABLE_OWNER_PID_* cases in GetExtendedTcpTable() --- dll/win32/iphlpapi/iphlpapi_main.c | 111 +++++++++++++++++++++++++++++ dll/win32/iphlpapi/ipstats.h | 5 ++ 2 files changed, 116 insertions(+) diff --git a/dll/win32/iphlpapi/iphlpapi_main.c b/dll/win32/iphlpapi/iphlpapi_main.c index bff2ea70888..2792be25a01 100644 --- a/dll/win32/iphlpapi/iphlpapi_main.c +++ b/dll/win32/iphlpapi/iphlpapi_main.c @@ -922,6 +922,117 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, U } break; + case TCP_TABLE_OWNER_PID_ALL: + { + PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable(); + PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable; + + if (pOurTcpTable) + { + if (sizeof(DWORD) + pOurTcpTable->dwNumEntries * sizeof(MIB_TCPROW_OWNER_PID) > *pdwSize || !pTheirTcpTable) + { + *pdwSize = sizeof(DWORD) + pOurTcpTable->dwNumEntries * sizeof(MIB_TCPROW_OWNER_PID); + ret = ERROR_INSUFFICIENT_BUFFER; + } + else + { + memcpy(pTheirTcpTable, pOurTcpTable, sizeof(DWORD) + pOurTcpTable->dwNumEntries * sizeof(MIB_TCPROW_OWNER_PID)); + + /* Don't sort on PID, so use basic helper */ + if (bOrder) + qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries, + sizeof(MIB_TCPROW_OWNER_PID), TcpTableSorter); + } + } + } + break; + + case TCP_TABLE_OWNER_PID_CONNECTIONS: + { + PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable(); + PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable; + + if (pOurTcpTable) + { + for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i) + { + if (pOurTcpTable->table[i].dwState != MIB_TCP_STATE_LISTEN) + { + ++count; + } + } + + if (sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID) > *pdwSize || !pTheirTcpTable) + { + *pdwSize = sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID); + ret = ERROR_INSUFFICIENT_BUFFER; + } + else + { + pTheirTcpTable->dwNumEntries = count; + + for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i) + { + if (pOurTcpTable->table[i].dwState != MIB_TCP_STATE_LISTEN) + { + memcpy(&pTheirTcpTable->table[count], &pOurTcpTable->table[i], sizeof(MIB_TCPROW_OWNER_PID)); + ++count; + } + } + ASSERT(count == pTheirTcpTable->dwNumEntries); + + /* Don't sort on PID, so use basic helper */ + if (bOrder) + qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries, + sizeof(MIB_TCPROW_OWNER_PID), TcpTableSorter); + } + } + } + break; + + case TCP_TABLE_OWNER_PID_LISTENER: + { + PMIB_TCPTABLE_OWNER_PID pOurTcpTable = getOwnerTcpTable(); + PMIB_TCPTABLE_OWNER_PID pTheirTcpTable = pTcpTable; + + if (pOurTcpTable) + { + for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i) + { + if (pOurTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN) + { + ++count; + } + } + + if (sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID) > *pdwSize || !pTheirTcpTable) + { + *pdwSize = sizeof(DWORD) + count * sizeof(MIB_TCPROW_OWNER_PID); + ret = ERROR_INSUFFICIENT_BUFFER; + } + else + { + pTheirTcpTable->dwNumEntries = count; + + for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i) + { + if (pOurTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN) + { + memcpy(&pTheirTcpTable->table[count], &pOurTcpTable->table[i], sizeof(MIB_TCPROW_OWNER_PID)); + ++count; + } + } + ASSERT(count == pTheirTcpTable->dwNumEntries); + + /* Don't sort on PID, so use basic helper */ + if (bOrder) + qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries, + sizeof(MIB_TCPROW_OWNER_PID), TcpTableSorter); + } + } + } + break; + default: UNIMPLEMENTED; ret = ERROR_INVALID_PARAMETER; diff --git a/dll/win32/iphlpapi/ipstats.h b/dll/win32/iphlpapi/ipstats.h index 428bafc3a22..1fd51574c30 100644 --- a/dll/win32/iphlpapi/ipstats.h +++ b/dll/win32/iphlpapi/ipstats.h @@ -105,4 +105,9 @@ DWORD getNumTcpEntries(void); */ 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); + #endif /* ndef WINE_IPSTATS_H_ */ -- 2.17.1