diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index f16849276f8..cadb247a097 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -81,7 +81,7 @@ @ stub GetBestRouteFromStack #@ stub GetCurrentThreadCompartmentId @ stdcall GetExtendedTcpTable( ptr ptr long long long long ) -#@ stub GetExtendedUdpTable +@ stdcall GetExtendedUdpTable( ptr ptr long long long long ) @ stdcall GetFriendlyIfIndex( long ) #@ stub GetIcmpStatisticsEx @ stdcall GetIcmpStatistics( ptr ) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 961736f0475..a9ab1e02d40 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -1917,31 +1917,46 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, */ DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder) { - DWORD ret; - PMIB_UDPTABLE table; + return GetExtendedUdpTable(pUdpTable, pdwSize, bOrder, AF_INET, UDP_TABLE_BASIC, 0); +} - TRACE("pUdpTable %p, pdwSize %p, bOrder %d\n", pUdpTable, pdwSize, bOrder); +/****************************************************************** + * GetExtendedUdpTable (IPHLPAPI.@) + */ +DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, + ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved) +{ + DWORD ret, size; + void *table; + + TRACE("pUdpTable %p, pdwSize %p, bOrder %d, ulAf %u, TableClass %u, Reserved %u\n", + pUdpTable, pdwSize, bOrder, ulAf, TableClass, Reserved); if (!pdwSize) return ERROR_INVALID_PARAMETER; - ret = AllocateAndGetUdpTableFromStack( &table, bOrder, GetProcessHeap(), 0 ); - if (!ret) { - DWORD size = FIELD_OFFSET( MIB_UDPTABLE, table[table->dwNumEntries] ); - if (!pUdpTable || *pdwSize < size) { - *pdwSize = size; - ret = ERROR_INSUFFICIENT_BUFFER; - } - else { - *pdwSize = size; - memcpy(pUdpTable, table, size); - } - HeapFree(GetProcessHeap(), 0, table); + if (ulAf != AF_INET || + (TableClass != UDP_TABLE_BASIC && TableClass != UDP_TABLE_OWNER_PID)) + { + FIXME("ulAf = %u, TableClass = %u not supported\n", ulAf, TableClass); + return ERROR_NOT_SUPPORTED; } - TRACE("returning %d\n", ret); + if ((ret = build_udp_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size))) + return ret; + + if (!pUdpTable || *pdwSize < size) + { + *pdwSize = size; + ret = ERROR_INSUFFICIENT_BUFFER; + } + else + { + *pdwSize = size; + memcpy(pUdpTable, table, size); + } + HeapFree(GetProcessHeap(), 0, table); return ret; } - /****************************************************************** * GetUniDirectionalAdapterInfo (IPHLPAPI.@) * diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 2f8ec90a684..18307d51faf 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -1433,203 +1433,6 @@ done: return ret; } - -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; -} - -static int compare_udp_rows(const void *a, const void *b) -{ - const MIB_UDPROW *rowA = a; - const MIB_UDPROW *rowB = b; - int ret; - - if ((ret = rowA->dwLocalAddr - rowB->dwLocalAddr) != 0) return ret; - return rowA->dwLocalPort - rowB->dwLocalPort; -} - - -/****************************************************************** - * AllocateAndGetUdpTableFromStack (IPHLPAPI.@) - * - * Get the UDP listener table. - * Like GetUdpTable(), but allocate the returned table from heap. - * - * PARAMS - * ppUdpTable [Out] pointer into which the MIB_UDPTABLE 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 ppUdpTable is NULL, whatever GetUdpTable() - * returns otherwise. - */ -DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable, BOOL bOrder, - HANDLE heap, DWORD flags) -{ - MIB_UDPTABLE *table; - MIB_UDPROW row; - DWORD ret = NO_ERROR, count = 16; - - TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppUdpTable, bOrder, heap, flags); - - if (!ppUdpTable) return ERROR_INVALID_PARAMETER; - - if (!(table = HeapAlloc( heap, flags, FIELD_OFFSET(MIB_UDPTABLE, table[count] )))) - return ERROR_OUTOFMEMORY; - - table->dwNumEntries = 0; - -#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; - } - fclose(fp); - } - else ret = ERROR_NOT_SUPPORTED; - } -#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK) - { - void *data; - int fd, len; - mib2_udpEntry_t *entry; - - if ((fd = open_streams_mib( "udp" )) != -1) - { - if ((data = read_mib_entry( fd, MIB2_UDP, MIB2_UDP_ENTRY, &len ))) - { - for (entry = data; (char *)(entry + 1) <= (char *)data + len; entry++) - { - row.dwLocalAddr = entry->udpLocalAddress; - row.dwLocalPort = htons( entry->udpLocalPort ); - if (!(table = append_udp_row( heap, flags, table, &count, &row ))) break; - } - HeapFree( GetProcessHeap(), 0, data ); - } - close( fd ); - } - else ret = ERROR_NOT_SUPPORTED; - } -#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN) - { - size_t Len = 0; - char *Buf = NULL; - struct xinpgen *pXIG, *pOrigXIG; - - 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; - } - - /* Might be nothing here; first entry is just a header it seems */ - if (Len <= sizeof (struct xinpgen)) goto done; - - pOrigXIG = (struct xinpgen *)Buf; - pXIG = pOrigXIG; - - for (pXIG = (struct xinpgen *)((char *)pXIG + pXIG->xig_len); - pXIG->xig_len > sizeof (struct xinpgen); - pXIG = (struct xinpgen *)((char *)pXIG + pXIG->xig_len)) - { - struct inpcb *pINData; - struct xsocket *pSockData; - - pINData = &((struct xinpcb *)pXIG)->xi_inp; - pSockData = &((struct xinpcb *)pXIG)->xi_socket; - - /* Ignore sockets for other protocols */ - if (pSockData->xso_protocol != IPPROTO_UDP) - continue; - - /* Ignore PCBs that were freed while generating the data */ - if (pINData->inp_gencnt > pOrigXIG->xig_gen) - continue; - - /* we're only interested in IPv4 addresses */ - if (!(pINData->inp_vflag & INP_IPV4) || - (pINData->inp_vflag & INP_IPV6)) - continue; - - /* If all 0's, skip it */ - if (!pINData->inp_laddr.s_addr && - !pINData->inp_lport) - continue; - - /* Fill in structure details */ - row.dwLocalAddr = pINData->inp_laddr.s_addr; - row.dwLocalPort = pINData->inp_lport; - if (!(table = append_udp_row( heap, flags, table, &count, &row ))) break; - } - - 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_udp_rows ); - *ppUdpTable = 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; @@ -2015,3 +1818,244 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO if (!ppTcpTable) return ERROR_INVALID_PARAMETER; return build_tcp_table( TCP_TABLE_BASIC_ALL, (void **)ppTcpTable, bOrder, heap, flags, NULL ); } + +static DWORD get_udp_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_UDPTABLE, table[row_count]); + if (row_size) *row_size = sizeof(MIB_UDPROW); + break; + } + case UDP_TABLE_OWNER_PID: + { + table_size = FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table[row_count]); + if (row_size) *row_size = sizeof(MIB_UDPROW_OWNER_PID); + break; + } + default: + ERR("unhandled class %u\n", class); + return 0; + } + return table_size; +} + +static MIB_UDPTABLE *append_udp_row( UDP_TABLE_CLASS class, HANDLE heap, DWORD flags, + MIB_UDPTABLE *table, DWORD *count, + const MIB_UDPROW_OWNER_PID *row, DWORD row_size ) +{ + if (table->dwNumEntries >= *count) + { + MIB_UDPTABLE *new_table; + DWORD new_count = table->dwNumEntries * 2, new_table_size; + + new_table_size = get_udp_table_sizes( class, new_count, NULL ); + if (!(new_table = HeapReAlloc( heap, flags, table, new_table_size ))) + { + HeapFree( heap, 0, table ); + return NULL; + } + *count = new_count; + table = new_table; + } + memcpy( (char *)table->table + (table->dwNumEntries * row_size), row, row_size ); + table->dwNumEntries++; + return table; +} + +static int compare_udp_rows(const void *a, const void *b) +{ + const MIB_UDPROW *rowA = a; + const MIB_UDPROW *rowB = b; + int ret; + + if ((ret = rowA->dwLocalAddr - rowB->dwLocalAddr) != 0) return ret; + return rowA->dwLocalPort - rowB->dwLocalPort; +} + +DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags, + DWORD *size ) +{ + MIB_UDPTABLE *table; + MIB_UDPROW_OWNER_PID row; + DWORD ret = NO_ERROR, count = 16, table_size, row_size; + + if (!(table_size = get_udp_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/udp", "r" ))) + { + char buf[512], *ptr; + struct pid_map *map = NULL; + unsigned int dummy, num_entries = 0; + int inode; + + 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 ))) + { + if (sscanf( ptr, "%u: %x:%x %*s %*s %*s %*s %*s %*s %*s %d", &dummy, + &row.dwLocalAddr, &row.dwLocalPort, &inode ) != 4) + continue; + row.dwLocalPort = htons( row.dwLocalPort ); + if (class == UDP_TABLE_OWNER_PID) + row.dwOwningPid = find_owning_pid( map, num_entries, inode ); + if (!(table = append_udp_row( class, heap, flags, table, &count, &row, row_size ))) + break; + } + HeapFree( GetProcessHeap(), 0, map ); + fclose( fp ); + } + else ret = ERROR_NOT_SUPPORTED; + } +#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK) + { + void *data; + int fd, len; + mib2_udpEntry_t *entry; + + if ((fd = open_streams_mib( "udp" )) != -1) + { + if ((data = read_mib_entry( fd, MIB2_UDP, MIB2_UDP_ENTRY, &len ))) + { + for (entry = data; (char *)(entry + 1) <= (char *)data + len; entry++) + { + row.dwLocalAddr = entry->udpLocalAddress; + row.dwLocalPort = htons( entry->udpLocalPort ); + if (!(table = append_udp_row( class, heap, flags, table, &count, &row, row_size ))) break; + } + HeapFree( GetProcessHeap(), 0, data ); + } + close( fd ); + } + else ret = ERROR_NOT_SUPPORTED; + } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN) + { + size_t Len = 0; + char *Buf = NULL; + struct xinpgen *pXIG, *pOrigXIG; + + 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; + } + + /* Might be nothing here; first entry is just a header it seems */ + if (Len <= sizeof (struct xinpgen)) goto done; + + pOrigXIG = (struct xinpgen *)Buf; + pXIG = pOrigXIG; + + for (pXIG = (struct xinpgen *)((char *)pXIG + pXIG->xig_len); + pXIG->xig_len > sizeof (struct xinpgen); + pXIG = (struct xinpgen *)((char *)pXIG + pXIG->xig_len)) + { + struct inpcb *pINData; + struct xsocket *pSockData; + + pINData = &((struct xinpcb *)pXIG)->xi_inp; + pSockData = &((struct xinpcb *)pXIG)->xi_socket; + + /* Ignore sockets for other protocols */ + if (pSockData->xso_protocol != IPPROTO_UDP) + continue; + + /* Ignore PCBs that were freed while generating the data */ + if (pINData->inp_gencnt > pOrigXIG->xig_gen) + continue; + + /* we're only interested in IPv4 addresses */ + if (!(pINData->inp_vflag & INP_IPV4) || + (pINData->inp_vflag & INP_IPV6)) + continue; + + /* If all 0's, skip it */ + if (!pINData->inp_laddr.s_addr && + !pINData->inp_lport) + continue; + + /* Fill in structure details */ + row.dwLocalAddr = pINData->inp_laddr.s_addr; + row.dwLocalPort = pINData->inp_lport; + if (!(table = append_udp_row( class, heap, flags, table, &count, &row, row_size ))) break; + } + + done: + HeapFree (GetProcessHeap (), 0, Buf); + } +#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_udp_rows ); + *tablep = table; + } + else HeapFree( heap, flags, table ); + if (size) *size = get_udp_table_sizes( class, count, NULL ); + TRACE( "returning ret %u table %p\n", ret, table ); + return ret; +} + +/****************************************************************** + * AllocateAndGetUdpTableFromStack (IPHLPAPI.@) + * + * Get the UDP listener table. + * Like GetUdpTable(), but allocate the returned table from heap. + * + * PARAMS + * ppUdpTable [Out] pointer into which the MIB_UDPTABLE 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 ppUdpTable is NULL, whatever GetUdpTable() + * returns otherwise. + */ +DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable, BOOL bOrder, + HANDLE heap, DWORD flags) +{ + TRACE("table %p, bOrder %d, heap %p, flags 0x%08x\n", ppUdpTable, bOrder, heap, flags); + + if (!ppUdpTable) return ERROR_INVALID_PARAMETER; + return build_udp_table( UDP_TABLE_BASIC, (void **)ppUdpTable, bOrder, heap, flags, NULL ); +} diff --git a/dlls/iphlpapi/ipstats.h b/dlls/iphlpapi/ipstats.h index 16854e8614b..bf5bb9269fc 100644 --- a/dlls/iphlpapi/ipstats.h +++ b/dlls/iphlpapi/ipstats.h @@ -38,5 +38,6 @@ DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable, BO DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *ppIpForwardTable, BOOL bOrder, HANDLE heap, DWORD flags) DECLSPEC_HIDDEN; DWORD build_tcp_table(TCP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; +DWORD build_udp_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; #endif /* ndef WINE_IPSTATS_H_ */ diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index aabcf04a24a..638d7e59c55 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -71,6 +71,7 @@ static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRE static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED); static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED); static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG); +static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG); static DWORD (WINAPI *pSetTcpEntry)(PMIB_TCPROW); static void loadIPHlpApi(void) @@ -102,6 +103,7 @@ static void loadIPHlpApi(void) pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange"); pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify"); pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable"); + pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable"); pSetTcpEntry = (void *)GetProcAddress(hLibrary, "SetTcpEntry"); } } @@ -1203,6 +1205,39 @@ static void test_GetExtendedTcpTable(void) HeapFree( GetProcessHeap(), 0, table_pid ); } +static void test_GetExtendedUdpTable(void) +{ + DWORD ret, size; + MIB_UDPTABLE *table; + MIB_UDPTABLE_OWNER_PID *table_pid; + + if (!pGetExtendedUdpTable) + { + win_skip("GetExtendedUdpTable not available\n"); + return; + } + ret = pGetExtendedUdpTable( NULL, NULL, TRUE, AF_INET, UDP_TABLE_BASIC, 0 ); + ok( ret == ERROR_INVALID_PARAMETER, "got %u\n", ret ); + + size = 0; + ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + + table = HeapAlloc( GetProcessHeap(), 0, size ); + ret = pGetExtendedUdpTable( table, &size, TRUE, AF_INET, UDP_TABLE_BASIC, 0 ); + ok( ret == ERROR_SUCCESS, "got %u\n", ret ); + HeapFree( GetProcessHeap(), 0, table ); + + size = 0; + ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + + table_pid = HeapAlloc( GetProcessHeap(), 0, size ); + ret = pGetExtendedUdpTable( table_pid, &size, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0 ); + ok( ret == ERROR_SUCCESS, "got %u\n", ret ); + HeapFree( GetProcessHeap(), 0, table_pid ); +} + START_TEST(iphlpapi) { @@ -1221,6 +1256,7 @@ START_TEST(iphlpapi) testWin2KFunctions(); test_GetAdaptersAddresses(); test_GetExtendedTcpTable(); + test_GetExtendedUdpTable(); freeIPHlpApi(); } } diff --git a/include/iphlpapi.h b/include/iphlpapi.h index 43909037c7c..ca8e48ffb63 100644 --- a/include/iphlpapi.h +++ b/include/iphlpapi.h @@ -29,6 +29,9 @@ extern "C" { DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved); +DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, + ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved); + DWORD WINAPI GetNumberOfInterfaces(PDWORD pdwNumIf); DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow); diff --git a/include/iprtrmib.h b/include/iprtrmib.h index 3d4e65e1f65..977b117957b 100644 --- a/include/iprtrmib.h +++ b/include/iprtrmib.h @@ -38,4 +38,11 @@ typedef enum _TCP_TABLE_CLASS TCP_TABLE_OWNER_MODULE_ALL } TCP_TABLE_CLASS, *PTCP_TABLE_CLASS; +typedef enum _UDP_TABLE_CLASS +{ + UDP_TABLE_BASIC, + UDP_TABLE_OWNER_PID, + UDP_TABLE_OWNER_MODULE +} UDP_TABLE_CLASS, *PUDP_TABLE_CLASS; + #endif /* WINE_IPRTRMIB_H__ */ diff --git a/include/udpmib.h b/include/udpmib.h index 56932793b69..c2d507fe8be 100644 --- a/include/udpmib.h +++ b/include/udpmib.h @@ -39,6 +39,7 @@ typedef struct _MIB_UDPROW_OWNER_PID { DWORD dwLocalAddr; DWORD dwLocalPort; + DWORD dwOwningPid; } MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID; typedef struct _MIB_UDPTABLE_OWNER_PID @@ -47,7 +48,6 @@ typedef struct _MIB_UDPTABLE_OWNER_PID MIB_UDPROW_OWNER_PID table[1]; } MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID; - /* UDP statistics */ typedef struct _MIB_UDPSTATS