ws2_32/tests: Add more SIO_ADDRESS_LIST_CHANGE tests.

Signed-off-by: Bruno Jesus <00cpxxx@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Bruno Jesus 2016-09-09 00:28:52 -03:00 committed by Alexandre Julliard
parent 637738f472
commit 77b391125f
2 changed files with 90 additions and 29 deletions

View File

@ -8349,8 +8349,9 @@ static void test_sioAddressListChange(void)
struct in_addr net_address; struct in_addr net_address;
WSAOVERLAPPED overlapped; WSAOVERLAPPED overlapped;
struct hostent *h; struct hostent *h;
DWORD num_bytes, error; DWORD num_bytes, error, tick;
SOCKET sock; SOCKET sock, sock2, sock3;
WSAEVENT event2, event3;
int acount; int acount;
int ret; int ret;
@ -8397,9 +8398,6 @@ todo_wine
sock = socket(AF_INET, 0, IPPROTO_TCP); sock = socket(AF_INET, 0, IPPROTO_TCP);
ok(sock != INVALID_SOCKET, "socket() failed\n"); ok(sock != INVALID_SOCKET, "socket() failed\n");
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_addr.s_addr = net_address.s_addr;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
ok (!ret, "bind() failed with error %d\n", GetLastError()); ok (!ret, "bind() failed with error %d\n", GetLastError());
@ -8419,9 +8417,6 @@ todo_wine
sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
ok(sock != INVALID_SOCKET, "socket() failed\n"); ok(sock != INVALID_SOCKET, "socket() failed\n");
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_addr.s_addr = net_address.s_addr;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
ok (!ret, "bind() failed with error %d\n", GetLastError()); ok (!ret, "bind() failed with error %d\n", GetLastError());
@ -8442,9 +8437,6 @@ todo_wine
sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
ok(sock != INVALID_SOCKET, "socket() failed\n"); ok(sock != INVALID_SOCKET, "socket() failed\n");
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_addr.s_addr = net_address.s_addr;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
ok (!ret, "bind() failed with error %d\n", GetLastError()); ok (!ret, "bind() failed with error %d\n", GetLastError());
@ -8461,6 +8453,40 @@ todo_wine
CloseHandle(overlapped.hEvent); CloseHandle(overlapped.hEvent);
closesocket(sock); closesocket(sock);
/* When the socket is overlapped non-blocking and the list change is requested without
* an overlapped structure the error will be different. */
sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
ok(sock != INVALID_SOCKET, "socket() failed\n");
SetLastError(0xdeadbeef);
ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
ok (!ret, "bind() failed with error %d\n", GetLastError());
set_blocking(sock, FALSE);
SetLastError(0xdeadbeef);
ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
error = GetLastError();
ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
ok (error == WSAEWOULDBLOCK, "expected 10035, got %d\n", error);
closesocket(sock);
/* Misuse of the API by using a blocking socket and not using an overlapped structure,
* this leads to a hang forever. */
if (0)
{
sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
SetLastError(0xdeadbeef);
bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
set_blocking(sock, TRUE);
WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
/* hang */
closesocket(sock);
}
if (!winetest_interactive) if (!winetest_interactive)
{ {
skip("Cannot test SIO_ADDRESS_LIST_CHANGE, interactive tests must be enabled\n"); skip("Cannot test SIO_ADDRESS_LIST_CHANGE, interactive tests must be enabled\n");
@ -8470,35 +8496,61 @@ todo_wine
/* Bind an overlapped socket to the first found network interface */ /* Bind an overlapped socket to the first found network interface */
sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n"); ok(sock != INVALID_SOCKET, "Expected socket to return a valid socket\n");
if (sock == INVALID_SOCKET) sock2 = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
{ ok(sock2 != INVALID_SOCKET, "Expected socket to return a valid socket\n");
skip("Cannot test SIO_ADDRESS_LIST_CHANGE, socket creation failed with %u\n", sock3 = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
WSAGetLastError()); ok(sock3 != INVALID_SOCKET, "Expected socket to return a valid socket\n");
return;
}
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_addr.s_addr = net_address.s_addr;
ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); ret = bind(sock, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
if (ret != 0) ok(!ret, "bind failed unexpectedly\n");
{ ret = bind(sock2, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
skip("Cannot test SIO_ADDRESS_LIST_CHANGE, failed to bind, error %u\n", WSAGetLastError()); ok(!ret, "bind failed unexpectedly\n");
goto end; ret = bind(sock3, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
} ok(!ret, "bind failed unexpectedly\n");
set_blocking(sock2, FALSE);
set_blocking(sock3, FALSE);
/* Wait for address changes, request that the user connects/disconnects an interface */ /* Wait for address changes, request that the user connects/disconnects an interface */
memset(&overlapped, 0, sizeof(overlapped)); memset(&overlapped, 0, sizeof(overlapped));
overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL); ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n"); ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
ok(WSAGetLastError() == WSA_IO_PENDING, "Expected pending last error %d\n", WSAGetLastError()); ok(WSAGetLastError() == WSA_IO_PENDING, "Expected pending last error, got %d\n", WSAGetLastError());
ret = WSAIoctl(sock2, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, NULL, NULL);
ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
ok(WSAGetLastError() == WSAEWOULDBLOCK, "Expected would block last error, got %d\n", WSAGetLastError());
event2 = WSACreateEvent();
event3 = WSACreateEvent();
ret = WSAEventSelect (sock2, event2, FD_ADDRESS_LIST_CHANGE);
ok(!ret, "WSAEventSelect failed with %d\n", WSAGetLastError());
/* sock3 did not request SIO_ADDRESS_LIST_CHANGE but it is trying to wait anyway */
ret = WSAEventSelect (sock3, event3, FD_ADDRESS_LIST_CHANGE);
ok(!ret, "WSAEventSelect failed with %d\n", WSAGetLastError());
trace("Testing socket-based ipv4 address list change notification. Please connect/disconnect or" trace("Testing socket-based ipv4 address list change notification. Please connect/disconnect or"
" change the ipv4 address of any of the local network interfaces (10 second timeout).\n"); " change the ipv4 address of any of the local network interfaces (15 second timeout).\n");
ret = WaitForSingleObject(overlapped.hEvent, 10000); tick = GetTickCount();
ret = WaitForSingleObject(overlapped.hEvent, 15000);
ok(ret == WAIT_OBJECT_0, "failed to get overlapped event %u\n", ret); ok(ret == WAIT_OBJECT_0, "failed to get overlapped event %u\n", ret);
end: ret = WaitForSingleObject(event2, 500);
todo_wine
ok(ret == WAIT_OBJECT_0, "failed to get change event %u\n", ret);
ret = WaitForSingleObject(event3, 500);
ok(ret == WAIT_TIMEOUT, "unexpected change event\n");
trace("Spent %d ms waiting.\n", GetTickCount() - tick);
WSACloseEvent(event2);
WSACloseEvent(event3);
closesocket(sock); closesocket(sock);
closesocket(sock2);
closesocket(sock3);
} }
static void test_synchronous_WSAIoctl(void) static void test_synchronous_WSAIoctl(void)

View File

@ -101,6 +101,15 @@ extern "C" {
#define FD_ACCEPT_BIT 3 #define FD_ACCEPT_BIT 3
#define FD_CONNECT_BIT 4 #define FD_CONNECT_BIT 4
#define FD_CLOSE_BIT 5 #define FD_CLOSE_BIT 5
#define FD_QOS_BIT 6
#define FD_GROUP_QOS_BIT 7
#define FD_ROUTING_INTERFACE_CHANGE_BIT 8
#define FD_ADDRESS_LIST_CHANGE_BIT 9
#define FD_QOS 0x00000040
#define FD_GROUP_QOS 0x00000080
#define FD_ROUTING_INTERFACE_CHANGE 0x00000100
#define FD_ADDRESS_LIST_CHANGE 0x00000200
/* Constants for LPCONDITIONPROC */ /* Constants for LPCONDITIONPROC */
#define CF_ACCEPT 0x0000 #define CF_ACCEPT 0x0000