ws2_32: Call the completion routine in GetAddrInfoExW.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9d5c801d35
commit
c3bcf83d14
|
@ -6997,6 +6997,7 @@ static struct WS_addrinfo *addrinfo_WtoA(const struct WS_addrinfoW *ai)
|
||||||
struct getaddrinfo_args
|
struct getaddrinfo_args
|
||||||
{
|
{
|
||||||
OVERLAPPED *overlapped;
|
OVERLAPPED *overlapped;
|
||||||
|
LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine;
|
||||||
ADDRINFOEXW **result;
|
ADDRINFOEXW **result;
|
||||||
char *nodename;
|
char *nodename;
|
||||||
char *servname;
|
char *servname;
|
||||||
|
@ -7007,6 +7008,7 @@ static void WINAPI getaddrinfo_callback(TP_CALLBACK_INSTANCE *instance, void *co
|
||||||
struct getaddrinfo_args *args = context;
|
struct getaddrinfo_args *args = context;
|
||||||
OVERLAPPED *overlapped = args->overlapped;
|
OVERLAPPED *overlapped = args->overlapped;
|
||||||
HANDLE event = overlapped->hEvent;
|
HANDLE event = overlapped->hEvent;
|
||||||
|
LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine = args->completion_routine;
|
||||||
struct WS_addrinfo *res;
|
struct WS_addrinfo *res;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -7023,10 +7025,12 @@ static void WINAPI getaddrinfo_callback(TP_CALLBACK_INSTANCE *instance, void *co
|
||||||
HeapFree(GetProcessHeap(), 0, args);
|
HeapFree(GetProcessHeap(), 0, args);
|
||||||
|
|
||||||
overlapped->Internal = ret;
|
overlapped->Internal = ret;
|
||||||
|
if (completion_routine) completion_routine(ret, 0, overlapped);
|
||||||
if (event) SetEvent(event);
|
if (event) SetEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WS_getaddrinfoW(const WCHAR *nodename, const WCHAR *servname, const struct WS_addrinfo *hints, ADDRINFOEXW **res, OVERLAPPED *overlapped)
|
static int WS_getaddrinfoW(const WCHAR *nodename, const WCHAR *servname, const struct WS_addrinfo *hints, ADDRINFOEXW **res,
|
||||||
|
OVERLAPPED *overlapped, LPLOOKUPSERVICE_COMPLETION_ROUTINE completion_routine)
|
||||||
{
|
{
|
||||||
int ret = EAI_MEMORY, len, i;
|
int ret = EAI_MEMORY, len, i;
|
||||||
char *nodenameA = NULL, *servnameA = NULL;
|
char *nodenameA = NULL, *servnameA = NULL;
|
||||||
|
@ -7082,8 +7086,15 @@ static int WS_getaddrinfoW(const WCHAR *nodename, const WCHAR *servname, const s
|
||||||
{
|
{
|
||||||
struct getaddrinfo_args *args;
|
struct getaddrinfo_args *args;
|
||||||
|
|
||||||
|
if (overlapped->hEvent && completion_routine)
|
||||||
|
{
|
||||||
|
ret = WSAEINVAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(args = HeapAlloc(GetProcessHeap(), 0, sizeof(*args)))) goto end;
|
if (!(args = HeapAlloc(GetProcessHeap(), 0, sizeof(*args)))) goto end;
|
||||||
args->overlapped = overlapped;
|
args->overlapped = overlapped;
|
||||||
|
args->completion_routine = completion_routine;
|
||||||
args->result = res;
|
args->result = res;
|
||||||
args->nodename = nodenameA;
|
args->nodename = nodenameA;
|
||||||
args->servname = servnameA;
|
args->servname = servnameA;
|
||||||
|
@ -7096,7 +7107,6 @@ static int WS_getaddrinfoW(const WCHAR *nodename, const WCHAR *servname, const s
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (local_nodenameW != nodename)
|
if (local_nodenameW != nodename)
|
||||||
HeapFree(GetProcessHeap(), 0, local_nodenameW);
|
HeapFree(GetProcessHeap(), 0, local_nodenameW);
|
||||||
WSASetLastError(ERROR_IO_PENDING);
|
WSASetLastError(ERROR_IO_PENDING);
|
||||||
|
@ -7138,12 +7148,10 @@ int WINAPI GetAddrInfoExW(const WCHAR *name, const WCHAR *servname, DWORD namesp
|
||||||
FIXME("Unsupported hints\n");
|
FIXME("Unsupported hints\n");
|
||||||
if (timeout)
|
if (timeout)
|
||||||
FIXME("Unsupported timeout\n");
|
FIXME("Unsupported timeout\n");
|
||||||
if (completion_routine)
|
|
||||||
FIXME("Unsupported completion_routine\n");
|
|
||||||
if (handle)
|
if (handle)
|
||||||
FIXME("Unsupported cancel handle\n");
|
FIXME("Unsupported cancel handle\n");
|
||||||
|
|
||||||
ret = WS_getaddrinfoW(name, servname, NULL, result, overlapped);
|
ret = WS_getaddrinfoW(name, servname, NULL, result, overlapped, completion_routine);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
if (handle) *handle = (HANDLE)0xdeadbeef;
|
if (handle) *handle = (HANDLE)0xdeadbeef;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -7181,7 +7189,7 @@ int WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hin
|
||||||
|
|
||||||
*res = NULL;
|
*res = NULL;
|
||||||
if (hints) hintsA = addrinfo_WtoA(hints);
|
if (hints) hintsA = addrinfo_WtoA(hints);
|
||||||
ret = WS_getaddrinfoW(nodename, servname, hintsA, &resex, NULL);
|
ret = WS_getaddrinfoW(nodename, servname, hintsA, &resex, NULL, NULL);
|
||||||
WS_freeaddrinfo(hintsA);
|
WS_freeaddrinfo(hintsA);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
|
|
||||||
|
|
|
@ -7617,11 +7617,36 @@ static void test_GetAddrInfoW(void)
|
||||||
ok(result2 == NULL, "got %p\n", result2);
|
ok(result2 == NULL, "got %p\n", result2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct completion_routine_test
|
||||||
|
{
|
||||||
|
WSAOVERLAPPED *overlapped;
|
||||||
|
DWORD error;
|
||||||
|
ADDRINFOEXW **result;
|
||||||
|
HANDLE event;
|
||||||
|
DWORD called;
|
||||||
|
} completion_routine_test;
|
||||||
|
|
||||||
|
static void CALLBACK completion_routine(DWORD error, DWORD byte_count, WSAOVERLAPPED *overlapped)
|
||||||
|
{
|
||||||
|
struct completion_routine_test *test = &completion_routine_test;
|
||||||
|
|
||||||
|
ok(error == test->error, "got %u\n", error);
|
||||||
|
ok(!byte_count, "got %u\n", byte_count);
|
||||||
|
ok(overlapped == test->overlapped, "got %p\n", overlapped);
|
||||||
|
ok(overlapped->Internal == test->error, "got %lu\n", overlapped->Internal);
|
||||||
|
ok(overlapped->Pointer == test->result, "got %p\n", overlapped->Pointer);
|
||||||
|
ok(overlapped->hEvent == NULL, "got %p\n", overlapped->hEvent);
|
||||||
|
|
||||||
|
test->called++;
|
||||||
|
SetEvent(test->event);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_GetAddrInfoExW(void)
|
static void test_GetAddrInfoExW(void)
|
||||||
{
|
{
|
||||||
static const WCHAR empty[] = {0};
|
static const WCHAR empty[] = {0};
|
||||||
static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0};
|
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 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;
|
||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
|
@ -7706,6 +7731,53 @@ static void test_GetAddrInfoExW(void)
|
||||||
todo_wine_if(ret != WAIT_TIMEOUT) /* Remove when abowe todo_wines are fixed */
|
todo_wine_if(ret != WAIT_TIMEOUT) /* Remove when abowe todo_wines are fixed */
|
||||||
ok(ret == WAIT_TIMEOUT, "wait failed\n");
|
ok(ret == WAIT_TIMEOUT, "wait failed\n");
|
||||||
|
|
||||||
|
/* event + completion routine */
|
||||||
|
result = (void*)0xdeadbeef;
|
||||||
|
memset(&overlapped, 0xcc, sizeof(overlapped));
|
||||||
|
overlapped.hEvent = event;
|
||||||
|
ResetEvent(event);
|
||||||
|
ret = pGetAddrInfoExW(localhost, NULL, NS_DNS, NULL, NULL, &result, NULL, &overlapped, completion_routine, NULL);
|
||||||
|
ok(ret == WSAEINVAL, "GetAddrInfoExW failed with %d\n", WSAGetLastError());
|
||||||
|
|
||||||
|
/* completion routine, existing domain */
|
||||||
|
result = (void *)0xdeadbeef;
|
||||||
|
overlapped.hEvent = NULL;
|
||||||
|
completion_routine_test.overlapped = &overlapped;
|
||||||
|
completion_routine_test.error = ERROR_SUCCESS;
|
||||||
|
completion_routine_test.result = &result;
|
||||||
|
completion_routine_test.event = event;
|
||||||
|
completion_routine_test.called = 0;
|
||||||
|
ResetEvent(event);
|
||||||
|
ret = pGetAddrInfoExW(winehq, NULL, NS_DNS, NULL, NULL, &result, NULL, &overlapped, completion_routine, NULL);
|
||||||
|
ok(ret == ERROR_IO_PENDING, "GetAddrInfoExW failed with %d\n", WSAGetLastError());
|
||||||
|
ok(!result, "result != NULL\n");
|
||||||
|
ok(WaitForSingleObject(event, 1000) == WAIT_OBJECT_0, "wait failed\n");
|
||||||
|
ret = pGetAddrInfoExOverlappedResult(&overlapped);
|
||||||
|
ok(!ret, "overlapped result is %d\n", ret);
|
||||||
|
ok(overlapped.hEvent == NULL, "hEvent changed %p\n", overlapped.hEvent);
|
||||||
|
ok(overlapped.Internal == ERROR_SUCCESS, "overlapped.Internal = %lx\n", overlapped.Internal);
|
||||||
|
ok(overlapped.Pointer == &result, "overlapped.Pointer != &result\n");
|
||||||
|
ok(completion_routine_test.called == 1, "got %u\n", completion_routine_test.called);
|
||||||
|
pFreeAddrInfoExW(result);
|
||||||
|
|
||||||
|
/* completion routine, non-existing domain */
|
||||||
|
result = (void *)0xdeadbeef;
|
||||||
|
completion_routine_test.overlapped = &overlapped;
|
||||||
|
completion_routine_test.error = WSAHOST_NOT_FOUND;
|
||||||
|
completion_routine_test.called = 0;
|
||||||
|
ResetEvent(event);
|
||||||
|
ret = pGetAddrInfoExW(nxdomain, NULL, NS_DNS, NULL, NULL, &result, NULL, &overlapped, completion_routine, NULL);
|
||||||
|
ok(ret == ERROR_IO_PENDING, "GetAddrInfoExW failed with %d\n", WSAGetLastError());
|
||||||
|
ok(!result, "result != NULL\n");
|
||||||
|
ok(WaitForSingleObject(event, 1000) == WAIT_OBJECT_0, "wait failed\n");
|
||||||
|
ret = pGetAddrInfoExOverlappedResult(&overlapped);
|
||||||
|
ok(ret == WSAHOST_NOT_FOUND, "overlapped result is %d\n", ret);
|
||||||
|
ok(overlapped.hEvent == NULL, "hEvent changed %p\n", overlapped.hEvent);
|
||||||
|
ok(overlapped.Internal == WSAHOST_NOT_FOUND, "overlapped.Internal = %lx\n", overlapped.Internal);
|
||||||
|
ok(overlapped.Pointer == &result, "overlapped.Pointer != &result\n");
|
||||||
|
ok(completion_routine_test.called == 1, "got %u\n", completion_routine_test.called);
|
||||||
|
ok(result == NULL, "got %p\n", result);
|
||||||
|
|
||||||
WSACloseEvent(event);
|
WSACloseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue