NTSTATUS NbfTdiReceiveDatagram( IN PIRP Irp ) /*++ Routine Description: This routine performs the TdiReceiveDatagram request for the transport provider. Receive datagrams just get queued up to an address, and are completed when a DATAGRAM or DATAGRAM_BROADCAST frame is received at the address. Arguments: Irp - I/O Request Packet for this request. Return Value: NTSTATUS - status of operation. --*/ { NTSTATUS status; KIRQL oldirql; PTP_ADDRESS address; PTP_ADDRESS_FILE addressFile; PIO_STACK_LOCATION irpSp; KIRQL cancelIrql; // // verify that the operation is taking place on an address. At the same // time we do this, we reference the address. This ensures it does not // get removed out from under us. Note also that we do the address // lookup within a try/except clause, thus protecting ourselves against // really bogus handles // irpSp = IoGetCurrentIrpStackLocation (Irp); addressFile = irpSp->FileObject->FsContext; status = NbfVerifyAddressObject (addressFile); if (!NT_SUCCESS (status)) { return status; } #if DBG if (((PTDI_REQUEST_KERNEL_RECEIVEDG)(&irpSp->Parameters))->ReceiveLength > 0) { ASSERT (Irp->MdlAddress != NULL); } #endif address = addressFile->Address; IoAcquireCancelSpinLock(&cancelIrql); ACQUIRE_SPIN_LOCK (&address->SpinLock,&oldirql); if ((address->Flags & (ADDRESS_FLAGS_STOPPING | ADDRESS_FLAGS_CONFLICT)) != 0) { RELEASE_SPIN_LOCK (&address->SpinLock,oldirql); IoReleaseCancelSpinLock(cancelIrql); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = (address->Flags & ADDRESS_FLAGS_STOPPING) ? STATUS_NETWORK_NAME_DELETED : STATUS_DUPLICATE_NAME; IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); } else { // // If this IRP has been cancelled, then call the // cancel routine. // if (Irp->Cancel) { RELEASE_SPIN_LOCK (&address->SpinLock, oldirql); IoReleaseCancelSpinLock(cancelIrql); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_CANCELLED; IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); } else { IoSetCancelRoutine(Irp, NbfCancelReceiveDatagram); NbfReferenceAddress ("Receive datagram", address, AREF_REQUEST); InsertTailList (&addressFile->ReceiveDatagramQueue,&Irp->Tail.Overlay.ListEntry); RELEASE_SPIN_LOCK (&address->SpinLock,oldirql); IoReleaseCancelSpinLock(cancelIrql); } } NbfDereferenceAddress ("Temp rcv datagram", address, AREF_VERIFY); return STATUS_PENDING; } /* TdiReceiveDatagram */
NTSTATUS NbfTdiSetEventHandler( IN PIRP Irp ) /*++ Routine Description: This routine performs the TdiSetEventHandler request for the transport provider. The caller (request dispatcher) verifies that this routine will not be executed on behalf of a user-mode client, as this request enables direct callouts at DISPATCH_LEVEL. Arguments: Irp - Pointer to the IRP for this request Return Value: NTSTATUS - status of operation. --*/ { NTSTATUS rc=STATUS_SUCCESS; KIRQL oldirql; PTDI_REQUEST_KERNEL_SET_EVENT parameters; PIO_STACK_LOCATION irpSp; PTP_ADDRESS address; PTP_ADDRESS_FILE addressFile; NTSTATUS status; // // Get the Address this is associated with; if there is none, get out. // irpSp = IoGetCurrentIrpStackLocation (Irp); if (irpSp->FileObject->FsContext2 != (PVOID) TDI_TRANSPORT_ADDRESS_FILE) { return STATUS_INVALID_ADDRESS; } addressFile = irpSp->FileObject->FsContext; status = NbfVerifyAddressObject (addressFile); if (!NT_SUCCESS (status)) { return status; } address = addressFile->Address; ACQUIRE_SPIN_LOCK (&address->SpinLock, &oldirql); parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&irpSp->Parameters; switch (parameters->EventType) { case TDI_EVENT_RECEIVE: if (parameters->EventHandler == NULL) { addressFile->ReceiveHandler = (PTDI_IND_RECEIVE)TdiDefaultReceiveHandler; addressFile->ReceiveHandlerContext = NULL; addressFile->RegisteredReceiveHandler = FALSE; IF_NBFDBG (NBF_DEBUG_DISPATCH) { NbfPrint0 ("NbfTdiSetEventHandler: set STREAM DefaultReceiveHandler.\n"); } } else {