[PATCH 2/5] iphlpapi: Implement GetExtendedUdpTable() on top of nsi.

Huw Davies huw at codeweavers.com
Wed Aug 18 02:54:45 CDT 2021


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/iphlpapi/iphlpapi_main.c | 225 +++++++++++++++++-----
 dlls/iphlpapi/ipstats.c       | 350 ----------------------------------
 dlls/iphlpapi/ipstats.h       |  33 ----
 3 files changed, 175 insertions(+), 433 deletions(-)
 delete mode 100644 dlls/iphlpapi/ipstats.h

diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index e78689d8f11..bcda2b81b6e 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -43,7 +43,6 @@
 #include "windns.h"
 #include "iphlpapi.h"
 #include "ifenum.h"
-#include "ipstats.h"
 #include "ipifcons.h"
 #include "fltdefs.h"
 #include "ifdef.h"
@@ -3289,81 +3288,207 @@ DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE
  * Get a table of active UDP connections.
  *
  * PARAMS
- *  pUdpTable [Out]    buffer for UDP connections table
- *  pdwSize   [In/Out] length of output buffer
- *  bOrder    [In]     whether to order the table
- *
- * RETURNS
- *  Success: NO_ERROR
- *  Failure: error code from winerror.h
+ *  table  [Out]    buffer for UDP connections table
+ *  size   [In/Out] length of output buffer
+ *  sort   [In]     whether to order the table
  *
- * NOTES
- *  If pdwSize is less than required, the function will return 
- *  ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to the
- *  required byte size.
- *  If bOrder is true, the returned table will be sorted, first by
- *  local address, then by local port number.
  */
-DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
+DWORD WINAPI GetUdpTable( MIB_UDPTABLE *table, DWORD *size, BOOL sort )
 {
-    return GetExtendedUdpTable(pUdpTable, pdwSize, bOrder, WS_AF_INET, UDP_TABLE_BASIC, 0);
+    return GetExtendedUdpTable( table, size, sort, WS_AF_INET, UDP_TABLE_BASIC, 0 );
 }
 
 /******************************************************************
  *    GetUdp6Table (IPHLPAPI.@)
  */
-DWORD WINAPI GetUdp6Table(PMIB_UDP6TABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
+DWORD WINAPI GetUdp6Table( MIB_UDP6TABLE *table, DWORD *size, BOOL sort )
 {
-    return GetExtendedUdpTable(pUdpTable, pdwSize, bOrder, WS_AF_INET6, UDP_TABLE_BASIC, 0);
+    return GetExtendedUdpTable( table, size, sort, WS_AF_INET6, UDP_TABLE_BASIC, 0 );
 }
 
-/******************************************************************
- *    GetExtendedUdpTable (IPHLPAPI.@)
- */
-DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder,
-                                 ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved)
+static DWORD udp_table_size( ULONG family, ULONG table_class, DWORD row_count, DWORD *row_size )
 {
-    DWORD ret, size;
-    void *table;
+    switch (table_class)
+    {
+    case UDP_TABLE_BASIC:
+        *row_size = (family == WS_AF_INET) ? sizeof(MIB_UDPROW) : sizeof(MIB_UDP6ROW);
+        return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE, table[row_count]) :
+            FIELD_OFFSET(MIB_UDP6TABLE, table[row_count]);
 
-    TRACE("pUdpTable %p, pdwSize %p, bOrder %d, ulAf %u, TableClass %u, Reserved %u\n",
-           pUdpTable, pdwSize, bOrder, ulAf, TableClass, Reserved);
+    case UDP_TABLE_OWNER_PID:
+        *row_size = (family == WS_AF_INET) ? sizeof(MIB_UDPROW_OWNER_PID) : sizeof(MIB_UDP6ROW_OWNER_PID);
+        return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table[row_count]) :
+            FIELD_OFFSET(MIB_UDP6TABLE_OWNER_PID, table[row_count]);
 
-    if (!pdwSize) return ERROR_INVALID_PARAMETER;
+    case UDP_TABLE_OWNER_MODULE:
+        *row_size = (family == WS_AF_INET) ? sizeof(MIB_UDPROW_OWNER_MODULE) : sizeof(MIB_UDP6ROW_OWNER_MODULE);
+        return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table[row_count]) :
+            FIELD_OFFSET(MIB_UDP6TABLE_OWNER_MODULE, table[row_count]);
 
-    if (TableClass == UDP_TABLE_OWNER_MODULE)
-        FIXME("UDP_TABLE_OWNER_MODULE not fully supported\n");
+    default:
+        ERR( "unhandled class %u\n", table_class );
+        return 0;
+    }
+}
 
-    switch (ulAf)
+static void udp_row_fill( void *table, DWORD num, ULONG family, ULONG table_class,
+                          struct nsi_udp_endpoint_key *key,
+                          struct nsi_udp_endpoint_static *stat )
+{
+    if (family == WS_AF_INET)
     {
-        case WS_AF_INET:
-            ret = build_udp_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size);
-            break;
-
-        case WS_AF_INET6:
-            ret = build_udp6_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size);
-            break;
-
+        switch (table_class)
+        {
+        case UDP_TABLE_BASIC:
+        {
+            MIB_UDPROW *row = ((MIB_UDPTABLE *)table)->table + num;
+            row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+            row->dwLocalPort = key->local.Ipv4.sin_port;
+            return;
+        }
+        case UDP_TABLE_OWNER_PID:
+        {
+            MIB_UDPROW_OWNER_PID *row = ((MIB_UDPTABLE_OWNER_PID *)table)->table + num;
+            row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+            row->dwLocalPort = key->local.Ipv4.sin_port;
+            row->dwOwningPid = stat->pid;
+            return;
+        }
+        case UDP_TABLE_OWNER_MODULE:
+        {
+            MIB_UDPROW_OWNER_MODULE *row = ((MIB_UDPTABLE_OWNER_MODULE *)table)->table + num;
+            row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+            row->dwLocalPort = key->local.Ipv4.sin_port;
+            row->dwOwningPid = stat->pid;
+            row->liCreateTimestamp.QuadPart = stat->create_time;
+            row->dwFlags = stat->flags;
+            row->OwningModuleInfo[0] = stat->mod_info;
+            memset( row->OwningModuleInfo + 1, 0, sizeof(row->OwningModuleInfo) - sizeof(row->OwningModuleInfo[0]) );
+            return;
+        }
         default:
-            FIXME("ulAf = %u not supported\n", ulAf);
-            ret = ERROR_NOT_SUPPORTED;
+            ERR( "Unknown class %d\n", table_class );
+            return;
+        }
     }
+    else
+    {
+        switch (table_class)
+        {
+        case UDP_TABLE_BASIC:
+        {
+            MIB_UDP6ROW *row = ((MIB_UDP6TABLE *)table)->table + num;
+            memcpy( &row->dwLocalAddr, &key->local.Ipv6.sin6_addr, sizeof(row->dwLocalAddr) );
+            row->dwLocalScopeId = key->local.Ipv6.sin6_scope_id;
+            row->dwLocalPort = key->local.Ipv6.sin6_port;
+            return;
+        }
+        case UDP_TABLE_OWNER_PID:
+        {
+            MIB_UDP6ROW_OWNER_PID *row = ((MIB_UDP6TABLE_OWNER_PID *)table)->table + num;
+            memcpy( &row->ucLocalAddr, &key->local.Ipv6.sin6_addr, sizeof(row->ucLocalAddr) );
+            row->dwLocalScopeId = key->local.Ipv6.sin6_scope_id;
+            row->dwLocalPort = key->local.Ipv6.sin6_port;
+            row->dwOwningPid = stat->pid;
+            return;
+        }
+        case UDP_TABLE_OWNER_MODULE:
+        {
+            MIB_UDP6ROW_OWNER_MODULE *row = ((MIB_UDP6TABLE_OWNER_MODULE *)table)->table + num;
+            memcpy( &row->ucLocalAddr, &key->local.Ipv6.sin6_addr, sizeof(row->ucLocalAddr) );
+            row->dwLocalScopeId = key->local.Ipv6.sin6_scope_id;
+            row->dwLocalPort = key->local.Ipv6.sin6_port;
+            row->dwOwningPid = stat->pid;
+            row->liCreateTimestamp.QuadPart = stat->create_time;
+            row->dwFlags = stat->flags;
+            row->OwningModuleInfo[0] = stat->mod_info;
+            memset( row->OwningModuleInfo + 1, 0, sizeof(row->OwningModuleInfo) - sizeof(row->OwningModuleInfo[0]) );
+            return;
+        }
+        default:
+            ERR( "Unknown class %d\n", table_class );
+            return;
+        }
+    }
+    ERR( "Unknown family %d\n", family );
+    return;
+}
 
-    if (ret)
-        return ret;
+static int udp_row_cmp( const void *a, const void *b )
+{
+    const MIB_UDPROW *rowA = a;
+    const MIB_UDPROW *rowB = b;
+    int ret;
+
+    if ((ret = RtlUlongByteSwap( rowA->dwLocalAddr ) - RtlUlongByteSwap( rowB->dwLocalAddr )) != 0) return ret;
+    return RtlUshortByteSwap( rowA->dwLocalPort ) - RtlUshortByteSwap( rowB->dwLocalPort );
+}
+
+static int udp6_row_cmp( const void *a, const void *b )
+{
+    const MIB_UDP6ROW *rowA = a;
+    const MIB_UDP6ROW *rowB = b;
+    int ret;
+
+    if ((ret = memcmp( &rowA->dwLocalAddr, &rowB->dwLocalAddr, sizeof(rowA->dwLocalAddr) )) != 0) return ret;
+    if ((ret = rowA->dwLocalScopeId - rowB->dwLocalScopeId) != 0) return ret;
+    return RtlUshortByteSwap( rowA->dwLocalPort ) - RtlUshortByteSwap( rowB->dwLocalPort );
+}
+
+/******************************************************************
+ *    GetExtendedUdpTable (IPHLPAPI.@)
+ */
+DWORD WINAPI GetExtendedUdpTable( void *table, DWORD *size, BOOL sort, ULONG family,
+                                  UDP_TABLE_CLASS table_class, ULONG reserved )
+{
+    DWORD err, count, needed, i, num = 0, row_size = 0;
+    struct nsi_udp_endpoint_key *key;
+    struct nsi_udp_endpoint_static *stat;
+
+    TRACE( "table %p, size %p, sort %d, family %u, table_class %u, reserved %u\n",
+           table, size, sort, family, table_class, reserved );
+
+    if (!size || !ip_module_id( family )) return ERROR_INVALID_PARAMETER;
+
+    err = NsiAllocateAndGetTable( 1, &NPI_MS_UDP_MODULEID, NSI_UDP_ENDPOINT_TABLE, (void **)&key, sizeof(*key),
+                                  NULL, 0, NULL, 0, (void **)&stat, sizeof(*stat), &count, 0 );
+    if (err) return err;
+
+    for (i = 0; i < count; i++)
+        if (key[i].local.si_family == family)
+            num++;
 
-    if (!pUdpTable || *pdwSize < size)
+    needed = udp_table_size( family, table_class, num, &row_size );
+    if (!table || *size < needed)
     {
-        *pdwSize = size;
-        ret = ERROR_INSUFFICIENT_BUFFER;
+        *size = needed;
+        err = ERROR_INSUFFICIENT_BUFFER;
     }
     else
     {
-        *pdwSize = size;
-        memcpy(pUdpTable, table, size);
+        *size = needed;
+        *(DWORD *)table = num;
+        num = 0;
+        for (i = 0; i < count; i++)
+        {
+            if (key[i].local.si_family != family) continue;
+            udp_row_fill( table, num++, family, table_class, key + i, stat + i );
+        }
+    }
+
+    if (!err && sort)
+    {
+        int (*fn)(const void *, const void *);
+        DWORD offset = udp_table_size( family, table_class, 0, &row_size );
+
+        if (family == WS_AF_INET) fn = udp_row_cmp;
+        else fn = udp6_row_cmp;
+
+        qsort( (BYTE *)table + offset, num, row_size, fn );
     }
-    HeapFree(GetProcessHeap(), 0, table);
-    return ret;
+
+    NsiFreeTable( key, NULL, NULL, stat );
+    return err;
 }
 
 static void unicast_row_fill( MIB_UNICASTIPADDRESS_ROW *row, USHORT fam, void *key, struct nsi_ip_unicast_rw *rw,
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 326db56f5bc..65bf65fec7b 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -158,7 +158,6 @@
 #include "winsock2.h"
 #include "ws2ipdef.h"
 #include "ifenum.h"
-#include "ipstats.h"
 #include "iphlpapi.h"
 
 #include "wine/debug.h"
@@ -868,355 +867,6 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE
     return ret;
 }
 
-static DWORD get_udp6_table_sizes( UDP_TABLE_CLASS class, DWORD row_count, DWORD *row_size )
-{
-    DWORD table_size;
-
-    switch (class)
-    {
-    case UDP_TABLE_BASIC:
-    {
-        table_size = FIELD_OFFSET(MIB_UDP6TABLE, table[row_count]);
-        if (row_size) *row_size = sizeof(MIB_UDP6ROW);
-        break;
-    }
-    case UDP_TABLE_OWNER_PID:
-    {
-        table_size = FIELD_OFFSET(MIB_UDP6TABLE_OWNER_PID, table[row_count]);
-        if (row_size) *row_size = sizeof(MIB_UDP6ROW_OWNER_PID);
-        break;
-    }
-    case UDP_TABLE_OWNER_MODULE:
-    {
-        table_size = FIELD_OFFSET(MIB_UDP6TABLE_OWNER_MODULE, table[row_count]);
-        if (row_size) *row_size = sizeof(MIB_UDP6ROW_OWNER_MODULE);
-        break;
-    }
-    default:
-        ERR("unhandled class %u\n", class);
-        return 0;
-    }
-    return table_size;
-}
-
-static int compare_udp6_rows(const void *a, const void *b)
-{
-    const MIB_UDP6ROW *rowA = a;
-    const MIB_UDP6ROW *rowB = b;
-    int ret;
-
-    if ((ret = memcmp(&rowA->dwLocalAddr, &rowB->dwLocalAddr, sizeof(rowA->dwLocalAddr))) != 0) return ret;
-    if ((ret = rowA->dwLocalScopeId - rowB->dwLocalScopeId) != 0) return ret;
-    return rowA->dwLocalPort - rowB->dwLocalPort;
-}
-
-#if defined(__linux__) || (defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN))
-struct ipv6_addr_scope
-{
-    IN6_ADDR addr;
-    DWORD scope;
-};
-
-static struct ipv6_addr_scope *get_ipv6_addr_scope_table(unsigned int *size)
-{
-    struct ipv6_addr_scope *table = NULL;
-    unsigned int table_size = 0;
-#ifdef __linux__
-    char buf[512], *ptr;
-    FILE *fp;
-#elif defined(HAVE_GETIFADDRS)
-    struct ifaddrs *addrs, *cur;
-#endif
-
-    if (!(table = HeapAlloc( GetProcessHeap(), 0, sizeof(table[0]) )))
-        return NULL;
-
-#ifdef __linux__
-    if (!(fp = fopen( "/proc/net/if_inet6", "r" )))
-        goto failed;
-
-    while ((ptr = fgets( buf, sizeof(buf), fp )))
-    {
-        WORD a[8];
-        DWORD scope;
-        struct ipv6_addr_scope *new_table;
-        struct ipv6_addr_scope *entry;
-        unsigned int i;
-
-        if (sscanf( ptr, "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx %*s %*s %x",
-            &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &scope ) != 9)
-            continue;
-
-        table_size++;
-        if (!(new_table = HeapReAlloc( GetProcessHeap(), 0, table, table_size * sizeof(table[0]) )))
-        {
-            fclose(fp);
-            goto failed;
-        }
-
-        table = new_table;
-        entry = &table[table_size - 1];
-
-        i = 0;
-        while (i < 8)
-        {
-            entry->addr.u.Word[i] = htons(a[i]);
-            i++;
-        }
-
-        entry->scope = htons(scope);
-    }
-
-    fclose(fp);
-#elif defined(HAVE_GETIFADDRS)
-    if (getifaddrs(&addrs) == -1)
-        goto failed;
-
-    for (cur = addrs; cur; cur = cur->ifa_next)
-    {
-        struct sockaddr_in6 *sin6;
-        struct ipv6_addr_scope *new_table;
-        struct ipv6_addr_scope *entry;
-
-        if (cur->ifa_addr->sa_family != AF_INET6)
-            continue;
-
-        sin6 = (struct sockaddr_in6 *)cur->ifa_addr;
-
-        table_size++;
-        if (!(new_table = HeapReAlloc( GetProcessHeap(), 0, table, table_size * sizeof(table[0]) )))
-        {
-            freeifaddrs(addrs);
-            goto failed;
-        }
-
-        table = new_table;
-        entry = &table[table_size - 1];
-
-        memcpy(&entry->addr, &sin6->sin6_addr, sizeof(entry->addr));
-        entry->scope = sin6->sin6_scope_id;
-    }
-
-    freeifaddrs(addrs);
-#else
-    FIXME( "not implemented\n" );
-    goto failed;
-#endif
-
-    *size = table_size;
-    return table;
-
-failed:
-    HeapFree( GetProcessHeap(), 0, table );
-    return NULL;
-}
-
-static DWORD find_ipv6_addr_scope(const IN6_ADDR *addr, const struct ipv6_addr_scope *table, unsigned int size)
-{
-    const BYTE multicast_scope_mask = 0x0F;
-    const BYTE multicast_scope_shift = 0;
-    unsigned int i = 0;
-
-    if (WS_IN6_IS_ADDR_UNSPECIFIED(addr))
-        return 0;
-
-    if (WS_IN6_IS_ADDR_MULTICAST(addr))
-        return htons((addr->u.Byte[1] & multicast_scope_mask) >> multicast_scope_shift);
-
-    if (!table)
-        return -1;
-
-    while (i < size)
-    {
-        if (memcmp(&table[i].addr, addr, sizeof(table[i].addr)) == 0)
-            return table[i].scope;
-        i++;
-    }
-
-    return -1;
-}
-#endif
-
-DWORD build_udp6_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags,
-                        DWORD *size )
-{
-    MIB_UDP6TABLE *table;
-    MIB_UDP6ROW_OWNER_MODULE row;
-    DWORD ret = NO_ERROR, count = 16, table_size, row_size;
-
-    if (!(table_size = get_udp6_table_sizes( class, count, &row_size )))
-        return ERROR_INVALID_PARAMETER;
-
-    if (!(table = HeapAlloc( heap, flags, table_size )))
-         return ERROR_OUTOFMEMORY;
-
-    table->dwNumEntries = 0;
-    memset( &row, 0, sizeof(row) );
-
-#ifdef __linux__
-    {
-        FILE *fp;
-
-        if ((fp = fopen( "/proc/net/udp6", "r" )))
-        {
-            char buf[512], *ptr;
-            struct pid_map *map = NULL;
-            unsigned int num_entries = 0;
-            struct ipv6_addr_scope *addr_scopes;
-            unsigned int addr_scopes_size = 0;
-            int inode;
-
-            addr_scopes = get_ipv6_addr_scope_table(&addr_scopes_size);
-
-            if (class >= UDP_TABLE_OWNER_PID) map = get_pid_map( &num_entries );
-
-            /* skip header line */
-            ptr = fgets( buf, sizeof(buf), fp );
-            while ((ptr = fgets( buf, sizeof(buf), fp )))
-            {
-                DWORD *local_addr = (DWORD *)&row.ucLocalAddr;
-
-                if (sscanf( ptr, "%*u: %8x%8x%8x%8x:%x %*s %*s %*s %*s %*s %*s %*s %d",
-                    &local_addr[0], &local_addr[1], &local_addr[2], &local_addr[3],
-                    &row.dwLocalPort, &inode ) != 6)
-                    continue;
-                row.dwLocalScopeId = find_ipv6_addr_scope((const IN6_ADDR *)&row.ucLocalAddr, addr_scopes, addr_scopes_size);
-                row.dwLocalPort = htons( row.dwLocalPort );
-
-                if (class >= UDP_TABLE_OWNER_PID)
-                    row.dwOwningPid = find_owning_pid( map, num_entries, inode );
-                if (class >= UDP_TABLE_OWNER_MODULE)
-                {
-                    row.liCreateTimestamp.QuadPart = 0; /* FIXME */
-                    row.dwFlags = 0;
-                    memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) );
-                }
-                if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size )))
-                    break;
-            }
-            HeapFree( GetProcessHeap(), 0, map );
-            HeapFree( GetProcessHeap(), 0, addr_scopes );
-            fclose( fp );
-        }
-        else ret = ERROR_NOT_SUPPORTED;
-    }
-#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN)
-    {
-        static const char zero[sizeof(IN6_ADDR)] = {0};
-
-        size_t len = 0;
-        char *buf = NULL;
-        struct xinpgen *xig, *orig_xig;
-        struct pid_map *map = NULL;
-        unsigned num_entries;
-        struct ipv6_addr_scope *addr_scopes = NULL;
-        unsigned int addr_scopes_size = 0;
-
-        if (sysctlbyname( "net.inet.udp.pcblist", NULL, &len, NULL, 0 ) < 0)
-        {
-            ERR( "Failure to read net.inet.udp.pcblist via sysctlbyname!\n" );
-            ret = ERROR_NOT_SUPPORTED;
-            goto done;
-        }
-
-        buf = HeapAlloc( GetProcessHeap(), 0, len );
-        if (!buf)
-        {
-            ret = ERROR_OUTOFMEMORY;
-            goto done;
-        }
-
-        if (sysctlbyname( "net.inet.udp.pcblist", buf, &len, NULL, 0 ) < 0)
-        {
-            ERR ("Failure to read net.inet.udp.pcblist via sysctlbyname!\n");
-            ret = ERROR_NOT_SUPPORTED;
-            goto done;
-        }
-
-        addr_scopes = get_ipv6_addr_scope_table( &addr_scopes_size );
-        if (!addr_scopes)
-        {
-            ret = ERROR_OUTOFMEMORY;
-            goto done;
-        }
-
-        if (class >= UDP_TABLE_OWNER_PID) map = get_pid_map( &num_entries );
-
-        /* Might be nothing here; first entry is just a header it seems */
-        if (len <= sizeof (struct xinpgen)) goto done;
-
-        orig_xig = (struct xinpgen *)buf;
-        xig = orig_xig;
-
-        for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
-             xig->xig_len > sizeof (struct xinpgen);
-             xig = (struct xinpgen *)((char *)xig + xig->xig_len))
-        {
-#if __FreeBSD_version >= 1200026
-            struct xinpcb *in = (struct xinpcb *)xig;
-            struct xsocket *sock = &in->xi_socket;
-#else
-            struct inpcb *in = &((struct xinpcb *)xig)->xi_inp;
-            struct xsocket *sock = &((struct xinpcb *)xig)->xi_socket;
-#endif
-
-            /* Ignore sockets for other protocols */
-            if (sock->xso_protocol != IPPROTO_UDP)
-                continue;
-
-            /* Ignore PCBs that were freed while generating the data */
-            if (in->inp_gencnt > orig_xig->xig_gen)
-                continue;
-
-            /* we're only interested in IPv6 addresses */
-            if (!(in->inp_vflag & INP_IPV6) ||
-                (in->inp_vflag & INP_IPV4))
-                continue;
-
-            /* If all 0's, skip it */
-            if (!memcmp( &in->in6p_laddr.s6_addr, zero, sizeof(zero) ) && !in->inp_lport)
-                continue;
-
-            /* Fill in structure details */
-            memcpy(row.ucLocalAddr, &in->in6p_laddr.s6_addr, sizeof(row.ucLocalAddr));
-            row.dwLocalPort = in->inp_lport;
-            row.dwLocalScopeId = find_ipv6_addr_scope((const IN6_ADDR *)&row.ucLocalAddr, addr_scopes, addr_scopes_size);
-            if (class >= UDP_TABLE_OWNER_PID)
-                row.dwOwningPid = find_owning_pid( map, num_entries, (UINT_PTR)sock->so_pcb );
-            if (class >= UDP_TABLE_OWNER_MODULE)
-            {
-                row.liCreateTimestamp.QuadPart = 0; /* FIXME */
-                row.dwFlags = 0;
-                row.SpecificPortBind = !(in->inp_flags & INP_ANONPORT);
-                memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) );
-            }
-            if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size )))
-                break;
-        }
-
-    done:
-        HeapFree( GetProcessHeap(), 0, map );
-        HeapFree( GetProcessHeap(), 0, buf );
-        HeapFree( GetProcessHeap(), 0, addr_scopes );
-    }
-#else
-    FIXME( "not implemented\n" );
-    ret = ERROR_NOT_SUPPORTED;
-#endif
-
-    if (!table) return ERROR_OUTOFMEMORY;
-    if (!ret)
-    {
-        if (order && table->dwNumEntries)
-            qsort( table->table, table->dwNumEntries, row_size, compare_udp6_rows );
-        *tablep = table;
-    }
-    else HeapFree( heap, flags, table );
-    if (size) *size = get_udp6_table_sizes( class, count, NULL );
-    TRACE( "returning ret %u table %p\n", ret, table );
-    return ret;
-}
-
 /******************************************************************
  *    AllocateAndGetUdpTableFromStack (IPHLPAPI.@)
  *
diff --git a/dlls/iphlpapi/ipstats.h b/dlls/iphlpapi/ipstats.h
deleted file mode 100644
index 60398609207..00000000000
--- a/dlls/iphlpapi/ipstats.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ipstats.h
- * Copyright (C) 2003,2006 Juan Lang
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * This module implements functions that get network-related statistics.
- * It's meant to hide some platform-specificisms.
- */
-#ifndef WINE_IPSTATS_H_
-#define WINE_IPSTATS_H_
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "iprtrmib.h"
-
-DWORD build_udp_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN;
-DWORD build_udp6_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN;
-
-#endif /* ndef WINE_IPSTATS_H_ */
-- 
2.23.0




More information about the wine-devel mailing list