*/
#include "precomp.h"
-#include <pseh.h>
+#include <pseh/pseh.h>
+
+extern VOID DeleteConnectionEndpoint( PCONNECTION_ENDPOINT Endpoint );
NTSTATUS DispPrepareIrpForCancel(
PTRANSPORT_CONTEXT Context,
}
/* IRP has already been cancelled */
-
+
IoReleaseCancelSpinLock(OldIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
/*KIRQL OldIrql;*/
PFILE_OBJECT FileObject;
PTRANSPORT_CONTEXT TranContext;
-
+
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
FileObject = (PFILE_OBJECT)Context;
PTRANSPORT_CONTEXT TranContext;
KIRQL OldIrql;
- TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
+ TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
Context, Status, Count));
Irp = Context;
TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
}
+VOID DDKAPI CancelQueuePassiveHandler( PVOID CancelRequestVoid )
+{
+ KIRQL OldIrql;
+ PCANCEL_REQUEST CancelReq;
+ PLIST_ENTRY CqEntry;
+
+ KeAcquireSpinLock( &CancelQueueLock, &OldIrql );
+
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Starting\n"));
+
+ for( CqEntry = CancelQueue.Flink;
+ CqEntry != &CancelQueue;
+ ) {
+ CancelReq = CONTAINING_RECORD(CqEntry, CANCEL_REQUEST, Entry);
+ ExInterlockedRemoveHeadList( &CancelQueue, &CancelQueueLock );
+ CqEntry = CancelQueue.Flink;
+
+ KeReleaseSpinLock( &CancelQueueLock, OldIrql );
+
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Executing %x\n", CancelReq));
+
+ switch( CancelReq->Type ) {
+ case TCP_CANCEL_DISCONNECT:
+ TCPDisconnect
+ ( CancelReq->Context,
+ CancelReq->Flags,
+ NULL,
+ NULL,
+ DispDataRequestComplete,
+ CancelReq->Irp );
+ break;
+
+ case TCP_CANCEL_CLOSE:
+ TCPClose( CancelReq->Context );
+ DeleteConnectionEndpoint( CancelReq->Context );
+ break;
+ }
+
+ TCPMarkForDisconnect( CancelReq->Context, FALSE );
+
+ ExFreePool( CancelReq );
+
+ KeAcquireSpinLock( &CancelQueueLock, &OldIrql );
+ }
+
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Ending\n"));
+
+ KeReleaseSpinLock( &CancelQueueLock, OldIrql );
+}
VOID DDKAPI DispCancelRequest(
PDEVICE_OBJECT Device,
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
+ PCANCEL_REQUEST CancelRequest;
/*NTSTATUS Status = STATUS_SUCCESS;*/
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
/* Try canceling the request */
switch(MinorFunction) {
case TDI_SEND:
- TCPDisconnect
- ( TranContext->Handle.ConnectionContext,
- TDI_DISCONNECT_RELEASE,
- NULL,
- NULL,
- DispDataRequestComplete,
- Irp );
- break;
-
case TDI_RECEIVE:
- TCPDisconnect
- ( TranContext->Handle.ConnectionContext,
- TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE,
- NULL,
- NULL,
- DispDataRequestComplete,
- Irp );
+ CancelRequest = ExAllocatePoolWithTag
+ ( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','k','O') );
+ TCPMarkForDisconnect( TranContext->Handle.ConnectionContext, TRUE );
+ if( CancelRequest ) {
+ TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE:-> %x\n", CancelRequest));
+ CancelRequest->Flags = TDI_DISCONNECT_RELEASE |
+ (MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0;
+ CancelRequest->Context = TranContext->Handle.ConnectionContext;
+ CancelRequest->Irp = Irp;
+ CancelRequest->Type = TCP_CANCEL_DISCONNECT;
+ ExInterlockedInsertTailList
+ ( &CancelQueue, &CancelRequest->Entry, &CancelQueueLock );
+ ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
+ }
break;
case TDI_SEND_DATAGRAM:
}
IoReleaseCancelSpinLock(Irp->CancelIrql);
-
+
+ DispCancelComplete(FileObject);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+}
+
+
+VOID DDKAPI DispCancelListenRequest(
+ PDEVICE_OBJECT Device,
+ PIRP Irp)
+/*
+ * FUNCTION: Cancels a listen IRP
+ * ARGUMENTS:
+ * Device = Pointer to device object
+ * Irp = Pointer to an I/O request packet
+ */
+{
+ PIO_STACK_LOCATION IrpSp;
+ PTRANSPORT_CONTEXT TranContext;
+ PFILE_OBJECT FileObject;
+ PCONNECTION_ENDPOINT Connection;
+ /*NTSTATUS Status = STATUS_SUCCESS;*/
+
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ FileObject = IrpSp->FileObject;
+ TranContext = (PTRANSPORT_CONTEXT)FileObject->FsContext;
+ ASSERT( TDI_LISTEN == IrpSp->MinorFunction);
+
+ TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X).\n", Irp));
+
+#ifdef 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);
+
+ DispDataRequestComplete(Irp, STATUS_CANCELLED, 0);
+
DispCancelComplete(FileObject);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
Parameters->ReturnConnectionInformation,
DispDataRequestComplete,
Irp );
-
+
TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
return Status;
DisReq->ReturnConnectionInformation,
DispDataRequestComplete,
Irp );
-
+
TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
return Status;
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
- TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
+ TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
Connection->AddressFile ));
if( Connection->AddressFile ) {
TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
/* 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 ) {
- Connection->AddressFile->Listener =
+ Connection->AddressFile->Listener =
TCPAllocateConnectionEndpoint( NULL );
- if( !Connection->AddressFile->Listener )
+ if( !Connection->AddressFile->Listener )
Status = STATUS_NO_MEMORY;
if( NT_SUCCESS(Status) ) {
- Connection->AddressFile->Listener->AddressFile =
+ Connection->AddressFile->Listener->AddressFile =
Connection->AddressFile;
-
+
Status = TCPSocket( Connection->AddressFile->Listener,
Connection->AddressFile->Family,
SOCK_STREAM,
}
if( NT_SUCCESS(Status) )
- Status = TCPListen( Connection->AddressFile->Listener, 1024 );
+ 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
- ( (PTDI_REQUEST)Parameters,
+ ( (PTDI_REQUEST)Parameters,
Connection->AddressFile->Listener,
Connection,
DispDataRequestComplete,
break;
case TDI_CONNECTION_FILE:
- AddrFile =
+ AddrFile =
((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->
AddressFile;
break;
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 = htons(AddrFile->Port);
- Address->Address[0].Address[0].in_addr =
- AddrFile->Address.Address.IPv4Address;
+ 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));
break;
case TDI_CONNECTION_FILE:
- Endpoint =
+ Endpoint =
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
break;
/* Initialize a receive request */
Status = DispPrepareIrpForCancel
- (TranContext->Handle.ConnectionContext,
- Irp,
+ (TranContext->Handle.ConnectionContext,
+ Irp,
(PDRIVER_CANCEL)DispCancelRequest);
TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
UINT Len;
NdisQueryBuffer( Irp->MdlAddress, &Data, &Len );
-
+
TI_DbgPrint(MID_TRACE,("About to TCPSendData\n"));
Status = TCPSendData(
TranContext->Handle.ConnectionContext,
if (Status != STATUS_PENDING)
{
DispDataRequestComplete(Irp, Status, BytesReceived);
- } else
+ } else
IoMarkIrpPending( Irp );
}
if (NT_SUCCESS(Status)) {
PCHAR DataBuffer;
UINT BufferSize;
-
+
TI_DbgPrint(MID_TRACE,("About to query buffer %x\n", Irp->MdlAddress));
NdisQueryBuffer( (PNDIS_BUFFER)Irp->MdlAddress,
&DataBuffer,
&BufferSize );
-
- /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
+
+ /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress
must be of type PTDI_ADDRESS_IP */
TI_DbgPrint(MID_TRACE,
- ("About to call send routine %x\n",
+ ("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) )
Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
- Request.Handle.AddressHandle,
+ Request.Handle.AddressHandle,
DgramInfo->SendDatagramInformation,
DataBuffer,
BufferSize,
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
Status = STATUS_SUCCESS;
-
+
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Set the event handler. if an event handler is associated with
ExFreePool(QueryContext);
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
- } else if( InputBufferLength ==
+ } else if( InputBufferLength ==
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
/* Handle the case where the user is probing the buffer for length */
TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
IoModifyAccess);
-
+
InputMdlLocked = TRUE;
Status = STATUS_SUCCESS;
} _SEH_HANDLE {
Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
Request.RequestContext = QueryContext;
Status = InfoTdiQueryInformationEx(&Request,
- &QueryContext->QueryInfo.ID,
+ &QueryContext->QueryInfo.ID,
NULL,
- &Size,
+ &Size,
&QueryContext->QueryInfo.Context);
DispTdiQueryInformationExComplete(QueryContext, Status, Size);
TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
return Status;
}
+/* TODO: Support multiple addresses per interface.
+ * For now just set the nte context to the interface index.
+ *
+ * Later on, create an NTE context and NTE instance
+ */
+
+NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+ NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST;
+ PIP_SET_ADDRESS IpAddrChange =
+ (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
+ IF_LIST_ITER(IF);
+
+ ForEachInterface(IF) {
+ if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) {
+ Status = STATUS_DUPLICATE_OBJECTID;
+ break;
+ }
+ if( IF->Index == IpAddrChange->NteIndex ) {
+ IPRemoveInterfaceRoute( IF );
+
+ IF->Unicast.Type = IP_ADDRESS_V4;
+ IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
+ IF->Netmask.Type = IP_ADDRESS_V4;
+ IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
+
+ TI_DbgPrint(MID_TRACE,("New Unicast Address: %x\n",
+ IF->Unicast.Address.IPv4Address));
+ TI_DbgPrint(MID_TRACE,("New Netmask : %x\n",
+ IF->Netmask.Address.IPv4Address));
+
+ IPAddInterfaceRoute( IF );
+
+ IpAddrChange->Address = IF->Index;
+ Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = IF->Index;
+ break;
+ }
+ } EndFor(IF);
+
+ Irp->IoStatus.Status = Status;
+ return Status;
+}
+
+NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer;
+ IF_LIST_ITER(IF);
+
+ ForEachInterface(IF) {
+ if( IF->Index == *NteIndex ) {
+ IF->Unicast.Type = IP_ADDRESS_V4;
+ IF->Unicast.Address.IPv4Address = 0;
+ IF->Netmask.Type = IP_ADDRESS_V4;
+ IF->Netmask.Address.IPv4Address = 0;
+ Status = STATUS_SUCCESS;
+ }
+ } EndFor(IF);
+
+ Irp->IoStatus.Status = Status;
+ return Status;
+}
+
/* EOF */