Factor out common datagram receive code.
Actually implement datagram cancellation.

afd:
Reorganize IRP cancellation and simplify socket shutdown.
Fix datagram recv with no address differently (and better).

Overall: fix hang after ping.

svn path=/trunk/; revision=30693
This commit is contained in:
Art Yerkes 2007-11-23 13:52:56 +00:00
parent c24f0e963d
commit 06220aab9e
14 changed files with 245 additions and 355 deletions

View file

@ -46,7 +46,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
BOOLEAN Write, BOOLEAN LockAddress ) { BOOLEAN Write, BOOLEAN LockAddress ) {
UINT i; UINT i;
/* Copy the buffer array so we don't lose it */ /* Copy the buffer array so we don't lose it */
UINT Lock = (LockAddress && AddressLen) ? 2 : 0; UINT Lock = LockAddress ? 2 : 0;
UINT Size = sizeof(AFD_WSABUF) * (Count + Lock); UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 ); PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
PMDL NewMdl; PMDL NewMdl;
@ -65,6 +65,9 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
NewBuf[Count].buf = (PVOID)AddressLen; NewBuf[Count].buf = (PVOID)AddressLen;
NewBuf[Count].len = sizeof(*AddressLen); NewBuf[Count].len = sizeof(*AddressLen);
Count++; Count++;
} else if( LockAddress ) {
RtlZeroMemory(NewBuf, sizeof(*NewBuf) * 2);
Count += 2;
} }
} _SEH_HANDLE { } _SEH_HANDLE {
AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info " AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info "

View file

@ -152,51 +152,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
} }
VOID DestroySocket( PAFD_FCB FCB ) { VOID DestroySocket( PAFD_FCB FCB ) {
UINT i;
BOOLEAN ReturnEarly = FALSE;
PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
AFD_DbgPrint(MIN_TRACE,("Called (%x)\n", FCB)); AFD_DbgPrint(MIN_TRACE,("Called (%x)\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return;
FCB->State = SOCKET_STATE_CLOSED;
InFlightRequest[0] = &FCB->ListenIrp;
InFlightRequest[1] = &FCB->ReceiveIrp;
InFlightRequest[2] = &FCB->SendIrp;
/* Return early here because we might be called in the mean time. */
if( FCB->Critical ||
FCB->ListenIrp.InFlightRequest ||
FCB->ReceiveIrp.InFlightRequest ||
FCB->SendIrp.InFlightRequest ) {
AFD_DbgPrint(MIN_TRACE,("Leaving socket alive (%x %x %x)\n",
FCB->ListenIrp.InFlightRequest,
FCB->ReceiveIrp.InFlightRequest,
FCB->SendIrp.InFlightRequest));
ReturnEarly = TRUE;
}
/* After PoolReeval, this FCB should not be involved in any outstanding
* poll requests */
/* Cancel our pending requests */
for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
NTSTATUS Status = STATUS_NO_SUCH_FILE;
if( InFlightRequest[i]->InFlightRequest ) {
AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
i, InFlightRequest[i]->InFlightRequest));
InFlightRequest[i]->InFlightRequest->IoStatus.Status = Status;
InFlightRequest[i]->InFlightRequest->IoStatus.Information = 0;
IoCancelIrp( InFlightRequest[i]->InFlightRequest );
}
}
SocketStateUnlock( FCB );
if( ReturnEarly ) return;
if( FCB->Recv.Window ) if( FCB->Recv.Window )
ExFreePool( FCB->Recv.Window ); ExFreePool( FCB->Recv.Window );
if( FCB->Send.Window ) if( FCB->Send.Window )
@ -218,9 +175,13 @@ static NTSTATUS STDCALL
AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp) PIO_STACK_LOCATION IrpSp)
{ {
UINT i;
AFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext; PAFD_FCB FCB = FileObject->FsContext;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp, FALSE);
AFD_DbgPrint(MID_TRACE, AFD_DbgPrint(MID_TRACE,
("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp)); ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
@ -233,15 +194,56 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect ); if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect );
FileObject->FsContext = NULL; FileObject->FsContext = NULL;
FCB->State = SOCKET_STATE_CLOSED;
SocketStateUnlock(FCB);
InFlightRequest[0] = FCB->ListenIrp;
InFlightRequest[1] = FCB->ReceiveIrp;
InFlightRequest[2] = FCB->SendIrp;
/* Return early here because we might be called in the mean time. */
if( !(FCB->Critical ||
FCB->ListenIrp.InFlightRequest ||
FCB->ReceiveIrp.InFlightRequest ||
FCB->SendIrp.InFlightRequest) ) {
AFD_DbgPrint(MIN_TRACE,("Leaving socket alive (%x %x %x)\n",
FCB->ListenIrp.InFlightRequest,
FCB->ReceiveIrp.InFlightRequest,
FCB->SendIrp.InFlightRequest));
SocketStateUnlock(FCB);
DestroySocket(FCB);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else
{
/* After PoolReeval, this FCB should not be involved in any outstanding
* poll requests */
/* Cancel our pending requests */
for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
NTSTATUS Status = STATUS_NO_SUCH_FILE;
if( InFlightRequest[i].InFlightRequest ) {
AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
i, InFlightRequest[i].InFlightRequest));
InFlightRequest[i].InFlightRequest->IoStatus.Status = Status;
InFlightRequest[i].InFlightRequest->IoStatus.Information = 0;
IoCancelIrp( InFlightRequest[i].InFlightRequest );
}
}
FCB->PendingClose = Irp;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
DestroySocket( FCB ); DestroySocket( FCB );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
AFD_DbgPrint(MID_TRACE, ("Returning success.\n")); AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
return STATUS_SUCCESS; return Irp->IoStatus.Status;
} }
static NTSTATUS STDCALL static NTSTATUS STDCALL

View file

@ -231,7 +231,6 @@ NTSTATUS NTAPI ReceiveComplete
if( FCB->State == SOCKET_STATE_CLOSED ) { if( FCB->State == SOCKET_STATE_CLOSED ) {
AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n")); AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n"));
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
DestroySocket( FCB );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} else if( FCB->State == SOCKET_STATE_LISTENING ) { } else if( FCB->State == SOCKET_STATE_LISTENING ) {
AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n")); AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
@ -435,13 +434,12 @@ PacketSocketRecvComplete(
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return STATUS_UNSUCCESSFUL;
FCB->ReceiveIrp.InFlightRequest = NULL; FCB->ReceiveIrp.InFlightRequest = NULL;
if( !SocketAcquireStateLock( FCB ) ) return STATUS_UNSUCCESSFUL;
if( FCB->State == SOCKET_STATE_CLOSED ) { if( FCB->State == SOCKET_STATE_CLOSED ) {
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
DestroySocket( FCB );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -47,7 +47,6 @@ static NTSTATUS NTAPI SendComplete
if( FCB->State == SOCKET_STATE_CLOSED ) { if( FCB->State == SOCKET_STATE_CLOSED ) {
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
DestroySocket( FCB );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -178,12 +177,6 @@ static NTSTATUS NTAPI PacketSocketSendComplete
FCB->SendIrp.InFlightRequest = NULL; FCB->SendIrp.InFlightRequest = NULL;
/* Request is not in flight any longer */ /* Request is not in flight any longer */
if( FCB->State == SOCKET_STATE_CLOSED ) {
SocketStateUnlock( FCB );
DestroySocket( FCB );
return STATUS_SUCCESS;
}
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -147,6 +147,7 @@ typedef struct _AFD_FCB {
PVOID Context; PVOID Context;
DWORD PollState; DWORD PollState;
UINT ContextSize; UINT ContextSize;
PIRP PendingClose;
LIST_ENTRY PendingIrpList[MAX_FUNCTIONS]; LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
LIST_ENTRY DatagramList; LIST_ENTRY DatagramList;
LIST_ENTRY PendingConnections; LIST_ENTRY PendingConnections;

View file

@ -9,6 +9,21 @@
#include <titypes.h> #include <titypes.h>
NTSTATUS DGReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived,
PDATAGRAM_COMPLETION_ROUTINE Complete,
PVOID Context,
PIRP Irp);
VOID DGRemoveIRP(
PADDRESS_FILE AddrFile,
PIRP Irp);
VOID DGDeliverData( VOID DGDeliverData(
PADDRESS_FILE AddrFile, PADDRESS_FILE AddrFile,

View file

@ -7,8 +7,6 @@
#ifndef __RAWIP_H #ifndef __RAWIP_H
#define __RAWIP_H #define __RAWIP_H
NTSTATUS RawIPSendDatagram( NTSTATUS RawIPSendDatagram(
PADDRESS_FILE AddrFile, PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo, PTDI_CONNECTION_INFORMATION ConnInfo,

View file

@ -113,6 +113,7 @@ typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)(
typedef DATAGRAM_COMPLETION_ROUTINE PDATAGRAM_COMPLETION_ROUTINE; typedef DATAGRAM_COMPLETION_ROUTINE PDATAGRAM_COMPLETION_ROUTINE;
typedef struct _DATAGRAM_RECEIVE_REQUEST { typedef struct _DATAGRAM_RECEIVE_REQUEST {
struct _ADDRESS_FILE *AddressFile; /* AddressFile on behalf of */
LIST_ENTRY ListEntry; /* Entry on list */ LIST_ENTRY ListEntry; /* Entry on list */
IP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */ IP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */
USHORT RemotePort; /* Remote port we receive from (0 means any) */ USHORT RemotePort; /* Remote port we receive from (0 means any) */
@ -123,6 +124,7 @@ typedef struct _DATAGRAM_RECEIVE_REQUEST {
PVOID Context; /* Pointer to context information */ PVOID Context; /* Pointer to context information */
DATAGRAM_COMPLETION_ROUTINE UserComplete; /* Completion routine */ DATAGRAM_COMPLETION_ROUTINE UserComplete; /* Completion routine */
PVOID UserContext; /* Pointer to context information */ PVOID UserContext; /* Pointer to context information */
PIRP Irp; /* IRP on behalf of */
} DATAGRAM_RECEIVE_REQUEST, *PDATAGRAM_RECEIVE_REQUEST; } DATAGRAM_RECEIVE_REQUEST, *PDATAGRAM_RECEIVE_REQUEST;
/* Datagram build routine prototype */ /* Datagram build routine prototype */

View file

@ -50,17 +50,6 @@ NTSTATUS UDPSendDatagram(
ULONG DataSize, ULONG DataSize,
PULONG DataUsed ); PULONG DataUsed );
NTSTATUS UDPReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived,
PDATAGRAM_COMPLETION_ROUTINE Complete,
PVOID Context);
VOID UDPReceive( VOID UDPReceive(
PIP_INTERFACE Interface, PIP_INTERFACE Interface,
PIP_PACKET IPPacket); PIP_PACKET IPPacket);

View file

@ -54,34 +54,6 @@ NTSTATUS DispPrepareIrpForCancel(
return IRPFinish(Irp, STATUS_CANCELLED); return IRPFinish(Irp, STATUS_CANCELLED);
} }
VOID DispCancelComplete(
PVOID Context)
/*
* FUNCTION: Completes a cancel request
* ARGUMENTS:
* Context = Pointer to context information (FILE_OBJECT)
*/
{
/*KIRQL OldIrql;*/
PFILE_OBJECT FileObject;
PTRANSPORT_CONTEXT TranContext;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
FileObject = (PFILE_OBJECT)Context;
TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext;
/* Set the cleanup event */
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
/* We are expected to release the cancel spin lock */
/*IoReleaseCancelSpinLock(OldIrql);*/
TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
}
VOID DispDataRequestComplete( VOID DispDataRequestComplete(
PVOID Context, PVOID Context,
NTSTATUS Status, NTSTATUS Status,
@ -156,8 +128,14 @@ VOID DispDoDisconnect( PVOID Data ) {
TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n")); TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0); DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
}
DispCancelComplete(DisType->FileObject); VOID DispDoPacketCancel( PVOID Data ) {
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
PIRP *IrpP = (PIRP *)Data, Irp = *IrpP;
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
} }
VOID NTAPI DispCancelRequest( VOID NTAPI DispCancelRequest(
@ -176,6 +154,7 @@ VOID NTAPI DispCancelRequest(
UCHAR MinorFunction; UCHAR MinorFunction;
DISCONNECT_TYPE DisType; DISCONNECT_TYPE DisType;
PVOID WorkItem; PVOID WorkItem;
PADDRESS_FILE AddrFile;
/*NTSTATUS Status = STATUS_SUCCESS;*/ /*NTSTATUS Status = STATUS_SUCCESS;*/
TI_DbgPrint(DEBUG_IRP, ("Called.\n")); TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@ -209,26 +188,26 @@ VOID NTAPI DispCancelRequest(
if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE), if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE),
DispDoDisconnect, &DisType ) ) DispDoDisconnect, &DisType ) )
ASSERT(0); ASSERT(0);
break; return;
case TDI_SEND_DATAGRAM: case TDI_SEND_DATAGRAM:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n")); TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n"));
break; break;
} }
/* Nothing to do. We don't keep them around. */
/*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
break; break;
case TDI_RECEIVE_DATAGRAM: case TDI_RECEIVE_DATAGRAM:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n")); TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
break; break;
} }
DGRemoveIRP(AddrFile, Irp);
/*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
break; break;
default: default:
@ -236,11 +215,9 @@ VOID NTAPI DispCancelRequest(
break; break;
} }
if( Irp->IoStatus.Status == STATUS_PENDING )
IoMarkIrpPending(Irp);
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
} }
@ -284,9 +261,6 @@ VOID NTAPI DispCancelListenRequest(
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
DispDataRequestComplete(Irp, STATUS_CANCELLED, 0); DispDataRequestComplete(Irp, STATUS_CANCELLED, 0);
DispCancelComplete(FileObject);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
} }
@ -822,7 +796,6 @@ NTSTATUS DispTdiReceive(
return Status; return Status;
} }
NTSTATUS DispTdiReceiveDatagram( NTSTATUS DispTdiReceiveDatagram(
PIRP Irp) PIRP Irp)
/* /*
@ -839,6 +812,7 @@ NTSTATUS DispTdiReceiveDatagram(
TDI_REQUEST Request; TDI_REQUEST Request;
NTSTATUS Status; NTSTATUS Status;
ULONG BytesReceived; ULONG BytesReceived;
PADDRESS_FILE AddrFile;
TI_DbgPrint(DEBUG_IRP, ("Called.\n")); TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@ -852,6 +826,8 @@ NTSTATUS DispTdiReceiveDatagram(
return STATUS_INVALID_ADDRESS; return STATUS_INVALID_ADDRESS;
} }
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
/* Initialize a receive request */ /* Initialize a receive request */
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
Request.RequestNotifyObject = DispDataRequestComplete; Request.RequestNotifyObject = DispDataRequestComplete;
@ -871,20 +847,21 @@ NTSTATUS DispTdiReceiveDatagram(
&DataBuffer, &DataBuffer,
&BufferSize ); &BufferSize );
Status = UDPReceiveDatagram( Status = DGReceiveDatagram(
Request.Handle.AddressHandle, AddrFile,
DgramInfo->ReceiveDatagramInformation, DgramInfo->ReceiveDatagramInformation,
DataBuffer, DataBuffer,
DgramInfo->ReceiveLength, DgramInfo->ReceiveLength,
DgramInfo->ReceiveFlags, DgramInfo->ReceiveFlags,
DgramInfo->ReturnDatagramInformation, DgramInfo->ReturnDatagramInformation,
&BytesReceived, &BytesReceived,
(PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete, (PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete,
Irp); Irp,
if (Status != STATUS_PENDING) { Irp);
DispDataRequestComplete(Irp, Status, BytesReceived); if (Status != STATUS_PENDING) {
} else DispDataRequestComplete(Irp, Status, BytesReceived);
IoMarkIrpPending(Irp); } else
IoMarkIrpPending(Irp);
} }
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status)); TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));

View file

@ -146,7 +146,6 @@ CP
} }
CP CP
Context->CancelIrps = FALSE; Context->CancelIrps = FALSE;
KeInitializeEvent(&Context->CleanupEvent, NotificationEvent, FALSE);
CP CP
IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp = IoGetCurrentIrpStackLocation(Irp);
IrpSp->FileObject->FsContext = Context; IrpSp->FileObject->FsContext = Context;
@ -274,20 +273,11 @@ VOID TiCleanupFileObjectComplete(
{ {
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION IrpSp;
PTRANSPORT_CONTEXT TranContext;
KIRQL OldIrql;
Irp = (PIRP)Context; Irp = (PIRP)Context;
IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp = IoGetCurrentIrpStackLocation(Irp);
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoAcquireCancelSpinLock(&OldIrql);
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
IoReleaseCancelSpinLock(OldIrql);
} }
@ -321,7 +311,6 @@ NTSTATUS TiCleanupFileObject(
IoAcquireCancelSpinLock(&OldIrql); IoAcquireCancelSpinLock(&OldIrql);
Context->CancelIrps = TRUE; Context->CancelIrps = TRUE;
KeResetEvent(&Context->CleanupEvent);
IoReleaseCancelSpinLock(OldIrql); IoReleaseCancelSpinLock(OldIrql);
@ -356,12 +345,6 @@ NTSTATUS TiCleanupFileObject(
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (Status != STATUS_PENDING)
TiCleanupFileObjectComplete(Irp, Status);
KeWaitForSingleObject(&Context->CleanupEvent,
UserRequest, KernelMode, FALSE, NULL);
return Irp->IoStatus.Status; return Irp->IoStatus.Status;
} }

View file

@ -10,6 +10,36 @@
#include "precomp.h" #include "precomp.h"
VOID DGRemoveIRP(
PADDRESS_FILE AddrFile,
PIRP Irp)
{
PLIST_ENTRY ListEntry;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n",
Irp, AddrFile));
for( ListEntry = AddrFile->ReceiveQueue.Flink;
ListEntry != &AddrFile->ReceiveQueue;
ListEntry = ListEntry->Flink )
{
ReceiveRequest = CONTAINING_RECORD
(ListEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
TI_DbgPrint(MAX_TRACE, ("Request: %08x?\n", ReceiveRequest));
if (ReceiveRequest->Irp == Irp)
{
RemoveEntryList(&ReceiveRequest->ListEntry);
exFreePool(ReceiveRequest);
break;
}
}
TI_DbgPrint(MAX_TRACE, ("Done.\n"));
}
VOID DGDeliverData( VOID DGDeliverData(
PADDRESS_FILE AddrFile, PADDRESS_FILE AddrFile,
PIP_ADDRESS SrcAddress, PIP_ADDRESS SrcAddress,
@ -153,3 +183,110 @@ VOID DGDeliverData(
TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
} }
VOID DGReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) {
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest =
(PDATAGRAM_RECEIVE_REQUEST)Context;
TI_DbgPrint(MAX_TRACE,("Called (%08x:%08x)\n", Status, Count));
ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count );
exFreePool( ReceiveRequest );
TI_DbgPrint(MAX_TRACE,("Done\n"));
}
NTSTATUS DGReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR BufferData,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived,
PDATAGRAM_COMPLETION_ROUTINE Complete,
PVOID Context,
PIRP Irp)
/*
* FUNCTION: Attempts to receive an DG datagram from a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer chain to store received data
* ReceiveLength = Maximum size to use of buffer, 0 if all can be used
* ReceiveFlags = Receive flags (None, Normal, Peek)
* ReturnInfo = Pointer to structure for return information
* BytesReceive = Pointer to structure for number of bytes received
* RETURNS:
* Status of operation
* NOTES:
* This is the high level interface for receiving DG datagrams
*/
{
KIRQL OldIrql;
NTSTATUS Status;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AF_IS_VALID(AddrFile))
{
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
if (ReceiveRequest)
{
/* Initialize a receive request */
/* Extract the remote address filter from the request (if any) */
if ((ConnInfo->RemoteAddressLength != 0) &&
(ConnInfo->RemoteAddress))
{
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&ReceiveRequest->RemoteAddress,
&ReceiveRequest->RemotePort);
if (!NT_SUCCESS(Status))
{
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
exFreePool(ReceiveRequest);
return Status;
}
}
else
{
ReceiveRequest->RemotePort = 0;
}
ReceiveRequest->ReturnInfo = ReturnInfo;
ReceiveRequest->Buffer = BufferData;
ReceiveRequest->BufferSize = ReceiveLength;
ReceiveRequest->UserComplete = Complete;
ReceiveRequest->UserContext = Context;
ReceiveRequest->Complete =
(PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete;
ReceiveRequest->Context = ReceiveRequest;
ReceiveRequest->AddressFile = AddrFile;
ReceiveRequest->Irp = Irp;
/* Queue receive request */
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
AF_SET_PENDING(AddrFile, AFF_RECEIVE);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
return STATUS_PENDING;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_INVALID_ADDRESS;
}
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
return Status;
}

View file

@ -228,110 +228,6 @@ NTSTATUS RawIPSendDatagram(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
VOID RawIpReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) {
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest =
(PDATAGRAM_RECEIVE_REQUEST)Context;
TI_DbgPrint(MAX_TRACE,("Called\n"));
ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count );
exFreePool( ReceiveRequest );
TI_DbgPrint(MAX_TRACE,("Done\n"));
}
NTSTATUS RawIPReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR BufferData,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived,
PDATAGRAM_COMPLETION_ROUTINE Complete,
PVOID Context)
/*
* FUNCTION: Attempts to receive an RawIp datagram from a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer chain to store received data
* ReceiveLength = Maximum size to use of buffer, 0 if all can be used
* ReceiveFlags = Receive flags (None, Normal, Peek)
* ReturnInfo = Pointer to structure for return information
* BytesReceive = Pointer to structure for number of bytes received
* RETURNS:
* Status of operation
* NOTES:
* This is the high level interface for receiving RawIp datagrams
*/
{
KIRQL OldIrql;
NTSTATUS Status;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AF_IS_VALID(AddrFile))
{
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
if (ReceiveRequest)
{
/* Initialize a receive request */
/* Extract the remote address filter from the request (if any) */
if ((ConnInfo->RemoteAddressLength != 0) &&
(ConnInfo->RemoteAddress))
{
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&ReceiveRequest->RemoteAddress,
&ReceiveRequest->RemotePort);
if (!NT_SUCCESS(Status))
{
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
exFreePool(ReceiveRequest);
return Status;
}
}
else
{
ReceiveRequest->RemotePort = 0;
}
ReceiveRequest->ReturnInfo = ReturnInfo;
ReceiveRequest->Buffer = BufferData;
ReceiveRequest->BufferSize = ReceiveLength;
ReceiveRequest->UserComplete = Complete;
ReceiveRequest->UserContext = Context;
ReceiveRequest->Complete =
(PDATAGRAM_COMPLETION_ROUTINE)RawIpReceiveComplete;
ReceiveRequest->Context = ReceiveRequest;
/* Queue receive request */
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
AF_SET_PENDING(AddrFile, AFF_RECEIVE);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_INVALID_ADDRESS;
}
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
return Status;
}
VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
/* /*

View file

@ -203,110 +203,6 @@ NTSTATUS UDPSendDatagram(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
VOID UDPReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) {
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest =
(PDATAGRAM_RECEIVE_REQUEST)Context;
TI_DbgPrint(MAX_TRACE,("Called\n"));
ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count );
exFreePool( ReceiveRequest );
TI_DbgPrint(MAX_TRACE,("Done\n"));
}
NTSTATUS UDPReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR BufferData,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived,
PDATAGRAM_COMPLETION_ROUTINE Complete,
PVOID Context)
/*
* FUNCTION: Attempts to receive an UDP datagram from a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer chain to store received data
* ReceiveLength = Maximum size to use of buffer, 0 if all can be used
* ReceiveFlags = Receive flags (None, Normal, Peek)
* ReturnInfo = Pointer to structure for return information
* BytesReceive = Pointer to structure for number of bytes received
* RETURNS:
* Status of operation
* NOTES:
* This is the high level interface for receiving UDP datagrams
*/
{
KIRQL OldIrql;
NTSTATUS Status;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AF_IS_VALID(AddrFile))
{
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
if (ReceiveRequest)
{
/* Initialize a receive request */
/* Extract the remote address filter from the request (if any) */
if ((ConnInfo->RemoteAddressLength != 0) &&
(ConnInfo->RemoteAddress))
{
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&ReceiveRequest->RemoteAddress,
&ReceiveRequest->RemotePort);
if (!NT_SUCCESS(Status))
{
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
exFreePool(ReceiveRequest);
return Status;
}
}
else
{
ReceiveRequest->RemotePort = 0;
}
ReceiveRequest->ReturnInfo = ReturnInfo;
ReceiveRequest->Buffer = BufferData;
ReceiveRequest->BufferSize = ReceiveLength;
ReceiveRequest->UserComplete = Complete;
ReceiveRequest->UserContext = Context;
ReceiveRequest->Complete =
(PDATAGRAM_COMPLETION_ROUTINE)UDPReceiveComplete;
ReceiveRequest->Context = ReceiveRequest;
/* Queue receive request */
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
AF_SET_PENDING(AddrFile, AFF_RECEIVE);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_INVALID_ADDRESS;
}
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
return Status;
}
VOID UDPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) VOID UDPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
/* /*