diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 3f3889fd2e7..91849461570 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -69,10 +69,17 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); - Status = TCPServiceListeningSocket - ( Connection->AddressFile->Listener, - Bucket->AssociatedEndpoint, - (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); + if (Connection->SignalState & SEL_ACCEPT) + { + Status = TCPServiceListeningSocket(Connection->AddressFile->Listener, + Bucket->AssociatedEndpoint, + (PTDI_REQUEST_KERNEL)&IrpSp->Parameters); + } + else + { + /* We got here because of a SEL_FIN event */ + Status = STATUS_CANCELLED; + } TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); @@ -121,12 +128,19 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) Connection->SocketContext)); TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); + if (Connection->SignalState & SEL_READ) + { + Status = TCPTranslateError(OskitTCPRecv(Connection->SocketContext, + RecvBuffer, + RecvLen, + &Received, + 0)); + } + else + { + /* We got here because of a SEL_FIN event */ + Status = STATUS_CANCELLED; + } TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); @@ -175,12 +189,19 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) ("Connection->SocketContext: %x\n", Connection->SocketContext)); - Status = TCPTranslateError - ( OskitTCPSend( Connection->SocketContext, - SendBuffer, - SendLen, - &Sent, - 0 ) ); + if (Connection->SignalState & SEL_WRITE) + { + Status = TCPTranslateError(OskitTCPSend(Connection->SocketContext, + SendBuffer, + SendLen, + &Sent, + 0)); + } + else + { + /* We got here because of a SEL_FIN event */ + Status = STATUS_CANCELLED; + } TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); @@ -648,7 +669,7 @@ NTSTATUS TCPDisconnect LockObject(Connection, &OldIrql); if (Flags & TDI_DISCONNECT_RELEASE) - Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); + Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE)); if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD)); diff --git a/reactos/lib/drivers/oskittcp/oskittcp/interface.c b/reactos/lib/drivers/oskittcp/oskittcp/interface.c index 9205757f8c8..67c6b190897 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/interface.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/interface.c @@ -148,6 +148,7 @@ int OskitTCPRecv( void *connection, OSK_UINT Len, OSK_UINT *OutLen, OSK_UINT Flags ) { + struct socket *so = connection; struct uio uio = { 0 }; struct iovec iov = { 0 }; int error = 0; @@ -155,9 +156,12 @@ int OskitTCPRecv( void *connection, if (!connection) return OSK_ESHUTDOWN; + + if (so->so_state & SS_CANTRCVMORE) + return OSK_ESHUTDOWN; OS_DbgPrint(OSK_MID_TRACE, - ("so->so_state %x\n", ((struct socket *)connection)->so_state)); + ("so->so_state %x\n", so->so_state)); if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB; if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT; @@ -290,12 +294,16 @@ int OskitTCPClose( void *socket ) { int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, OSK_UINT *OutLen, OSK_UINT flags ) { + struct socket *so = socket; int error; struct uio uio; struct iovec iov; if (!socket) return OSK_ESHUTDOWN; + + if (so->so_state & SS_CANTSENDMORE) + return OSK_ESHUTDOWN; iov.iov_len = Len; iov.iov_base = (char *)Data; diff --git a/reactos/lib/drivers/oskittcp/oskittcp/sleep.c b/reactos/lib/drivers/oskittcp/oskittcp/sleep.c index e6779fd6675..0fcc7c9ef69 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/sleep.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/sleep.c @@ -31,11 +31,13 @@ void wakeup( struct socket *so, void *token ) { OS_DbgPrint(OSK_MID_TRACE,("Socket accepting q\n")); flags |= SEL_ACCEPT; } - if( so->so_rcv.sb_cc > 0 ) { + if( so->so_rcv.sb_cc > 0 && !(so->so_state & SS_CANTRCVMORE) && + (so->so_state & SS_ISCONNECTED) ) { OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n")); flags |= SEL_READ; } - if( 0 < sbspace(&so->so_snd) ) { + if( 0 < sbspace(&so->so_snd) && !(so->so_state & SS_CANTSENDMORE) && + (so->so_state & SS_ISCONNECTED) ) { OS_DbgPrint(OSK_MID_TRACE,("Socket writeable\n")); flags |= SEL_WRITE; } @@ -51,7 +53,7 @@ void wakeup( struct socket *so, void *token ) { if( OtcpEvent.SocketState ) OtcpEvent.SocketState( OtcpEvent.ClientData, so, - so ? so->so_connection : 0, + so->so_connection, flags ); if( OtcpEvent.Wakeup ) diff --git a/reactos/lib/drivers/oskittcp/oskittcp/uipc_socket.c b/reactos/lib/drivers/oskittcp/oskittcp/uipc_socket.c index 4a9451dacac..8cad81cccd6 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/uipc_socket.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/uipc_socket.c @@ -826,7 +826,13 @@ soshutdown(so, how) { register struct protosw *pr = so->so_proto; +#ifndef __REACTOS__ + /* Reads are always killed whether we want + * them stopped or not. We don't want this + * happening on ROS so this code is commented out + */ how++; +#endif if (how & FREAD) sorflush(so); if (how & FWRITE)