|
|
/////////////////////////////////////////////////////////
//
// Copyright (c) 2001 Microsoft Corporation
//
// Module Name:
// events.cpp
//
// Abstract:
// This module contains code which sets/clears the event handlers
//
//////////////////////////////////////////////////////////
#include "sysvars.h"
//////////////////////////////////////////////////////////////
// private constants, types, and prototypes
//////////////////////////////////////////////////////////////
const PCHAR strFunc1 = "TSSetEventHandler"; const PCHAR strFuncP1 = "TSSetEventComplete";
//
// information necessary to complete the command
//
struct EVENT_CONTEXT { PIRP pUpperIrp; // irp from dll to complete
}; typedef EVENT_CONTEXT *PEVENT_CONTEXT;
//
// completion function
//
TDI_STATUS TSSetEventComplete( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context );
//
// dummy event handlers
//
TDI_STATUS TSErrorHandler( PVOID pvTdiEventContext, TDI_STATUS lStatus );
TDI_STATUS TSSendPossibleHandler( PVOID pvTdiEventContext, PVOID pvConnectionContext, ULONG ulBytesAvailable );
TDI_STATUS TSErrorExHandler( PVOID pvTdiEventContext, TDI_STATUS lStatus, PVOID pvBuffer );
//////////////////////////////////////////////////////////////
// public functions
//////////////////////////////////////////////////////////////
// -----------------------------------------------------------------
//
// Function: TSSetEventHandler
//
// Arguments: pAddressObject -- our address object structure
// pSendBuffer -- arguments from user dll
// pIrp -- completion information
//
// Returns: NTSTATUS (normally pending)
//
// Descript: This function enables or disables event handlers
//
// -------------------------------------------------------------------------------------------
NTSTATUS TSSetEventHandler(PGENERIC_HEADER pGenericHeader, PSEND_BUFFER pSendBuffer, PIRP pUpperIrp) { ULONG ulEventId = pSendBuffer->COMMAND_ARGS.ulEventId; PADDRESS_OBJECT pAddressObject;
if (pGenericHeader->ulSignature == ulEndpointObject) { PENDPOINT_OBJECT pEndpoint = (PENDPOINT_OBJECT)pGenericHeader;
pAddressObject = pEndpoint->pAddressObject; } else { pAddressObject = (PADDRESS_OBJECT)pGenericHeader; }
//
// show debug, if it is turned on
//
if (ulDebugLevel & ulDebugShowCommand) { DebugPrint2("\nCommand = ulSETEVENTHANDLER\n" "AddressObject = %p\n" "EventId = 0x%08x\n", pAddressObject, ulEventId); }
//
// allocate all the necessary structures
//
PEVENT_CONTEXT pEventContext = NULL; //
// first, our context
//
if ((TSAllocateMemory((PVOID *)&pEventContext, sizeof(EVENT_CONTEXT), strFunc1, "EventContext")) != STATUS_SUCCESS) { goto cleanup; }
//
// then the irp itself
//
PIRP pLowerIrp = TSAllocateIrp(pAddressObject->GenHead.pDeviceObject, NULL); if (pLowerIrp) { PVOID pvEventContext = pAddressObject; PVOID pvEventHandler = NULL; BOOLEAN fNeedIrpPool = FALSE;
switch (ulEventId) { case TDI_EVENT_CONNECT: pvEventHandler = (PVOID)TSConnectHandler; fNeedIrpPool = TRUE; break; case TDI_EVENT_DISCONNECT: pvEventHandler = (PVOID)TSDisconnectHandler; fNeedIrpPool = TRUE; break; case TDI_EVENT_ERROR: pvEventHandler = (PVOID)TSErrorHandler; break; case TDI_EVENT_RECEIVE: fNeedIrpPool = TRUE; pvEventHandler = (PVOID)TSReceiveHandler; break; case TDI_EVENT_RECEIVE_DATAGRAM: fNeedIrpPool = TRUE; pvEventHandler = (PVOID)TSRcvDatagramHandler; break; case TDI_EVENT_RECEIVE_EXPEDITED: fNeedIrpPool = TRUE; pvEventHandler = (PVOID)TSRcvExpeditedHandler; break; case TDI_EVENT_SEND_POSSIBLE: pvEventHandler = (PVOID)TSSendPossibleHandler; break; case TDI_EVENT_CHAINED_RECEIVE: pvEventHandler = (PVOID)TSChainedReceiveHandler; break; case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM: pvEventHandler = (PVOID)TSChainedRcvDatagramHandler; break; case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED: pvEventHandler = (PVOID)TSChainedRcvExpeditedHandler; break; case TDI_EVENT_ERROR_EX: pvEventHandler = (PVOID)TSErrorExHandler; break; }
//
// if need to have irp pool for the handler, make sure that there
// is one allocated..
//
if ((!pAddressObject->pIrpPool) && fNeedIrpPool) { pAddressObject->pIrpPool = TSAllocateIrpPool(pAddressObject->GenHead.pDeviceObject, ulIrpPoolSize); } //
// if made it to here, everything is correctly allocated
// set up irp and call the tdi provider
//
pEventContext->pUpperIrp = pUpperIrp;
#pragma warning(disable: CONSTANT_CONDITIONAL)
TdiBuildSetEventHandler(pLowerIrp, pAddressObject->GenHead.pDeviceObject, pAddressObject->GenHead.pFileObject, TSSetEventComplete, pEventContext, ulEventId, pvEventHandler, pvEventContext);
#pragma warning(default: CONSTANT_CONDITIONAL)
//
// make the call to the tdi provider
//
pSendBuffer->pvLowerIrp = pLowerIrp; // so command can be cancelled
NTSTATUS lStatus = IoCallDriver(pAddressObject->GenHead.pDeviceObject, pLowerIrp);
if (((!NT_SUCCESS(lStatus)) && ulDebugLevel & ulDebugShowCommand)) { DebugPrint2("%s: unexpected status for IoCallDriver [0x%08x]\n", strFunc1, lStatus); } return STATUS_PENDING; }
//
// get here if an allocation error occurred
//
cleanup: if (pEventContext) { TSFreeMemory(pEventContext); } return STATUS_INSUFFICIENT_RESOURCES; }
/////////////////////////////////////////////////////////////
// private functions
/////////////////////////////////////////////////////////////
// ---------------------------------------------------------
//
// Function: TSSetEventComplete
//
// Arguments: pDeviceObject -- device object that called tdiquery
// pIrp -- IRP used in the call
// pContext -- context used for the call
//
// Returns: status of operation (STATUS_MORE_PROCESSING_REQUIRED)
//
// Descript: Gets the result of the setevent, stuffs results into
// receive buffer, completes the IRP from the dll, and
// cleans up the Irp and associated data from the setevent
//
// ---------------------------------------------------------
#pragma warning(disable: UNREFERENCED_PARAM)
TDI_STATUS TSSetEventComplete(PDEVICE_OBJECT pDeviceObject, PIRP pLowerIrp, PVOID pvContext) { PEVENT_CONTEXT pEventContext = (PEVENT_CONTEXT)pvContext; NTSTATUS lStatus = pLowerIrp->IoStatus.Status; PRECEIVE_BUFFER pReceiveBuffer = TSGetReceiveBuffer(pEventContext->pUpperIrp);
pReceiveBuffer->lStatus = lStatus;
if (ulDebugLevel & ulDebugShowCommand) { if (NT_SUCCESS(lStatus)) { if (pLowerIrp->IoStatus.Information) { DebugPrint2("%s: Information = 0x%08x\n", strFuncP1, pLowerIrp->IoStatus.Information); } } else { DebugPrint2("%s: Completed with status 0x%08x\n", strFuncP1, lStatus); } } TSCompleteIrp(pEventContext->pUpperIrp);
//
// now cleanup
//
TSFreeIrp(pLowerIrp, NULL); TSFreeMemory(pEventContext);
return TDI_MORE_PROCESSING; }
#pragma warning(default: UNREFERENCED_PARAM)
/////////////////////////////////////////////
// dummy event handlers
/////////////////////////////////////////////
#pragma warning(disable: UNREFERENCED_PARAM)
TDI_STATUS TSErrorHandler(PVOID pvTdiEventContext, TDI_STATUS TdiStatus) { return TSErrorExHandler(pvTdiEventContext, TdiStatus, NULL); }
TDI_STATUS TSSendPossibleHandler(PVOID pvTdiEventContext, PVOID pvConnectionContext, ULONG ulBytesAvailable) { DebugPrint3("TSSendPossibleHandler Called\n" "AddressObject = %p\n" "ConnectContext = %p\n" "BytesAvail = 0x%08x\n", pvTdiEventContext, pvConnectionContext, ulBytesAvailable); return TDI_SUCCESS; }
TDI_STATUS TSErrorExHandler(PVOID pvTdiEventContext, TDI_STATUS TdiStatus, PVOID pvBuffer) { PADDRESS_OBJECT pAddressObject = (PADDRESS_OBJECT)pvTdiEventContext;
if (ulDebugLevel & ulDebugShowCommand) { DebugPrint3("TSErrorExHandler Called\n" "AddressObject = %p\n" "Status = 0x%08x\n" "Buffer = %p\n", pvTdiEventContext, TdiStatus, pvBuffer); } return STATUS_SUCCESS; }
#pragma warning(default: UNREFERENCED_PARAM)
/////////////////////////////////////////////////////////////////////////////////
// end of file events.cpp
/////////////////////////////////////////////////////////////////////////////////
|