- Improvements for select/implementation of event select.

- Added EventSelect PKEVENT, and other bits needed in AFD_FCB to implement
  event select.
- Select and event select are now properly notified on socket hangup.
- Added more places where state changes are needed.
- PollReeval now has the alternate goal of firing the event select event.
- Fixed crash with unsupported protocols, re: null device
- Set AFD_EVENT_SEND and AFD_EVENT_RECEIVE appropriately on connect complete.
- Fixed sending FIN from a dying socket and receiving SEL_FIN on one in tcpip,
  by adding an additional way to lookup sockets.
- Removed even more spew.
- Small speedup: don't need to redo checksum in tcp_input.  It's already done
  in our ip defrag code.

svn path=/trunk/; revision=11765
This commit is contained in:
Art Yerkes 2004-11-21 20:54:52 +00:00
parent 55ff4ad170
commit 23398b098d
14 changed files with 240 additions and 58 deletions

View file

@ -19,37 +19,47 @@ int TCPSocketState(void *ClientData,
void *WhichSocket,
void *WhichConnection,
OSK_UINT NewState ) {
NTSTATUS Status = STATUS_SUCCESS;
PCONNECTION_ENDPOINT Connection = WhichConnection;
PTCP_COMPLETION_ROUTINE Complete;
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
TI_DbgPrint(MID_TRACE,("Called: NewState %x (Conn %x)\n",
NewState, Connection));
if( !Connection ) {
TI_DbgPrint(MID_TRACE,("Socket closing.\n"));
return 0;
}
TI_DbgPrint(MID_TRACE,("Called: NewState %x (Conn %x) (Change %x)\n",
NewState, Connection,
Connection ? Connection->State ^ NewState :
NewState));
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
if( (NewState & SEL_CONNECT) &&
!(Connection->State & SEL_CONNECT) ) {
if( !Connection ) {
TI_DbgPrint(MID_TRACE,("Socket closing.\n"));
Connection = FileFindConnectionByContext( WhichSocket );
if( !Connection ) {
TcpipRecursiveMutexLeave( &TCPLock );
return 0;
} else
TI_DbgPrint(MID_TRACE,("Found socket %x\n", Connection));
}
if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) &&
!(Connection->State & (SEL_CONNECT | SEL_FIN)) ) {
while( !IsListEmpty( &Connection->ConnectRequest ) ) {
Connection->State |= SEL_CONNECT;
Connection->State |= NewState & (SEL_CONNECT | SEL_FIN);
Entry = RemoveHeadList( &Connection->ConnectRequest );
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Complete = Bucket->Request.RequestNotifyObject;
TI_DbgPrint(MID_TRACE,
("Completing Connect Request %x\n", Bucket->Request));
if( NewState & SEL_FIN ) Status = STATUS_CONNECTION_REFUSED;
TcpipRecursiveMutexLeave( &TCPLock );
Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
Complete( Bucket->Request.RequestContext, Status, 0 );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
/* Frees the bucket allocated in TCPConnect */
PoolFreeBuffer( Bucket );
}
} else if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) {
}
if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) {
TI_DbgPrint(MID_TRACE,("Readable (or closed): irp list %s\n",
IsListEmpty(&Connection->ReceiveRequest) ?
"empty" : "nonempty"));
@ -81,6 +91,7 @@ int TCPSocketState(void *ClientData,
("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
if( (NewState & SEL_FIN) && !RecvLen ) {
TI_DbgPrint(MID_TRACE, ("EOF From socket\n"));
Status = STATUS_END_OF_FILE;
Received = 0;
} else {

View file

@ -155,9 +155,7 @@ int OskitTCPRecv( void *connection,
&tcp_flags );
if( error == 0 ) {
OS_DbgPrint(OSK_MID_TRACE,("Successful read from TCP:\n"));
*OutLen = Len - uio.uio_resid;
OskitDumpBuffer( Data, *OutLen );
}
return error;
@ -203,8 +201,6 @@ int OskitTCPBind( void *socket, void *connection,
addr.sa_family = addr.sa_len;
addr.sa_len = sizeof(struct sockaddr);
OskitDumpBuffer( (OSK_PCHAR)&addr, sizeof(addr) );
error = sobind(so, &sabuf);
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
@ -274,7 +270,6 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
int error = 0;
if ( !m )
return ENOBUFS;
OskitDumpBuffer( Data, Len );
error = sosend( socket, NULL, NULL, m, NULL, 0 );
*OutLen = Len;
return error;
@ -318,8 +313,6 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
("OskitTCPReceiveDatagram: %d (%d header) Bytes\n", Len,
IpHeaderLen));
OskitDumpBuffer( Data, Len );
tcp_input(Ip, IpHeaderLen);
/* The buffer Ip is freed by tcp_input */

View file

@ -289,12 +289,14 @@ tcp_input(m, iphlen)
ti->ti_x1 = 0;
ti->ti_len = (u_short)tlen;
HTONS(ti->ti_len);
#ifndef __REACTOS__ /* Checksum already done in IPReceive */
ti->ti_sum = in_cksum(m, len);
if (ti->ti_sum) {
printf("TCP: Bad Checksum\n");
tcpstat.tcps_rcvbadsum++;
goto drop;
}
#endif
#endif /* TUBA_INCLUDE */
/*

View file

@ -417,8 +417,6 @@ m_copydata(m, off, len, cp)
panic("m_copydata");
count = min(m->m_len - off, len);
bcopy(mtod(m, caddr_t) + off, cp, count);
OS_DbgPrint(OSK_MID_TRACE,("buf %x, len %d\n", m, count));
OskitDumpBuffer(m->m_data, count);
len -= count;
cp += count;
off = 0;

View file

@ -1,4 +1,4 @@
/* $Id: bind.c,v 1.5 2004/10/03 20:36:45 arty Exp $
/* $Id: bind.c,v 1.6 2004/11/21 20:54:52 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/bind.c
@ -19,6 +19,11 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) {
AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n",
FCB->LocalAddress->Address[0].AddressType));
if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) {
AFD_DbgPrint(MID_TRACE,("Null Device\n"));
return STATUS_NO_SUCH_DEVICE;
}
if( FCB->LocalAddress ) {
Status = TdiOpenAddressFile
( &FCB->TdiDeviceName,

View file

@ -1,4 +1,4 @@
/* $Id: connect.c,v 1.4 2004/10/03 21:16:27 arty Exp $
/* $Id: connect.c,v 1.5 2004/11/21 20:54:52 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/connect.c
@ -13,7 +13,14 @@
#include "debug.h"
NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
NTSTATUS Status = TdiOpenConnectionEndpointFile
NTSTATUS Status;
if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) {
AFD_DbgPrint(MID_TRACE,("Null Device\n"));
return STATUS_NO_SUCH_DEVICE;
}
Status = TdiOpenConnectionEndpointFile
( &FCB->TdiDeviceName,
&FCB->Connection.Handle,
&FCB->Connection.Object );
@ -55,12 +62,12 @@ NTSTATUS DDKAPI StreamSocketConnectComplete
Irp->IoStatus.Status));
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
FCB->PollState |= AFD_EVENT_CONNECT;
FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND;
FCB->State = SOCKET_STATE_CONNECTED;
AFD_DbgPrint(MID_TRACE,("Going to connected state %d\n", FCB->State));
PollReeval( FCB->DeviceExt, FCB->FileObject );
} else {
FCB->PollState |= AFD_EVENT_CONNECT_FAIL;
FCB->PollState |= AFD_EVENT_CONNECT_FAIL | AFD_EVENT_RECEIVE;
AFD_DbgPrint(MID_TRACE,("Going to bound state\n"));
FCB->State = SOCKET_STATE_BOUND;
PollReeval( FCB->DeviceExt, FCB->FileObject );

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.12 2004/11/17 05:17:22 arty Exp $
/* $Id: main.c,v 1.13 2004/11/21 20:54:52 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/main.c
@ -163,8 +163,6 @@ VOID DestroySocket( PAFD_FCB FCB ) {
return;
}
FCB->PollState |= AFD_EVENT_CLOSE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
/* After PoolReeval, this FCB should not be involved in any outstanding
* poll requests */
@ -211,10 +209,11 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB));
FileObject->FsContext = NULL;
FCB->PollState |= AFD_EVENT_CLOSE;
PollReeval( FCB->DeviceExt, FileObject );
if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect );
FileObject->FsContext = NULL;
DestroySocket( FCB );
Irp->IoStatus.Status = STATUS_SUCCESS;
@ -280,6 +279,12 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
case IOCTL_AFD_SELECT:
return AfdSelect( DeviceObject, Irp, IrpSp );
case IOCTL_AFD_EVENT_SELECT:
return AfdEventSelect( DeviceObject, Irp, IrpSp );
case IOCTL_AFD_ENUM_NETWORK_EVENTS:
return AfdEnumEvents( DeviceObject, Irp, IrpSp );
case IOCTL_AFD_RECV_DATAGRAM:
return AfdPacketSocketReadData( DeviceObject, Irp, IrpSp );
@ -333,8 +338,6 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE\n"));
case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE:
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE\n"));
case IOCTL_AFD_EVENT_SELECT:
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_EVENT_SELECT\n"));
case IOCTL_AFD_DEFER_ACCEPT:
AFD_DbgPrint(MIN_TRACE, ("IOCTL_AFD_DEFER_ACCEPT\n"));
case IOCTL_AFD_GET_PENDING_CONNECT_DATA:

View file

@ -1,4 +1,4 @@
/* $Id: read.c,v 1.11 2004/11/17 05:17:22 arty Exp $
/* $Id: read.c,v 1.12 2004/11/21 20:54:52 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/read.c
@ -89,9 +89,6 @@ NTSTATUS DDKAPI ReceiveComplete
return STATUS_SUCCESS;
}
/* Reset in flight request because the last has been completed */
FCB->ReceiveIrp.InFlightRequest = NULL;
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
/* Update the receive window */
FCB->Recv.Content = Irp->IoStatus.Information;
@ -153,8 +150,10 @@ NTSTATUS DDKAPI 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]);
@ -166,14 +165,18 @@ NTSTATUS DDKAPI ReceiveComplete
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
}
/* Handle closing signal */
FCB->PollState |= AFD_EVENT_CLOSE;
}
if( FCB->Recv.Content ) {
FCB->PollState |= AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
} else
FCB->PollState &= ~AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
SocketStateUnlock( FCB );
if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
@ -195,6 +198,10 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
FCB->EventsFired &= ~AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
Irp, 0, NULL, FALSE );
@ -415,10 +422,11 @@ PacketSocketRecvComplete(
if( !IsListEmpty( &FCB->DatagramList ) ) {
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
FCB->PollState |= AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
} else
FCB->PollState &= ~AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
/* Now relaunch the datagram request */
SocketCalloutEnter( FCB );
@ -455,6 +463,9 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
FCB->EventsFired &= ~AFD_EVENT_RECEIVE;
/* Check that the socket is bound */
if( FCB->State != SOCKET_STATE_BOUND )
return UnlockAndMaybeComplete
@ -481,22 +492,38 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
&DatagramRecv->ListEntry );
Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = DatagramRecv->Len;
if( IsListEmpty( &FCB->DatagramList ) )
FCB->PollState &= ~AFD_EVENT_RECEIVE;
else
FCB->PollState |= AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return UnlockAndMaybeComplete
( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
} else {
Status = SatisfyPacketRecvRequest
( FCB, Irp, DatagramRecv,
(PUINT)&Irp->IoStatus.Information );
if( IsListEmpty( &FCB->DatagramList ) )
FCB->PollState &= ~AFD_EVENT_RECEIVE;
else
FCB->PollState |= AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return UnlockAndMaybeComplete
( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
}
} else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
FCB->PollState &= ~AFD_EVENT_RECEIVE;
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
Status = STATUS_CANT_WAIT;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
} else {
FCB->PollState &= ~AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
}
}

View file

@ -1,4 +1,4 @@
/* $Id: select.c,v 1.6 2004/11/17 05:17:22 arty Exp $
/* $Id: select.c,v 1.7 2004/11/21 20:54:52 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/select.c
@ -172,6 +172,72 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
return Status;
}
NTSTATUS STDCALL
AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
PFILE_OBJECT FileObject = IrpSp->FileObject;
NTSTATUS Status = STATUS_NO_MEMORY;
PAFD_EVENT_SELECT_INFO EventSelectInfo =
(PAFD_EVENT_SELECT_INFO)LockRequest( Irp, IrpSp );
PAFD_FCB FCB = FileObject->FsContext;
AFD_DbgPrint(MID_TRACE,("Called (Event %x Triggers %x)\n",
EventSelectInfo->EventObject,
EventSelectInfo->Events));
if( !SocketAcquireStateLock( FCB ) ) {
UnlockRequest( Irp, IrpSp );
return LostSocket( Irp, FALSE );
}
FCB->EventSelectTriggers = FCB->EventsFired = 0;
if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect );
FCB->EventSelect = NULL;
if( EventSelectInfo->EventObject && EventSelectInfo->Events ) {
Status = ObReferenceObjectByHandle( (PVOID)EventSelectInfo->
EventObject,
FILE_ALL_ACCESS,
NULL,
KernelMode,
(PVOID *)&FCB->EventSelect,
NULL );
if( !NT_SUCCESS(Status) )
FCB->EventSelect = NULL;
else
FCB->EventSelectTriggers = EventSelectInfo->Events;
} else /* Work done, cancelling select */
Status = STATUS_SUCCESS;
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp,
0, NULL, TRUE );
}
NTSTATUS STDCALL
AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_ENUM_NETWORK_EVENTS_INFO EnumReq =
(PAFD_ENUM_NETWORK_EVENTS_INFO)LockRequest( Irp, IrpSp );
PAFD_FCB FCB = FileObject->FsContext;
AFD_DbgPrint(MID_TRACE,("Called (FCB %x)\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) {
UnlockRequest( Irp, IrpSp );
return LostSocket( Irp, FALSE );
}
EnumReq->PollEvents = FCB->PollState;
RtlZeroMemory( EnumReq->EventStatus, sizeof(EnumReq->EventStatus) );
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp,
0, NULL, TRUE );
}
/* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */
BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
UINT i;
@ -210,14 +276,35 @@ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
PAFD_ACTIVE_POLL Poll = NULL;
PLIST_ENTRY ThePollEnt = NULL;
PAFD_FCB FCB;
KIRQL OldIrql;
PAFD_POLL_INFO PollReq;
PKEVENT EventSelect = NULL;
AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n",
DeviceExt, FileObject));
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
/* Take care of any event select signalling */
FCB = (PAFD_FCB)FileObject->FsContext;
/* Not sure if i can do this at DISPATCH_LEVEL ... try it at passive */
AFD_DbgPrint(MID_TRACE,("Current State: %x, Events Fired: %x, "
"Select Triggers %x\n",
FCB->PollState, FCB->EventsFired,
FCB->EventSelectTriggers));
if( FCB->PollState & ~FCB->EventsFired & FCB->EventSelectTriggers ) {
FCB->EventsFired |= FCB->PollState;
EventSelect = FCB->EventSelect;
}
if( !FCB ) {
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
return;
}
/* Now signal normal select irps */
ThePollEnt = DeviceExt->Polls.Flink;
while( ThePollEnt != &DeviceExt->Polls ) {
@ -235,5 +322,8 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
AFD_DbgPrint(MID_TRACE,("Setting event %x\n", EventSelect));
if( EventSelect ) KeSetEvent( EventSelect, IO_NETWORK_INCREMENT, FALSE );
AFD_DbgPrint(MID_TRACE,("Leaving\n"));
}

View file

@ -1,4 +1,4 @@
/* $Id: write.c,v 1.11 2004/11/15 18:24:57 arty Exp $
/* $Id: write.c,v 1.12 2004/11/21 20:54:52 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/write.c
@ -163,6 +163,9 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
FCB->EventsFired &= ~AFD_EVENT_SEND;
if( !(SendReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, TotalBytesCopied, NULL, FALSE );
@ -307,6 +310,9 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
FCB->EventsFired &= ~AFD_EVENT_SEND;
/* Check that the socket is bound */
if( FCB->State != SOCKET_STATE_BOUND )
return UnlockAndMaybeComplete

View file

@ -1,4 +1,4 @@
/* $Id: afd.h,v 1.24 2004/11/17 05:17:22 arty Exp $
/* $Id: afd.h,v 1.25 2004/11/21 20:54:52 arty Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -82,6 +82,7 @@ typedef struct _AFD_ACTIVE_POLL {
PAFD_DEVICE_EXTENSION DeviceExt;
KDPC TimeoutDpc;
KTIMER Timer;
PKEVENT EventObject;
} AFD_ACTIVE_POLL, *PAFD_ACTIVE_POLL;
typedef struct _IRP_LIST {
@ -129,6 +130,9 @@ typedef struct _AFD_FCB {
AFD_DATA_WINDOW Send, Recv;
FAST_MUTEX Mutex;
KEVENT StateLockedEvent;
PKEVENT EventSelect;
DWORD EventSelectTriggers;
DWORD EventsFired;
UNICODE_STRING TdiDeviceName;
PVOID Context;
DWORD PollState;
@ -223,6 +227,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
NTSTATUS STDCALL
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp );
NTSTATUS STDCALL
AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp );
NTSTATUS STDCALL
AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp );
VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceObject, PFILE_OBJECT FileObject );
/* tdi.c */

View file

@ -27,6 +27,8 @@ NTSTATUS FileOpenConnection(
PTDI_REQUEST Request,
PVOID ClientContext);
PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context );
NTSTATUS FileCloseConnection(
PTDI_REQUEST Request);

View file

@ -402,6 +402,36 @@ TI_DbgPrint(MIN_TRACE, ("X1 Blink 0x%x\n", Connection->ReceivedSegments.Blink));
}
/*
* FUNCTION: Find a connection by examining the context field. This
* is needed in some situations where a FIN reply is needed after a
* socket is formally broken.
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) {
PLIST_ENTRY Entry;
KIRQL OldIrql;
PCONNECTION_ENDPOINT Connection = NULL;
KeAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql );
for( Entry = ConnectionEndpointListHead.Flink;
Entry != &ConnectionEndpointListHead;
Entry = Entry->Flink ) {
Connection =
CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry );
if( Connection->SocketContext == Context ) break;
else Connection = NULL;
}
KeReleaseSpinLock( &ConnectionEndpointListLock, OldIrql );
return Connection;
}
/*
* FUNCTION: Closes an connection file object
* ARGUMENTS:
@ -468,7 +498,6 @@ NTSTATUS FileOpenControlChannel(
return STATUS_SUCCESS;
}
/*
* FUNCTION: Closes a control channel file object
* ARGUMENTS:

View file

@ -7,6 +7,7 @@
#ifndef __AFD_SHARED_H
#define __AFD_SHARED_H
#define AFD_MAX_EVENTS 10
#define AFD_PACKET_COMMAND_LENGTH 15
#define AfdCommand "AfdOpenPacketXX"
@ -123,6 +124,12 @@ typedef struct _AFD_EVENT_SELECT_INFO {
ULONG Events;
} AFD_EVENT_SELECT_INFO, *PAFD_EVENT_SELECT_INFO;
typedef struct _AFD_ENUM_NETWORK_EVENTS_INFO {
HANDLE Event;
ULONG PollEvents;
NTSTATUS EventStatus[AFD_MAX_EVENTS];
} AFD_ENUM_NETWORK_EVENTS_INFO, *PAFD_ENUM_NETWORK_EVENTS_INFO;
typedef struct _AFD_DISCONNECT_INFO {
ULONG DisconnectType;
LARGE_INTEGER Timeout;
@ -205,6 +212,7 @@ typedef struct _AFD_DISCONNECT_INFO {
#define AFD_SET_DISCONNECT_OPTIONS_SIZE 29
#define AFD_GET_INFO 30
#define AFD_EVENT_SELECT 33
#define AFD_ENUM_NETWORK_EVENTS 34
#define AFD_DEFER_ACCEPT 35
#define AFD_GET_PENDING_CONNECT_DATA 41
@ -272,6 +280,8 @@ typedef struct _AFD_DISCONNECT_INFO {
_AFD_CONTROL_CODE(AFD_DEFER_ACCEPT, METHOD_NEITHER)
#define IOCTL_AFD_GET_PENDING_CONNECT_DATA \
_AFD_CONTROL_CODE(AFD_GET_PENDING_CONNECT_DATA, METHOD_NEITHER)
#define IOCTL_AFD_ENUM_NETWORK_EVENTS \
_AFD_CONTROL_CODE(AFD_ENUM_NETWORK_EVENTS, METHOD_NEITHER)
typedef struct _AFD_SOCKET_INFORMATION {
BOOL CommandChannel;
@ -352,17 +362,6 @@ typedef struct _FILE_REPLY_EVENTSELECT {
INT Status;
} FILE_REPLY_EVENTSELECT, *PFILE_REPLY_EVENTSELECT;
typedef struct _FILE_REQUEST_ENUMNETWORKEVENTS {
WSAEVENT hEventObject;
} FILE_REQUEST_ENUMNETWORKEVENTS, *PFILE_REQUEST_ENUMNETWORKEVENTS;
typedef struct _FILE_REPLY_ENUMNETWORKEVENTS {
INT Status;
WSANETWORKEVENTS NetworkEvents;
} FILE_REPLY_ENUMNETWORKEVENTS, *PFILE_REPLY_ENUMNETWORKEVENTS;
typedef struct _FILE_REQUEST_RECV {
LPWSABUF Buffers;
DWORD BufferCount;