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

This commit is contained in:
Hans Leidekker 2011-06-14 10:31:26 +02:00 committed by Alexandre Julliard
parent 4b62257b14
commit 3581d2c6d1
2 changed files with 36 additions and 13 deletions

View File

@ -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);

View File

@ -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);
@ -3915,6 +3927,16 @@ static void test_WSASendTo(void)
return;
}
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());