ws2_32: Implement GetAddrInfoW and FreeAddrInfoW.
This commit is contained in:
parent
3e6d0789d0
commit
fea6d0a764
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue