summaryrefslogblamecommitdiffstats
path: root/private/ntos/tdi/st/event.c
blob: 9c98c9596a73e6220a5da5305f3dd21605eb5e4a (plain) (tree)
























































































































































































                                                                                  
/*++

Copyright (c) 1989-1993  Microsoft Corporation

Module Name:

    event.c

Abstract:

    This module contains code which performs the following TDI services:

        o   TdiSetEventHandler

Environment:

    Kernel mode

Revision History:

--*/

#include "st.h"


NTSTATUS
StTdiSetEventHandler(
    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);

    addressFile  = irpSp->FileObject->FsContext;
    status = StVerifyAddressObject (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;
        } else {
            addressFile->ReceiveHandler =
                (PTDI_IND_RECEIVE)parameters->EventHandler;
            addressFile->ReceiveHandlerContext = parameters->EventContext;
            addressFile->RegisteredReceiveHandler = TRUE;
        }

        break;

    case TDI_EVENT_RECEIVE_EXPEDITED:

        if (parameters->EventHandler == NULL) {
            addressFile->ExpeditedDataHandler =
                (PTDI_IND_RECEIVE_EXPEDITED)TdiDefaultRcvExpeditedHandler;
            addressFile->ExpeditedDataHandlerContext = NULL;
            addressFile->RegisteredExpeditedDataHandler = FALSE;
        } else {
            addressFile->ExpeditedDataHandler =
                (PTDI_IND_RECEIVE_EXPEDITED)parameters->EventHandler;
            addressFile->ExpeditedDataHandlerContext = parameters->EventContext;
            addressFile->RegisteredExpeditedDataHandler = TRUE;
        }

        break;

    case TDI_EVENT_RECEIVE_DATAGRAM:

        if (parameters->EventHandler == NULL) {
            addressFile->ReceiveDatagramHandler =
                (PTDI_IND_RECEIVE_DATAGRAM)TdiDefaultRcvDatagramHandler;
            addressFile->ReceiveDatagramHandlerContext = NULL;
            addressFile->RegisteredReceiveDatagramHandler = FALSE;
        } else {
            addressFile->ReceiveDatagramHandler =
                (PTDI_IND_RECEIVE_DATAGRAM)parameters->EventHandler;
            addressFile->ReceiveDatagramHandlerContext = parameters->EventContext;
            addressFile->RegisteredReceiveDatagramHandler = TRUE;
        }

        break;

    case TDI_EVENT_ERROR:

        if (parameters->EventHandler == NULL) {
            addressFile->ErrorHandler =
                (PTDI_IND_ERROR)TdiDefaultErrorHandler;
            addressFile->ErrorHandlerContext = NULL;
            addressFile->RegisteredErrorHandler = FALSE;
        } else {
            addressFile->ErrorHandler =
                (PTDI_IND_ERROR)parameters->EventHandler;
            addressFile->ErrorHandlerContext = parameters->EventContext;
            addressFile->RegisteredErrorHandler = TRUE;
        }

        break;

    case TDI_EVENT_DISCONNECT:

        if (parameters->EventHandler == NULL) {
            addressFile->DisconnectHandler =
                (PTDI_IND_DISCONNECT)TdiDefaultDisconnectHandler;
            addressFile->DisconnectHandlerContext = NULL;
            addressFile->RegisteredDisconnectHandler = FALSE;
        } else {
            addressFile->DisconnectHandler =
                (PTDI_IND_DISCONNECT)parameters->EventHandler;
            addressFile->DisconnectHandlerContext = parameters->EventContext;
            addressFile->RegisteredDisconnectHandler = TRUE;
        }

        break;

    case TDI_EVENT_CONNECT:

        if (parameters->EventHandler == NULL) {
            addressFile->ConnectionHandler =
                (PTDI_IND_CONNECT)TdiDefaultConnectHandler;
            addressFile->ConnectionHandlerContext = NULL;
            addressFile->RegisteredConnectionHandler = FALSE;
        } else {
            addressFile->ConnectionHandler =
                (PTDI_IND_CONNECT)parameters->EventHandler;
            addressFile->ConnectionHandlerContext = parameters->EventContext;
            addressFile->RegisteredConnectionHandler = TRUE;
        }
            break;

    default:

        rc = STATUS_INVALID_PARAMETER;

    } /* switch */

    RELEASE_SPIN_LOCK (&address->SpinLock, oldirql);

    StDereferenceAddress ("Set event handler", address);

    return rc;
} /* TdiSetEventHandler */