https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c949a12506046b0aa9bc7…
commit c949a12506046b0aa9bc74e6a8fa1dabefcecba7
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Nov 24 20:32:55 2018 +0100
Commit: Pierre Schweitzer <pierre(a)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_ */