[PATCH] ws2_32: Add support for hints in GetAddrInfoExW.

Hans Leidekker hans at codeweavers.com
Thu May 13 08:39:51 CDT 2021


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 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);
-- 
2.30.2




More information about the wine-devel mailing list