⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcprcv.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
//// 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 + -