https://git.reactos.org/?p=reactos.git;a=commitdiff;h=702d44c683c1289a0e023…
commit 702d44c683c1289a0e023022c8f63aaafb939c1b
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Nov 24 19:04:04 2018 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sat Nov 24 21:41:08 2018 +0100
[IPHLPAPI] Implement the IPv4 TCP_TABLE_BASIC_* cases in GetExtendedTcpTable()
---
dll/win32/iphlpapi/iphlpapi_main.c | 116 ++++++++++++++++++++++++++++++++++---
1 file changed, 107 insertions(+), 9 deletions(-)
diff --git a/dll/win32/iphlpapi/iphlpapi_main.c b/dll/win32/iphlpapi/iphlpapi_main.c
index c06796f6d8..bff2ea7088 100644
--- a/dll/win32/iphlpapi/iphlpapi_main.c
+++ b/dll/win32/iphlpapi/iphlpapi_main.c
@@ -794,6 +794,8 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,
PMIB_IPFORWARDRO
return ret;
}
+static int TcpTableSorter(const void *a, const void *b);
+
/******************************************************************
* GetExtendedTcpTable (IPHLPAPI.@)
*
@@ -816,20 +818,116 @@ DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,
PMIB_IPFORWARDRO
DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG
ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved)
{
+ DWORD i, count;
DWORD ret = NO_ERROR;
- if (TableClass == TCP_TABLE_OWNER_PID_ALL) {
- if (*pdwSize == 0) {
- *pdwSize = sizeof(MIB_TCPTABLE_OWNER_PID);
- return ERROR_INSUFFICIENT_BUFFER;
- } else {
- ZeroMemory(pTcpTable, sizeof(MIB_TCPTABLE_OWNER_PID));
- return NO_ERROR;
+ if (!pdwSize)
+ {
+ return ERROR_INVALID_PARAMETER;
}
- }
+ if (ulAf != AF_INET)
+ {
+ UNIMPLEMENTED;
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ switch (TableClass)
+ {
+ case TCP_TABLE_BASIC_ALL:
+ ret = GetTcpTable(pTcpTable, pdwSize, bOrder);
+ break;
+
+ case TCP_TABLE_BASIC_CONNECTIONS:
+ {
+ PMIB_TCPTABLE pOurTcpTable = getTcpTable();
+ PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
+
+ if (pOurTcpTable)
+ {
+ for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+ {
+ if (pOurTcpTable->table[i].State != MIB_TCP_STATE_LISTEN)
+ {
+ ++count;
+ }
+ }
+
+ if (sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW) > *pdwSize ||
!pTheirTcpTable)
+ {
+ *pdwSize = sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW);
+ ret = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else
+ {
+ pTheirTcpTable->dwNumEntries = count;
+
+ for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+ {
+ if (pOurTcpTable->table[i].State != MIB_TCP_STATE_LISTEN)
+ {
+ memcpy(&pTheirTcpTable->table[count],
&pOurTcpTable->table[i], sizeof(MIB_TCPROW));
+ ++count;
+ }
+ }
+ ASSERT(count == pTheirTcpTable->dwNumEntries);
+
+ if (bOrder)
+ qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+ sizeof(MIB_TCPROW), TcpTableSorter);
+ }
+ }
+ }
+ break;
+
+ case TCP_TABLE_BASIC_LISTENER:
+ {
+ PMIB_TCPTABLE pOurTcpTable = getTcpTable();
+ PMIB_TCPTABLE pTheirTcpTable = pTcpTable;
+
+ if (pOurTcpTable)
+ {
+ for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+ {
+ if (pOurTcpTable->table[i].State == MIB_TCP_STATE_LISTEN)
+ {
+ ++count;
+ }
+ }
+
+ if (sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW) > *pdwSize ||
!pTheirTcpTable)
+ {
+ *pdwSize = sizeof(MIB_TCPTABLE) + count * sizeof(MIB_TCPROW);
+ ret = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else
+ {
+ pTheirTcpTable->dwNumEntries = count;
+
+ for (i = 0, count = 0; i < pOurTcpTable->dwNumEntries; ++i)
+ {
+ if (pOurTcpTable->table[i].State == MIB_TCP_STATE_LISTEN)
+ {
+ memcpy(&pTheirTcpTable->table[count],
&pOurTcpTable->table[i], sizeof(MIB_TCPROW));
+ ++count;
+ }
+ }
+ ASSERT(count == pTheirTcpTable->dwNumEntries);
+
+ if (bOrder)
+ qsort(pTheirTcpTable->table, pTheirTcpTable->dwNumEntries,
+ sizeof(MIB_TCPROW), TcpTableSorter);
+ }
+ }
+ }
+ break;
+
+ default:
+ UNIMPLEMENTED;
+ ret = ERROR_INVALID_PARAMETER;
+ break;
+ }
- UNIMPLEMENTED;
return ret;
}