mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch for support of ws2_32.dll.WSAPoll.
This commit is contained in:
parent
92379575c7
commit
7cad745ad6
@ -39,12 +39,13 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
-----------------------------------
|
||||
|
||||
**Bug fixes and features included in the next upcoming release [4]:**
|
||||
**Bug fixes and features included in the next upcoming release [5]:**
|
||||
|
||||
* Add shell32 placeholder icons to match offsets with Windows ([Wine Bug #30185](https://bugs.winehq.org/show_bug.cgi?id=30185))
|
||||
* Add stubbed ISWbemSecurity interfaces in wbemdisp
|
||||
* Also handle '\r' as whitespace in wbemprox queries
|
||||
* Assign a drive serial number during prefix creation/update ([Wine Bug #17823](https://bugs.winehq.org/show_bug.cgi?id=17823))
|
||||
* Support for ws2_32.dll.WSAPoll ([Wine Bug #38601](https://bugs.winehq.org/show_bug.cgi?id=38601))
|
||||
|
||||
|
||||
**Bug fixes and features in Wine Staging 1.7.43 [235]:**
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -3,6 +3,7 @@ wine-staging (1.7.44) UNRELEASED; urgency=low
|
||||
* Added patch with stubbed ISWbemSecurity interfaces in wbemdisp.
|
||||
* Added patch with shell32 placeholder icons to match offsets with Windows.
|
||||
* Added patch to assign a drive serial number during prefix creation/update.
|
||||
* Added patch for support of ws2_32.dll.WSAPoll.
|
||||
* Removed patch to reset device state in SysKeyboard*Impl_Acquire (accepted
|
||||
upstream).
|
||||
* Removed patch to avoid creating thread queues for foreign threads in
|
||||
|
@ -275,6 +275,7 @@ patch_enable_all ()
|
||||
enable_ws2_32_APC_Performance="$1"
|
||||
enable_ws2_32_Connect_Time="$1"
|
||||
enable_ws2_32_TransmitFile="$1"
|
||||
enable_ws2_32_WSAPoll="$1"
|
||||
enable_ws2_32_WriteWatches="$1"
|
||||
enable_ws2_32_getaddrinfo="$1"
|
||||
enable_wtsapi32_EnumerateProcesses="$1"
|
||||
@ -884,6 +885,9 @@ patch_enable ()
|
||||
ws2_32-TransmitFile)
|
||||
enable_ws2_32_TransmitFile="$2"
|
||||
;;
|
||||
ws2_32-WSAPoll)
|
||||
enable_ws2_32_WSAPoll="$2"
|
||||
;;
|
||||
ws2_32-WriteWatches)
|
||||
enable_ws2_32_WriteWatches="$2"
|
||||
;;
|
||||
@ -5674,6 +5678,25 @@ if test "$enable_ws2_32_TransmitFile" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ws2_32-WSAPoll
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#38601] Support for ws2_32.dll.WSAPoll
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c, dlls/ws2_32/ws2_32.spec, include/winsock2.h
|
||||
# |
|
||||
if test "$enable_ws2_32_WSAPoll" -eq 1; then
|
||||
patch_apply ws2_32-WSAPoll/0001-include-Add-stuff-related-to-WSAPoll-try-2.patch
|
||||
patch_apply ws2_32-WSAPoll/0002-ws2_32-tests-Add-WSAPoll-tests.patch
|
||||
patch_apply ws2_32-WSAPoll/0003-ws2_32-Add-WSAPoll-implementation.patch
|
||||
(
|
||||
echo '+ { "Bruno Jesus", "include: Add stuff related to WSAPoll().", 2 },';
|
||||
echo '+ { "Bruno Jesus", "ws2_32/tests: Add WSAPoll() tests.", 1 },';
|
||||
echo '+ { "Bruno Jesus", "ws2_32: Add WSAPoll() implementation.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ws2_32-getaddrinfo
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -0,0 +1,81 @@
|
||||
From bf1a093e98df52aa4576c93f3e0e165fdf73e1e4 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Jesus <00cpxxx@gmail.com>
|
||||
Date: Fri, 22 May 2015 22:42:53 -0300
|
||||
Subject: include: Add stuff related to WSAPoll() (try 2)
|
||||
|
||||
try 2:
|
||||
I found the solution to typedef the struct pollfd just like it's done
|
||||
with fd_set.
|
||||
---
|
||||
include/winsock2.h | 34 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 34 insertions(+)
|
||||
|
||||
diff --git a/include/winsock2.h b/include/winsock2.h
|
||||
index fa3d26b..c90d0f6 100644
|
||||
--- a/include/winsock2.h
|
||||
+++ b/include/winsock2.h
|
||||
@@ -112,6 +112,31 @@ extern "C" {
|
||||
#define SD_SEND 0x01
|
||||
#define SD_BOTH 0x02
|
||||
|
||||
+/* Constants for WSAPoll() */
|
||||
+#ifndef USE_WS_PREFIX
|
||||
+#define POLLERR 0x0001
|
||||
+#define POLLHUP 0x0002
|
||||
+#define POLLNVAL 0x0004
|
||||
+#define POLLWRNORM 0x0010
|
||||
+#define POLLWRBAND 0x0020
|
||||
+#define POLLRDNORM 0x0100
|
||||
+#define POLLRDBAND 0x0200
|
||||
+#define POLLPRI 0x0400
|
||||
+#define POLLIN (POLLRDNORM|POLLRDBAND)
|
||||
+#define POLLOUT (POLLWRNORM)
|
||||
+#else
|
||||
+#define WS_POLLERR 0x0001
|
||||
+#define WS_POLLHUP 0x0002
|
||||
+#define WS_POLLNVAL 0x0004
|
||||
+#define WS_POLLWRNORM 0x0010
|
||||
+#define WS_POLLWRBAND 0x0020
|
||||
+#define WS_POLLRDNORM 0x0100
|
||||
+#define WS_POLLRDBAND 0x0200
|
||||
+#define WS_POLLPRI 0x0400
|
||||
+#define WS_POLLIN (WS_POLLRDNORM|WS_POLLRDBAND)
|
||||
+#define WS_POLLOUT (WS_POLLWRNORM)
|
||||
+#endif
|
||||
+
|
||||
/* Constants for WSAIoctl() */
|
||||
#ifdef USE_WS_PREFIX
|
||||
#define WS_IOC_UNIX 0x00000000
|
||||
@@ -259,6 +284,13 @@ typedef struct _WSAPROTOCOLCHAIN
|
||||
|
||||
#define SECURITY_PROTOCOL_NONE 0x0000
|
||||
|
||||
+typedef struct /*WS(pollfd)*/
|
||||
+{
|
||||
+ SOCKET fd;
|
||||
+ SHORT events;
|
||||
+ SHORT revents;
|
||||
+} WSAPOLLFD;
|
||||
+
|
||||
#define WSAPROTOCOL_LEN 255
|
||||
typedef struct _WSAPROTOCOL_INFOA
|
||||
{
|
||||
@@ -662,6 +694,7 @@ INT WINAPI WSALookupServiceNextW(HANDLE,DWORD,LPDWORD,LPWSAQUERYSETW);
|
||||
int WINAPI WSANSPIoctl(HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION);
|
||||
int WINAPI WSANtohl(SOCKET,ULONG,ULONG*);
|
||||
int WINAPI WSANtohs(SOCKET,WS(u_short),WS(u_short)*);
|
||||
+int WINAPI WSAPoll(WSAPOLLFD*,ULONG,int);
|
||||
INT WINAPI WSAProviderConfigChange(LPHANDLE,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||
int WINAPI WSARecv(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||
int WINAPI WSARecvDisconnect(SOCKET,LPWSABUF);
|
||||
@@ -736,6 +769,7 @@ typedef int (WINAPI *LPFN_WSANSPIOCTL)(HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LP
|
||||
typedef int (WINAPI *LPFN_WSANTOHL)(SOCKET,ULONG,ULONG*);
|
||||
typedef int (WINAPI *LPFN_WSANTOHS)(SOCKET,WS(u_short),WS(u_short)*);
|
||||
typedef INT (WINAPI *LPFN_WSAPROVIDERCONFIGCHANGE)(LPHANDLE,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||
+typedef int (WINAPI *LPFN_WSAPOLL)(WSAPOLLFD*,ULONG,int);
|
||||
typedef int (WINAPI *LPFN_WSARECV)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||
typedef int (WINAPI *LPFN_WSARECVDISCONNECT)(SOCKET,LPWSABUF);
|
||||
typedef int (WINAPI *LPFN_WSARECVFROM)(SOCKET,LPWSABUF,DWORD,LPDWORD,LPDWORD,struct WS(sockaddr)*,LPINT,LPWSAOVERLAPPED,LPWSAOVERLAPPED_COMPLETION_ROUTINE);
|
||||
--
|
||||
2.4.1
|
||||
|
266
patches/ws2_32-WSAPoll/0002-ws2_32-tests-Add-WSAPoll-tests.patch
Normal file
266
patches/ws2_32-WSAPoll/0002-ws2_32-tests-Add-WSAPoll-tests.patch
Normal file
@ -0,0 +1,266 @@
|
||||
From c550660596dfe05e3b275dec643e5b4ebd2bdb7e Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Jesus <00cpxxx@gmail.com>
|
||||
Date: Fri, 22 May 2015 22:43:00 -0300
|
||||
Subject: ws2_32/tests: Add WSAPoll() tests
|
||||
|
||||
---
|
||||
dlls/ws2_32/tests/sock.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 222 insertions(+)
|
||||
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index 6d328e6..3d584f2 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -71,6 +71,7 @@ static int (WINAPI *pInetPton)(INT,LPSTR,LPVOID);
|
||||
static int (WINAPI *pWSALookupServiceBeginW)(LPWSAQUERYSETW,DWORD,LPHANDLE);
|
||||
static int (WINAPI *pWSALookupServiceEnd)(HANDLE);
|
||||
static int (WINAPI *pWSALookupServiceNextW)(HANDLE,DWORD,LPDWORD,LPWSAQUERYSETW);
|
||||
+static int (WINAPI *pWSAPoll)(WSAPOLLFD *,ULONG,INT);
|
||||
|
||||
/**************** Structs and typedefs ***************/
|
||||
|
||||
@@ -1163,6 +1164,7 @@ static void Init (void)
|
||||
pWSALookupServiceBeginW = (void *)GetProcAddress(hws2_32, "WSALookupServiceBeginW");
|
||||
pWSALookupServiceEnd = (void *)GetProcAddress(hws2_32, "WSALookupServiceEnd");
|
||||
pWSALookupServiceNextW = (void *)GetProcAddress(hws2_32, "WSALookupServiceNextW");
|
||||
+ pWSAPoll = (void *)GetProcAddress(hws2_32, "WSAPoll");
|
||||
|
||||
ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" );
|
||||
tls = TlsAlloc();
|
||||
@@ -6275,6 +6277,225 @@ end:
|
||||
WSACloseEvent(ov.hEvent);
|
||||
}
|
||||
|
||||
+#define POLL_CLEAR() ix = 0
|
||||
+#define POLL_SET(s, ev) {fds[ix].fd = s; fds[ix++].events = ev;}
|
||||
+#define POLL_ISSET(s, rev) poll_isset(fds, ix, s, rev)
|
||||
+static BOOL poll_isset(WSAPOLLFD *fds, int max, SOCKET s, int rev)
|
||||
+{
|
||||
+ int k;
|
||||
+ for (k = 0; k < max; k++)
|
||||
+ if (fds[k].fd == s && (fds[k].revents == rev)) return TRUE;
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+static void test_WSAPoll(void)
|
||||
+{
|
||||
+ int ix, ret, err, poll_timeout;
|
||||
+ SOCKET fdListen, fdRead, fdWrite;
|
||||
+ struct sockaddr_in address;
|
||||
+ socklen_t len;
|
||||
+ static char tmp_buf[1024];
|
||||
+ WSAPOLLFD fds[16];
|
||||
+ HANDLE thread_handle;
|
||||
+ DWORD id;
|
||||
+
|
||||
+ if (!pWSAPoll) /* >= Vista */
|
||||
+ {
|
||||
+ skip("WSAPoll is unsupported, some tests will be skipped.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Invalid parameters test */
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = pWSAPoll(NULL, 0, 0);
|
||||
+ err = GetLastError();
|
||||
+ ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
|
||||
+ ok(err == WSAEINVAL, "expected 10022, got %d\n", err);
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = pWSAPoll(NULL, 1, 0);
|
||||
+ err = GetLastError();
|
||||
+ ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
|
||||
+ ok(err == WSAEFAULT, "expected 10014, got %d\n", err);
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = pWSAPoll(NULL, 0, 1);
|
||||
+ err = GetLastError();
|
||||
+ ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
|
||||
+ ok(err == WSAEINVAL, "expected 10022, got %d\n", err);
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = pWSAPoll(NULL, 1, 1);
|
||||
+ err = GetLastError();
|
||||
+ ok(ret == SOCKET_ERROR, "expected -1, got %d\n", ret);
|
||||
+ ok(err == WSAEFAULT, "expected 10014, got %d\n", err);
|
||||
+
|
||||
+ /* WSAPoll() tries to mime the unix poll() call. The following tests do:
|
||||
+ * - check if a connection attempt ended with success or error;
|
||||
+ * - check if a pending connection is waiting for acceptance;
|
||||
+ * - check for data to read, availability for write and OOB data
|
||||
+ */
|
||||
+ memset(&address, 0, sizeof(address));
|
||||
+ address.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
+ address.sin_family = AF_INET;
|
||||
+ len = sizeof(address);
|
||||
+ fdListen = setup_server_socket(&address, &len);
|
||||
+ poll_timeout = 100;
|
||||
+
|
||||
+ /* When no events are pending poll returns 0 with no error */
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+
|
||||
+ /* Test listening socket connection attempt notifications */
|
||||
+ fdWrite = setup_connector_socket(&address, len, TRUE);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN | POLLOUT);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdListen, POLLRDNORM), "fdListen socket events incorrect\n");
|
||||
+ len = sizeof(address);
|
||||
+ fdRead = accept(fdListen, (struct sockaddr*) &address, &len);
|
||||
+ ok(fdRead != INVALID_SOCKET, "expected a valid socket\n");
|
||||
+
|
||||
+ /* Test client side connection attempt notifications */
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdRead, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 2, "expected 2, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdWrite, POLLWRNORM), "fdWrite socket events incorrect\n");
|
||||
+ ok(POLL_ISSET(fdRead, POLLWRNORM), "fdRead socket events incorrect\n");
|
||||
+ len = sizeof(id);
|
||||
+ id = 0xdeadbeef;
|
||||
+ ok(!getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char*)&id, &len),
|
||||
+ "getsockopt failed with %d\n",WSAGetLastError());
|
||||
+ ok(id == 0, "expected 0, got %d\n", id);
|
||||
+
|
||||
+ /* Test data receiving notifications */
|
||||
+ ret = send(fdWrite, "1234", 4, 0);
|
||||
+ ok(ret == 4, "expected 4, got %d\n", ret);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdRead, POLLIN);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdRead, POLLRDNORM), "fdRead socket events incorrect\n");
|
||||
+ ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), 0);
|
||||
+ ok(ret == 4, "expected 4, got %d\n", ret);
|
||||
+ ok(!strcmp(tmp_buf, "1234"), "data received differs from sent\n");
|
||||
+
|
||||
+ /* Test OOB data notifications */
|
||||
+ ret = send(fdWrite, "A", 1, MSG_OOB);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdRead, POLLIN);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdRead, POLLRDBAND), "fdRead socket events incorrect\n");
|
||||
+ tmp_buf[0] = 0xAF;
|
||||
+ ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), MSG_OOB);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(tmp_buf[0] == 'A', "expected 'A', got 0x%02X\n", tmp_buf[0]);
|
||||
+
|
||||
+ /* If the socket is OOBINLINED the notification is like normal data */
|
||||
+ ret = 1;
|
||||
+ ret = setsockopt(fdRead, SOL_SOCKET, SO_OOBINLINE, (char*) &ret, sizeof(ret));
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+ ret = send(fdWrite, "A", 1, MSG_OOB);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdRead, POLLIN | POLLOUT);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ tmp_buf[0] = 0xAF;
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), MSG_OOB);
|
||||
+ ok(ret == SOCKET_ERROR, "expected -1, got %d", ret);
|
||||
+ ok(GetLastError() == WSAEINVAL, "expected 10022, got %d\n", GetLastError());
|
||||
+ ret = recv(fdRead, tmp_buf, sizeof(tmp_buf), 0);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(tmp_buf[0] == 'A', "expected 'A', got 0x%02X\n", tmp_buf[0]);
|
||||
+
|
||||
+ /* Test connection closed notifications */
|
||||
+ ret = closesocket(fdRead);
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdListen, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdWrite, POLLIN);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdWrite, POLLHUP), "fdWrite socket events incorrect\n");
|
||||
+ ret = recv(fdWrite, tmp_buf, sizeof(tmp_buf), 0);
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+
|
||||
+ /* When a connection is attempted to a non-listening socket due to a bug
|
||||
+ * in the MS code it will never be notified. This is a long standing issue
|
||||
+ * that will never be fixed for compatibility reasons so we have to deal
|
||||
+ * with it manually. */
|
||||
+ ret = closesocket(fdWrite);
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+ ret = closesocket(fdListen);
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+ len = sizeof(address);
|
||||
+ fdWrite = setup_connector_socket(&address, len, TRUE);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
+ poll_timeout = 2000;
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
+ len = sizeof(id);
|
||||
+ id = 0xdeadbeef;
|
||||
+ ok(!getsockopt(fdWrite, SOL_SOCKET, SO_ERROR, (char*)&id, &len),
|
||||
+ "getsockopt failed with %d\n", WSAGetLastError());
|
||||
+ ok(id == WSAECONNREFUSED, "expected 10061, got %d\n", id);
|
||||
+ closesocket(fdWrite);
|
||||
+
|
||||
+ /* Try poll() on a closed socket after connection */
|
||||
+ ok(!tcp_socketpair(&fdRead, &fdWrite), "creating socket pair failed\n");
|
||||
+ closesocket(fdRead);
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
+ POLL_SET(fdRead, POLLIN | POLLOUT);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdRead, POLLNVAL), "fdRead socket events incorrect\n");
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdWrite, POLLWRNORM | POLLHUP) || broken(POLL_ISSET(fdWrite, POLLWRNORM)) /* <= 2008 */,
|
||||
+ "fdWrite socket events incorrect\n");
|
||||
+ closesocket(fdWrite);
|
||||
+
|
||||
+ /* Close the socket currently being polled in a thread */
|
||||
+ ok(!tcp_socketpair(&fdRead, &fdWrite), "creating socket pair failed\n");
|
||||
+ thread_handle = CreateThread(NULL, 0, SelectCloseThread, &fdWrite, 0, &id);
|
||||
+ ok(thread_handle != NULL, "CreateThread failed unexpectedly: %d\n", GetLastError());
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdWrite, POLLWRNORM), "fdWrite socket events incorrect\n");
|
||||
+ WaitForSingleObject (thread_handle, 1000);
|
||||
+ closesocket(fdRead);
|
||||
+ /* test again with less flags - behavior changes */
|
||||
+ ok(!tcp_socketpair(&fdRead, &fdWrite), "creating socket pair failed\n");
|
||||
+ thread_handle = CreateThread(NULL, 0, SelectCloseThread, &fdWrite, 0, &id);
|
||||
+ ok(thread_handle != NULL, "CreateThread failed unexpectedly: %d\n", GetLastError());
|
||||
+ POLL_CLEAR();
|
||||
+ POLL_SET(fdWrite, POLLIN);
|
||||
+ ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+ ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+ ok(POLL_ISSET(fdWrite, POLLNVAL), "fdWrite socket events incorrect\n");
|
||||
+ WaitForSingleObject (thread_handle, 1000);
|
||||
+ closesocket(fdRead);
|
||||
+}
|
||||
+#undef POLL_SET
|
||||
+#undef POLL_ISSET
|
||||
+#undef POLL_CLEAR
|
||||
+
|
||||
static void test_GetAddrInfoW(void)
|
||||
{
|
||||
static const WCHAR port[] = {'8','0',0};
|
||||
@@ -8682,6 +8903,7 @@ START_TEST( sock )
|
||||
test_WSASendMsg();
|
||||
test_WSASendTo();
|
||||
test_WSARecv();
|
||||
+ test_WSAPoll();
|
||||
|
||||
test_events(0);
|
||||
test_events(1);
|
||||
--
|
||||
2.4.1
|
||||
|
@ -0,0 +1,182 @@
|
||||
From 43a7c89c8b133520b7ca998821f8b3039216e9ac Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Jesus <00cpxxx@gmail.com>
|
||||
Date: Fri, 22 May 2015 22:43:11 -0300
|
||||
Subject: ws2_32: Add WSAPoll() implementation
|
||||
|
||||
Still some todos to fix but fixes https://bugs.winehq.org/show_bug.cgi?id=38600
|
||||
---
|
||||
dlls/ws2_32/socket.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/ws2_32/tests/sock.c | 4 +++
|
||||
dlls/ws2_32/ws2_32.spec | 1 +
|
||||
3 files changed, 99 insertions(+)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index fdf68a3..68e6d54 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -740,6 +740,17 @@ static const int ws_eai_map[][2] =
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
+static const int ws_poll_map[][2] =
|
||||
+{
|
||||
+ MAP_OPTION( POLLERR ),
|
||||
+ MAP_OPTION( POLLHUP ),
|
||||
+ MAP_OPTION( POLLNVAL ),
|
||||
+ MAP_OPTION( POLLWRNORM ),
|
||||
+ MAP_OPTION( POLLWRBAND ),
|
||||
+ MAP_OPTION( POLLRDNORM ),
|
||||
+ { WS_POLLRDBAND, POLLPRI }
|
||||
+};
|
||||
+
|
||||
static const char magic_loopback_addr[] = {127, 12, 34, 56};
|
||||
|
||||
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||
@@ -1374,6 +1385,40 @@ convert_socktype_u2w(int unixsocktype) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static int convert_poll_w2u(int events)
|
||||
+{
|
||||
+ int i, ret;
|
||||
+ for (i = ret = 0; events && i < sizeof(ws_poll_map) / sizeof(ws_poll_map[0]); i++)
|
||||
+ {
|
||||
+ if (ws_poll_map[i][0] & events)
|
||||
+ {
|
||||
+ ret |= ws_poll_map[i][1];
|
||||
+ events &= ~ws_poll_map[i][0];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (events)
|
||||
+ FIXME("Unsupported WSAPoll() flags 0x%x\n", events);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int convert_poll_u2w(int events)
|
||||
+{
|
||||
+ int i, ret;
|
||||
+ for (i = ret = 0; events && i < sizeof(ws_poll_map) / sizeof(ws_poll_map[0]); i++)
|
||||
+ {
|
||||
+ if (ws_poll_map[i][1] & events)
|
||||
+ {
|
||||
+ ret |= ws_poll_map[i][0];
|
||||
+ events &= ~ws_poll_map[i][1];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (events)
|
||||
+ FIXME("Unsupported poll() flags 0x%x\n", events);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int set_ipx_packettype(int sock, int ptype)
|
||||
{
|
||||
#ifdef HAS_IPX
|
||||
@@ -4886,6 +4931,55 @@ int WINAPI WS_select(int nfds, WS_fd_set *ws_readfds,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/***********************************************************************
|
||||
+ * WSAPoll
|
||||
+ */
|
||||
+int WINAPI WSAPoll(WSAPOLLFD *wfds, ULONG count, int timeout)
|
||||
+{
|
||||
+ int i, ret;
|
||||
+ struct pollfd *ufds;
|
||||
+
|
||||
+ if (!count)
|
||||
+ {
|
||||
+ SetLastError(WSAEINVAL);
|
||||
+ return SOCKET_ERROR;
|
||||
+ }
|
||||
+ if (!wfds)
|
||||
+ {
|
||||
+ SetLastError(WSAEFAULT);
|
||||
+ return SOCKET_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (!(ufds = HeapAlloc(GetProcessHeap(), 0, count * sizeof(ufds[0]))))
|
||||
+ {
|
||||
+ SetLastError(WSAENOBUFS);
|
||||
+ return SOCKET_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ {
|
||||
+ ufds[i].fd = get_sock_fd(wfds[i].fd, 0, NULL);
|
||||
+ ufds[i].events = convert_poll_w2u(wfds[i].events);
|
||||
+ ufds[i].revents = 0;
|
||||
+ }
|
||||
+
|
||||
+ ret = do_poll(ufds, count, timeout);
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ {
|
||||
+ if (ufds[i].fd != -1)
|
||||
+ {
|
||||
+ release_sock_fd(wfds[i].fd, ufds[i].fd);
|
||||
+ wfds[i].revents = convert_poll_u2w(ufds[i].revents);
|
||||
+ }
|
||||
+ else
|
||||
+ wfds[i].revents = WS_POLLNVAL;
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, ufds);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/* helper to send completion messages for client-only i/o operation case */
|
||||
static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus,
|
||||
ULONG Information )
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index 3d584f2..1ed1aba 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -6426,6 +6426,7 @@ static void test_WSAPoll(void)
|
||||
POLL_SET(fdWrite, POLLIN);
|
||||
ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+todo_wine
|
||||
ok(POLL_ISSET(fdWrite, POLLHUP), "fdWrite socket events incorrect\n");
|
||||
ret = recv(fdWrite, tmp_buf, sizeof(tmp_buf), 0);
|
||||
ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
@@ -6444,6 +6445,7 @@ static void test_WSAPoll(void)
|
||||
POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
poll_timeout = 2000;
|
||||
ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
+todo_wine
|
||||
ok(ret == 0, "expected 0, got %d\n", ret);
|
||||
len = sizeof(id);
|
||||
id = 0xdeadbeef;
|
||||
@@ -6465,6 +6467,7 @@ static void test_WSAPoll(void)
|
||||
POLL_SET(fdWrite, POLLIN | POLLOUT);
|
||||
ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+todo_wine
|
||||
ok(POLL_ISSET(fdWrite, POLLWRNORM | POLLHUP) || broken(POLL_ISSET(fdWrite, POLLWRNORM)) /* <= 2008 */,
|
||||
"fdWrite socket events incorrect\n");
|
||||
closesocket(fdWrite);
|
||||
@@ -6488,6 +6491,7 @@ static void test_WSAPoll(void)
|
||||
POLL_SET(fdWrite, POLLIN);
|
||||
ret = pWSAPoll(fds, ix, poll_timeout);
|
||||
ok(ret == 1, "expected 1, got %d\n", ret);
|
||||
+todo_wine
|
||||
ok(POLL_ISSET(fdWrite, POLLNVAL), "fdWrite socket events incorrect\n");
|
||||
WaitForSingleObject (thread_handle, 1000);
|
||||
closesocket(fdRead);
|
||||
diff --git a/dlls/ws2_32/ws2_32.spec b/dlls/ws2_32/ws2_32.spec
|
||||
index f7c6c2d..a4e0b6b 100644
|
||||
--- a/dlls/ws2_32/ws2_32.spec
|
||||
+++ b/dlls/ws2_32/ws2_32.spec
|
||||
@@ -89,6 +89,7 @@
|
||||
@ stdcall WSANSPIoctl(ptr long ptr long ptr long ptr ptr)
|
||||
@ stdcall WSANtohl(long long ptr)
|
||||
@ stdcall WSANtohs(long long ptr)
|
||||
+@ stdcall WSAPoll(ptr long long)
|
||||
@ stdcall WSAProviderConfigChange(ptr ptr ptr)
|
||||
@ stdcall WSARecv(long ptr long ptr ptr ptr ptr)
|
||||
@ stdcall WSARecvDisconnect(long ptr)
|
||||
--
|
||||
2.4.1
|
||||
|
1
patches/ws2_32-WSAPoll/definition
Normal file
1
patches/ws2_32-WSAPoll/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [38601] Support for ws2_32.dll.WSAPoll
|
Loading…
Reference in New Issue
Block a user