VOID NTAPI DisconnectTimeoutDpc(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) { PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext; PLIST_ENTRY Entry; PTDI_BUCKET Bucket; LockObjectAtDpcLevel(Connection); /* We timed out waiting for pending sends so force it to shutdown */ TCPTranslateError(LibTCPShutdown(Connection, 0, 1)); while (!IsListEmpty(&Connection->SendRequest)) { Entry = RemoveHeadList(&Connection->SendRequest); Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry); Bucket->Information = 0; Bucket->Status = STATUS_FILE_CLOSED; CompleteBucket(Connection, Bucket, FALSE); } while (!IsListEmpty(&Connection->ShutdownRequest)) { Entry = RemoveHeadList( &Connection->ShutdownRequest ); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Bucket->Status = STATUS_TIMEOUT; Bucket->Information = 0; CompleteBucket(Connection, Bucket, FALSE); } UnlockObjectFromDpcLevel(Connection); DereferenceObject(Connection); }
NTSTATUS DispTdiListen( PIRP Irp) /* * FUNCTION: TDI_LISTEN handler * ARGUMENTS: * Irp = Pointer to an I/O request packet * RETURNS: * Status of operation */ { PCONNECTION_ENDPOINT Connection; PTDI_REQUEST_KERNEL Parameters; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); /* Get associated connection endpoint file object. Quit if none exists */ TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); Status = STATUS_INVALID_PARAMETER; goto done; } Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; if (Connection == NULL) { TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); Status = STATUS_INVALID_PARAMETER; goto done; } Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters; Status = DispPrepareIrpForCancel (TranContext->Handle.ConnectionContext, Irp, (PDRIVER_CANCEL)DispCancelListenRequest); LockObject(Connection, &OldIrql); if (Connection->AddressFile == NULL) { TI_DbgPrint(MID_TRACE, ("No associated address file\n")); UnlockObject(Connection, OldIrql); Status = STATUS_INVALID_PARAMETER; goto done; } LockObjectAtDpcLevel(Connection->AddressFile); /* 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( NT_SUCCESS(Status) && !Connection->AddressFile->Listener ) { Connection->AddressFile->Listener = TCPAllocateConnectionEndpoint( NULL ); if( !Connection->AddressFile->Listener ) Status = STATUS_NO_MEMORY; if( NT_SUCCESS(Status) ) { ReferenceObject(Connection->AddressFile); Connection->AddressFile->Listener->AddressFile = Connection->AddressFile; Status = TCPSocket( Connection->AddressFile->Listener, Connection->AddressFile->Family, SOCK_STREAM, Connection->AddressFile->Protocol ); } if( NT_SUCCESS(Status) ) { ReferenceObject(Connection->AddressFile->Listener); Status = TCPListen( Connection->AddressFile->Listener, 1024 ); /* BACKLOG */ } } if( NT_SUCCESS(Status) ) { Status = TCPAccept ( (PTDI_REQUEST)Parameters, Connection->AddressFile->Listener, Connection, DispDataRequestComplete, Irp ); } UnlockObjectFromDpcLevel(Connection->AddressFile); UnlockObject(Connection, OldIrql); done: if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else IoMarkIrpPending(Irp); TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status)); return Status; }
NTSTATUS DispTdiAssociateAddress( PIRP Irp) /* * FUNCTION: TDI_ASSOCIATE_ADDRESS handler * ARGUMENTS: * Irp = Pointer to an I/O request packet * RETURNS: * Status of operation */ { PTDI_REQUEST_KERNEL_ASSOCIATE Parameters; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; PCONNECTION_ENDPOINT Connection, LastConnection; PFILE_OBJECT FileObject; PADDRESS_FILE AddrFile = NULL; NTSTATUS Status; KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); /* Get associated connection endpoint file object. Quit if none exists */ TranContext = IrpSp->FileObject->FsContext; if (!TranContext) { TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; if (!Connection) { TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n")); return STATUS_INVALID_PARAMETER; } Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters; Status = ObReferenceObjectByHandle( Parameters->AddressHandle, 0, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n", Parameters->AddressHandle, Status)); return STATUS_INVALID_PARAMETER; } LockObject(Connection, &OldIrql); if (Connection->AddressFile) { ObDereferenceObject(FileObject); UnlockObject(Connection, 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); UnlockObject(Connection, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", FileObject->FsContext2)); return STATUS_INVALID_PARAMETER; } /* Get associated address file object. Quit if none exists */ TranContext = FileObject->FsContext; if (!TranContext) { ObDereferenceObject(FileObject); UnlockObject(Connection, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { UnlockObject(Connection, OldIrql); ObDereferenceObject(FileObject); TI_DbgPrint(MID_TRACE, ("No address file object.\n")); return STATUS_INVALID_PARAMETER; } LockObjectAtDpcLevel(AddrFile); ReferenceObject(AddrFile); Connection->AddressFile = AddrFile; /* Add connection endpoint to the address file */ ReferenceObject(Connection); if (AddrFile->Connection == NULL) AddrFile->Connection = Connection; else { LastConnection = AddrFile->Connection; while (LastConnection->Next != NULL) LastConnection = LastConnection->Next; LastConnection->Next = Connection; } ObDereferenceObject(FileObject); UnlockObjectFromDpcLevel(AddrFile); UnlockObject(Connection, OldIrql); return STATUS_SUCCESS; }