https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c949a12506046b0aa9bc74...
commit c949a12506046b0aa9bc74e6a8fa1dabefcecba7 Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Sat Nov 24 20:32:55 2018 +0100 Commit: Pierre Schweitzer pierre@reactos.org CommitDate: Sat Nov 24 21:41:09 2018 +0100
[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 bff2ea7088..2792be25a0 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 428bafc3a2..1fd51574c3 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_ */