📄 tcprcv.c
字号:
/////////////////////////////////////////////////////////////////////////////
//// INCLUDE FILES
#include "ndis.h"
#include "TDI.H"
#include "TDIKRNL.H"
#include "PCATDIH.h"
#include "inetinc.h"
#include "KSUtil.h"
#include "addr.h"
#include "tcpconn.h"
#include "tcprcv.h"
// Copyright And Configuration Management ----------------------------------
//
// TCP Receive Function Filters - TCPRcv.c
// Transport Data Interface (TDI) Filter For Windows NT
//
// Transport Data Interface (TDI) Filter Samples
// For
// Windows NT
//
// Copyright (c) 2000, Printing Communications Associates, Inc.
//
// Thomas F. Divine
// 4201 Brunswick Court
// Smyrna, Georgia 30080 USA
// (770) 432-4580
// tdivine@pcausa.com
//
// End ---------------------------------------------------------------------
NTSTATUS
TDIH_TdiReceiveOnEventComplete(
PDEVICE_OBJECT pDeviceObject,
PIRP Irp,
void *Context
);
/////////////////////////////////////////////////////////////////////////////
//// TDIH_TdiReceiveEventHandler
//
// Purpose
// This is the hook for TDI_EVENT_RECIEVE event.
//
// Parameters
// See NTDDK documentation for TDI_EVENT_RECIEVE.
//
// Return Value
// See NTDDK documentation for TDI_EVENT_RECIEVE.
//
// Remarks
// This hook is called by the TCP device to indicate a packet to a
// TDI client who has set a TDI_EVENT_RECEIVE event handler on the
// Address Object.
//
// The receive event handling path should be as efficient and quick as
// possible. If too much time is spent in the receive event handler,
// packets can be lost. This is especially true of the receive DG event
// handler, where even verbose debug print output can cause packets
// to be lost.
//
NTSTATUS
TDIH_TdiReceiveEventHandler(
PVOID TdiEventContext, // Context From SetEventHandler
CONNECTION_CONTEXT ConnectionContext,
ULONG ReceiveFlags,
ULONG BytesIndicated,
ULONG BytesAvailable,
ULONG *BytesTaken,
PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes
PIRP *IoRequestPacket // TdiReceive IRP if STATUS_MORE_PROCESSING_REQUIRED
)
{
NTSTATUS Status;
AddrObj *pAddrObj;
PTDIH_DeviceExtension pTDIH_DeviceExtension;
TCPConn *pTCPConn;
KdPrint(("TDIH_TdiReceiveEventHandler: Entry...\n") );
KdPrint((" Bytes Indicated: %d; BytesAvailable: %d; Flags: 0x%8.8x\n",
BytesIndicated, BytesAvailable, ReceiveFlags));
//
// EventContext Points To Our Address Object Record
//
ASSERT( TdiEventContext );
pAddrObj = (AddrObj * )TdiEventContext;
if( !pAddrObj )
{
KdPrint(( "TDIH_RcvEventHandler: Caller Event Handler NULL!!!\n" ));
*BytesTaken = 0;
return( STATUS_DATA_NOT_ACCEPTED );
}
//
// Map Caller's ConnectionContext To Our TCP Connection Record
//
ASSERT( ConnectionContext );
pTCPConn = TDIH_GetConnFromConnectionContext( ConnectionContext );
if( !pTCPConn )
{
KdPrint(("TDIH_TdiReceiveEventHandler: TCPConn Record Not Found!!!\n") );
}
//
// Sanity Check On Caller's Receive Event Handler
//
if( !pAddrObj->ao_rcv )
{
KdPrint(( "TDIH_RcvEventHandler: Caller Event Handler NULL!!!\n" ));
*BytesTaken = 0;
return( STATUS_DATA_NOT_ACCEPTED );
}
pTDIH_DeviceExtension = pAddrObj->ao_DeviceExtension;
//
// Pass To Receive Event Handler Set On The Address Object
//
Status = pAddrObj->ao_rcv(
pAddrObj->ao_rcvcontext,
ConnectionContext,
ReceiveFlags,
BytesIndicated,
BytesAvailable,
BytesTaken,
Tsdu, // pointer describing this TSDU, typically a lump of bytes
IoRequestPacket // TdiReceive IRP if STATUS_MORE_PROCESSING_REQUIRED
);
KdPrint(( "TDIH_ReceiveEventHandler: Status: 0x%8.8X; Taken: %d\n",
Status, *BytesTaken ));
if( Status == STATUS_MORE_PROCESSING_REQUIRED
&& IoRequestPacket && *IoRequestPacket
)
{
PIO_STACK_LOCATION IrpSp = NULL;
KdPrint((" Returned STATUS_MORE_PROCESSING_REQUIRED\n"));
//
// Handle TDI_RECEIVE Request Passdown
// -----------------------------------
// The caller has provided a TDI_RECEIVE request at IoRequestPacket
// to obtain the remaining Tdsu data.
//
// In the PassThru sample driver we want to filter processing of
// the request using our own completion handler. The key steps are:
//
// 1.) Copy the current IRP stack location to next.
// 2.) Set our completion routine.
// 3.) Emulate the effect of IoCallDriver in advancing the
// IRP stack location.
//
// Get the current I/O stack location.
IrpSp = IoGetCurrentIrpStackLocation( *IoRequestPacket );
ASSERT(IrpSp);
// Be careful about not screwing up badly. This is actually not recommended by the I/O Manager.
if ((*IoRequestPacket)->CurrentLocation == 1)
{
KdPrint(("TDIH_TdiReceiveEventHandler encountered bogus current location\n"));
}
IoCopyCurrentIrpStackLocationToNext( (*IoRequestPacket) );
//
// Set Completion Routine
//
IoSetCompletionRoutine(
(*IoRequestPacket),
TDIH_TdiReceiveOnEventComplete,
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));
// IoSetNextIrpStackLocation
(*IoRequestPacket)->CurrentLocation--;
(*IoRequestPacket)->Tail.Overlay.CurrentStackLocation--;
}
return( Status );
}
/////////////////////////////////////////////////////////////////////////////
//// TDIH_TdiChainedReceiveEventHandler
//
// Purpose
// This is the hook for TDI_EVENT_CHAINED_RECIEVE event.
//
// Parameters
// See NTDDK documentation for TDI_EVENT_CHAINED_RECIEVE.
//
// Return Value
// See NTDDK documentation for TDI_EVENT_CHAINED_RECIEVE.
//
// Remarks
// This hook is called by the TCP device to indicate a packet to a
// TDI client who has set a TDI_EVENT_CHAINED_RECEIVE event handler on the
// Address Object.
//
// It is defined in the NT DDK. However, its first actual use seems to
// be in Windows 2000.
//
// The receive event handling path should be as efficient and quick as
// possible. If too much time is spent in the receive event handler,
// packets can be lost. This is especially true of the receive DG event
// handler, where even verbose debug print output can cause packets
// to be lost.
//
NTSTATUS
TDIH_TdiChainedReceiveEventHandler(
PVOID TdiEventContext, // Context From SetEventHandler
CONNECTION_CONTEXT ConnectionContext,
ULONG ReceiveFlags,
ULONG ReceiveLength, // length of client data in TSDU
ULONG StartingOffset, // offset of start of client data in TSDU
PMDL Tsdu, // TSDU data chain
PVOID TsduDescriptor // for call to TdiReturnChainedReceives
)
{
NTSTATUS Status;
AddrObj *pAddrObj;
PTDIH_DeviceExtension pTDIH_DeviceExtension;
TCPConn *pTCPConn;
KdPrint(("TDIH_TdiChainedReceiveEventHandler: Entry...\n") );
KdPrint((" ReceiveLength: %d; StartingOffset: %d; Flags: 0x%8.8x\n",
ReceiveLength, StartingOffset, ReceiveFlags));
//
// EventContext Points To Our Address Object Record
//
ASSERT( TdiEventContext );
pAddrObj = (AddrObj * )TdiEventContext;
if( !pAddrObj )
{
KdPrint(( "TDIH_TdiChainedReceiveEventHandler: Caller Event Handler NULL!!!\n" ));
return( STATUS_DATA_NOT_ACCEPTED );
}
//
// Map Caller's ConnectionContext To Our TCP Connection Record
//
ASSERT( ConnectionContext );
pTCPConn = TDIH_GetConnFromConnectionContext( ConnectionContext );
if( !pTCPConn )
{
KdPrint(("TDIH_TdiChainedReceiveEventHandler: TCPConn Record Not Found!!!\n") );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -