Bruno Jesus : ws2_32: Convert send/recv flags to native system.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Mar 30 10:12:57 CDT 2015


Module: wine
Branch: master
Commit: dcc0bae95df6e2d94ed54cc48b0eb80e882440bf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dcc0bae95df6e2d94ed54cc48b0eb80e882440bf

Author: Bruno Jesus <00cpxxx at gmail.com>
Date:   Sun Mar 29 00:53:30 2015 -0300

ws2_32: Convert send/recv flags to native system.

---

 dlls/ws2_32/socket.c | 59 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 11 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 1bcb63c..cda9641 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -462,6 +462,14 @@ static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS C
 
 #define MAP_OPTION(opt) { WS_##opt, opt }
 
+static const int ws_flags_map[][2] =
+{
+    MAP_OPTION( MSG_OOB ),
+    MAP_OPTION( MSG_PEEK ),
+    MAP_OPTION( MSG_DONTROUTE ),
+    MAP_OPTION( MSG_WAITALL ),
+};
+
 static const int ws_sock_map[][2] =
 {
     MAP_OPTION( SO_DEBUG ),
@@ -1014,6 +1022,33 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
 }
 
 /***********************************************************************
+ *          convert_flags()
+ *
+ * Converts send/recv flags from Windows format.
+ * Return the converted flag bits, unsupported flags remain unchanged.
+ */
+static int convert_flags(int flags)
+{
+    int i, out;
+    if (!flags) return 0;
+
+    for (out = i = 0; flags && i < sizeof(ws_flags_map) / sizeof(ws_flags_map[0]); i++)
+    {
+        if (ws_flags_map[i][0] & flags)
+        {
+            out |= ws_flags_map[i][1];
+            flags &= ~ws_flags_map[i][0];
+        }
+    }
+    if (flags)
+    {
+        FIXME("Unknown send/recv flags 0x%x, using anyway...\n", flags);
+        out |= flags;
+    }
+    return out;
+}
+
+/***********************************************************************
  *          convert_sockopt()
  *
  * Converts socket flags from Windows format.
@@ -1940,7 +1975,7 @@ static void WINAPI ws2_async_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserv
  *
  * Workhorse for both synchronous and asynchronous recv() operations.
  */
-static int WS2_recv( int fd, struct ws2_async *wsa )
+static int WS2_recv( int fd, struct ws2_async *wsa, int flags )
 {
 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
     char pktbuf[512];
@@ -1970,7 +2005,7 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
     hdr.msg_flags = 0;
 #endif
 
-    while ((n = recvmsg(fd, &hdr, wsa->flags)) == -1)
+    while ((n = recvmsg(fd, &hdr, flags)) == -1)
     {
         if (errno != EINTR)
             return -1;
@@ -2025,7 +2060,7 @@ static NTSTATUS WS2_async_recv( void *user, IO_STATUS_BLOCK *iosb,
         if ((status = wine_server_handle_to_fd( wsa->hSocket, FILE_READ_DATA, &fd, NULL ) ))
             break;
 
-        result = WS2_recv( fd, wsa );
+        result = WS2_recv( fd, wsa, convert_flags(wsa->flags) );
         wine_server_release_fd( wsa->hSocket, fd );
         if (result >= 0)
         {
@@ -2173,7 +2208,7 @@ finish:
  *
  * Workhorse for both synchronous and asynchronous send() operations.
  */
-static int WS2_send( int fd, struct ws2_async *wsa )
+static int WS2_send( int fd, struct ws2_async *wsa, int flags )
 {
     struct msghdr hdr;
     union generic_unix_sockaddr unix_addr;
@@ -2221,7 +2256,7 @@ static int WS2_send( int fd, struct ws2_async *wsa )
     hdr.msg_flags = 0;
 #endif
 
-    while ((ret = sendmsg(fd, &hdr, wsa->flags)) == -1)
+    while ((ret = sendmsg(fd, &hdr, flags)) == -1)
     {
         if (errno != EINTR)
             return -1;
@@ -2262,7 +2297,7 @@ static NTSTATUS WS2_async_send( void *user, IO_STATUS_BLOCK *iosb,
             break;
 
         /* check to see if the data is ready (non-blocking) */
-        result = WS2_send( fd, wsa );
+        result = WS2_send( fd, wsa, convert_flags(wsa->flags) );
         wine_server_release_fd( wsa->hSocket, fd );
 
         if (result >= 0)
@@ -4673,7 +4708,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
                        LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
 {
     unsigned int i, options;
-    int n, fd, err, overlapped;
+    int n, fd, err, overlapped, flags;
     struct ws2_async *wsa = NULL, localwsa;
     int totalLength = 0;
     DWORD bytes_sent;
@@ -4722,7 +4757,8 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
         totalLength += lpBuffers[i].len;
     }
 
-    n = WS2_send( fd, wsa );
+    flags = convert_flags(dwFlags);
+    n = WS2_send( fd, wsa, flags );
     if (n == -1 && errno != EAGAIN)
     {
         err = wsaErrno();
@@ -4814,7 +4850,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
                 goto error; /* msdn says a timeout in send is fatal */
             }
 
-            n = WS2_send( fd, wsa );
+            n = WS2_send( fd, wsa, flags );
             if (n == -1 && errno != EAGAIN)
             {
                 err = wsaErrno();
@@ -6712,7 +6748,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
                           LPWSABUF lpControlBuffer )
 {
     unsigned int i, options;
-    int n, fd, err, overlapped;
+    int n, fd, err, overlapped, flags;
     struct ws2_async *wsa = NULL, localwsa;
     BOOL is_blocking;
     DWORD timeout_start = GetTickCount();
@@ -6773,9 +6809,10 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
         wsa->iovec[i].iov_len  = lpBuffers[i].len;
     }
 
+    flags = convert_flags(wsa->flags);
     for (;;)
     {
-        n = WS2_recv( fd, wsa );
+        n = WS2_recv( fd, wsa, flags );
         if (n == -1)
         {
             if (errno != EAGAIN)




More information about the wine-cvs mailing list