From e7af1f92a3f419019e05258db31d64717a12ee8a Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 13 May 2021 15:39:51 +0200 Subject: [PATCH] ws2_32: Add support for hints in GetAddrInfoExW. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/ws2_32/protocol.c | 18 +++++++++++++----- dlls/ws2_32/tests/protocol.c | 24 +++++++++++++++++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index 64af105f0b9..15616fdaf34 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -568,6 +568,7 @@ struct getaddrinfo_args ADDRINFOEXW **result; char *nodename; char *servname; + struct WS_addrinfo *hints; }; static void WINAPI getaddrinfo_callback(TP_CALLBACK_INSTANCE *instance, void *context) @@ -579,7 +580,7 @@ static void WINAPI getaddrinfo_callback(TP_CALLBACK_INSTANCE *instance, void *co struct WS_addrinfo *res; int ret; - ret = WS_getaddrinfo( args->nodename, args->servname, NULL, &res ); + ret = WS_getaddrinfo( args->nodename, args->servname, args->hints, &res ); if (res) { *args->result = addrinfo_list_AtoW(res); @@ -660,12 +661,21 @@ static int WS_getaddrinfoW( const WCHAR *nodename, const WCHAR *servname, goto end; } - if (!(args = HeapAlloc( GetProcessHeap(), 0, sizeof(*args) ))) goto end; + if (!(args = HeapAlloc( GetProcessHeap(), 0, sizeof(*args) + sizeof(*args->hints) ))) goto end; args->overlapped = overlapped; args->completion_routine = completion_routine; args->result = res; args->nodename = nodenameA; args->servname = servnameA; + if (hints) + { + args->hints = (struct WS_addrinfo *)(args + 1); + args->hints->ai_flags = hints->ai_flags; + args->hints->ai_family = hints->ai_family; + args->hints->ai_socktype = hints->ai_socktype; + args->hints->ai_protocol = hints->ai_protocol; + } + else args->hints = NULL; overlapped->Internal = WSAEINPROGRESS; if (!TrySubmitThreadpoolCallback( getaddrinfo_callback, args, NULL )) @@ -714,14 +724,12 @@ int WINAPI GetAddrInfoExW( const WCHAR *name, const WCHAR *servname, DWORD names FIXME( "Unsupported namespace %u\n", namespace ); if (namespace_id) FIXME( "Unsupported namespace_id %s\n", debugstr_guid(namespace_id) ); - if (hints) - FIXME( "Unsupported hints\n" ); if (timeout) FIXME( "Unsupported timeout\n" ); if (handle) FIXME( "Unsupported cancel handle\n" ); - ret = WS_getaddrinfoW( name, servname, NULL, result, overlapped, completion_routine ); + ret = WS_getaddrinfoW( name, servname, (struct WS_addrinfo *)hints, result, overlapped, completion_routine ); if (ret) return ret; if (handle) *handle = (HANDLE)0xdeadbeef; return 0; diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c index 8937e84d63f..27ef6ff92aa 100644 --- a/dlls/ws2_32/tests/protocol.c +++ b/dlls/ws2_32/tests/protocol.c @@ -1599,7 +1599,7 @@ static void test_GetAddrInfoExW(void) static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0}; static const WCHAR winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; static const WCHAR nxdomain[] = {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0}; - ADDRINFOEXW *result; + ADDRINFOEXW *result, hints; OVERLAPPED overlapped; HANDLE event; int ret; @@ -1666,6 +1666,28 @@ static void test_GetAddrInfoExW(void) ok(!result->ai_provider, "ai_provider = %s\n", wine_dbgstr_guid(result->ai_provider)); pFreeAddrInfoExW(result); + /* hints */ + result = (void *)0xdeadbeef; + memset(&overlapped, 0xcc, sizeof(overlapped)); + ResetEvent(event); + overlapped.hEvent = event; + WSASetLastError(0xdeadbeef); + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ALL | AI_V4MAPPED; + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + ret = pGetAddrInfoExW(winehq, NULL, NS_ALL, NULL, &hints, &result, NULL, &overlapped, NULL, NULL); + ok(ret == ERROR_IO_PENDING, "GetAddrInfoExW failed with %d\n", WSAGetLastError()); + ok(WSAGetLastError() == ERROR_IO_PENDING, "expected 11001, got %d\n", WSAGetLastError()); + ret = overlapped.Internal; + ok(ret == WSAEINPROGRESS || ret == ERROR_SUCCESS, "overlapped.Internal = %u\n", ret); + ok(WaitForSingleObject(event, 1000) == WAIT_OBJECT_0, "wait failed\n"); + ret = pGetAddrInfoExOverlappedResult(&overlapped); + ok(!ret, "overlapped result is %d\n", ret); + ok(result != NULL, "result == NULL\n"); + pFreeAddrInfoExW(result); + result = (void *)0xdeadbeef; memset(&overlapped, 0xcc, sizeof(overlapped)); ResetEvent(event);