From: Paul Gofman pgofman@codeweavers.com
--- dlls/iphlpapi/iphlpapi.spec | 2 +- dlls/iphlpapi/iphlpapi_main.c | 13 ++++++ dlls/iphlpapi/tests/iphlpapi.c | 85 ++++++++++++++++++++++++++++++++++ include/iphlpapi.h | 1 + 4 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index 9dad2be88ce..9da2a26f29f 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -123,7 +123,7 @@ @ stdcall GetNetworkParams( ptr ptr ) @ stdcall GetNumberOfInterfaces( ptr ) #@ stub GetOwnerModuleFromPidAndInfo -#@ stub GetOwnerModuleFromTcp6Entry +@ stdcall GetOwnerModuleFromTcp6Entry( ptr long ptr ptr ) @ stdcall GetOwnerModuleFromTcpEntry( ptr long ptr ptr ) #@ stub GetOwnerModuleFromUdp6Entry #@ stub GetOwnerModuleFromUdpEntry diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index d833c88d8a4..262fd0dca82 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -3321,6 +3321,19 @@ DWORD WINAPI GetOwnerModuleFromTcpEntry( PMIB_TCPROW_OWNER_MODULE entry, TCPIP_O return get_owner_module_from_pid( class, buffer, size, entry->dwOwningPid ); }
+/****************************************************************** + * GetOwnerModuleFromTcp6Entry (IPHLPAPI.@) + */ +DWORD WINAPI GetOwnerModuleFromTcp6Entry( PMIB_TCP6ROW_OWNER_MODULE entry, TCPIP_OWNER_MODULE_INFO_CLASS class, + void *buffer, DWORD *size ) +{ + TRACE( "entry %p, class %d, buffer %p, size %p.\n", entry, class, buffer, size ); + + if (!entry) return ERROR_INVALID_PARAMETER; + + return get_owner_module_from_pid( class, buffer, size, entry->dwOwningPid ); +} + /****************************************************************** * GetTcpTable (IPHLPAPI.@) * diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 7f98d322991..982880fdb9d 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -2393,6 +2393,91 @@ static void test_GetExtendedTcpTable_owner( int family ) } ok( found_it, "no table entry for socket\n" ); } + else + { + MIB_TCP6TABLE_OWNER_MODULE *t = raw_table; + TCPIP_OWNER_MODULE_BASIC_INFO *info; + MIB_TCP6ROW_OWNER_MODULE entry; + WCHAR mod[MAX_PATH], *name; + DWORD sz, expected, name_len; + BYTE buf[MAX_PATH + sizeof(TCPIP_OWNER_MODULE_BASIC_INFO) + 128]; + HANDLE process; + char *p; + + info = (TCPIP_OWNER_MODULE_BASIC_INFO *)buf; + + mod[0] = 0; + GetModuleFileNameW( NULL, mod, ARRAY_SIZE(mod) ); + name = wcsrchr( mod, '\' ); + ok( !!name, "could not get name, mod %s.\n", debugstr_w(mod) ); + ++name; + name_len = (wcslen( name ) + 1) * sizeof(WCHAR); + expected = sizeof(TCPIP_OWNER_MODULE_BASIC_INFO) + name_len + (wcslen( mod ) + 1) * sizeof(WCHAR); + memset( &entry, 0, sizeof(entry) ); + + sz = sizeof(buf); + ret = GetOwnerModuleFromTcp6Entry( NULL, TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + ok( ret == ERROR_INVALID_PARAMETER, "got %lu.\n", ret ); + + entry.dwOwningPid = 0; + ret = GetOwnerModuleFromTcp6Entry( &entry, TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + ok( ret == ERROR_NOT_FOUND, "got %lu.\n", ret ); + + entry.dwOwningPid = 0xffff; + ret = GetOwnerModuleFromTcp6Entry( &entry, TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + ok( ret == ERROR_INVALID_PARAMETER, "got %lu.\n", ret ); + + entry.dwOwningPid = GetCurrentProcessId(); + sz = 1; + ret = GetOwnerModuleFromTcp6Entry( &entry, TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + ok( ret == ERROR_INSUFFICIENT_BUFFER, "got %lu.\n", ret ); + ok( sz == expected, "got %lu, expected %lu.\n", sz, expected ); + + ret = GetOwnerModuleFromTcp6Entry( &entry, TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + ok( !ret, "got %lu.\n", ret ); + + p = (char *)(info + 1); + ok( (char *)info->pModuleName == p, "got %p, %p.\n", info, p ); + p += name_len; + ok( (char *)info->pModulePath == p, "got %p, %p.\n", info, p); + ok( !wcscmp( info->pModuleName, name ), "got %s, %s.\n", debugstr_w(info->pModuleName), debugstr_w(name) ); + + found_it = FALSE; + for (i = 0; i < t->dwNumEntries; ++i) + { + info = (TCPIP_OWNER_MODULE_BASIC_INFO *)buf; + + memset(buf, 0xcc, sizeof(buf)); + sz = sizeof(buf) + 1; + ret = GetOwnerModuleFromTcp6Entry( &t->table[i], TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + ok(sz == sizeof(buf) + 1, "got %ld.\n", sz); + ok( !ret || ret == ERROR_NOT_FOUND || ret == ERROR_ACCESS_DENIED + || ret == ERROR_MOD_NOT_FOUND, + /* This is weird, newer Windows seems to return non-zero OwningModuleInfo[0] sometimes but then + * GetOwnerModuleFromTcp6Entry always fails with ERROR_MOD_NOT_FOUND, while that succeeds for the + * same PID in MIB_TCPTABLE_OWNER_MODULE and zeroed OwningModuleInfo */ + "got %#lx, pid %ld, info %#I64x.\n", ret, t->table[i].dwOwningPid, t->table[i].OwningModuleInfo[0] ); + + memset( &entry, 0, sizeof(entry) ); + entry.dwOwningPid = t->table[i].dwOwningPid; + if (entry.dwOwningPid == GetCurrentProcessId()) + found_it = TRUE; + ret = GetOwnerModuleFromTcp6Entry( &entry, TCPIP_OWNER_MODULE_INFO_BASIC, buf, &sz ); + process = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, entry.dwOwningPid ); + ok( !ret || ret == ERROR_NOT_FOUND || ret == ERROR_ACCESS_DENIED, + "got %#lx, pid %ld, info %#I64x.\n", ret, t->table[i].dwOwningPid, t->table[i].OwningModuleInfo[0] ); + if (!ret && !wcscmp( info->pModuleName, L"System" )) + { + ok( !wcscmp( info->pModulePath, L"System" ), "got %s.\n", debugstr_w(info->pModulePath) ); + } + else if (ret == ERROR_ACCESS_DENIED) + { + process = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, entry.dwOwningPid ); + ok( !process && GetLastError() == ERROR_ACCESS_DENIED, "got process %p, err %lu.\n", process, GetLastError() ); + } + } + ok( found_it, "no table entry for socket\n" ); + }
done: closesocket( sock ); diff --git a/include/iphlpapi.h b/include/iphlpapi.h index 0dbc034e556..ca280a65806 100644 --- a/include/iphlpapi.h +++ b/include/iphlpapi.h @@ -66,6 +66,7 @@ IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpStatistics(PMIB_IPSTATS pStats); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIpStatisticsEx(PMIB_IPSTATS pStats, DWORD dwFamily); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetIcmpStatisticsEx(PMIB_ICMP_EX pStats, DWORD dwFamily); +IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetOwnerModuleFromTcp6Entry(PMIB_TCP6ROW_OWNER_MODULE entry, TCPIP_OWNER_MODULE_INFO_CLASS class, void *info, DWORD *size); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetOwnerModuleFromTcpEntry(PMIB_TCPROW_OWNER_MODULE entry, TCPIP_OWNER_MODULE_INFO_CLASS class, void *info, DWORD *size); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats); IPHLPAPI_DLL_LINKAGE DWORD WINAPI GetTcpStatisticsEx(PMIB_TCPSTATS pStats, DWORD dwFamily);