diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/tdi/loopback/endpoint.c | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/private/ntos/tdi/loopback/endpoint.c b/private/ntos/tdi/loopback/endpoint.c new file mode 100644 index 000000000..fd252d291 --- /dev/null +++ b/private/ntos/tdi/loopback/endpoint.c @@ -0,0 +1,373 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + endpoint.c + +Abstract: + + This module implements endpoint logic for the loopback Transport + Provider driver for NT LAN Manager. + +Author: + + Chuck Lenzmeier (chuckl) 15-Aug-1991 + +Revision History: + +--*/ + +#include "loopback.h" + + +VOID +LoopDereferenceEndpoint ( + IN PLOOP_ENDPOINT Endpoint + ) + +/*++ + +Routine Description: + + This routine is called to dereference an endpoint block. If the + reference count on the block goes to zero, the endpoint block is + deleted. + + The Loopback device object's spin lock must be held when this + routine is called. + +Arguments: + + Endpoint - Supplies a pointer to an endpoint block + +Return Value: + + None. + +--*/ + +{ + PIRP closeIrp; + + IF_DEBUG(LOOP3) { + DbgPrint( " Dereferencing endpoint %lx; old refcnt %lx\n", + Endpoint, Endpoint->BlockHeader.ReferenceCount ); + } + + ASSERT( (LONG)Endpoint->BlockHeader.ReferenceCount > 0 ); + + if ( --Endpoint->BlockHeader.ReferenceCount != 0 ) { + return; + } + + IF_DEBUG(LOOP3) DbgPrint( " Deleting endpoint %lx\n", Endpoint ); + + RemoveEntryList( &Endpoint->DeviceListEntry ); + + RELEASE_LOOP_LOCK( "DerefEndp deleting" ); + + ObDereferenceObject( Endpoint->DeviceObject ); + + // + // If a Close IRP is pending, complete it now. + // + + closeIrp = Endpoint->CloseIrp; + + if ( closeIrp != NULL ) { + + IF_DEBUG(LOOP3) { + DbgPrint( " Completing Close IRP %lx\n", closeIrp ); + } + closeIrp->IoStatus.Status = STATUS_SUCCESS; + closeIrp->IoStatus.Information = 0; + + IoCompleteRequest( closeIrp, 2 ); + + } + + DEBUG SET_BLOCK_TYPE( Endpoint, BlockTypeGarbage ); + DEBUG SET_BLOCK_STATE( Endpoint, BlockStateDead ); + DEBUG SET_BLOCK_SIZE( Endpoint, -1 ); + DEBUG Endpoint->BlockHeader.ReferenceCount = -1; + DEBUG Endpoint->DeviceObject = NULL; + + ExFreePool( Endpoint ); + + ACQUIRE_LOOP_LOCK( "DerefEndp done" ); + + return; + +} // LoopDereferenceEndpoint + + +PLOOP_ENDPOINT +LoopFindBoundAddress ( + IN PCHAR NetbiosName + ) + +/*++ + +Routine Description: + + This routine searches the list of endpoints for the loopback device + for one that has the specified address bound to it. + + The loopback device object's spin lock must be owned when this + function is called. + +Arguments: + + NetbiosName - Pointer to NetBIOS name string, formatted according + to TDI specification. + +Return Value: + + PLOOP_OBJECT - Pointer to LOOP_ENDPOINT block if matching address + found, else NULL + +--*/ + +{ + PLIST_ENTRY listEntry; + PLOOP_ENDPOINT endpoint; + LONG compareResult; + CLONG i; + + listEntry = LoopDeviceObject->EndpointList.Flink; + + while ( listEntry != &LoopDeviceObject->EndpointList ) { + + endpoint = CONTAINING_RECORD( + listEntry, + LOOP_ENDPOINT, + DeviceListEntry + ); + + if ( GET_BLOCK_STATE(endpoint) == BlockStateActive ) { + + compareResult = 0; + for ( i = 0; i < NETBIOS_NAME_LENGTH; i++ ) { + if ( endpoint->NetbiosName[i] != NetbiosName[i] ) { + compareResult = 1; + break; + } + } + + if ( compareResult == 0 ) { + return endpoint; + } + + } + + listEntry = listEntry->Flink; + + } + + return NULL; + +} // LoopFindBoundAddress + + +NTSTATUS +LoopSetEventHandler ( + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp + ) + +/*++ + +Routine Description: + + This routine processes a Set Receive Handler request. + +Arguments: + + Irp - Pointer to I/O request packet + + IrpSp - Pointer to current stack location in IRP + +Return Value: + + NTSTATUS - Status of request + +--*/ + +{ + NTSTATUS status = STATUS_SUCCESS; + PTDI_REQUEST_KERNEL_SET_EVENT setEventRequest; + PLOOP_ENDPOINT endpoint; + PVOID handler; + PVOID context; + PSZ s; + + IrpSp; // prevent compiler warnings + + IF_DEBUG(LOOP1) DbgPrint( " SetEventHandler request\n" ); + + setEventRequest = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; + + handler = setEventRequest->EventHandler; + context = setEventRequest->EventContext; + + // + // Get the endpoint address and update the handler address. + // + + ACQUIRE_LOOP_LOCK( "SetEventHandler initial" ); + + endpoint = (PLOOP_ENDPOINT)IrpSp->FileObject->FsContext; + IF_DEBUG(LOOP2) DbgPrint( " Endpoint address: %lx\n", endpoint ); + + if ( endpoint == NULL ) { + IF_DEBUG(LOOP2) { + DbgPrint( " Can't SetEventHandler on control channel\n" ); + } + status = STATUS_INVALID_PARAMETER; + goto complete; + } + + if ( GET_BLOCK_TYPE(endpoint) != BlockTypeLoopEndpoint ) { + status = STATUS_INVALID_PARAMETER; + goto complete; + } + + switch ( setEventRequest->EventType ) { + + case TDI_EVENT_CONNECT: + + IF_DEBUG(LOOP2) s = "connect"; + + endpoint->ConnectHandler = (PTDI_IND_CONNECT)handler; + endpoint->ConnectContext = context; + + break; + + case TDI_EVENT_DISCONNECT: + + IF_DEBUG(LOOP2) s = "disconnect"; + + endpoint->DisconnectHandler = (PTDI_IND_DISCONNECT)handler; + endpoint->DisconnectContext = context; + + break; + + case TDI_EVENT_ERROR: + + IF_DEBUG(LOOP2) s = "error"; + + endpoint->ErrorHandler = (PTDI_IND_ERROR)handler; + endpoint->ErrorContext = context; + + break; + + case TDI_EVENT_RECEIVE: + + IF_DEBUG(LOOP2) s = "receive"; + + endpoint->ReceiveHandler = (PTDI_IND_RECEIVE)handler; + endpoint->ReceiveContext = context; + + break; + + case TDI_EVENT_RECEIVE_DATAGRAM: + + IF_DEBUG(LOOP2) s = "receive datagram"; + + endpoint->ReceiveDatagramHandler = (PTDI_IND_RECEIVE_DATAGRAM)handler; + endpoint->ReceiveDatagramContext = context; + + break; + + case TDI_EVENT_RECEIVE_EXPEDITED: + + IF_DEBUG(LOOP2) s = "receive expedited"; + + endpoint->ReceiveExpeditedHandler = + (PTDI_IND_RECEIVE_EXPEDITED)handler; + endpoint->ReceiveExpeditedContext = context; + + break; + + default: + + DEBUG { + DbgPrint( " Invalid event type: %lx\n", + setEventRequest->EventType ); + } + ASSERT( FALSE ); + status = STATUS_INVALID_PARAMETER; + goto complete; + + } + + IF_DEBUG(LOOP2) { + DbgPrint( " New %s handler address: %lx, context: %lx\n", + s, handler, context ); + } + +complete: + + RELEASE_LOOP_LOCK( "SetEventHandler final" ); + + // + // Complete the I/O request. + // + + Irp->IoStatus.Status = status; + + IoCompleteRequest( Irp, 2 ); + + IF_DEBUG(LOOP1) DbgPrint( " SetReceiveHandler request complete\n" ); + return status; + +} // LoopSetEventHandler + + +NTSTATUS +LoopVerifyEndpoint ( + IN PLOOP_ENDPOINT Endpoint + ) + +/*++ + +Routine Description: + + This routine verifies that the specified endpoint block is really + an endpoint created by the loopback driver. + + The loopback device object's spin lock must be owned when this + function is called. + +Arguments: + + Endpoint - Pointer to endpoint block + +Return Value: + + NTSTATUS - STATUS_SUCCESS or STATUS_INVALID_PARAMETER + +--*/ + +{ + PLIST_ENTRY listEntry; + + listEntry = LoopDeviceObject->EndpointList.Flink; + + while ( listEntry != &LoopDeviceObject->EndpointList ) { + + if ( CONTAINING_RECORD( listEntry, LOOP_ENDPOINT, DeviceListEntry ) == + Endpoint ) { + return STATUS_SUCCESS; + } + + listEntry = listEntry->Flink; + + } + + return STATUS_INVALID_PARAMETER; + +} // LoopVerifyEndpoint + |