Commit d069e498 authored by Alexandre Julliard's avatar Alexandre Julliard

iphlpapi: Reimplement GetUdpTable to avoid parsing the same information three times.

parent 9b309b01
...@@ -1686,30 +1686,16 @@ DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats) ...@@ -1686,30 +1686,16 @@ DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats)
DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder) 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, TRACE("pUdpTable %p, pdwSize %p, bOrder %d\n", pUdpTable, pdwSize, bOrder);
(DWORD)bOrder);
if (!pdwSize)
ret = ERROR_INVALID_PARAMETER;
else {
DWORD numEntries = getNumUdpEntries();
DWORD size = sizeof(MIB_UDPTABLE);
if (numEntries > 1) if (!pdwSize) return ERROR_INVALID_PARAMETER;
size += (numEntries - 1) * sizeof(MIB_UDPROW);
if (!pUdpTable || *pdwSize < size) {
*pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER;
}
else {
PMIB_UDPTABLE table;
ret = getUdpTable(&table, GetProcessHeap(), 0); ret = getUdpTable(&table, GetProcessHeap(), 0);
if (!ret) { if (!ret) {
size = sizeof(MIB_UDPTABLE); DWORD size = FIELD_OFFSET( MIB_UDPTABLE, table[table->dwNumEntries] );
if (table->dwNumEntries > 1) if (!pUdpTable || *pdwSize < size) {
size += (table->dwNumEntries - 1) * sizeof(MIB_UDPROW);
if (*pdwSize < size) {
*pdwSize = size; *pdwSize = size;
ret = ERROR_INSUFFICIENT_BUFFER; ret = ERROR_INSUFFICIENT_BUFFER;
} }
...@@ -1719,14 +1705,9 @@ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder) ...@@ -1719,14 +1705,9 @@ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder)
if (bOrder) if (bOrder)
qsort(pUdpTable->table, pUdpTable->dwNumEntries, qsort(pUdpTable->table, pUdpTable->dwNumEntries,
sizeof(MIB_UDPROW), UdpTableSorter); sizeof(MIB_UDPROW), UdpTableSorter);
ret = NO_ERROR;
} }
HeapFree(GetProcessHeap(), 0, table); HeapFree(GetProcessHeap(), 0, table);
} }
else
ret = ERROR_OUTOFMEMORY;
}
}
TRACE("returning %d\n", ret); TRACE("returning %d\n", ret);
return ret; return ret;
} }
......
/* Copyright (C) 2003,2006 Juan Lang /*
* Copyright (C) 2003,2006 Juan Lang
* Copyright (C) 2007 TransGaming Technologies Inc. * Copyright (C) 2007 TransGaming Technologies Inc.
* Copyright (C) 2009 Alexandre Julliard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -14,9 +16,6 @@ ...@@ -14,9 +16,6 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 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" #include "config.h"
...@@ -1480,71 +1479,70 @@ DWORD getNumUdpEntries(void) ...@@ -1480,71 +1479,70 @@ DWORD getNumUdpEntries(void)
#endif #endif
} }
static MIB_UDPTABLE *append_udp_row( HANDLE heap, DWORD flags, MIB_UDPTABLE *table,
DWORD *count, const MIB_UDPROW *row )
{
if (table->dwNumEntries >= *count)
{
MIB_UDPTABLE *new_table;
DWORD new_count = table->dwNumEntries * 2;
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;
}
DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTable, HANDLE heap, DWORD flags) DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTable, HANDLE heap, DWORD flags)
{ {
DWORD ret; MIB_UDPTABLE *table;
MIB_UDPROW row;
DWORD ret = NO_ERROR, count = 16;
#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) if (!ppUdpTable) return ERROR_INVALID_PARAMETER;
ERR ("unimplemented!\n");
return ERROR_NOT_SUPPORTED;
#endif
if (!ppUdpTable) if (!(table = HeapAlloc( heap, flags, FIELD_OFFSET(MIB_UDPTABLE, table[count] ))))
ret = ERROR_INVALID_PARAMETER; return ERROR_OUTOFMEMORY;
else {
DWORD numEntries = getNumUdpEntries();
DWORD size = sizeof(MIB_UDPTABLE);
PMIB_UDPTABLE table;
if (numEntries > 1) table->dwNumEntries = 0;
size += (numEntries - 1) * sizeof(MIB_UDPROW);
table = HeapAlloc(heap, flags, size); #ifdef __linux__
if (table) { {
FILE *fp; FILE *fp;
ret = NO_ERROR; if ((fp = fopen("/proc/net/udp", "r")))
*ppUdpTable = table; {
table->dwNumEntries = 0; char buf[512], *ptr;
/* get from /proc/net/udp, no error if can't */ DWORD dummy;
fp = fopen("/proc/net/udp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */ /* skip header line */
ptr = fgets(buf, sizeof(buf), fp); ptr = fgets(buf, sizeof(buf), fp);
while (ptr && table->dwNumEntries < numEntries) { while ((ptr = fgets(buf, sizeof(buf), fp)))
memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_UDPROW)); {
ptr = fgets(buf, sizeof(buf), fp); if (sscanf( ptr, "%u: %x:%x", &dummy, &row.dwLocalAddr, &row.dwLocalPort ) != 3)
if (ptr) { continue;
char *endPtr; row.dwLocalPort = htons( row.dwLocalPort );
if (!(table = append_udp_row( heap, flags, table, &count, &row )))
if (ptr && *ptr) { break;
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;
}
table->dwNumEntries++;
}
} }
fclose(fp); fclose(fp);
} }
else else ret = ERROR_NOT_SUPPORTED;
ret = ERROR_NOT_SUPPORTED;
}
else
ret = ERROR_OUTOFMEMORY;
} }
#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; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment