Bruno Jesus : ws2_32: Try harder to get the host name address in getaddrinfo.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Sep 8 08:15:46 CDT 2015


Module: wine
Branch: master
Commit: 18a02d8f41013aa8bf3cdd03750eb706ce52e58c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=18a02d8f41013aa8bf3cdd03750eb706ce52e58c

Author: Bruno Jesus <00cpxxx at gmail.com>
Date:   Tue Sep  8 11:14:32 2015 +0800

ws2_32: Try harder to get the host name address in getaddrinfo.

---

 dlls/ws2_32/socket.c     | 18 +++++++++++-----
 dlls/ws2_32/tests/sock.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index ca82ec9..5cf3e0f 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -5996,7 +5996,7 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr
     struct addrinfo *unixaires = NULL;
     int   result;
     struct addrinfo unixhints, *punixhints = NULL;
-    char *hostname = NULL;
+    char *hostname;
     const char *node;
 
     *res = NULL;
@@ -6006,13 +6006,13 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr
         return WSAHOST_NOT_FOUND;
     }
 
+    hostname = get_hostname();
+    if (!hostname) return WSA_NOT_ENOUGH_MEMORY;
+
     if (!nodename)
         node = NULL;
     else if (!nodename[0])
-    {
-        node = hostname = get_hostname();
-        if (!node) return WSA_NOT_ENOUGH_MEMORY;
-    }
+        node = hostname;
     else
         node = nodename;
 
@@ -6056,6 +6056,14 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr
     /* getaddrinfo(3) is thread safe, no need to wrap in CS */
     result = getaddrinfo(node, servname, punixhints, &unixaires);
 
+    if (result && !strcmp(hostname, node))
+    {
+        /* If it didn't work it means the host name IP is not in /etc/hosts, try again
+        * by sending a NULL host and avoid sending a NULL servname too because that
+        * is invalid */
+        ERR_(winediag)("Failed to resolve your host name IP\n");
+        result = getaddrinfo(NULL, servname ? servname : "0", punixhints, &unixaires);
+    }
     TRACE("%s, %s %p -> %p %d\n", debugstr_a(nodename), debugstr_a(servname), hints, res, result);
     HeapFree(GetProcessHeap(), 0, hostname);
 
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 2d14496..03e1627 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6313,6 +6313,8 @@ static void test_GetAddrInfoW(void)
     static const WCHAR zero[] = {'0',0};
     int i, ret;
     ADDRINFOW *result, *result2, *p, hint;
+    WCHAR name[256];
+    DWORD size = sizeof(name);
 
     if (!pGetAddrInfoW || !pFreeAddrInfoW)
     {
@@ -6320,6 +6322,8 @@ static void test_GetAddrInfoW(void)
         return;
     }
     memset(&hint, 0, sizeof(ADDRINFOW));
+    name[0] = 0;
+    GetComputerNameExW( ComputerNamePhysicalDnsHostname, name, &size );
 
     result = (ADDRINFOW *)0xdeadbeef;
     WSASetLastError(0xdeadbeef);
@@ -6395,6 +6399,30 @@ static void test_GetAddrInfoW(void)
     ok(WSAGetLastError() == 0, "expected 0, got %d\n", WSAGetLastError());
     pFreeAddrInfoW(result);
 
+    /* try to get information from the computer name, result is the same
+     * as if requesting with an empty host name. */
+    ret = pGetAddrInfoW(name, NULL, NULL, &result);
+    ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+
+    ret = pGetAddrInfoW(empty, NULL, NULL, &result2);
+    ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+    compare_addrinfow(result, result2);
+    pFreeAddrInfoW(result);
+    pFreeAddrInfoW(result2);
+
+    ret = pGetAddrInfoW(name, empty, NULL, &result);
+    ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+
+    ret = pGetAddrInfoW(empty, empty, NULL, &result2);
+    ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+    compare_addrinfow(result, result2);
+    pFreeAddrInfoW(result);
+    pFreeAddrInfoW(result2);
+
     result = (ADDRINFOW *)0xdeadbeef;
     WSASetLastError(0xdeadbeef);
     ret = pGetAddrInfoW(NULL, NULL, NULL, &result);
@@ -6475,6 +6503,8 @@ static void test_getaddrinfo(void)
 {
     int i, ret;
     ADDRINFOA *result, *result2, *p, hint;
+    CHAR name[256];
+    DWORD size = sizeof(name);
 
     if (!pgetaddrinfo || !pfreeaddrinfo)
     {
@@ -6482,6 +6512,7 @@ static void test_getaddrinfo(void)
         return;
     }
     memset(&hint, 0, sizeof(ADDRINFOA));
+    GetComputerNameExA( ComputerNamePhysicalDnsHostname, name, &size );
 
     result = (ADDRINFOA *)0xdeadbeef;
     WSASetLastError(0xdeadbeef);
@@ -6558,6 +6589,30 @@ static void test_getaddrinfo(void)
     ok(WSAGetLastError() == 0, "expected 0, got %d\n", WSAGetLastError());
     pfreeaddrinfo(result);
 
+    /* try to get information from the computer name, result is the same
+     * as if requesting with an empty host name. */
+    ret = pgetaddrinfo(name, NULL, NULL, &result);
+    ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+
+    ret = pgetaddrinfo("", NULL, NULL, &result2);
+    ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+    compare_addrinfo(result, result2);
+    pfreeaddrinfo(result);
+    pfreeaddrinfo(result2);
+
+    ret = pgetaddrinfo(name, "", NULL, &result);
+    ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+
+    ret = pgetaddrinfo("", "", NULL, &result2);
+    ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError());
+    ok(result != NULL, "GetAddrInfoW failed\n");
+    compare_addrinfo(result, result2);
+    pfreeaddrinfo(result);
+    pfreeaddrinfo(result2);
+
     result = (ADDRINFOA *)0xdeadbeef;
     WSASetLastError(0xdeadbeef);
     ret = pgetaddrinfo("nxdomain.codeweavers.com", NULL, NULL, &result);




More information about the wine-cvs mailing list