Module: wine Branch: master Commit: d069e498e17ae8daea44bf284deb0492c301d219 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d069e498e17ae8daea44bf284d...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Mar 2 12:43:33 2009 +0100
iphlpapi: Reimplement GetUdpTable to avoid parsing the same information three times.
---
dlls/iphlpapi/iphlpapi_main.c | 39 ++++---------- dlls/iphlpapi/ipstats.c | 118 ++++++++++++++++++++--------------------- 2 files changed, 68 insertions(+), 89 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index f580ca8..c9ced14 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -1685,31 +1685,17 @@ DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats) */ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder) { - DWORD ret; + DWORD ret; + PMIB_UDPTABLE table;
- TRACE("pUdpTable %p, pdwSize %p, bOrder %d\n", pUdpTable, pdwSize, - (DWORD)bOrder); - if (!pdwSize) - ret = ERROR_INVALID_PARAMETER; - else { - DWORD numEntries = getNumUdpEntries(); - DWORD size = sizeof(MIB_UDPTABLE); + TRACE("pUdpTable %p, pdwSize %p, bOrder %d\n", pUdpTable, pdwSize, bOrder);
- if (numEntries > 1) - size += (numEntries - 1) * sizeof(MIB_UDPROW); - if (!pUdpTable || *pdwSize < size) { - *pdwSize = size; - ret = ERROR_INSUFFICIENT_BUFFER; - } - else { - PMIB_UDPTABLE table; + if (!pdwSize) return ERROR_INVALID_PARAMETER;
- ret = getUdpTable(&table, GetProcessHeap(), 0); - if (!ret) { - size = sizeof(MIB_UDPTABLE); - if (table->dwNumEntries > 1) - size += (table->dwNumEntries - 1) * sizeof(MIB_UDPROW); - if (*pdwSize < size) { + ret = getUdpTable(&table, GetProcessHeap(), 0); + if (!ret) { + DWORD size = FIELD_OFFSET( MIB_UDPTABLE, table[table->dwNumEntries] ); + if (!pUdpTable || *pdwSize < size) { *pdwSize = size; ret = ERROR_INSUFFICIENT_BUFFER; } @@ -1719,16 +1705,11 @@ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder) if (bOrder) qsort(pUdpTable->table, pUdpTable->dwNumEntries, sizeof(MIB_UDPROW), UdpTableSorter); - ret = NO_ERROR; } HeapFree(GetProcessHeap(), 0, table); - } - else - ret = ERROR_OUTOFMEMORY; } - } - TRACE("returning %d\n", ret); - return ret; + TRACE("returning %d\n", ret); + return ret; }
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index ada1430..57398bb 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -1,5 +1,7 @@ -/* Copyright (C) 2003,2006 Juan Lang +/* + * Copyright (C) 2003,2006 Juan Lang * Copyright (C) 2007 TransGaming Technologies Inc. + * Copyright (C) 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,9 +16,6 @@ * 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 file implements statistics getting using the /proc filesystem exported - * by Linux, and maybe other OSes. */
#include "config.h" @@ -1480,72 +1479,71 @@ DWORD getNumUdpEntries(void) #endif }
-DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTable, HANDLE heap, DWORD flags) +static MIB_UDPTABLE *append_udp_row( HANDLE heap, DWORD flags, MIB_UDPTABLE *table, + DWORD *count, const MIB_UDPROW *row ) { - DWORD ret; + if (table->dwNumEntries >= *count) + { + MIB_UDPTABLE *new_table; + DWORD new_count = table->dwNumEntries * 2;
-#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; -#endif + if (!(new_table = HeapReAlloc( heap, flags, table, FIELD_OFFSET(MIB_UDPTABLE, table[new_count] )))) + { + HeapFree( heap, 0, table ); + return NULL; + } + *count = new_count; + table = new_table; + } + memcpy( &table->table[table->dwNumEntries++], row, sizeof(*row) ); + return table; +}
- if (!ppUdpTable) - ret = ERROR_INVALID_PARAMETER; - else { - DWORD numEntries = getNumUdpEntries(); - DWORD size = sizeof(MIB_UDPTABLE); - PMIB_UDPTABLE table; +DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTable, HANDLE heap, DWORD flags) +{ + MIB_UDPTABLE *table; + MIB_UDPROW row; + DWORD ret = NO_ERROR, count = 16;
- if (numEntries > 1) - size += (numEntries - 1) * sizeof(MIB_UDPROW); - table = HeapAlloc(heap, flags, size); - if (table) { - FILE *fp; + if (!ppUdpTable) return ERROR_INVALID_PARAMETER;
- ret = NO_ERROR; - *ppUdpTable = table; - table->dwNumEntries = 0; - /* get from /proc/net/udp, no error if can't */ - fp = fopen("/proc/net/udp", "r"); - if (fp) { - char buf[512] = { 0 }, *ptr; + if (!(table = HeapAlloc( heap, flags, FIELD_OFFSET(MIB_UDPTABLE, table[count] )))) + return ERROR_OUTOFMEMORY;
- /* skip header line */ - ptr = fgets(buf, sizeof(buf), fp); - while (ptr && table->dwNumEntries < numEntries) { - memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_UDPROW)); - ptr = fgets(buf, sizeof(buf), fp); - if (ptr) { - char *endPtr; + table->dwNumEntries = 0;
- if (ptr && *ptr) { - strtoul(ptr, &endPtr, 16); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - ptr++; - table->table[table->dwNumEntries].dwLocalAddr = strtoul(ptr, - &endPtr, 16); - ptr = endPtr; - } - if (ptr && *ptr) { - ptr++; - table->table[table->dwNumEntries].dwLocalPort = strtoul(ptr, - &endPtr, 16); - ptr = endPtr; +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen("/proc/net/udp", "r"))) + { + char buf[512], *ptr; + DWORD dummy; + + /* skip header line */ + ptr = fgets(buf, sizeof(buf), fp); + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + if (sscanf( ptr, "%u: %x:%x", &dummy, &row.dwLocalAddr, &row.dwLocalPort ) != 3) + continue; + row.dwLocalPort = htons( row.dwLocalPort ); + if (!(table = append_udp_row( heap, flags, table, &count, &row ))) + break; } - table->dwNumEntries++; - } + fclose(fp); } - fclose(fp); - } - else - ret = ERROR_NOT_SUPPORTED; + else ret = ERROR_NOT_SUPPORTED; } - else - ret = ERROR_OUTOFMEMORY; - } - return ret; +#else + FIXME( "not implemented\n" ); + ret = ERROR_NOT_SUPPORTED; +#endif + + if (!table) return ERROR_OUTOFMEMORY; + if (!ret) *ppUdpTable = table; + else HeapFree( heap, flags, table ); + return ret; }