📄 udprcv.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 "udprcv.h"
// Copyright And Configuration Management ----------------------------------
//
// UDP Receive Function Filters - UDPRcv.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_TdiReceiveDGOnEventComplete(
PDEVICE_OBJECT pDeviceObject,
PIRP Irp,
void *Context
);
/////////////////////////////////////////////////////////////////////////////
//// TDIH_TdiReceiveDGEventHandler
//
// Purpose
// This is the hook for TDI_EVENT_RECIEVE_DATAGRAM event.
//
// Parameters
// See NTDDK documentation for TDI_EVENT_RECIEVE_DATAGRAM.
//
// Return Value
// See NTDDK documentation for TDI_EVENT_RECIEVE_DATAGRAM.
//
// Remarks
// This hook is called by the UDP device to indicate a packet to a
// TDI client who has set a TDI_EVENT_RECEIVE_DATAGRAM event handler
// on the Address Object.
//
NTSTATUS
TDIH_TdiReceiveDGEventHandler(
PVOID TdiEventContext, // Context From SetEventHandler
LONG SourceAddressLength, // length of the originator of the datagram
PVOID SourceAddress, // string describing the originator of the datagram
LONG OptionsLength, // options for the receive
PVOID Options, //
ULONG ReceiveDatagramFlags, //
ULONG BytesIndicated, // number of bytes in this indication
ULONG BytesAvailable, // number of bytes in complete Tsdu
ULONG *BytesTaken, // number of bytes used by indication routine
PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes
PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
)
{
NTSTATUS Status;
AddrObj *pAddrObj;
PTDIH_DeviceExtension pTDIH_DeviceExtension;
// KdPrint(("TDIH_TdiReceiveDGEventHandler: Entry...\n") );
// KdPrint((" Bytes Indicated: %d; BytesAvailable: %d; Flags: 0x%8.8x\n",
// BytesIndicated, BytesAvailable, ReceiveDatagramFlags));
//
// EventContext Points To Our Address Object Record
//
ASSERT( TdiEventContext );
pAddrObj = (AddrObj * )TdiEventContext;
if( !pAddrObj )
{
return( STATUS_DATA_NOT_ACCEPTED );
}
pTDIH_DeviceExtension = pAddrObj->ao_DeviceExtension;
//
// Pass To Receive Datagram Event Handler Set On The Address Object
//
ASSERT( pAddrObj->ao_rcvdg );
Status = pAddrObj->ao_rcvdg(
pAddrObj->ao_rcvdgcontext,
SourceAddressLength, // length of the originator of the datagram
SourceAddress, // string describing the originator of the datagram
OptionsLength, // options for the receive
Options, //
ReceiveDatagramFlags, //
BytesIndicated, // number of bytes in this indication
BytesAvailable, // number of bytes in complete Tsdu
BytesTaken, // number of bytes used by indication routine
Tsdu, // pointer describing this TSDU, typically a lump of bytes
IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
);
// KdPrint(( "TDIH_RcvDGEventHandler: 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_DATAGRAM Request Passdown
// --------------------------------------------
// The caller has provided a TDI_RECEIVE_DATAGRAN 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_RcvDGEventHandler encountered bogus current location\n"));
}
IoCopyCurrentIrpStackLocationToNext( (*IoRequestPacket) );
//
// Set Completion Routine
//
IoSetCompletionRoutine(
(*IoRequestPacket),
TDIH_TdiReceiveDGOnEventComplete,
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_TdiChainedReceiveDGEventHandler
//
// Purpose
// This is the hook for TDI_EVENT_CHAINED_RECIEVE_DATAGRAM event.
//
// Parameters
// See NTDDK documentation for TDI_EVENT_CHAINED_RECIEVE_DATAGRAM.
//
// Return Value
// See NTDDK documentation for TDI_EVENT_CHAINED_RECIEVE_DATAGRAM.
//
// Remarks
// This hook is called by the UDP device to indicate a packet to a
// TDI client who has set a TDI_EVENT_CHAINED_RECEIVE_DATAGRAM event
// handler on the Address Object.
//
// It is defined in the NT DDK. However, its first actual use seems to
// be in Windows 2000.
//
NTSTATUS
TDIH_TdiChainedReceiveDGEventHandler(
PVOID TdiEventContext, // Context From SetEventHandler
LONG SourceAddressLength, // length of the originator of the datagram
PVOID SourceAddress, // string describing the originator of the datagram
LONG OptionsLength, // options for the receive
PVOID Options, //
ULONG ReceiveDatagramFlags, //
ULONG ReceiveDatagramLength, // 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;
// KdPrint(("TDIH_TdiChainedReceiveDGEventHandler: Entry...\n") );
// KdPrint((" ReceiveDatagramLength: %d; StartingOffset: %d; Flags: 0x%8.8x\n",
// ReceiveDatagramLength, StartingOffset, ReceiveDatagramFlags));
//
// EventContext Points To Our Address Object Record
//
ASSERT( TdiEventContext );
pAddrObj = (AddrObj * )TdiEventContext;
if( !pAddrObj )
{
return( STATUS_DATA_NOT_ACCEPTED );
}
pTDIH_DeviceExtension = pAddrObj->ao_DeviceExtension;
//
// Pass To Receive Datagram Event Handler Set On The Address Object
//
ASSERT( pAddrObj->ao_chainedrcvdg );
Status = pAddrObj->ao_chainedrcvdg(
pAddrObj->ao_chainedrcvdgcontext,
SourceAddressLength, // length of the originator of the datagram
SourceAddress, // string describing the originator of the datagram
OptionsLength, // options for the receive
Options, //
ReceiveDatagramFlags, //
ReceiveDatagramLength, // length of client data in TSDU
StartingOffset, // offset of start of client data in TSDU
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -