Hans Leidekker : ws2_32: Implement GetAddrInfoW and FreeAddrInfoW.
Alexandre Julliard
julliard at winehq.org
Mon Apr 27 08:04:05 CDT 2009
Module: wine
Branch: master
Commit: fea6d0a76413c7285297d6bbeeba81c5481d0147
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fea6d0a76413c7285297d6bbeeba81c5481d0147
Author: Hans Leidekker <hans at codeweavers.com>
Date: Fri Apr 24 16:01:56 2009 +0200
ws2_32: Implement GetAddrInfoW and FreeAddrInfoW.
---
dlls/ws2_32/socket.c | 140 +++++++++++++++++++++++++++++++++++++++++++++-
dlls/ws2_32/tests/sock.c | 27 +++++++++
dlls/ws2_32/ws2_32.spec | 1 +
3 files changed, 166 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 9324833..42bab60 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3583,13 +3583,149 @@ outofmem:
#endif
}
+static struct WS_addrinfoW *addrinfo_AtoW(const struct WS_addrinfo *ai)
+{
+ struct WS_addrinfoW *ret;
+
+ if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_addrinfoW)))) return NULL;
+ ret->ai_flags = ai->ai_flags;
+ ret->ai_family = ai->ai_family;
+ ret->ai_socktype = ai->ai_socktype;
+ ret->ai_protocol = ai->ai_protocol;
+ ret->ai_addrlen = ai->ai_addrlen;
+ ret->ai_canonname = NULL;
+ ret->ai_addr = NULL;
+ ret->ai_next = NULL;
+ if (ai->ai_canonname)
+ {
+ int len = MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0);
+ if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len)))
+ {
+ HeapFree(GetProcessHeap(), 0, ret);
+ return NULL;
+ }
+ MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len);
+ }
+ if (ai->ai_addr)
+ {
+ if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_sockaddr))))
+ {
+ HeapFree(GetProcessHeap(), 0, ret->ai_canonname);
+ HeapFree(GetProcessHeap(), 0, ret);
+ return NULL;
+ }
+ memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct WS_sockaddr));
+ }
+ return ret;
+}
+
+static struct WS_addrinfoW *addrinfo_list_AtoW(const struct WS_addrinfo *info)
+{
+ struct WS_addrinfoW *ret, *infoW;
+
+ if (!(ret = infoW = addrinfo_AtoW(info))) return NULL;
+ while (info->ai_next)
+ {
+ if (!(infoW->ai_next = addrinfo_AtoW(info->ai_next)))
+ {
+ FreeAddrInfoW(ret);
+ return NULL;
+ }
+ infoW = infoW->ai_next;
+ info = info->ai_next;
+ }
+ return ret;
+}
+
+static struct WS_addrinfo *addrinfo_WtoA(const struct WS_addrinfoW *ai)
+{
+ struct WS_addrinfo *ret;
+
+ if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_addrinfo)))) return NULL;
+ ret->ai_flags = ai->ai_flags;
+ ret->ai_family = ai->ai_family;
+ ret->ai_socktype = ai->ai_socktype;
+ ret->ai_protocol = ai->ai_protocol;
+ ret->ai_addrlen = ai->ai_addrlen;
+ ret->ai_canonname = NULL;
+ ret->ai_addr = NULL;
+ ret->ai_next = NULL;
+ if (ai->ai_canonname)
+ {
+ int len = WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0, NULL, NULL);
+ if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len)))
+ {
+ HeapFree(GetProcessHeap(), 0, ret);
+ return NULL;
+ }
+ WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len, NULL, NULL);
+ }
+ if (ai->ai_addr)
+ {
+ if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_sockaddr))))
+ {
+ HeapFree(GetProcessHeap(), 0, ret->ai_canonname);
+ HeapFree(GetProcessHeap(), 0, ret);
+ return NULL;
+ }
+ memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct WS_sockaddr));
+ }
+ return ret;
+}
+
/***********************************************************************
* GetAddrInfoW (WS2_32.@)
*/
int WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hints, PADDRINFOW *res)
{
- FIXME("empty stub!\n");
- return EAI_FAIL;
+ int ret, len;
+ char *nodenameA, *servnameA = NULL;
+ struct WS_addrinfo *resA, *hintsA = NULL;
+
+ len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL);
+ if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY;
+ WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL);
+
+ if (servname)
+ {
+ len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL);
+ if (!(servnameA = HeapAlloc(GetProcessHeap(), 0, len)))
+ {
+ HeapFree(GetProcessHeap(), 0, nodenameA);
+ return EAI_MEMORY;
+ }
+ WideCharToMultiByte(CP_ACP, 0, servname, -1, servnameA, len, NULL, NULL);
+ }
+
+ if (hints) hintsA = addrinfo_WtoA(hints);
+ ret = WS_getaddrinfo(nodenameA, servnameA, hintsA, &resA);
+ WS_freeaddrinfo(hintsA);
+
+ if (!ret)
+ {
+ *res = addrinfo_list_AtoW(resA);
+ WS_freeaddrinfo(resA);
+ }
+
+ HeapFree(GetProcessHeap(), 0, nodenameA);
+ HeapFree(GetProcessHeap(), 0, servnameA);
+ return ret;
+}
+
+/***********************************************************************
+ * FreeAddrInfoW (WS2_32.@)
+ */
+void WINAPI FreeAddrInfoW(PADDRINFOW ai)
+{
+ while (ai)
+ {
+ ADDRINFOW *next;
+ HeapFree(GetProcessHeap(), 0, ai->ai_canonname);
+ HeapFree(GetProcessHeap(), 0, ai->ai_addr);
+ next = ai->ai_next;
+ HeapFree(GetProcessHeap(), 0, ai);
+ ai = next;
+ }
}
int WINAPI WS_getnameinfo(const SOCKADDR *sa, WS_socklen_t salen, PCHAR host,
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 23aa59c..dbd43d8 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -2310,6 +2310,32 @@ static void test_WSASendTo(void)
"a successful call to WSASendTo()\n");
}
+static void test_GetAddrInfoW(void)
+{
+ static const WCHAR port[] = {'8','0',0};
+ static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0};
+
+ int ret;
+ ADDRINFOW *result, hint;
+
+ memset(&hint, 0, sizeof(ADDRINFOW));
+
+ ret = GetAddrInfoW(NULL, NULL, NULL, &result);
+ ok(ret == WSAHOST_NOT_FOUND, "got %d expected WSAHOST_NOT_FOUND\n", ret);
+
+ ret = GetAddrInfoW(localhost, NULL, NULL, &result);
+ ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+ FreeAddrInfoW(result);
+
+ ret = GetAddrInfoW(localhost, port, NULL, &result);
+ ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+ FreeAddrInfoW(result);
+
+ ret = GetAddrInfoW(localhost, port, &hint, &result);
+ ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError());
+ FreeAddrInfoW(result);
+}
+
/**************** Main program ***************/
START_TEST( sock )
@@ -2353,6 +2379,7 @@ START_TEST( sock )
test_WSASendTo();
test_ipv6only();
+ test_GetAddrInfoW();
Exit();
}
diff --git a/dlls/ws2_32/ws2_32.spec b/dlls/ws2_32/ws2_32.spec
index 74e71be..a77c215 100644
--- a/dlls/ws2_32/ws2_32.spec
+++ b/dlls/ws2_32/ws2_32.spec
@@ -50,6 +50,7 @@
500 stub WEP
+@ stdcall FreeAddrInfoW(ptr)
@ stdcall GetAddrInfoW(wstr wstr ptr ptr)
@ stdcall WSApSetPostRoutine(ptr)
@ stdcall WPUCompleteOverlappedRequest(long ptr long long ptr)
More information about the wine-cvs
mailing list