372 lines
10 KiB
C++
372 lines
10 KiB
C++
|
/////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 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
|
||
|
/////////////////////////////////////////////////////////////////////////////////
|
||
|
|