NTSTATUS
TDIClnSetEventHandler(
PFILE_OBJECT pAddrFileObj, // Address file object.
PDEVICE_OBJECT pTcpDevObj, // TDI driver's device object.
LONG EventType, // Type of event.
PVOID pEventHandler, // Event handler routine.
PVOID pEventContext // Context for event handler.
)
/**************************************************************************************************/
/* */
/* Set up an event handler. */
/* */
/* Note: This routine is synchronous. */
/* */
/**************************************************************************************************/
{
NTSTATUS status;
KEVENT Event;
IO_STATUS_BLOCK IoStatus;
PIRP pIrp;
do { // Single-iteration loop, to make possible escape via break.
KeInitializeEvent(&Event, NotificationEvent, FALSE);
// Get an Irp for internal device ioctl.
pIrp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER,
pTcpDevObj, // TDI driver's device object.
pAddrFileObj, // Address file object.
&Event, // Event to be signalled when Irp completes.
&IoStatus // I/O status block.
);
if (NULL==pIrp)
{
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
TdiBuildSetEventHandler(pIrp,
pTcpDevObj,
pAddrFileObj,
NULL, // I/O completion routine.
NULL, // Context for I/O completion routine.
EventType,
pEventHandler, // Event handler routine.
pEventContext // Context for event handler routine.
);
status = IoCallDriver(pTcpDevObj, pIrp);
if (STATUS_PENDING==status) // Have to wait on this Irp?
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0);
// Problem from IoCallDriver() or Problem discovered in completion?
if ( ( STATUS_SUCCESS!=status && STATUS_PENDING!=status )
|| ( STATUS_PENDING==status && 0!=IoStatus.Status ) )
{
// Note: If problem was in IoCallDriver(), IoStatus.Status probably won't be meaningful.
DebugPrint(("TDIClnSetEventHandler: Problem in IoCallDriver(). status = 0x%08x, IoStatus.Status = 0x%08x\n",
STATUS_PENDING==status ? 0 : status , IoStatus.Status));
}
} while(0); // End 'do-while' single-iteration loop.
status = ((STATUS_SUCCESS==status) || (STATUS_PENDING==status)) ? IoStatus.Status : status;