From e6c94e606c3c2bc7e0b133b38e3a26dfd5ae1018 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 4 Dec 2004 23:29:56 +0000 Subject: [PATCH] afd/connect.c: - only pend the irp if we got a pending return from tcpip. afd/info.c: - info stub for blocking mode info. afd/main.c: - added disconnect plumbing. - some reformatting, add break after each inactive case. afd/read.c: - early return for already closed socket. - function to correctly complete pending recv irps on a closed socket. - fixed read completion bug, content properly zeroed before buffer is replenished. - only attempt to fulfill read irps if we got data back. - call ProcessClose in the no data case. - major changes to AfdConnectedSocketRead due to connection close. we now recognize the case where the request to tcpip returns zero bytes immediately and take action, doing processclose. afd/tdi.c: - Added TdiDisconnect. route.c: - router: fixed routing bug. we used to reject the default route if the address didn't match at least one bit of the target network, even if the netmask is zero. if.c: - change RouterGetRoute to RouteGetRouteToDestination tcp.c: - simplify TCPReceiveData by removing eof clause. not needed. - added SEL_FIN branch in signalling. - added TCPTranslateError to TCPConnect - added TCPDisconnect dispatch.c: - Implement disconnect ip_output.c: - Make a contiguous area from each output packet. We need to streamline this. msafd: - Added MsafdReturnWithErrno - streamlined function returns with standardize errno selection. svn path=/trunk/; revision=11933 --- reactos/drivers/lib/ip/network/router.c | 4 +- reactos/drivers/lib/ip/transport/tcp/event.c | 9 +- reactos/drivers/lib/ip/transport/tcp/if.c | 24 +-- reactos/drivers/lib/ip/transport/tcp/tcp.c | 114 +++++++++---- .../drivers/lib/oskittcp/include/oskittcp.h | 1 + .../drivers/lib/oskittcp/oskittcp/interface.c | 11 +- .../drivers/lib/oskittcp/oskittcp/ip_output.c | 19 ++- .../lib/oskittcp/oskittcp/tcp_output.c | 1 - reactos/drivers/net/afd/afd/connect.c | 7 +- reactos/drivers/net/afd/afd/info.c | 6 +- reactos/drivers/net/afd/afd/main.c | 122 +++++++++++--- reactos/drivers/net/afd/afd/read.c | 153 ++++++++++++------ reactos/drivers/net/afd/afd/tdi.c | 54 +++++++ reactos/drivers/net/afd/include/tdi_proto.h | 10 ++ reactos/drivers/net/tcpip/datalink/lan.c | 4 - reactos/drivers/net/tcpip/include/debug.h | 2 +- reactos/drivers/net/tcpip/include/tcp.h | 8 + reactos/drivers/net/tcpip/tcpip/dispatch.c | 72 +++------ reactos/drivers/net/tcpip/tcpip/main.c | 4 +- reactos/lib/msafd/include/msafd.h | 3 + reactos/lib/msafd/misc/dllmain.c | 37 ++++- reactos/lib/msafd/misc/sndrcv.c | 110 ++++--------- 22 files changed, 496 insertions(+), 279 deletions(-) diff --git a/reactos/drivers/lib/ip/network/router.c b/reactos/drivers/lib/ip/network/router.c index a2f84ea46bb..a5fad347c08 100644 --- a/reactos/drivers/lib/ip/network/router.c +++ b/reactos/drivers/lib/ip/network/router.c @@ -250,7 +250,7 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination) TI_DbgPrint(DEBUG_ROUTER,("This-Route: %s (Sharing %d bits)\n", A2S(&NCE->Address), Length)); - if(Length >= MaskLength && Length > BestLength) { + if(Length >= MaskLength && (Length > BestLength || !BestLength)) { /* This seems to be a better router */ BestNCE = NCE; BestLength = Length; @@ -308,7 +308,7 @@ PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination) } if( NCE ) - TI_DbgPrint(MID_TRACE,("Interface->MTU: %d\n", NCE->Interface->MTU)); + TI_DbgPrint(DEBUG_ROUTER,("Interface->MTU: %d\n", NCE->Interface->MTU)); return NCE; } diff --git a/reactos/drivers/lib/ip/transport/tcp/event.c b/reactos/drivers/lib/ip/transport/tcp/event.c index 1ff89cf1e94..d8f42cf829a 100644 --- a/reactos/drivers/lib/ip/transport/tcp/event.c +++ b/reactos/drivers/lib/ip/transport/tcp/event.c @@ -66,14 +66,17 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { RemoteAddress.Type = IP_ADDRESS_V4; RemoteAddress.Address.IPv4Address = Header->DstAddr; } else { - DbgPrint("Don't currently handle IPv6\n"); - KeBugCheck(4); + TI_DbgPrint(MIN_TRACE,("Outgoing packet is not IPv4\n")); + OskitDumpBuffer( data, len ); + return OSK_EINVAL; } RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4; - if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) + if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { + TI_DbgPrint(MIN_TRACE,("No route to %s\n", A2S(&RemoteAddress))); return OSK_EADDRNOTAVAIL; + } NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL, MaxLLHeaderSize + len ); diff --git a/reactos/drivers/lib/ip/transport/tcp/if.c b/reactos/drivers/lib/ip/transport/tcp/if.c index e85e9c4c5e9..729bc0eabee 100644 --- a/reactos/drivers/lib/ip/transport/tcp/if.c +++ b/reactos/drivers/lib/ip/transport/tcp/if.c @@ -38,7 +38,7 @@ PVOID TCPPrepareInterface( PIP_INTERFACE IF ) { struct sockaddr_in *dstaddr_in = (struct sockaddr_in *)&addr_in[1]; if( !ifaddr ) return NULL; - TI_DbgPrint(MID_TRACE,("Called\n")); + TI_DbgPrint(DEBUG_TCPIF,("Called\n")); ifaddr->ifa_dstaddr = (struct sockaddr *)dstaddr_in; /* XXX - Point-to-point interfaces not supported yet */ @@ -52,7 +52,7 @@ PVOID TCPPrepareInterface( PIP_INTERFACE IF ) { if( !NT_SUCCESS(Status) ) addr_in->sin_addr.s_addr = 0; - TI_DbgPrint(MID_TRACE,("Prepare interface %x : addr %x\n", + TI_DbgPrint(DEBUG_TCPIF,("Prepare interface %x : addr %x\n", IF, addr_in->sin_addr.s_addr)); ifaddr->ifa_flags = 0; /* XXX what goes here? */ @@ -60,7 +60,7 @@ PVOID TCPPrepareInterface( PIP_INTERFACE IF ) { ifaddr->ifa_metric = 1; /* We can get it like in ninfo.c, if we want */ ifaddr->ifa_mtu = IF->MTU; - TI_DbgPrint(MID_TRACE,("Leaving\n")); + TI_DbgPrint(DEBUG_TCPIF,("Leaving\n")); return ifaddr; } @@ -74,34 +74,34 @@ POSK_IFADDR TCPFindInterface( void *ClientData, IP_ADDRESS Destination; struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr; - TI_DbgPrint(MID_TRACE,("called for type %d\n", FindType)); + TI_DbgPrint(DEBUG_TCPIF,("called for type %d\n", FindType)); if( !ReqAddr ) { - TI_DbgPrint(MID_TRACE,("no addr or no ifaddr (%x)\n", ReqAddr)); + TI_DbgPrint(DEBUG_TCPIF,("no addr or no ifaddr (%x)\n", ReqAddr)); return NULL; } Destination.Type = IP_ADDRESS_V4; Destination.Address.IPv4Address = addr_in->sin_addr.s_addr; - TI_DbgPrint(MID_TRACE,("Address is %x\n", addr_in->sin_addr.s_addr)); + TI_DbgPrint(DEBUG_TCPIF,("Address is %x\n", addr_in->sin_addr.s_addr)); - NCE = RouterGetRoute(&Destination); + NCE = RouteGetRouteToDestination(&Destination); if( !NCE || !NCE->Interface ) { - TI_DbgPrint(MID_TRACE,("no neighbor cache or no interface (%x %x)\n", + TI_DbgPrint(DEBUG_TCPIF,("no neighbor cache or no interface (%x %x)\n", NCE, NCE ? NCE->Interface : 0)); return NULL; } - TI_DbgPrint(MID_TRACE,("NCE: %x\n", NCE)); - TI_DbgPrint(MID_TRACE,("NCE->Interface: %x\n", NCE->Interface)); - TI_DbgPrint(MID_TRACE,("NCE->Interface->TCPContext: %x\n", + TI_DbgPrint(DEBUG_TCPIF,("NCE: %x\n", NCE)); + TI_DbgPrint(DEBUG_TCPIF,("NCE->Interface: %x\n", NCE->Interface)); + TI_DbgPrint(DEBUG_TCPIF,("NCE->Interface->TCPContext: %x\n", NCE->Interface->TCPContext)); addr_in = (struct sockaddr_in *) ((POSK_IFADDR)NCE->Interface->TCPContext)->ifa_addr; - TI_DbgPrint(MID_TRACE,("returning addr %x\n", addr_in->sin_addr.s_addr)); + TI_DbgPrint(DEBUG_TCPIF,("returning addr %x\n", addr_in->sin_addr.s_addr)); return NCE->Interface->TCPContext; } diff --git a/reactos/drivers/lib/ip/transport/tcp/tcp.c b/reactos/drivers/lib/ip/transport/tcp/tcp.c index bbdbe367c55..748f0cdec13 100644 --- a/reactos/drivers/lib/ip/transport/tcp/tcp.c +++ b/reactos/drivers/lib/ip/transport/tcp/tcp.c @@ -24,7 +24,9 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, PTCP_COMPLETION_ROUTINE Complete; PTDI_BUCKET Bucket; PLIST_ENTRY Entry; + BOOLEAN CompletedOne = FALSE; + /* Things that can happen when we try the initial connection */ if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) && !(Connection->State & (SEL_CONNECT | SEL_FIN)) ) { @@ -41,8 +43,10 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, PoolFreeBuffer( Bucket ); } } - if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) { - TI_DbgPrint(DEBUG_TCP,("Readable (or closed): irp list %s\n", + + /* Things that happen after we're connected */ + if( (NewState & SEL_READ) ) { + TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", IsListEmpty(&Connection->ReceiveRequest) ? "empty" : "nonempty")); @@ -72,29 +76,23 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, TI_DbgPrint(DEBUG_TCP, ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); - if( (NewState & SEL_FIN) && !RecvLen ) { - TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - Status = STATUS_END_OF_FILE; - Received = 0; - } else { - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint - (DEBUG_TCP, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); - } + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint + (DEBUG_TCP, + ("Connection->SocketContext: %x\n", + Connection->SocketContext)); + TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); + + Status = TCPTranslateError + ( OskitTCPRecv( Connection->SocketContext, + RecvBuffer, + RecvLen, + &Received, + 0 ) ); TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); - - if( Status == STATUS_SUCCESS && Received != 0 ) { + + if( Status == STATUS_SUCCESS ) { TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", Received, Status)); @@ -104,8 +102,8 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, Received ); - } else if( Status == STATUS_PENDING || - (Status == STATUS_SUCCESS && Received == 0) ) { + CompletedOne = TRUE; + } else if( Status == STATUS_PENDING ) { InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry ); break; @@ -114,9 +112,21 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, ("Completing Receive request: %x %x\n", Bucket->Request, Status)); Complete( Bucket->Request.RequestContext, Status, 0 ); + CompletedOne = TRUE; } } - } + } + if( NewState & SEL_FIN ) { + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + + while( !IsListEmpty( &Connection->ReceiveRequest ) ) { + Entry = RemoveHeadList( &Connection->ReceiveRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); + } + } Connection->Signalled = FALSE; } @@ -404,10 +414,11 @@ NTSTATUS TCPConnect sizeof(AddressToConnect.sin_addr) ); AddressToConnect.sin_port = RemotePort; - Status = OskitTCPConnect(Connection->SocketContext, - Connection, - &AddressToConnect, - sizeof(AddressToConnect)); + Status = TCPTranslateError + ( OskitTCPConnect( Connection->SocketContext, + Connection, + &AddressToConnect, + sizeof(AddressToConnect) ) ); TcpipRecursiveMutexLeave( &TCPLock ); @@ -417,6 +428,44 @@ NTSTATUS TCPConnect return Status; } +NTSTATUS TCPDisconnect +( PCONNECTION_ENDPOINT Connection, + UINT Flags, + PTDI_CONNECTION_INFORMATION ConnInfo, + PTDI_CONNECTION_INFORMATION ReturnInfo, + PTCP_COMPLETION_ROUTINE Complete, + PVOID Context ) { + NTSTATUS Status; + + TI_DbgPrint(DEBUG_TCP,("started\n")); + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + + switch( Flags & (TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE) ) { + case 0: + case TDI_DISCONNECT_ABORT: + Flags = 0; + break; + + case TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE: + Flags = 2; + break; + + case TDI_DISCONNECT_RELEASE: + Flags = 1; + break; + } + + Status = TCPTranslateError + ( OskitTCPShutdown( Connection->SocketContext, Flags ) ); + + TcpipRecursiveMutexLeave( &TCPLock ); + + TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status)); + + return Status; +} + NTSTATUS TCPClose ( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status; @@ -505,12 +554,11 @@ NTSTATUS TCPReceiveData DataLen, &Received, ReceiveFlags ) ); - + TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received)); /* Keep this request around ... there was no data yet */ - if( Status == STATUS_PENDING || - (Status == STATUS_SUCCESS && Received == 0) ) { + if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( !Bucket ) { diff --git a/reactos/drivers/lib/oskittcp/include/oskittcp.h b/reactos/drivers/lib/oskittcp/include/oskittcp.h index 83b087ccc7f..bf7f5192b86 100644 --- a/reactos/drivers/lib/oskittcp/include/oskittcp.h +++ b/reactos/drivers/lib/oskittcp/include/oskittcp.h @@ -107,6 +107,7 @@ extern void InitOskitTCP(); extern void DeinitOskitTCP(); extern void TimerOskitTCP(); extern void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len ); +extern int OskitTCPShutdown( void *socket, int disconn_type ); extern int OskitTCPSocket( void *Connection, void **ConnectionContext, int Af, int Type, int Proto ); extern void RegisterOskitTCPEventHandlers diff --git a/reactos/drivers/lib/oskittcp/oskittcp/interface.c b/reactos/drivers/lib/oskittcp/oskittcp/interface.c index 613f40cd02b..60ba5e5dfbb 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/interface.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/interface.c @@ -257,6 +257,11 @@ done: return (error); } +int OskitTCPShutdown( void *socket, int disconn_type ) { + struct socket *so = socket; + return soshutdown( socket, disconn_type ); +} + int OskitTCPClose( void *socket ) { struct socket *so = socket; so->so_connection = 0; @@ -333,9 +338,6 @@ void OskitTCPSetAddress( void *socket, inp->inp_lport = LocalPort; inp->inp_faddr.s_addr = RemoteAddress; inp->inp_fport = RemotePort; - DbgPrint("OSKIT: SET ADDR %x:%x -> %x:%x\n", - LocalAddress, LocalPort, - RemoteAddress, RemotePort); } void OskitTCPGetAddress( void *socket, @@ -350,9 +352,6 @@ void OskitTCPGetAddress( void *socket, *LocalPort = inp->inp_lport; *RemoteAddress = inp->inp_faddr.s_addr; *RemotePort = inp->inp_fport; - DbgPrint("OSKIT: GET ADDR %x:%x -> %x:%x\n", - *LocalAddress, *LocalPort, - *RemoteAddress, *RemotePort); } } diff --git a/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c b/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c index 3a491656af3..9766d4cc909 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/ip_output.c @@ -361,9 +361,14 @@ sendit: ip->ip_sum = in_cksum(m, hlen); #ifdef __REACTOS__ if( OtcpEvent.PacketSend ) { - OS_DbgPrint(OSK_MID_TRACE,("Mark\n")); + struct mbuf *new_m; + MGET( new_m, M_DONTWAIT, 0 ); + MCLGET( new_m, M_DONTWAIT ); + m_copydata( m, 0, htons(ip->ip_len), new_m->m_data ); + new_m->m_len = htons(ip->ip_len); error = OtcpEvent.PacketSend( OtcpEvent.ClientData, - m->m_data, m->m_len ); + new_m->m_data, new_m->m_len ); + m_free( new_m ); goto done; } #else @@ -485,9 +490,15 @@ sendorfree: m_freem(m); #else if( error == 0 && OtcpEvent.PacketSend ) { - OS_DbgPrint(OSK_MID_TRACE,("Mark\n")); + struct mbuf *new_m; + MGET( new_m, M_DONTWAIT, 0 ); + MCLGET( new_m, M_DONTWAIT ); + m_copydata( m, 0, htons(ip->ip_len), new_m->m_data ); + new_m->m_len = htons(ip->ip_len); error = OtcpEvent.PacketSend( OtcpEvent.ClientData, - m->m_data, m->m_len ); + new_m->m_data, new_m->m_len ); + m_free( new_m ); + goto done; } OS_DbgPrint(OSK_MID_TRACE,("Error from upper layer: %d\n", error)); diff --git a/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c b/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c index c328fc23116..a838cbfeb2e 100644 --- a/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c +++ b/reactos/drivers/lib/oskittcp/oskittcp/tcp_output.c @@ -576,7 +576,6 @@ send: else ti->ti_seq = htonl(tp->snd_max); ti->ti_ack = htonl(tp->rcv_nxt); - printf("ti->ti_ack = %d\n", ti->ti_ack); if (optlen) { (void)memcpy(ti + 1, opt, optlen); diff --git a/reactos/drivers/net/afd/afd/connect.c b/reactos/drivers/net/afd/afd/connect.c index 6413cf95c89..c4bcb581232 100644 --- a/reactos/drivers/net/afd/afd/connect.c +++ b/reactos/drivers/net/afd/afd/connect.c @@ -1,4 +1,4 @@ -/* $Id: connect.c,v 1.6 2004/11/30 04:49:50 arty Exp $ +/* $Id: connect.c,v 1.7 2004/12/04 23:29:54 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/connect.c @@ -203,8 +203,9 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( TargetAddress ); AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); - - return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT ); + + if( Status == STATUS_PENDING ) + return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT ); } else Status = STATUS_NO_MEMORY; break; diff --git a/reactos/drivers/net/afd/afd/info.c b/reactos/drivers/net/afd/afd/info.c index ffdfc68e597..82c8e25e15c 100644 --- a/reactos/drivers/net/afd/afd/info.c +++ b/reactos/drivers/net/afd/afd/info.c @@ -1,4 +1,4 @@ -/* $Id: info.c,v 1.4 2004/07/29 04:09:06 arty Exp $ +/* $Id: info.c,v 1.5 2004/12/04 23:29:54 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/info.c @@ -40,6 +40,10 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, case AFD_INFO_GROUP_ID_TYPE: InfoReq->Information.Ulong = 0; /* What is group id */ break; + + case AFD_INFO_BLOCKING_MODE: + InfoReq->Information.Ulong = 0; + break; default: AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n", diff --git a/reactos/drivers/net/afd/afd/main.c b/reactos/drivers/net/afd/afd/main.c index 256825ad4db..6b0396a40f2 100644 --- a/reactos/drivers/net/afd/afd/main.c +++ b/reactos/drivers/net/afd/afd/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.14 2004/11/30 04:49:50 arty Exp $ +/* $Id: main.c,v 1.15 2004/12/04 23:29:54 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/main.c @@ -226,6 +226,49 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, return STATUS_SUCCESS; } +NTSTATUS STDCALL +AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp) { + PFILE_OBJECT FileObject = IrpSp->FileObject; + PAFD_FCB FCB = FileObject->FsContext; + PAFD_DISCONNECT_INFO DisReq; + IO_STATUS_BLOCK Iosb; + PTDI_CONNECTION_INFORMATION ConnInfo; + NTSTATUS Status; + USHORT Flags = 0; + + if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE ); + + if( !(DisReq = LockRequest( Irp, IrpSp )) ) + return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, + Irp, 0, NULL, FALSE ); + + Status = TdiBuildNullConnectionInfo + ( &ConnInfo, FCB->RemoteAddress->Address[0].AddressType ); + + if( !NT_SUCCESS(Status) || !ConnInfo ) + return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, + Irp, 0, NULL, TRUE ); + + if( DisReq->DisconnectType & AFD_DISCONNECT_SEND ) + Flags |= TDI_DISCONNECT_RELEASE; + if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ) + Flags |= TDI_DISCONNECT_ABORT; + + Status = TdiDisconnect( FCB->Connection.Object, + &DisReq->Timeout, + Flags, + &Iosb, + NULL, + NULL, + FCB->AddressFrom, + ConnInfo); + + ExFreePool( ConnInfo ); + + return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE ); +} + NTSTATUS STDCALL AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -305,44 +348,81 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) case IOCTL_AFD_SET_CONTEXT: return AfdSetContext( DeviceObject, Irp, IrpSp ); - case IOCTL_AFD_WAIT_FOR_LISTEN: + case IOCTL_AFD_WAIT_FOR_LISTEN: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_WAIT_FOR_LISTEN\n")); - case IOCTL_AFD_ACCEPT: + break; + + case IOCTL_AFD_ACCEPT: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_ACCEPT\n")); - case IOCTL_AFD_DISCONNECT: - AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_DISCONNECT\n")); - case IOCTL_AFD_GET_TDI_HANDLES: + break; + + case IOCTL_AFD_DISCONNECT: + return AfdDisconnect( DeviceObject, Irp, IrpSp ); + + case IOCTL_AFD_GET_TDI_HANDLES: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_TDI_HANDLES\n")); - case IOCTL_AFD_SET_INFO: + break; + + case IOCTL_AFD_SET_INFO: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_INFO\n")); - case IOCTL_AFD_SET_CONNECT_DATA: + break; + + case IOCTL_AFD_SET_CONNECT_DATA: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_DATA\n")); - case IOCTL_AFD_SET_CONNECT_OPTIONS: + break; + + case IOCTL_AFD_SET_CONNECT_OPTIONS: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_OPTIONS\n")); - case IOCTL_AFD_SET_DISCONNECT_DATA: + break; + + case IOCTL_AFD_SET_DISCONNECT_DATA: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_DATA\n")); - case IOCTL_AFD_SET_DISCONNECT_OPTIONS: + break; + + case IOCTL_AFD_SET_DISCONNECT_OPTIONS: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_OPTIONS\n")); - case IOCTL_AFD_GET_CONNECT_DATA: + break; + + case IOCTL_AFD_GET_CONNECT_DATA: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_CONNECT_DATA\n")); - case IOCTL_AFD_GET_CONNECT_OPTIONS: + break; + + case IOCTL_AFD_GET_CONNECT_OPTIONS: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_CONNECT_OPTIONS\n")); - case IOCTL_AFD_GET_DISCONNECT_DATA: + break; + + case IOCTL_AFD_GET_DISCONNECT_DATA: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_DISCONNECT_DATA\n")); - case IOCTL_AFD_GET_DISCONNECT_OPTIONS: + break; + + case IOCTL_AFD_GET_DISCONNECT_OPTIONS: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_DISCONNECT_OPTIONS\n")); - case IOCTL_AFD_SET_CONNECT_DATA_SIZE: + break; + + case IOCTL_AFD_SET_CONNECT_DATA_SIZE: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_DATA_SIZE\n")); - case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE: + break; + + case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE\n")); - case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE: + break; + + case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE\n")); - case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE: + break; + + case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE\n")); - case IOCTL_AFD_DEFER_ACCEPT: + break; + + case IOCTL_AFD_DEFER_ACCEPT: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_DEFER_ACCEPT\n")); - case IOCTL_AFD_GET_PENDING_CONNECT_DATA: + break; + + case IOCTL_AFD_GET_PENDING_CONNECT_DATA: AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_GET_PENDING_CONNECT_DATA\n")); + break; + default: Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Information = 0; diff --git a/reactos/drivers/net/afd/afd/read.c b/reactos/drivers/net/afd/afd/read.c index 2f39124b763..3ddd4282682 100644 --- a/reactos/drivers/net/afd/afd/read.c +++ b/reactos/drivers/net/afd/afd/read.c @@ -1,4 +1,4 @@ -/* $Id: read.c,v 1.13 2004/11/30 04:49:50 arty Exp $ +/* $Id: read.c,v 1.14 2004/12/04 23:29:54 arty Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/read.c @@ -23,6 +23,10 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, *TotalBytesCopied = 0; PAFD_MAPBUF Map; + AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n", + BytesAvailable)); + + if( FCB->PollState & AFD_EVENT_CLOSE ) return STATUS_SUCCESS; if( !BytesAvailable ) return STATUS_PENDING; Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount); @@ -64,6 +68,31 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, return STATUS_SUCCESS; } +VOID ProcessClose( PAFD_FCB FCB ) { + PLIST_ENTRY NextIrpEntry; + PIRP NextIrp; + + AFD_DbgPrint(MID_TRACE,("Socket shutdown from remote side\n")); + + /* Kill remaining recv irps */ + while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { + NextIrpEntry = + RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); + NextIrp = + CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); + AFD_DbgPrint(MID_TRACE,("Completing recv %x (%x)\n", + NextIrp, STATUS_END_OF_FILE)); + NextIrp->IoStatus.Status = STATUS_SUCCESS; + NextIrp->IoStatus.Information = 0; + IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); + } + + /* Handle closing signal */ + FCB->PollState |= AFD_EVENT_CLOSE; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); +} + NTSTATUS DDKAPI ReceiveComplete ( PDEVICE_OBJECT DeviceObject, PIRP Irp, @@ -84,6 +113,8 @@ NTSTATUS DDKAPI ReceiveComplete if( !SocketAcquireStateLock( FCB ) ) return Status; FCB->ReceiveIrp.InFlightRequest = NULL; + FCB->Recv.Content = Irp->IoStatus.Information; + FCB->Recv.BytesUsed = 0; if( FCB->State == SOCKET_STATE_CLOSED ) { SocketStateUnlock( FCB ); @@ -91,10 +122,8 @@ NTSTATUS DDKAPI ReceiveComplete return STATUS_SUCCESS; } - if( NT_SUCCESS(Irp->IoStatus.Status) ) { - /* Update the receive window */ - FCB->Recv.Content = Irp->IoStatus.Information; - FCB->Recv.BytesUsed = 0; + if( NT_SUCCESS(Irp->IoStatus.Status) && + Irp->IoStatus.Information ) { /* Kick the user that receive would be possible now */ /* XXX Not implemented yet */ @@ -135,8 +164,7 @@ NTSTATUS DDKAPI ReceiveComplete } } - if( NT_SUCCESS(Status) && FCB->Recv.Window && !FCB->Recv.Content && - NT_SUCCESS(Irp->IoStatus.Status) ) { + if( FCB->Recv.Window && !FCB->Recv.Content ) { AFD_DbgPrint(MID_TRACE, ("Exhausted our buffer. Requesting new: %x\n", FCB)); @@ -151,25 +179,15 @@ NTSTATUS DDKAPI ReceiveComplete ReceiveComplete, FCB ); - SocketCalloutLeave( FCB ); - } else - FCB->PollState |= AFD_EVENT_RECEIVE; - } else { - /* Kill remaining recv irps */ - while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { - NextIrpEntry = - RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); - NextIrp = - CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); - AFD_DbgPrint(MID_TRACE,("Completing recv %x (%x)\n", - NextIrp, Status)); - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); - } + if( Status == STATUS_SUCCESS && + !FCB->ReceiveIrp.Iosb.Information ) { + ProcessClose( FCB ); + } - /* Handle closing signal */ - FCB->PollState |= AFD_EVENT_CLOSE; + SocketCalloutLeave( FCB ); + } else Status = STATUS_SUCCESS; + } else { + ProcessClose( FCB ); } if( FCB->Recv.Content ) { @@ -215,41 +233,70 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* Launch a new recv request if we have no data */ - if( FCB->Recv.Window && !(FCB->Recv.Content - FCB->Recv.BytesUsed) && - !FCB->ReceiveIrp.InFlightRequest ) { + if( !(FCB->PollState & AFD_EVENT_CLOSE ) ) { + AFD_DbgPrint(MID_TRACE,("Not EOF yet\n")); + if( FCB->Recv.Window && !(FCB->Recv.Content - FCB->Recv.BytesUsed) && + !FCB->ReceiveIrp.InFlightRequest ) { + FCB->Recv.Content = 0; + FCB->Recv.BytesUsed = 0; + AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n")); + + SocketCalloutEnter( FCB ); + + Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest, + FCB->Connection.Object, + TDI_RECEIVE_NORMAL, + FCB->Recv.Window, + FCB->Recv.Size, + &FCB->ReceiveIrp.Iosb, + ReceiveComplete, + FCB ); + + if( Status == STATUS_SUCCESS ) { + if( !FCB->ReceiveIrp.Iosb.Information ) { + AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n")); + ProcessClose( FCB ); + } + FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; + } + + SocketCalloutLeave( FCB ); + } else { + AFD_DbgPrint(MID_TRACE,("There is probably more data here\n")); + if( FCB->ReceiveIrp.InFlightRequest ) { + AFD_DbgPrint(MID_TRACE,("We're waiting on a previous irp\n")); + Status = STATUS_PENDING; + } else { + AFD_DbgPrint(MID_TRACE,("The buffer is likely not empty\n")); + Status = STATUS_SUCCESS; + } + } + } else { + AFD_DbgPrint(MID_TRACE,("EOF Happened already\n")); FCB->Recv.Content = 0; FCB->Recv.BytesUsed = 0; - AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n")); + Status = STATUS_SUCCESS; - SocketCalloutEnter( FCB ); + ProcessClose( FCB ); + } - Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest, - FCB->Connection.Object, - TDI_RECEIVE_NORMAL, - FCB->Recv.Window, - FCB->Recv.Size, - &FCB->ReceiveIrp.Iosb, - ReceiveComplete, - FCB ); - - SocketCalloutLeave( FCB ); - } else Status = STATUS_SUCCESS; - - if( NT_SUCCESS(Status) ) - Status = TryToSatisfyRecvRequestFromBuffer - ( FCB, RecvReq, &TotalBytesCopied ); + if( NT_SUCCESS(Status) ) { + AFD_DbgPrint(MID_TRACE,("TryToSatisfy\n")); + Status = TryToSatisfyRecvRequestFromBuffer + ( FCB, RecvReq, &TotalBytesCopied ); + } if( Status != STATUS_PENDING || RecvReq->AfdFlags & AFD_IMMEDIATE ) { - if( Status == STATUS_PENDING ) { - AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); - Status = STATUS_CANT_WAIT; - TotalBytesCopied = 0; - } - UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); - return UnlockAndMaybeComplete( FCB, Status, Irp, - TotalBytesCopied, NULL, TRUE ); + if( Status == STATUS_PENDING ) { + AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); + Status = STATUS_CANT_WAIT; + TotalBytesCopied = 0; + } + UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); + return UnlockAndMaybeComplete( FCB, Status, Irp, + TotalBytesCopied, NULL, TRUE ); } else { - return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); + return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); } } diff --git a/reactos/drivers/net/afd/afd/tdi.c b/reactos/drivers/net/afd/afd/tdi.c index ce2b74acc76..1d0af0a149e 100644 --- a/reactos/drivers/net/afd/afd/tdi.c +++ b/reactos/drivers/net/afd/afd/tdi.c @@ -1086,4 +1086,58 @@ NTSTATUS TdiSendDatagram( return Status; } +NTSTATUS TdiDisconnect( + PFILE_OBJECT TransportObject, + PLARGE_INTEGER Time, + USHORT Flags, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext, + PTDI_CONNECTION_INFORMATION RequestConnectionInfo, + PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) { + PDEVICE_OBJECT DeviceObject; + NTSTATUS Status; + KEVENT Event; + PIRP Irp; + + DeviceObject = IoGetRelatedDeviceObject(TransportObject); + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject)); + + DeviceObject = IoGetRelatedDeviceObject(TransportObject); + if (!DeviceObject) { + AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); + return STATUS_INVALID_PARAMETER; + } + + Irp = TdiBuildInternalDeviceControlIrp + ( TDI_SEND_DATAGRAM, /* Sub function */ + DeviceObject, /* Device object */ + TransportObject, /* File object */ + &Event, /* Event */ + Iosb ); /* Status */ + + if (!Irp) { + AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + return STATUS_INSUFFICIENT_RESOURCES; + } + + TdiBuildDisconnect + (Irp, /* I/O Request Packet */ + DeviceObject, /* Device object */ + TransportObject, /* File object */ + CompletionRoutine, /* Completion routine */ + CompletionContext, /* Completion context */ + Time, /* Time */ + Flags, /* Disconnect flags */ + RequestConnectionInfo, /* Indication of who to disconnect */ + ReturnConnectionInfo); /* Indication of who disconnected */ + + Status = TdiCall(Irp, DeviceObject, &Event, Iosb); + + return Status; +} + /* EOF */ diff --git a/reactos/drivers/net/afd/include/tdi_proto.h b/reactos/drivers/net/afd/include/tdi_proto.h index 0983f6c1bd2..4e0efa7bd68 100644 --- a/reactos/drivers/net/afd/include/tdi_proto.h +++ b/reactos/drivers/net/afd/include/tdi_proto.h @@ -14,4 +14,14 @@ NTSTATUS TdiOpenConnectionEndpointFile(PUNICODE_STRING DeviceName, NTSTATUS TdiCloseDevice(HANDLE Handle, PFILE_OBJECT FileObject); +NTSTATUS TdiDisconnect +( PFILE_OBJECT TransportObject, + PLARGE_INTEGER Time, + USHORT Flags, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext, + PTDI_CONNECTION_INFORMATION RequestConnectionInfo, + PTDI_CONNECTION_INFORMATION ReturnConnectionInfo ); + #endif/*_TDI_PROTO_H*/ diff --git a/reactos/drivers/net/tcpip/datalink/lan.c b/reactos/drivers/net/tcpip/datalink/lan.c index 341221141ac..183a7244503 100644 --- a/reactos/drivers/net/tcpip/datalink/lan.c +++ b/reactos/drivers/net/tcpip/datalink/lan.c @@ -228,8 +228,6 @@ VOID STDCALL LanReceiveWorker( PVOID Context ) { IPPacket.ContigSize, IPPacket.TotalSize, BytesTransferred)); - /*OskitDumpBuffer( IPPacket.Header, IPPacket.TotalSize );*/ - PacketType = PC(IPPacket.NdisPacket)->PacketType; IPPacket.Position = 0; @@ -575,8 +573,6 @@ VOID LANTransmit( ((PCHAR)LinkAddress)[5] & 0xff)); } - /*OskitDumpBuffer( Data, Size );*/ - TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql ); TI_DbgPrint(MID_TRACE, ("NdisSend\n")); NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket); diff --git a/reactos/drivers/net/tcpip/include/debug.h b/reactos/drivers/net/tcpip/include/debug.h index fc0eb72e8b3..95f649cf380 100644 --- a/reactos/drivers/net/tcpip/include/debug.h +++ b/reactos/drivers/net/tcpip/include/debug.h @@ -19,7 +19,7 @@ #define DEBUG_MEMORY 0x00000200 #define DEBUG_PBUFFER 0x00000400 #define DEBUG_IRP 0x00000800 -#define DEBUG_REFCOUNT 0x00001000 +#define DEBUG_TCPIF 0x00001000 #define DEBUG_ADDRFILE 0x00002000 #define DEBUG_DATALINK 0x00004000 #define DEBUG_ARP 0x00008000 diff --git a/reactos/drivers/net/tcpip/include/tcp.h b/reactos/drivers/net/tcpip/include/tcp.h index 0c0b3006de1..3d7ef448fc1 100644 --- a/reactos/drivers/net/tcpip/include/tcp.h +++ b/reactos/drivers/net/tcpip/include/tcp.h @@ -113,6 +113,14 @@ NTSTATUS TCPConnect( PTCP_COMPLETION_ROUTINE Complete, PVOID Context); +NTSTATUS TCPDisconnect( + PCONNECTION_ENDPOINT Connection, + UINT Flags, + PTDI_CONNECTION_INFORMATION ConnInfo, + PTDI_CONNECTION_INFORMATION ReturnInfo, + PTCP_COMPLETION_ROUTINE Complete, + PVOID Context); + NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog, diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index c07dde5201a..4545fc17a15 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -1,3 +1,4 @@ + /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS TCP/IP protocol driver @@ -411,14 +412,18 @@ NTSTATUS DispTdiDisconnect( * Status of operation */ { - PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters; + NTSTATUS Status; + PTDI_REQUEST_KERNEL_DISCONNECT DisReq; + PCONNECTION_ENDPOINT Connection; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); - Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters; + DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters; + + /* Get associated connection endpoint file object. Quit if none exists */ TranContext = IrpSp->FileObject->FsContext; if (!TranContext) { @@ -426,56 +431,23 @@ NTSTATUS DispTdiDisconnect( return STATUS_INVALID_CONNECTION; } - switch (Parameters->QueryType) - { - case TDI_QUERY_ADDRESS_INFO: - { - PTDI_ADDRESS_INFO AddressInfo; - PADDRESS_FILE AddrFile; - PTA_IP_ADDRESS Address; - - AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress); - - switch ((ULONG)IrpSp->FileObject->FsContext2) { - case TDI_TRANSPORT_ADDRESS_FILE: - AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; - break; - - case TDI_CONNECTION_FILE: - AddrFile = ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->AddressFile; - break; - - default: - TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); - return STATUS_INVALID_PARAMETER; - } - - if (!AddrFile) { - TI_DbgPrint(MID_TRACE, ("No address file object.\n")); - return STATUS_INVALID_PARAMETER; - } - - if (MmGetMdlByteCount(Irp->MdlAddress) < - (sizeof(TDI_ADDRESS_INFO) + sizeof(TDI_ADDRESS_IP))) { - TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); - return STATUS_BUFFER_OVERFLOW; - } - - Address = (PTA_IP_ADDRESS)&AddressInfo->Address; - Address->TAAddressCount = 1; - Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; - Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; - Address->Address[0].Address[0].sin_port = AddrFile->Port; - Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address; - RtlZeroMemory( - &Address->Address[0].Address[0].sin_zero, - sizeof(Address->Address[0].Address[0].sin_zero)); - - return STATUS_SUCCESS; - } + Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + if (!Connection) { + TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); + return STATUS_INVALID_CONNECTION; } - return STATUS_NOT_IMPLEMENTED; + Status = TCPDisconnect( + TranContext->Handle.ConnectionContext, + DisReq->RequestFlags, + DisReq->RequestConnectionInformation, + DisReq->ReturnConnectionInformation, + DispDataRequestComplete, + Irp ); + + TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status)); + + return Status; } diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index 218597f1d6c..155a1b96775 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -12,9 +12,9 @@ #define NDEBUG #ifndef NDEBUG -DWORD DebugTraceLevel = DEBUG_TCP; +DWORD DebugTraceLevel = DEBUG_ULTRA; #else -DWORD DebugTraceLevel = 0; /*DEBUG_IP | DEBUG_PBUFFER | DEBUG_DATALINK;*/ +DWORD DebugTraceLevel = 0; #endif /* NDEBUG */ PDEVICE_OBJECT TCPDeviceObject = NULL; diff --git a/reactos/lib/msafd/include/msafd.h b/reactos/lib/msafd/include/msafd.h index 3235244cda2..298e71e130a 100644 --- a/reactos/lib/msafd/include/msafd.h +++ b/reactos/lib/msafd/include/msafd.h @@ -460,6 +460,9 @@ VOID SockProcessQueuedAsyncSelect( PIO_STATUS_BLOCK IoStatusBlock ); +DWORD MsafdReturnWithErrno( NTSTATUS Status, LPINT Errno, DWORD Received, + LPDWORD ReturnedBytes ); + typedef VOID (*PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock); #endif /* __MSAFD_H */ diff --git a/reactos/lib/msafd/misc/dllmain.c b/reactos/lib/msafd/misc/dllmain.c index 63e1e6d5df8..ba3b883d97a 100644 --- a/reactos/lib/msafd/misc/dllmain.c +++ b/reactos/lib/msafd/misc/dllmain.c @@ -259,6 +259,24 @@ error: } +DWORD MsafdReturnWithErrno( NTSTATUS Status, LPINT Errno, DWORD Received, + LPDWORD ReturnedBytes ) { + switch (Status) { + case STATUS_CANT_WAIT: *Errno = WSAEWOULDBLOCK; break; + case STATUS_TIMEOUT: + case STATUS_SUCCESS: + /* Return Number of bytes Read */ + if( ReturnedBytes ) *ReturnedBytes = Received; break; + case STATUS_PENDING: *Errno = WSA_IO_PENDING; break; + case STATUS_BUFFER_OVERFLOW: *Errno = WSAEMSGSIZE; break; + default: *Errno = WSAEINVAL; break; + } + + /* Success */ + return Status == STATUS_SUCCESS ? 0 : SOCKET_ERROR; +} + + INT WSPAPI WSPCloseSocket( @@ -357,7 +375,8 @@ WSPBind( NtClose( SockEvent ); - return 0; + return MsafdReturnWithErrno + ( IOSB.Status, lpErrno, IOSB.Information, NULL ); } int @@ -403,7 +422,8 @@ WSPListen( NtClose( SockEvent ); - return 0; + return MsafdReturnWithErrno + ( IOSB.Status, lpErrno, IOSB.Information, NULL ); } @@ -430,7 +450,7 @@ WSPSelect( Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); - if( !NT_SUCCESS(Status) ) return -1; + if( !NT_SUCCESS(Status) ) return SOCKET_ERROR; /* Find out how many sockets we have, and how large the buffer needs * to be */ @@ -544,6 +564,7 @@ WSPSelect( } NtClose( SockEvent ); + switch( IOSB.Status ) { case STATUS_SUCCESS: case STATUS_TIMEOUT: *lpErrno = 0; break; @@ -913,8 +934,8 @@ WSPConnect( AFD_DbgPrint(MID_TRACE,("Ending\n")); NtClose( SockEvent ); - - return Status; + + return MsafdReturnWithErrno( IOSB.Status, lpErrno, 0, NULL ); } int WSPAPI @@ -983,7 +1004,7 @@ WSPShutdown( NtClose( SockEvent ); - return 0; + return MsafdReturnWithErrno( IOSB.Status, lpErrno, 0, NULL ); } @@ -1033,13 +1054,13 @@ WSPIoctl( switch( dwIoControlCode ) { case FIONBIO: - if( cbInBuffer < sizeof(INT) ) return -1; + if( cbInBuffer < sizeof(INT) ) return SOCKET_ERROR; Socket->SharedData.NonBlocking = *((PINT)lpvInBuffer) ? 1 : 0; AFD_DbgPrint(MID_TRACE,("[%x] Set nonblocking %d\n", Handle, Socket->SharedData.NonBlocking)); return 0; default: - return -1; + return SOCKET_ERROR; } } diff --git a/reactos/lib/msafd/misc/sndrcv.c b/reactos/lib/msafd/misc/sndrcv.c index 04d1d160d90..b467151b917 100644 --- a/reactos/lib/msafd/misc/sndrcv.c +++ b/reactos/lib/msafd/misc/sndrcv.c @@ -10,9 +10,11 @@ * Alex 16/07/2004 - Complete Rewrite */ +#define DBG #include #include #include +#include INT WSPAPI @@ -101,7 +103,8 @@ WSPRecv( HANDLE Event; HANDLE SockEvent; PSOCKET_INFORMATION Socket; - + + AFD_DbgPrint(MID_TRACE,("Called\n")); /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); @@ -185,45 +188,29 @@ WSPRecv( /* Wait for completition of not overlapped */ if (Status == STATUS_PENDING && lpOverlapped == NULL) { - WaitForSingleObject(SockEvent, 0); // BUGBUG, shouldn wait infintely for receive... - Status = IOSB->Status; + /* It's up to the protocol to time out recv. We must wait + * until the protocol decides it's had enough. */ + WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB->Status; } NtClose( SockEvent ); - /* Return the Flags */ - *ReceiveFlags = 0; + AFD_DbgPrint(MID_TRACE,("Status %x Information %d\n", + Status, IOSB->Information)); + + /* Return the Flags */ + *ReceiveFlags = 0; + switch (Status) { - case STATUS_CANT_WAIT: - return WSAEWOULDBLOCK; - - case STATUS_SUCCESS: - break; - - case STATUS_PENDING : - return WSA_IO_PENDING; - - case STATUS_BUFFER_OVERFLOW: - return WSAEMSGSIZE; - - case STATUS_RECEIVE_EXPEDITED: - *ReceiveFlags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED : - *ReceiveFlags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL : - *ReceiveFlags = MSG_PARTIAL; - break; + case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break; + case STATUS_RECEIVE_PARTIAL_EXPEDITED: + *ReceiveFlags = MSG_PARTIAL | MSG_OOB; break; + case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break; } - - /* Return Number of bytes Read */ - *lpNumberOfBytesRead = (DWORD)IOSB->Information; - - /* Success */ - return STATUS_SUCCESS; + + return MsafdReturnWithErrno + ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); } int @@ -341,39 +328,18 @@ WSPRecvFrom( NtClose( SockEvent ); - /* Return the Flags */ - *ReceiveFlags = 0; + /* Return the Flags */ + *ReceiveFlags = 0; + switch (Status) { - case STATUS_CANT_WAIT: - return WSAEWOULDBLOCK; + case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; break; + case STATUS_RECEIVE_PARTIAL_EXPEDITED: + *ReceiveFlags = MSG_PARTIAL | MSG_OOB; break; + case STATUS_RECEIVE_PARTIAL: *ReceiveFlags = MSG_PARTIAL; break; + } - case STATUS_SUCCESS: - break; - - case STATUS_PENDING : - return WSA_IO_PENDING; - - case STATUS_BUFFER_OVERFLOW: - return WSAEMSGSIZE; - - case STATUS_RECEIVE_EXPEDITED: - *ReceiveFlags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED : - *ReceiveFlags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL : - *ReceiveFlags = MSG_PARTIAL; - break; - } - - /* Return Number of bytes Read */ - *lpNumberOfBytesRead = (DWORD)IOSB->Information; - - /* Success */ - return STATUS_SUCCESS; + return MsafdReturnWithErrno + ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); } @@ -483,13 +449,10 @@ WSPSend( return WSA_IO_PENDING; } - /* Return Number of bytes Sent */ - *lpNumberOfBytesSent = (DWORD)IOSB->Information; - AFD_DbgPrint(MID_TRACE,("Leaving (Success, %d)\n", IOSB->Information)); - /* Success */ - return STATUS_SUCCESS; + return MsafdReturnWithErrno + ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); } int @@ -611,11 +574,8 @@ WSPSendTo( return WSA_IO_PENDING; } - /* Return Number of bytes Sent */ - *lpNumberOfBytesSent = (DWORD)IOSB->Information; - - /* Success */ - return STATUS_SUCCESS; + return MsafdReturnWithErrno + ( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); } INT WSPAPI