#include "precomp.h"
#include <pseh/pseh2.h>
+
+NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
+ KIRQL OldIrql;
+
+ Irp->IoStatus.Status = Status;
+
+ if( Status == STATUS_PENDING )
+ IoMarkIrpPending( Irp );
+ else {
+ IoAcquireCancelSpinLock(&OldIrql);
+ (void)IoSetCancelRoutine( Irp, NULL );
+ IoReleaseCancelSpinLock(OldIrql);
+
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+ }
+
+ return Status;
+}
+
NTSTATUS DispPrepareIrpForCancel(
PTRANSPORT_CONTEXT Context,
PIRP Irp,
{
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
- PTRANSPORT_CONTEXT TranContext;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
Irp = Context;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
IoAcquireCancelSpinLock(&OldIrql);
(void)IoSetCancelRoutine(Irp, NULL);
- if (Irp->Cancel || TranContext->CancelIrps) {
- /* The IRP has been cancelled */
-
- TI_DbgPrint(DEBUG_IRP, ("IRP is cancelled.\n"));
-
- Status = STATUS_CANCELLED;
- Count = 0;
- }
-
IoReleaseCancelSpinLock(OldIrql);
Irp->IoStatus.Status = Status;
TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
}
-typedef struct _DISCONNECT_TYPE {
- UINT Type;
- PVOID Context;
- PIRP Irp;
- PFILE_OBJECT FileObject;
-} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
-
-VOID DispDoDisconnect( PVOID Data ) {
- PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data;
-
- TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n"));
- TCPDisconnect
- ( DisType->Context,
- DisType->Type,
- NULL,
- NULL,
- DispDataRequestComplete,
- DisType->Irp );
- TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
-
- DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
-}
-
VOID NTAPI DispCancelRequest(
PDEVICE_OBJECT Device,
PIRP Irp)
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
- DISCONNECT_TYPE DisType;
- PVOID WorkItem;
- /*NTSTATUS Status = STATUS_SUCCESS;*/
+ BOOLEAN DequeuedIrp = TRUE;
+
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
-#ifdef DBG
+#if DBG
if (!Irp->Cancel)
TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
#endif
switch(MinorFunction) {
case TDI_SEND:
case TDI_RECEIVE:
- DisType.Type = TDI_DISCONNECT_RELEASE |
- ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
- DisType.Context = TranContext->Handle.ConnectionContext;
- DisType.Irp = Irp;
- DisType.FileObject = FileObject;
-
- TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
-
- IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE),
- DispDoDisconnect, &DisType ) )
- ASSERT(0);
- return;
+ DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
+ break;
case TDI_SEND_DATAGRAM:
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
break;
}
- DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+ DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
break;
case TDI_RECEIVE_DATAGRAM:
break;
}
- DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+ DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+ break;
+
+ case TDI_CONNECT:
+ DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
break;
default:
TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
+ ASSERT(FALSE);
break;
}
- IoReleaseCancelSpinLock(Irp->CancelIrql);
- IRPFinish(Irp, STATUS_CANCELLED);
+ if (DequeuedIrp)
+ IRPFinish(Irp, STATUS_CANCELLED);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
PCONNECTION_ENDPOINT Connection;
- /*NTSTATUS Status = STATUS_SUCCESS;*/
+
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X).\n", Irp));
-#ifdef DBG
+#if DBG
if (!Irp->Cancel)
TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
#endif
/* Try canceling the request */
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
- TCPAbortListenForSocket(
- Connection->AddressFile->Listener,
- Connection );
- IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- Irp->IoStatus.Information = 0;
- IRPFinish(Irp, STATUS_CANCELLED);
+ if (TCPAbortListenForSocket(Connection->AddressFile->Listener,
+ Connection))
+ {
+ Irp->IoStatus.Information = 0;
+ IRPFinish(Irp, STATUS_CANCELLED);
+ }
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile = NULL;
NTSTATUS Status;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_INVALID_PARAMETER;
}
- if (Connection->AddressFile) {
- TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
- return STATUS_INVALID_PARAMETER;
- }
-
Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
Status = ObReferenceObjectByHandle(
return STATUS_INVALID_PARAMETER;
}
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+ if (Connection->AddressFile) {
+ ObDereferenceObject(FileObject);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
ObDereferenceObject(FileObject);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
FileObject->FsContext2));
return STATUS_INVALID_PARAMETER;
TranContext = FileObject->FsContext;
if (!TranContext) {
ObDereferenceObject(FileObject);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_PARAMETER;
}
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
if (!AddrFile) {
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
ObDereferenceObject(FileObject);
TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
return STATUS_INVALID_PARAMETER;
}
+ KeAcquireSpinLockAtDpcLevel(&AddrFile->Lock);
+
Connection->AddressFile = AddrFile;
/* Add connection endpoint to the address file */
/* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
ObDereferenceObject(FileObject);
+ KeReleaseSpinLockFromDpcLevel(&AddrFile->Lock);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
return Status;
}
/* Get associated connection endpoint file object. Quit if none exists */
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
- Status = TCPConnect(
- TranContext->Handle.ConnectionContext,
- Parameters->RequestConnectionInformation,
- Parameters->ReturnConnectionInformation,
- DispDataRequestComplete,
- Irp );
+ Status = DispPrepareIrpForCancel(TranContext->Handle.ConnectionContext,
+ Irp,
+ DispCancelRequest);
+
+ if (NT_SUCCESS(Status)) {
+ Status = TCPConnect(
+ TranContext->Handle.ConnectionContext,
+ Parameters->RequestConnectionInformation,
+ Parameters->ReturnConnectionInformation,
+ DispDataRequestComplete,
+ Irp );
+ }
done:
if (Status != STATUS_PENDING) {
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
return Status;
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_INVALID_PARAMETER;
}
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
if (!Connection->AddressFile) {
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
return STATUS_INVALID_PARAMETER;
}
+ KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock);
+
+ /* Remove this connection from the address file */
+ Connection->AddressFile->Connection = NULL;
+
+ KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock);
+
+ /* Remove the address file from this connection */
+ Connection->AddressFile = NULL;
+
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
return STATUS_SUCCESS;
}
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(MAX_TRACE, ("TCP Disconnect returned %08x\n", Status));
return Status;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status = STATUS_SUCCESS;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
/* Get associated connection endpoint file object. Quit if none exists */
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
- TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
- Connection->AddressFile ));
- if( Connection->AddressFile ) {
- TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
- Connection->AddressFile->Listener));
+ Status = DispPrepareIrpForCancel
+ (TranContext->Handle.ConnectionContext,
+ Irp,
+ (PDRIVER_CANCEL)DispCancelListenRequest);
+
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+ if (Connection->AddressFile == NULL)
+ {
+ TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ Status = STATUS_INVALID_PARAMETER;
+ goto done;
}
+ KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock);
+
/* Listening will require us to create a listening socket and store it in
* the address file. It will be signalled, and attempt to complete an irp
* when a new connection arrives. */
/* The important thing to note here is that the irp we'll complete belongs
* to the socket to be accepted onto, not the listener */
- if( !Connection->AddressFile->Listener ) {
+ if( NT_SUCCESS(Status) && !Connection->AddressFile->Listener ) {
Connection->AddressFile->Listener =
TCPAllocateConnectionEndpoint( NULL );
Status = TCPListen( Connection->AddressFile->Listener, 1024 );
/* BACKLOG */
}
- if( NT_SUCCESS(Status) ) {
- Status = DispPrepareIrpForCancel
- (TranContext->Handle.ConnectionContext,
- Irp,
- (PDRIVER_CANCEL)DispCancelListenRequest);
- }
if( NT_SUCCESS(Status) ) {
Status = TCPAccept
Irp );
}
+ KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
done:
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status));
return Status;
case TDI_CONNECTION_FILE:
Endpoint =
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
- TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
- DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr);
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
- return STATUS_SUCCESS;
+ return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
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;
- }
-
- return STATUS_SUCCESS;
}
case TDI_QUERY_CONNECTION_INFO:
switch ((ULONG)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
+ Endpoint = AddrFile ? AddrFile->Connection : NULL;
break;
case TDI_CONNECTION_FILE:
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
return Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
if (NT_SUCCESS(Status))
{
- PCHAR DataBuffer;
+ PVOID DataBuffer;
UINT BufferSize;
NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
return Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
if (NT_SUCCESS(Status))
{
- PCHAR Data;
+ PVOID Data;
UINT Len;
NdisQueryBuffer( Irp->MdlAddress, &Data, &Len );
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
return Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
(PDRIVER_CANCEL)DispCancelRequest);
if (NT_SUCCESS(Status)) {
- PCHAR DataBuffer;
+ PVOID DataBuffer;
UINT BufferSize;
TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress));
("About to call send routine %x\n",
(*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
- if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send) )
+ if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send != NULL) )
Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
Request.Handle.AddressHandle,
DgramInfo->SendDatagramInformation,
DataBuffer,
BufferSize,
&Irp->IoStatus.Information);
- else
+ else {
Status = STATUS_UNSUCCESSFUL;
+ ASSERT(FALSE);
+ }
}
done:
} else
IoMarkIrpPending(Irp);
- TcpipRecursiveMutexLeave( &TCPLock );
-
TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
return Status;
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
Status = STATUS_SUCCESS;
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Set the event handler. if an event handler is associated with
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
Status = STATUS_INVALID_PARAMETER;
}
- TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return Status;
}
*/
{
PTI_QUERY_CONTEXT QueryContext;
- UINT Count = 0;
QueryContext = (PTI_QUERY_CONTEXT)Context;
if (NT_SUCCESS(Status)) {
- Count = CopyBufferToBufferChain(
+ CopyBufferToBufferChain(
QueryContext->InputMdl,
FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
(PCHAR)&QueryContext->QueryInfo.Context,
QueryContext->Irp->IoStatus.Information = ByteCount;
QueryContext->Irp->IoStatus.Status = Status;
- exFreePool(QueryContext);
+ ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
}
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
OutputBuffer = Irp->UserBuffer;
- QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
+ QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
if (QueryContext) {
_SEH2_TRY {
InputMdl = IoAllocateMdl(InputBuffer,
IoFreeMdl(OutputMdl);
}
- exFreePool(QueryContext);
+ ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
} else if( InputBufferLength ==
Size = 0;
- QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
+ QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
_SEH2_TRY {
if( !NT_SUCCESS(Status) || !InputMdl ) {
if( InputMdl ) IoFreeMdl( InputMdl );
- exFreePool(QueryContext);
+ ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
return Status;
}