https://git.reactos.org/?p=reactos.git;a=commitdiff;h=702d44c683c1289a0e0230...
commit 702d44c683c1289a0e023022c8f63aaafb939c1b Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Sat Nov 24 19:04:04 2018 +0100 Commit: Pierre Schweitzer pierre@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; }