📄 addr.c
字号:
);
// ATTENTION!!! Close Orphan TCPConn's ???
}
else
{
KdPrint((" AddrObject For Close NOT FOUND!!!\n" ));
}
UTIL_DecrementLargeInteger(
pTDIH_DeviceExtension->OutstandingIoRequests,
(unsigned long)1,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
// If the outstanding count is 0, signal the appropriate event which will
// allow any pending detach to proceed.
UTIL_IsLargeIntegerZero(
CanDetachProceed,
pTDIH_DeviceExtension->OutstandingIoRequests,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
if (CanDetachProceed)
{
// signal the event object. Note that this is simply an
// advisory check we do here (to wake up a sleeping thread).
// It is the responsibility of the thread performing the detach to
// ensure that no operations are truly in progress.
KeSetEvent(&(pTDIH_DeviceExtension->IoInProgressEvent), IO_NO_INCREMENT, FALSE);
}
// Although the success return value is hard-coded here, you can
// return an appropriate value (either success or more-processing-reqd)
// based upon what it is that you wish to do in your completion routine.
return(STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////
//// TDIH_TdiCloseAddress
//
// Purpose
// This is the hook for TdiCloseAddress
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TDIH_TdiCloseAddress(
PTDIH_DeviceExtension pTDIH_DeviceExtension,
PIRP Irp,
PIO_STACK_LOCATION IrpSp
)
{
NTSTATUS RC;
KdPrint(( "TDIH_TdiCloseAddress: Entry...\n" ));
//
// Pass The Request To A TCP/IP Device
//
try
{
PDEVICE_OBJECT pLowerDeviceObject = NULL;
pLowerDeviceObject = pTDIH_DeviceExtension->LowerDeviceObject;
// Be careful about not screwing up badly. This is actually not recommended by the I/O Manager.
if (Irp->CurrentLocation == 1)
{
ULONG ReturnedInformation = 0;
// Bad!! Fudge the error code. Break if we can ...
KdPrint(("TDIH_TdiCloseAddress encountered bogus current location\n"));
// UTIL_BreakPoint();
RC = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return( RC );
}
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(
Irp,
TDIH_TdiCloseAddressComplete,
pTDIH_DeviceExtension,
TRUE,
TRUE,
TRUE
);
UTIL_IncrementLargeInteger(
pTDIH_DeviceExtension->OutstandingIoRequests,
(unsigned long)1,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
// Clear the fast-IO notification event protected by the resource
// we have acquired.
KeClearEvent(&(pTDIH_DeviceExtension->IoInProgressEvent));
ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL );
RC = IoCallDriver(pLowerDeviceObject, Irp);
try_return(RC);
try_exit: NOTHING;
}
finally
{
}
return(RC);
}
/////////////////////////////////////////////////////////////////////////////
//// TDIH_TdiSetEventComplete
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TDIH_TdiSetEventComplete(
PDEVICE_OBJECT pDeviceObject,
PIRP Irp,
void *Context
)
{
PTDIH_DeviceExtension pTDIH_DeviceExtension;
BOOLEAN CanDetachProceed = FALSE;
PDEVICE_OBJECT pAssociatedDeviceObject = NULL;
NTSTATUS Status = Irp->IoStatus.Status;
KdPrint(( "TDIH_TdiSetEventComplete: Status: 0x%8.8X\n", Status ));
pTDIH_DeviceExtension = (PTDIH_DeviceExtension )(Context);
ASSERT( pTDIH_DeviceExtension );
//
// Propogate The IRP Pending Flag
//
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
// Ensure that this is a valid device object pointer, else return
// immediately.
pAssociatedDeviceObject = pTDIH_DeviceExtension->pFilterDeviceObject;
if (pAssociatedDeviceObject != pDeviceObject)
{
KdPrint(( "TDIH_TdiSetEventComplete: Invalid Device Object Pointer\n" ));
return(STATUS_SUCCESS);
}
// Note that you could do all sorts of processing at this point
// depending upon the results of the operation. Be careful though
// about what you chose to do, about the fact that this completion
// routine is being invoked in an arbitrary thread context and probably
// at high IRQL.
UTIL_DecrementLargeInteger(
pTDIH_DeviceExtension->OutstandingIoRequests,
(unsigned long)1,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
// If the outstanding count is 0, signal the appropriate event which will
// allow any pending detach to proceed.
UTIL_IsLargeIntegerZero(
CanDetachProceed,
pTDIH_DeviceExtension->OutstandingIoRequests,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
if (CanDetachProceed)
{
// signal the event object. Note that this is simply an
// advisory check we do here (to wake up a sleeping thread).
// It is the responsibility of the thread performing the detach to
// ensure that no operations are truly in progress.
KeSetEvent(&(pTDIH_DeviceExtension->IoInProgressEvent), IO_NO_INCREMENT, FALSE);
}
// Although the success return value is hard-coded here, you can
// return an appropriate value (either success or more-processing-reqd)
// based upon what it is that you wish to do in your completion routine.
return(STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////
//// TDIH_TdiSetEvent
//
// Purpose
// This is the hook for TdiSetEvent
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TDIH_TdiSetEvent(
PTDIH_DeviceExtension pTDIH_DeviceExtension,
PIRP Irp,
PIO_STACK_LOCATION IrpSp
)
{
NTSTATUS RC;
AddrObj *pAddrObj;
PTDI_REQUEST_KERNEL_SET_EVENT pSrc, pDest;
PDEVICE_OBJECT pLowerDeviceObject = NULL;
PIO_STACK_LOCATION irpNextSp = NULL;
pLowerDeviceObject = pTDIH_DeviceExtension->LowerDeviceObject;
// Be careful about not screwing up badly. This is actually not recommended by the I/O Manager.
if (Irp->CurrentLocation == 1)
{
ULONG ReturnedInformation = 0;
// Bad!! Fudge the error code. Break if we can ...
KdPrint(("TDIH_TdiSetEvent encountered bogus current location\n"));
// UTIL_BreakPoint();
RC = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return( RC );
}
IoCopyCurrentIrpStackLocationToNext( Irp );
pSrc = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
irpNextSp = IoGetNextIrpStackLocation(Irp);
pDest = (PTDI_REQUEST_KERNEL_SET_EVENT)&irpNextSp->Parameters;
IoSetCompletionRoutine(
Irp,
TDIH_TdiSetEventComplete,
pTDIH_DeviceExtension,
TRUE,
TRUE,
TRUE
);
//
// Locate Our Address Object
//
pAddrObj = TDIH_GetAddrObjFromFileObject( IrpSp->FileObject );
if( pAddrObj )
{
switch( pSrc->EventType )
{
case TDI_EVENT_CONNECT:
KdPrint(( "TDIH_TdiSetEvent: Hooking connect event\n" ));
if( pSrc->EventHandler )
{
//
// Hook The Caller's Event Handler
// -------------------------------
// Save the caller's handler and context and replace it
// with our own.
//
pAddrObj->ao_connect = pSrc->EventHandler;
pAddrObj->ao_conncontext = pSrc->EventContext;
pDest->EventHandler = (PVOID )TDIH_TdiConnectEventHandler;
pDest->EventContext = (PVOID )pAddrObj; // context is our Address Object Record
}
else
{
//
// Caller Has No Event Handler
// ---------------------------
// This could be used to "unset" and event handler. In most
// cases we don't want to be called either...
//
pAddrObj->ao_connect = NULL;
pAddrObj->ao_conncontext = NULL;
pDest->EventHandler = NULL;
pDest->EventContext = NULL;
}
break;
case TDI_EVENT_RECEIVE:
KdPrint(( "TDIH_TdiSetEvent: Hooking receive event\n" ));
if( pSrc->EventHandler )
{
//
// Hook The Caller's Event Handler
// -------------------------------
// Save the caller's handler and context and replace it
// with our own.
//
pAddrObj->ao_rcv = pSrc->EventHandler;
pAddrObj->ao_rcvcontext = pSrc->EventContext;
pDest->EventHandler = (PVOID )TDIH_TdiReceiveEventHandler;
pDest->EventContext = (PVOID )pAddrObj; // context is our Address Object Record
}
else
{
//
// Caller Has No Event Handler
// ---------------------------
// This could be used to "unset" and event handler. In most
// cases we don't want to be called either...
//
pAddrObj->ao_rcv = NULL;
pAddrObj->ao_rcvcontext = NULL;
pDest->EventHandler = NULL;
pDest->EventContext = NULL;
}
break;
case TDI_EVENT_CHAINED_RECEIVE:
KdPrint(( "TDIH_TdiSetEvent: Hooking chained receive event\n" ));
if( pSrc->EventHandler )
{
//
// Hook The Caller's Event Handler
// -------------------------------
// Save the caller's handler and context and replace it
// with our own.
//
pAddrObj->ao_chainedrcv = pSrc->EventHandler;
pAddrObj->ao_chainedrcvcontext = pSrc->EventContext;
pDest->EventHandler = (PVOID )TDIH_TdiChainedReceiveEventHandler;
pDest->EventContext = (PVOID )pAddrObj; // context is our Address Object Record
}
else
{
//
// Caller Has No Event Handler
// ---------------------------
// This could be used to "unset" and event handler. In most
// cases we don't want to be called either...
//
pAddrObj->ao_chainedrcv = NULL;
pAddrObj->ao_chainedrcvcontext = NULL;
pDest->EventHandler = NULL;
pDest->EventContext = NULL;
}
break;
case TDI_EVENT_RECEIVE_DATAGRAM:
KdPrint(( "TDIH_TdiSetEvent: Hooking receive datagram event\n" ));
if( pSrc->EventHandler )
{
//
// Hook The Caller's Event Handler
// -------------------------------
// Save the caller's handler and context and replace it
// with our own.
//
pAddrObj->ao_rcvdg = pSrc->EventHandler;
pAddrObj->ao_rcvdgcontext = pSrc->EventContext;
pDest->EventHandler = (PVOID )TDIH_TdiReceiveDGEventHandler;
pDest->EventContext = (PVOID )pAddrObj; // context is our Address Object Record
}
else
{
//
// Caller Has No Event Handler
// ---------------------------
// This could be used to "unset" and event handler. In most
// cases we don't want to be called either...
//
pAddrObj->ao_rcvdg = NULL;
pAddrObj->ao_rcvdgcontext = NULL;
pDest->EventHandler = NULL;
pDest->EventContext = NULL;
}
break;
case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
KdPrint(( "TDIH_TdiSetEvent: Hooking chained receive datagram event\n" ));
if( pSrc->EventHandler )
{
//
// Hook The Caller's Event Handler
// -------------------------------
// Save the caller's handler and context and replace it
// with our own.
//
pAddrObj->ao_chainedrcvdg = pSrc->EventHandler;
pAddrObj->ao_chainedrcvdgcontext = pSrc->EventContext;
pDest->EventHandler = (PVOID )TDIH_TdiChainedReceiveDGEventHandler;
pDest->EventContext = (PVOID )pAddrObj; // context is our Address Object Record
}
else
{
//
// Caller Has No Event Handler
// ---------------------------
// This could be used to "unset" and event handler. In most
// cases we don't want to be called either...
//
pAddrObj->ao_chainedrcvdg = NULL;
pAddrObj->ao_chainedrcvdgcontext = NULL;
pDest->EventHandler = NULL;
pDest->EventContext = NULL;
}
break;
case TDI_EVENT_DISCONNECT:
case TDI_EVENT_ERROR:
case TDI_EVENT_RECEIVE_EXPEDITED:
case TDI_EVENT_SEND_POSSIBLE:
default:
KdPrint(( "TDIH_TdiSetEvent: Hooking %d event\n", pSrc->EventType ));
break;
}
}
else
{
KdPrint((" AddrObject For Event NOT FOUND!!!\n" ));
}
//
// Pass The Request Down To The Lower Device
//
UTIL_IncrementLargeInteger(
pTDIH_DeviceExtension->OutstandingIoRequests,
(unsigned long)1,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
// Clear the fast-IO notification event protected by the resource
// we have acquired.
KeClearEvent(&(pTDIH_DeviceExtension->IoInProgressEvent));
ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL );
RC = IoCallDriver(pLowerDeviceObject, Irp);
return(RC);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -