diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index e9701625316..837eb3dde24 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -1859,14 +1859,14 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, if (!pdwSize) return ERROR_INVALID_PARAMETER; - if (ulAf != AF_INET || - TableClass == TCP_TABLE_OWNER_MODULE_LISTENER || - TableClass == TCP_TABLE_OWNER_MODULE_CONNECTIONS || - TableClass == TCP_TABLE_OWNER_MODULE_ALL) + if (ulAf != AF_INET) { - FIXME("ulAf = %u, TableClass = %u not supported\n", ulAf, TableClass); + FIXME("ulAf = %u not supported\n", ulAf); return ERROR_NOT_SUPPORTED; } + if (TableClass >= TCP_TABLE_OWNER_MODULE_LISTENER) + FIXME("module classes not fully supported\n"); + if ((ret = build_tcp_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size))) return ret; @@ -1924,11 +1924,9 @@ DWORD WINAPI GetExtendedUdpTable(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, if (!pdwSize) return ERROR_INVALID_PARAMETER; - if (ulAf != AF_INET || - (TableClass != UDP_TABLE_BASIC && TableClass != UDP_TABLE_OWNER_PID && - TableClass != UDP_TABLE_OWNER_MODULE)) + if (ulAf != AF_INET) { - FIXME("ulAf = %u, TableClass = %u not supported\n", ulAf, TableClass); + FIXME("ulAf = %u not supported\n", ulAf); return ERROR_NOT_SUPPORTED; } if (TableClass == UDP_TABLE_OWNER_MODULE) diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 87651d36636..9ca51e90fae 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -140,6 +140,7 @@ #include "wine/debug.h" #include "wine/server.h" +#include "wine/unicode.h" #ifndef HAVE_NETINET_TCP_FSM_H #define TCPS_ESTABLISHED 1 @@ -1815,6 +1816,14 @@ static DWORD get_tcp_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD if (row_size) *row_size = sizeof(MIB_TCPROW_OWNER_PID); break; } + case TCP_TABLE_OWNER_MODULE_LISTENER: + case TCP_TABLE_OWNER_MODULE_CONNECTIONS: + case TCP_TABLE_OWNER_MODULE_ALL: + { + table_size = FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table[row_count]); + if (row_size) *row_size = sizeof(MIB_TCPROW_OWNER_MODULE); + break; + } default: ERR("unhandled class %u\n", class); return 0; @@ -1824,7 +1833,7 @@ static DWORD get_tcp_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD static MIB_TCPTABLE *append_tcp_row( TCP_TABLE_CLASS class, HANDLE heap, DWORD flags, MIB_TCPTABLE *table, DWORD *count, - const MIB_TCPROW_OWNER_PID *row, DWORD row_size ) + const MIB_TCPROW_OWNER_MODULE *row, DWORD row_size ) { if (table->dwNumEntries >= *count) { @@ -2012,7 +2021,7 @@ DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE DWORD *size ) { MIB_TCPTABLE *table; - MIB_TCPROW_OWNER_PID row; + MIB_TCPROW_OWNER_MODULE row; DWORD ret = NO_ERROR, count = 16, table_size, row_size; if (!(table_size = get_tcp_table_sizes( class, count, &row_size ))) @@ -2034,9 +2043,7 @@ DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE unsigned int dummy, num_entries = 0; int inode; - if (class == TCP_TABLE_OWNER_PID_ALL || - class == TCP_TABLE_OWNER_PID_LISTENER || - class == TCP_TABLE_OWNER_PID_CONNECTIONS) map = get_pid_map( &num_entries ); + if (class >= TCP_TABLE_OWNER_PID_LISTENER) map = get_pid_map( &num_entries ); /* skip header line */ ptr = fgets(buf, sizeof(buf), fp); @@ -2050,11 +2057,14 @@ DWORD build_tcp_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE row.dwRemotePort = htons( row.dwRemotePort ); row.dwState = TCPStateToMIBState( row.dwState ); if (!match_class( class, row.dwState )) continue; - if (class == TCP_TABLE_OWNER_PID_ALL || - class == TCP_TABLE_OWNER_PID_LISTENER || - class == TCP_TABLE_OWNER_PID_CONNECTIONS) - row.dwOwningPid = find_owning_pid( map, num_entries, inode ); + if (class >= TCP_TABLE_OWNER_PID_LISTENER) + row.dwOwningPid = find_owning_pid( map, num_entries, inode ); + if (class >= TCP_TABLE_OWNER_MODULE_LISTENER) + { + row.liCreateTimestamp.QuadPart = 0; /* FIXME */ + memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); + } if (!(table = append_tcp_row( class, heap, flags, table, &count, &row, row_size ))) break; } @@ -2304,8 +2314,7 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE unsigned int dummy, num_entries = 0; int inode; - if (class == UDP_TABLE_OWNER_PID || class == UDP_TABLE_OWNER_MODULE) - map = get_pid_map( &num_entries ); + if (class >= UDP_TABLE_OWNER_PID) map = get_pid_map( &num_entries ); /* skip header line */ ptr = fgets( buf, sizeof(buf), fp ); @@ -2315,8 +2324,15 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE &row.dwLocalAddr, &row.dwLocalPort, &inode ) != 4) continue; row.dwLocalPort = htons( row.dwLocalPort ); - if (class == UDP_TABLE_OWNER_PID || class == UDP_TABLE_OWNER_MODULE) + + if (class >= UDP_TABLE_OWNER_PID) row.dwOwningPid = find_owning_pid( map, num_entries, inode ); + if (class >= UDP_TABLE_OWNER_MODULE) + { + row.liCreateTimestamp.QuadPart = 0; /* FIXME */ + row.u.dwFlags = 0; + memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); + } if (!(table = append_udp_row( class, heap, flags, table, &count, &row, row_size ))) break; } diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index d15e05c4f69..dcbd3ab6a5e 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -1193,6 +1193,7 @@ static void test_GetExtendedTcpTable(void) DWORD ret, size; MIB_TCPTABLE *table; MIB_TCPTABLE_OWNER_PID *table_pid; + MIB_TCPTABLE_OWNER_MODULE *table_module; if (!pGetExtendedTcpTable) { @@ -1237,6 +1238,24 @@ static void test_GetExtendedTcpTable(void) ret = pGetExtendedTcpTable( table_pid, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0 ); ok( ret == ERROR_SUCCESS, "got %u\n", ret ); HeapFree( GetProcessHeap(), 0, table_pid ); + + size = 0; + ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + + table_module = HeapAlloc( GetProcessHeap(), 0, size ); + ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 ); + ok( ret == ERROR_SUCCESS, "got %u\n", ret ); + HeapFree( GetProcessHeap(), 0, table_module ); + + size = 0; + ret = pGetExtendedTcpTable( NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + + table_module = HeapAlloc( GetProcessHeap(), 0, size ); + ret = pGetExtendedTcpTable( table_module, &size, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_LISTENER, 0 ); + ok( ret == ERROR_SUCCESS, "got %u\n", ret ); + HeapFree( GetProcessHeap(), 0, table_module ); } static void test_GetExtendedUdpTable(void) @@ -1244,6 +1263,7 @@ static void test_GetExtendedUdpTable(void) DWORD ret, size; MIB_UDPTABLE *table; MIB_UDPTABLE_OWNER_PID *table_pid; + MIB_UDPTABLE_OWNER_MODULE *table_module; if (!pGetExtendedUdpTable) { @@ -1270,6 +1290,15 @@ static void test_GetExtendedUdpTable(void) 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 ); + + size = 0; + ret = pGetExtendedUdpTable( NULL, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %u\n", ret ); + + table_module = HeapAlloc( GetProcessHeap(), 0, size ); + ret = pGetExtendedUdpTable( table_module, &size, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 ); + ok( ret == ERROR_SUCCESS, "got %u\n", ret ); + HeapFree( GetProcessHeap(), 0, table_module ); } START_TEST(iphlpapi) diff --git a/include/tcpmib.h b/include/tcpmib.h index 8c3efa1a921..477500c4fb2 100644 --- a/include/tcpmib.h +++ b/include/tcpmib.h @@ -115,6 +115,24 @@ typedef struct _MIB_TCPTABLE_OWNER_PID MIB_TCPROW_OWNER_PID table[1]; } MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID; +typedef struct _MIB_TCPROW_OWNER_MODULE +{ + DWORD dwState; + DWORD dwLocalAddr; + DWORD dwLocalPort; + DWORD dwRemoteAddr; + DWORD dwRemotePort; + DWORD dwOwningPid; + LARGE_INTEGER liCreateTimestamp; + ULONGLONG OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE]; +} MIB_TCPROW_OWNER_MODULE, *PMIB_TCPROW_OWNER_MODULE; + +typedef struct _MIB_TCPTABLE_OWNER_MODULE +{ + DWORD dwNumEntries; + MIB_TCPROW_OWNER_MODULE table[1]; +} MIB_TCPTABLE_OWNER_MODULE, *PMIB_TCPTABLE_OWNER_MODULE; + typedef struct _MIB_TCPROW2 { DWORD dwState;