Alexandre Julliard : iphlpapi: Reimplement GetUdpTable to avoid parsing the same information three times.
Alexandre Julliard
julliard at winehq.org
Mon Mar 2 09:01:53 CST 2009
Module: wine
Branch: master
Commit: d069e498e17ae8daea44bf284deb0492c301d219
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d069e498e17ae8daea44bf284deb0492c301d219
Author: Alexandre Julliard <julliard at 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;
}
More information about the wine-cvs
mailing list