ws2_32: Accept NULL lpNumberOfBytesSent for overlapped calls to WSASend/To.
Hans Leidekker
hans at codeweavers.com
Tue Jun 14 03:31:26 CDT 2011
See http://bugs.winehq.org/show_bug.cgi?id=19491
---
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;
--
1.7.4.1
More information about the wine-patches
mailing list