Hans Leidekker : ws2_32: Accept NULL lpNumberOfBytesSent for overlapped calls to WSASend/To.

Alexandre Julliard julliard at winehq.org
Tue Jun 14 11:57:46 CDT 2011


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Tue Jun 14 10:31:26 2011 +0200

ws2_32: Accept NULL lpNumberOfBytesSent for overlapped calls to WSASend/To.

---

 dlls/ws2_32/socket.c     |   25 +++++++++++++------------
 dlls/ws2_32/tests/sock.c |   24 +++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index e1a32fb..0c51985 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3790,9 +3790,10 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
 {
     unsigned int i, options;
     int n, fd, err;
-    struct ws2_async *wsa;
+    struct ws2_async *wsa = NULL;
     int totalLength = 0;
     ULONG_PTR cvalue = (lpOverlapped && ((ULONG_PTR)lpOverlapped->hEvent & 1) == 0) ? (ULONG_PTR)lpOverlapped : 0;
+    DWORD bytes_sent;
 
     TRACE("socket %04lx, wsabuf %p, nbufs %d, flags %d, to %p, tolen %d, ovl %p, func %p\n",
           s, lpBuffers, dwBufferCount, dwFlags,
@@ -3803,6 +3804,11 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
 
     if ( fd == -1 ) return SOCKET_ERROR;
 
+    if (!lpOverlapped && !lpNumberOfBytesSent)
+    {
+        err = WSAEFAULT;
+        goto error;
+    }
     if (!(wsa = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET(struct ws2_async, iovec[dwBufferCount]) )))
     {
         err = WSAEFAULT;
@@ -3824,12 +3830,6 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
         totalLength += lpBuffers[i].len;
     }
 
-    if (!lpNumberOfBytesSent)
-    {
-        err = WSAEFAULT;
-        goto error;
-    }
-
     for (;;)
     {
         n = WS2_send( fd, wsa );
@@ -3881,7 +3881,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
 
         iosb->u.Status = STATUS_SUCCESS;
         iosb->Information = n;
-        *lpNumberOfBytesSent = n;
+        if (lpNumberOfBytesSent) *lpNumberOfBytesSent = n;
         if (!wsa->completion_func)
         {
             if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n );
@@ -3900,7 +3900,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
          * sending blocks until the entire buffer is sent. */
         DWORD timeout_start = GetTickCount();
 
-        *lpNumberOfBytesSent = n == -1 ? 0 : n;
+        bytes_sent = n == -1 ? 0 : n;
 
         while (wsa->first_iovec < wsa->n_iovecs)
         {
@@ -3930,7 +3930,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
             }
 
             if (n >= 0)
-                *lpNumberOfBytesSent += n;
+                bytes_sent += n;
         }
     }
     else  /* non-blocking */
@@ -3942,11 +3942,12 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
             err = WSAEWOULDBLOCK;
             goto error;
         }
-        *lpNumberOfBytesSent = n;
+        bytes_sent = n;
     }
 
-    TRACE(" -> %i bytes\n", *lpNumberOfBytesSent);
+    TRACE(" -> %i bytes\n", bytes_sent);
 
+    if (lpNumberOfBytesSent) *lpNumberOfBytesSent = bytes_sent;
     HeapFree( GetProcessHeap(), 0, wsa );
     release_sock_fd( s, fd );
     WSASetLastError(0);
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index ef01ed2..de9c400 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -3030,8 +3030,9 @@ static void test_send(void)
         goto end;
 
     bytes_sent = 0;
+    WSASetLastError(12345);
     ret = WSASend(dst, &buf, 1, &bytes_sent, 0, &ov, NULL);
-    ok((ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING) || broken(bytes_sent == buflen),
+    ok((ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING) || broken(bytes_sent == buflen),
        "Failed to start overlapped send %d - %d - %d/%d\n", ret, WSAGetLastError(), bytes_sent, buflen);
 
     /* don't check for completion yet, we may need to drain the buffer while still sending */
@@ -3064,6 +3065,16 @@ static void test_send(void)
            "Got %d instead of %d (%d - %d)\n", bytes_sent, buflen, bret, GetLastError());
     }
 
+    WSASetLastError(12345);
+    ret = WSASend(INVALID_SOCKET, &buf, 1, NULL, 0, &ov, NULL);
+    ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
+       "WSASend failed %d - %d\n", ret, WSAGetLastError());
+
+    WSASetLastError(12345);
+    ret = WSASend(dst, &buf, 1, NULL, 0, &ov, NULL);
+    ok(ret == SOCKET_ERROR && WSAGetLastError() == ERROR_IO_PENDING,
+       "Failed to start overlapped send %d - %d\n", ret, WSAGetLastError());
+
 end:
     if (src != INVALID_SOCKET)
         closesocket(src);
@@ -3903,6 +3914,7 @@ static void test_WSASendTo(void)
     char buf[12] = "hello world";
     WSABUF data_buf;
     DWORD bytesSent;
+    int ret;
 
     addr.sin_family = AF_INET;
     addr.sin_port = htons(139);
@@ -3916,6 +3928,16 @@ static void test_WSASendTo(void)
     }
 
     WSASetLastError(12345);
+    ret = WSASendTo(INVALID_SOCKET, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
+    ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK,
+       "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
+
+    WSASetLastError(12345);
+    ret = WSASendTo(s, &data_buf, 1, NULL, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL);
+    ok(ret == SOCKET_ERROR && WSAGetLastError() == WSAEFAULT,
+       "WSASendTo() failed: %d/%d\n", ret, WSAGetLastError());
+
+    WSASetLastError(12345);
     if(WSASendTo(s, &data_buf, 1, &bytesSent, 0, (struct sockaddr*)&addr, sizeof(addr), NULL, NULL)) {
         ok(0, "WSASendTo() failed error: %d\n", WSAGetLastError());
         return;




More information about the wine-cvs mailing list