From: Qian Hong Subject: [PATCH] ws2_32: Improved error handling in gethostname when name length is insufficient. Message-Id: <55004704.4050406@codeweavers.com> Date: Wed, 11 Mar 2015 21:45:40 +0800 Windows supports NetBIOS name length max to 15, don't fail silently for Windows application with insufficient name length. --- dlls/ws2_32/socket.c | 31 +++++++++++++++++++++++++------ dlls/ws2_32/tests/sock.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index a9f60cc..9cfd5e8 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -6056,16 +6056,35 @@ struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto) */ int WINAPI WS_gethostname(char *name, int namelen) { + char buf[HOST_NAME_MAX]; + int len; + TRACE("name %p, len %d\n", name, namelen); - if (gethostname(name, namelen) == 0) + if (!name) { - TRACE("<- '%s'\n", name); - return 0; + SetLastError(WSAEFAULT); + return SOCKET_ERROR; } - SetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno()); - TRACE("<- ERROR !\n"); - return SOCKET_ERROR; + + if (gethostname(buf, HOST_NAME_MAX) != 0) + { + SetLastError(wsaErrno()); + return SOCKET_ERROR; + } + + TRACE("<- '%s'\n", buf); + len = strlen(buf); + if (len > 15) + WARN("Windows supports NetBIOS name length max to 15!\n"); + if (namelen < len) + { + SetLastError(WSAEFAULT); + WARN("<- name length not enough!\n"); + return SOCKET_ERROR; + } + strcpy(name, buf); + return 0; } diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index f27d522..69b9449 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4193,6 +4193,34 @@ static void test_gethostbyname_hack(void) * resolve nonexistent host names to addresses of the ISP's spam pages. */ } +static void test_gethostname(void) +{ + struct hostent *he; + char name[256]; + int ret, len; + + WSASetLastError(0xdeadbeef); + ret = gethostname(NULL, 256); + ok(ret == -1, "gethostname() returned %d\n", ret); + ok(WSAGetLastError() == WSAEFAULT, "gethostname with null buffer " + "failed with %d, expected %d\n", WSAGetLastError(), WSAEFAULT); + + ret = gethostname(name, 256); + ok(ret == 0, "gethostname() call failed: %d\n", WSAGetLastError()); + + he = gethostbyname(name); + ok(he != NULL, "gethostbyname(\"%s\") failed: %d\n", name, WSAGetLastError()); + + WSASetLastError(0xdeadbeef); + len = strlen(name) - 1; + strcpy(name, "deadbeef"); + ret = gethostname(name, len); + ok(ret == -1, "gethostname() returned %d\n", ret); + ok(!strcmp(name, "deadbeef"), "name changed unexpected!\n"); + ok(WSAGetLastError() == WSAEFAULT, "gethostname with insufficient length " + "failed with %d, expected %d\n", WSAGetLastError(), WSAEFAULT); +} + static void test_inet_addr(void) { u_long addr; @@ -8381,6 +8409,7 @@ START_TEST( sock ) test_ioctlsocket(); test_dns(); test_gethostbyname_hack(); + test_gethostname(); test_WSASendMsg(); test_WSASendTo();