Commit 53dc1b0a authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

ws2_32: Use IOCTL_AFD_WINE_SHUTDOWN in WS_shutdown().

parent 89e1cf3d
......@@ -2272,64 +2272,6 @@ static NTSTATUS WS2_async_send( void *user, IO_STATUS_BLOCK *iosb, NTSTATUS stat
return status;
}
/***********************************************************************
* WS2_async_shutdown (INTERNAL)
*
* Handler for shutdown() operations on overlapped sockets.
*/
static NTSTATUS WS2_async_shutdown( void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status )
{
struct ws2_async_shutdown *wsa = user;
int fd, err = 1;
switch (status)
{
case STATUS_ALERTED:
if ((status = wine_server_handle_to_fd( wsa->hSocket, 0, &fd, NULL ) ))
break;
switch ( wsa->type )
{
case ASYNC_TYPE_READ: break;
case ASYNC_TYPE_WRITE: err = shutdown( fd, 1 ); break;
}
status = err ? wsaErrStatus() : STATUS_SUCCESS;
close( fd );
break;
}
iosb->u.Status = status;
iosb->Information = 0;
release_async_io( &wsa->io );
return status;
}
/***********************************************************************
* WS2_register_async_shutdown (INTERNAL)
*
* Helper function for WS_shutdown() on overlapped sockets.
*/
static int WS2_register_async_shutdown( SOCKET s, int type )
{
struct ws2_async_shutdown *wsa;
NTSTATUS status;
TRACE("socket %04lx type %d\n", s, type);
wsa = (struct ws2_async_shutdown *)alloc_async_io( sizeof(*wsa), WS2_async_shutdown );
if ( !wsa )
return WSAEFAULT;
wsa->hSocket = SOCKET2HANDLE(s);
wsa->type = type;
status = register_async( type, wsa->hSocket, &wsa->io, 0, NULL, NULL, &wsa->iosb );
if (status != STATUS_PENDING)
{
HeapFree( GetProcessHeap(), 0, wsa );
return NtStatusToWSAError( status );
}
return 0;
}
/***********************************************************************
* accept (WS2_32.1)
......@@ -5512,74 +5454,24 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
return SOCKET_ERROR;
}
/***********************************************************************
* shutdown (WS2_32.22)
* shutdown (ws2_32.22)
*/
int WINAPI WS_shutdown(SOCKET s, int how)
int WINAPI WS_shutdown( SOCKET s, int how )
{
int fd, err = WSAENOTSOCK;
unsigned int options = 0, clear_flags = 0;
fd = get_sock_fd( s, 0, &options );
TRACE("socket %04lx, how 0x%x, options 0x%x\n", s, how, options );
if (fd == -1)
return SOCKET_ERROR;
switch( how )
{
case SD_RECEIVE: /* drop receives */
clear_flags |= FD_READ;
break;
case SD_SEND: /* drop sends */
clear_flags |= FD_WRITE;
break;
case SD_BOTH: /* drop all */
clear_flags |= FD_READ|FD_WRITE;
/*fall through */
default:
clear_flags |= FD_WINE_LISTENING;
}
if (!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
{
switch ( how )
{
case SD_RECEIVE:
err = WS2_register_async_shutdown( s, ASYNC_TYPE_READ );
break;
case SD_SEND:
err = WS2_register_async_shutdown( s, ASYNC_TYPE_WRITE );
break;
case SD_BOTH:
default:
err = WS2_register_async_shutdown( s, ASYNC_TYPE_READ );
if (!err) err = WS2_register_async_shutdown( s, ASYNC_TYPE_WRITE );
break;
}
if (err) goto error;
}
else /* non-overlapped mode */
{
if (how != SD_RECEIVE && shutdown( fd, SHUT_WR ))
{
err = wsaErrno();
goto error;
}
}
IO_STATUS_BLOCK io;
NTSTATUS status;
release_sock_fd( s, fd );
_enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 );
return 0;
TRACE( "socket %#lx, how %u\n", s, how );
error:
release_sock_fd( s, fd );
_enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
SetLastError( err );
return SOCKET_ERROR;
status = NtDeviceIoControlFile( (HANDLE)s, NULL, NULL, NULL, &io,
IOCTL_AFD_WINE_SHUTDOWN, &how, sizeof(how), NULL, 0 );
SetLastError( NtStatusToWSAError( status ) );
return status ? -1 : 0;
}
/***********************************************************************
* socket (WS2_32.23)
*/
......
......@@ -6405,12 +6405,12 @@ static void test_shutdown(void)
WSASetLastError(0xdeadbeef);
ret = shutdown(client, SD_SEND);
ok(ret == -1, "expected failure\n");
todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef);
ret = shutdown(client, SD_RECEIVE);
ok(ret == -1, "expected failure\n");
todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr));
ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
......@@ -6425,8 +6425,8 @@ static void test_shutdown(void)
WSASetLastError(0xdeadbeef);
ret = shutdown(client, SD_SEND);
todo_wine ok(!ret, "expected success\n");
todo_wine ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
ok(!ret, "expected success\n");
ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef);
ret = send(client, "test", 5, 0);
......@@ -6501,7 +6501,7 @@ static void test_shutdown(void)
WSASetLastError(0xdeadbeef);
ret = shutdown(client, 0xdeadbeef);
ok(ret == -1, "expected failure\n");
todo_wine ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
ok(WSAGetLastError() == WSAEINVAL, "got error %u\n", WSAGetLastError());
closesocket(client);
closesocket(server);
......@@ -6628,12 +6628,12 @@ static void test_shutdown(void)
WSASetLastError(0xdeadbeef);
ret = shutdown(listener, SD_SEND);
ok(ret == -1, "expected failure\n");
todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef);
ret = shutdown(listener, SD_RECEIVE);
todo_wine ok(ret == -1, "expected failure\n");
todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
ok(ret == -1, "expected failure\n");
ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError());
closesocket(listener);
......@@ -6671,8 +6671,8 @@ static void test_shutdown(void)
WSASetLastError(0xdeadbeef);
ret = shutdown(client, SD_SEND);
todo_wine ok(!ret, "expected success\n");
todo_wine ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
ok(!ret, "expected success\n");
ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef);
ret = sendto(client, "test", 5, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment