https://git.reactos.org/?p=reactos.git;a=commitdiff;h=58cef01422060fc69d790d49c60df69b737e69c9

commit 58cef01422060fc69d790d49c60df69b737e69c9
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Sat Nov 24 21:22:42 2018 +0100
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Sat Nov 24 21:41:10 2018 +0100

    [IPHLPAPI] Implement GetExtendedUdpTable()
    We only support IPv4 and UDP_TABLE_BASIC, UDP_TABLE_OWNER_PID
    for now
    
    CORE-5126
---
 dll/win32/iphlpapi/iphlpapi.spec   |   2 +-
 dll/win32/iphlpapi/iphlpapi_main.c | 103 ++++++++++++++++++++++++++++++++++++-
 dll/win32/iphlpapi/ipstats.h       |   5 ++
 3 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/dll/win32/iphlpapi/iphlpapi.spec b/dll/win32/iphlpapi/iphlpapi.spec
index 76b5fb30d3..ee112c6c91 100644
--- a/dll/win32/iphlpapi/iphlpapi.spec
+++ b/dll/win32/iphlpapi/iphlpapi.spec
@@ -33,7 +33,7 @@
 @ stdcall GetBestRoute( long long long )
 @ stub GetBestRouteFromStack
 @ stdcall GetExtendedTcpTable( ptr ptr long long long long )
-@ stdcall -stub GetExtendedUdpTable( ptr ptr long long long long )
+@ stdcall GetExtendedUdpTable( ptr ptr long long long long )
 @ stdcall GetFriendlyIfIndex( long )
 @ stdcall GetIcmpStatistics( ptr )
 @ stdcall GetIcmpStatisticsEx(ptr long)
diff --git a/dll/win32/iphlpapi/iphlpapi_main.c 
b/dll/win32/iphlpapi/iphlpapi_main.c
index a0e83aee4d..d1333cbf47 100644
--- a/dll/win32/iphlpapi/iphlpapi_main.c
+++ b/dll/win32/iphlpapi/iphlpapi_main.c
@@ -1091,7 +1091,108 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, 
PDWORD pdwSize, BOOL bOrder, U
             break;
     }
 
-    return ret;        
+    return ret;
+}
+
+
+static int UdpTableSorter(const void *a, const void *b);
+
+/******************************************************************
+ *    GetExtendedUdpTable (IPHLPAPI.@)
+ *
+ * Get the table of UDP endpoints available to the application.
+ *
+ * PARAMS
+ *  pUdpTable [Out]    table struct with the filtered UDP endpoints available 
to application
+ *  pdwSize   [In/Out] estimated size of the structure returned in pUdpTable, 
in bytes
+ *  bOrder    [In]     whether to order the table
+ *  ulAf       [in]    version of IP used by the UDP endpoints
+ *  TableClass [in]    type of the UDP table structure from UDP_TABLE_CLASS
+ *  Reserved [in]      reserved - this value must be zero
+ *
+ * RETURNS
+ *  Success: NO_ERROR
+ *  Failure: either ERROR_INSUFFICIENT_BUFFER or ERROR_INVALID_PARAMETER
+ *
+ * NOTES
+ */
+
+DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, 
ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved)
+{
+       DWORD ret = NO_ERROR;
+
+    if (!pdwSize)
+    {
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    if (ulAf != AF_INET)
+    {
+        UNIMPLEMENTED;
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    switch (TableClass)
+    {
+        case UDP_TABLE_BASIC:
+        {
+            PMIB_UDPTABLE pOurUdpTable = getUdpTable();
+            PMIB_UDPTABLE pTheirUdpTable = pUdpTable;
+
+            if (pOurUdpTable)
+            {
+                if (sizeof(DWORD) + pOurUdpTable->dwNumEntries * 
sizeof(MIB_UDPROW) > *pdwSize || !pTheirUdpTable)
+                {
+                    *pdwSize = sizeof(DWORD) + pOurUdpTable->dwNumEntries * 
sizeof(MIB_UDPROW);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    memcpy(pTheirUdpTable, pOurUdpTable, sizeof(DWORD) + 
pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW_OWNER_PID));
+
+                    if (bOrder)
+                        qsort(pTheirUdpTable->table, 
pTheirUdpTable->dwNumEntries,
+                              sizeof(MIB_UDPROW), UdpTableSorter);
+                }
+
+                free(pOurUdpTable);
+            }
+        }
+        break;
+
+        case UDP_TABLE_OWNER_PID:
+        {
+            PMIB_UDPTABLE_OWNER_PID pOurUdpTable = getOwnerUdpTable();
+            PMIB_UDPTABLE_OWNER_PID pTheirUdpTable = pUdpTable;
+
+            if (pOurUdpTable)
+            {
+                if (sizeof(DWORD) + pOurUdpTable->dwNumEntries * 
sizeof(MIB_UDPROW_OWNER_PID) > *pdwSize || !pTheirUdpTable)
+                {
+                    *pdwSize = sizeof(DWORD) + pOurUdpTable->dwNumEntries * 
sizeof(MIB_UDPROW_OWNER_PID);
+                    ret = ERROR_INSUFFICIENT_BUFFER;
+                }
+                else
+                {
+                    memcpy(pTheirUdpTable, pOurUdpTable, sizeof(DWORD) + 
pOurUdpTable->dwNumEntries * sizeof(MIB_UDPROW_OWNER_PID));
+
+                    if (bOrder)
+                        qsort(pTheirUdpTable->table, 
pTheirUdpTable->dwNumEntries,
+                              sizeof(MIB_UDPROW_OWNER_PID), UdpTableSorter);
+                }
+
+                free(pOurUdpTable);
+            }
+        }
+        break;
+
+        default:
+            UNIMPLEMENTED;
+            ret = ERROR_INVALID_PARAMETER;
+            break;
+    }
+
+    return ret;
 }
 
 
diff --git a/dll/win32/iphlpapi/ipstats.h b/dll/win32/iphlpapi/ipstats.h
index 1fd51574c3..da49d2b1d3 100644
--- a/dll/win32/iphlpapi/ipstats.h
+++ b/dll/win32/iphlpapi/ipstats.h
@@ -97,6 +97,11 @@ DWORD getNumUdpEntries(void);
  */
 PMIB_UDPTABLE getUdpTable(void);
 
+/* Allocates and returns to you the UDP state table with owner PID,
+ * or NULL if it can't allocate enough memory.  free() the returned table.
+ */
+PMIB_UDPTABLE_OWNER_PID getOwnerUdpTable(void);
+
 /* Returns the number of entries in the TCP state table. */
 DWORD getNumTcpEntries(void);
 

Reply via email to