Huw Davies : iphlpapi: Implement AllocateAndGetIpNetTableFromStack() on top of GetIpNetTable().

Alexandre Julliard julliard at winehq.org
Tue Aug 10 16:24:07 CDT 2021


Module: wine
Branch: master
Commit: b63195d595db662e6d716395bc4fd5c12710790f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b63195d595db662e6d716395bc4fd5c12710790f

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Aug 10 09:20:50 2021 +0100

iphlpapi: Implement AllocateAndGetIpNetTableFromStack() on top of GetIpNetTable().

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/iphlpapi/iphlpapi_main.c |  23 +++++
 dlls/iphlpapi/ipstats.c       | 193 ------------------------------------------
 2 files changed, 23 insertions(+), 193 deletions(-)

diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 24cfedd2b02..fe2daa0f24d 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -2317,6 +2317,29 @@ err:
     return err;
 }
 
+/******************************************************************
+ *    AllocateAndGetIpNetTableFromStack (IPHLPAPI.@)
+ */
+DWORD WINAPI AllocateAndGetIpNetTableFromStack( MIB_IPNETTABLE **table, BOOL sort, HANDLE heap, DWORD flags )
+{
+    DWORD err, size = FIELD_OFFSET(MIB_IPNETTABLE, table[2]), attempt;
+
+    TRACE( "table %p, sort %d, heap %p, flags 0x%08x\n", table, sort, heap, flags );
+
+    for (attempt = 0; attempt < 5; attempt++)
+    {
+        *table = HeapAlloc( heap, flags, size );
+        if (!*table) return ERROR_NOT_ENOUGH_MEMORY;
+
+        err = GetIpNetTable( *table, &size, sort );
+        if (!err) break;
+        HeapFree( heap, flags, *table );
+        if (err != ERROR_INSUFFICIENT_BUFFER) break;
+    }
+
+    return err;
+}
+
 static void ipnet_row2_fill( MIB_IPNET_ROW2 *row, USHORT fam, void *key, struct nsi_ip_neighbour_rw *rw,
                              struct nsi_ip_neighbour_dynamic *dyn )
 {
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 7bb4ff0603e..115bafa6f8e 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -1220,199 +1220,6 @@ static void *append_table_row( HANDLE heap, DWORD flags, void *table, DWORD *tab
     return table;
 }
 
-static int compare_ipnet_rows(const void *a, const void *b)
-{
-    const MIB_IPNETROW *rowA = a;
-    const MIB_IPNETROW *rowB = b;
-
-    return ntohl(rowA->dwAddr) - ntohl(rowB->dwAddr);
-}
-
-
-/******************************************************************
- *    AllocateAndGetIpNetTableFromStack (IPHLPAPI.@)
- *
- * Get the IP-to-physical address mapping table.
- * Like GetIpNetTable(), but allocate the returned table from heap.
- *
- * PARAMS
- *  ppIpNetTable [Out] pointer into which the MIB_IPNETTABLE is
- *                     allocated and returned.
- *  bOrder       [In]  whether to sort the table
- *  heap         [In]  heap from which the table is allocated
- *  flags        [In]  flags to HeapAlloc
- *
- * RETURNS
- *  ERROR_INVALID_PARAMETER if ppIpNetTable is NULL, other error codes
- *  on failure, NO_ERROR on success.
- */
-DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable, BOOL bOrder,
-                                               HANDLE heap, DWORD flags)
-{
-    MIB_IPNETTABLE *table;
-    MIB_IPNETROW row;
-    DWORD ret = NO_ERROR, count = 16, table_size = FIELD_OFFSET( MIB_IPNETTABLE, table[count] );
-
-    TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppIpNetTable, bOrder, heap, flags);
-
-    if (!ppIpNetTable) return ERROR_INVALID_PARAMETER;
-
-    if (!(table = HeapAlloc( heap, flags, table_size )))
-        return ERROR_OUTOFMEMORY;
-
-    table->dwNumEntries = 0;
-
-#ifdef __linux__
-    {
-        FILE *fp;
-
-        if ((fp = fopen("/proc/net/arp", "r")))
-        {
-            char buf[512], *ptr;
-            DWORD atf_flags;
-
-            /* skip header line */
-            ptr = fgets(buf, sizeof(buf), fp);
-            while ((ptr = fgets(buf, sizeof(buf), fp)))
-            {
-                memset( &row, 0, sizeof(row) );
-
-                row.dwAddr = inet_addr(ptr);
-                while (*ptr && !isspace(*ptr)) ptr++;
-                strtoul(ptr + 1, &ptr, 16); /* hw type (skip) */
-                atf_flags = strtoul(ptr + 1, &ptr, 16);
-
-#ifdef ATF_COM
-                if (atf_flags & ATF_COM) row.u.Type = MIB_IPNET_TYPE_DYNAMIC;
-                else
-#endif
-#ifdef ATF_PERM
-                if (atf_flags & ATF_PERM) row.u.Type = MIB_IPNET_TYPE_STATIC;
-                else
-#endif
-                    row.u.Type = MIB_IPNET_TYPE_OTHER;
-
-                while (*ptr && isspace(*ptr)) ptr++;
-                while (*ptr && !isspace(*ptr))
-                {
-                    row.bPhysAddr[row.dwPhysAddrLen++] = strtoul(ptr, &ptr, 16);
-                    if (*ptr) ptr++;
-                }
-                while (*ptr && isspace(*ptr)) ptr++;
-                while (*ptr && !isspace(*ptr)) ptr++;   /* mask (skip) */
-                while (*ptr && isspace(*ptr)) ptr++;
-                getInterfaceIndexByName(ptr, &row.dwIndex);
-
-                if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, sizeof(row) )))
-                    break;
-            }
-            fclose(fp);
-        }
-        else ret = ERROR_NOT_SUPPORTED;
-    }
-#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK)
-    {
-        void *data;
-        int fd, len, namelen;
-        mib2_ipNetToMediaEntry_t *entry;
-        char name[64];
-
-        if ((fd = open_streams_mib( NULL )) != -1)
-        {
-            if ((data = read_mib_entry( fd, MIB2_IP, MIB2_IP_MEDIA, &len )))
-            {
-                for (entry = data; (char *)(entry + 1) <= (char *)data + len; entry++)
-                {
-                    row.dwPhysAddrLen = min( entry->ipNetToMediaPhysAddress.o_length, MAXLEN_PHYSADDR );
-                    memcpy( row.bPhysAddr, entry->ipNetToMediaPhysAddress.o_bytes, row.dwPhysAddrLen );
-                    row.dwAddr = entry->ipNetToMediaNetAddress;
-                    row.u.Type = entry->ipNetToMediaType;
-                    namelen = min( sizeof(name) - 1, entry->ipNetToMediaIfIndex.o_length );
-                    memcpy( name, entry->ipNetToMediaIfIndex.o_bytes, namelen );
-                    name[namelen] = 0;
-                    getInterfaceIndexByName( name, &row.dwIndex );
-                    if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, sizeof(row) )))
-                        break;
-                }
-                HeapFree( GetProcessHeap(), 0, data );
-            }
-            close( fd );
-        }
-        else ret = ERROR_NOT_SUPPORTED;
-    }
-#elif defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
-    {
-      int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO};
-      size_t needed;
-      char *buf = NULL, *lim, *next;
-      struct rt_msghdr *rtm;
-      struct sockaddr_inarp *sinarp;
-      struct sockaddr_dl *sdl;
-
-      if (sysctl (mib, ARRAY_SIZE(mib),  NULL, &needed, NULL, 0) == -1)
-      {
-         ERR ("failed to get arp table\n");
-         ret = ERROR_NOT_SUPPORTED;
-         goto done;
-      }
-
-      buf = HeapAlloc (GetProcessHeap (), 0, needed);
-      if (!buf)
-      {
-          ret = ERROR_OUTOFMEMORY;
-          goto done;
-      }
-
-      if (sysctl (mib, ARRAY_SIZE(mib), buf, &needed, NULL, 0) == -1)
-      {
-         ret = ERROR_NOT_SUPPORTED;
-         goto done;
-      }
-
-      lim = buf + needed;
-      next = buf;
-      while(next < lim)
-      {
-          rtm = (struct rt_msghdr *)next;
-          sinarp=(struct sockaddr_inarp *)(rtm + 1);
-          sdl = (struct sockaddr_dl *)((char *)sinarp + ROUNDUP(sinarp->sin_len));
-          if(sdl->sdl_alen) /* arp entry */
-          {
-              memset( &row, 0, sizeof(row) );
-              row.dwAddr = sinarp->sin_addr.s_addr;
-              row.dwIndex = sdl->sdl_index;
-              row.dwPhysAddrLen = min( 8, sdl->sdl_alen );
-              memcpy( row.bPhysAddr, &sdl->sdl_data[sdl->sdl_nlen], row.dwPhysAddrLen );
-              if(rtm->rtm_rmx.rmx_expire == 0) row.u.Type = MIB_IPNET_TYPE_STATIC;
-              else if(sinarp->sin_other & SIN_PROXY) row.u.Type = MIB_IPNET_TYPE_OTHER;
-              else if(rtm->rtm_rmx.rmx_expire != 0) row.u.Type = MIB_IPNET_TYPE_DYNAMIC;
-              else row.u.Type = MIB_IPNET_TYPE_INVALID;
-
-              if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, sizeof(row) )))
-                  break;
-          }
-          next += rtm->rtm_msglen;
-      }
-done:
-      HeapFree( GetProcessHeap (), 0, buf );
-    }
-#else
-    FIXME( "not implemented\n" );
-    ret = ERROR_NOT_SUPPORTED;
-#endif
-
-    if (!table) return ERROR_OUTOFMEMORY;
-    if (!ret)
-    {
-        if (bOrder && table->dwNumEntries)
-            qsort( table->table, table->dwNumEntries, sizeof(row), compare_ipnet_rows );
-        *ppIpNetTable = table;
-    }
-    else HeapFree( heap, flags, table );
-    TRACE( "returning ret %u table %p\n", ret, table );
-    return ret;
-}
-
 static DWORD get_tcp_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD *row_size )
 {
     DWORD table_size;




More information about the wine-cvs mailing list