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

📄 pcatdih.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////
//// 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 "tcpsend.h"
#include "tcprcv.h"
#include "udpsend.h"
#include "udprcv.h"

// Copyright And Configuration Management ----------------------------------
//
//                 TDI Filter Driver Entry Module - PCATDIH.c
//
//                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 ---------------------------------------------------------------------


/////////////////////////////////////////////////////////////////////////////
//                        Forward Procedure Prototypes                     //
/////////////////////////////////////////////////////////////////////////////

FILE_FULL_EA_INFORMATION UNALIGNED *
FindEA(
    PFILE_FULL_EA_INFORMATION  StartEA,
    CHAR                      *TargetName,
    USHORT                     TargetNameLength
    );

#ifdef DBG

VOID
TDIH_Unload(
   PDRIVER_OBJECT DriverObject
   );

#endif // DBG

/////////////////////////////////////////////////////////////////////////////
//               D E F A U L T  F U N C T I O N  H A N D L I N G           //
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//// TDIH_InternalDeviceControlCompletion
//
// Purpose
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
TDIH_InternalDeviceControlCompletion(
   PDEVICE_OBJECT    pDeviceObject,
   PIRP              Irp,
   void              *Context
   )
{
   PTDIH_DeviceExtension pTDIH_DeviceExtension;
   BOOLEAN           CanDetachProceed = FALSE;
   PDEVICE_OBJECT    pAssociatedDeviceObject = NULL;

   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_InternalDeviceControlCompletion: 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_DispatchInternalDeviceControl
//
// Purpose
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
TDIH_DispatchInternalDeviceControl(
   PDEVICE_OBJECT pDeviceObject,
   PIRP           Irp
   )
{
   NTSTATUS                RC = STATUS_SUCCESS;
   PIO_STACK_LOCATION      IrpSp = NULL;
   PTDIH_DeviceExtension   pTDIH_DeviceExtension;
   PDEVICE_OBJECT          pLowerDeviceObject = NULL;
   BOOLEAN                 CompleteIrp = FALSE;
   ULONG                   ReturnedInformation = 0;

   // Get a pointer to the device extension that must exist for
   // all of the device objects created by the filter driver.
   pTDIH_DeviceExtension = (PTDIH_DeviceExtension )(pDeviceObject->DeviceExtension);

   // Get the current I/O stack location.
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
   ASSERT(IrpSp);

   //
   // Possibly Call Win32 API Device Dispatcher
   //
   if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_W32API_DEVICE )
   {
      return( W32API_Dispatch( pDeviceObject, Irp ) );
   }

#ifdef USE_IP_FILTER
   //
   // Possibly Call IP Device Filter Dispatcher
   //
   if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_IP_FILTER_DEVICE )
   {
      return( IPFilter_Dispatch( pDeviceObject, Irp ) );
   }
#endif // USE_IP_FILTER

#ifdef USE_AFD_FILTER
   //
   // Possibly Call AFD Device Filter Dispatcher
   //
   if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_AFD_FILTER_DEVICE )
   {
      return( AfdFilter_Dispatch( pDeviceObject, Irp ) );
   }
#endif // USE_AFD_FILTER

   if (((int)IrpSp->FileObject->FsContext2) == TDI_CONNECTION_FILE)
   {
      switch(IrpSp->MinorFunction)
      {
         case TDI_SEND:
            return( TDIH_TdiSend( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_RECEIVE:
            return( TDIH_TdiReceive( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_ASSOCIATE_ADDRESS:
            return( TDIH_TdiAssociateAddress( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_DISASSOCIATE_ADDRESS:
            return( TDIH_TdiDisAssociateAddress( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_CONNECT:
            return( TDIH_TdiConnect( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_DISCONNECT:
            return( TDIH_TdiDisconnect( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_LISTEN:
            KdPrint(("TdiListen: Entry\n" ));
            break;

         case TDI_ACCEPT:
            KdPrint(("TdiAccept: Entry\n" ));
            break;

         default:
            break;
      }
   }
   else if (((int)IrpSp->FileObject->FsContext2) == TDI_TRANSPORT_ADDRESS_FILE)
   {
      switch(IrpSp->MinorFunction)
      {
         case TDI_SEND_DATAGRAM:
            return( TDIH_TdiSendDatagram( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_RECEIVE_DATAGRAM:
            return( TDIH_TdiReceiveDatagram( pTDIH_DeviceExtension, Irp, IrpSp ) );

         case TDI_SET_EVENT_HANDLER:
            return( TDIH_TdiSetEvent( pTDIH_DeviceExtension, Irp, IrpSp ) );

         default:
            break;
      }
   }

   //
   // Handle Functions Common To All TDI Objects
   //
   switch(IrpSp->MinorFunction)
   {
      case TDI_QUERY_INFORMATION:
            {
               PTDI_REQUEST_KERNEL_QUERY_INFORMATION p;
               p = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;

               switch( p->QueryType )
               {
                  case TDI_QUERY_BROADCAST_ADDRESS:
                     KdPrint(("TdiQueryInformation: BROADCAST_ADDRESS\n" ));
                     break;

                  case TDI_QUERY_PROVIDER_INFORMATION:
                     KdPrint(("TdiQueryInformation: PROVIDER_INFORMATION\n" ));
                     break;

                  case TDI_QUERY_ADDRESS_INFO:
                     KdPrint(("TdiQueryInformation: ADDRESS_INFO\n" ));
                     break;

                  case TDI_QUERY_CONNECTION_INFO:
                     KdPrint(("TdiQueryInformation: CONNECTION_INFO\n" ));
                     break;

                  case TDI_QUERY_PROVIDER_STATISTICS:
                     KdPrint(("TdiQueryInformation: PROVIDER_STATISTICS\n" ));
                     break;

                  case TDI_QUERY_DATAGRAM_INFO:
                     KdPrint(("TdiQueryInformation: DATAGRAM_INFO\n" ));
                     break;

                  case TDI_QUERY_DATA_LINK_ADDRESS:
                     KdPrint(("TdiQueryInformation: DATA_LINK_ADDRESS\n" ));
                     break;

                  case TDI_QUERY_NETWORK_ADDRESS:
                     KdPrint(("TdiQueryInformation: NETWORK_ADDRESS\n" ));
                     break;

                  case TDI_QUERY_MAX_DATAGRAM_INFO:
                     KdPrint(("TdiQueryInformation: MAX_DATAGRAM_INFO\n" ));
                     break;

                  default:
                     KdPrint(("TdiQueryInformation: QueryType: %d\n",
                        p->QueryType ));
                     break;
               }
            }
            break;

      case TDI_SET_INFORMATION:
            KdPrint(("TdiSetInformation: Entry\n" ));
            break;

      case TDI_ACTION:
            KdPrint(("TdiAction: Entry\n" ));
            break;

      default:
         break;
   }

   try
   {
      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_DispatchInternalDeviceControl encountered bogus current location\n"));

         KdPrint(("   TDIH_DispatchInternalDeviceControl: Node Type: %d, Context2: %d; Major FCN: 0x%2.2X, Minor FCN: 0x%2.2X\n",
                     pTDIH_DeviceExtension->NodeIdentifier.NodeType,
                     (int)IrpSp->FileObject->FsContext2,
                     IrpSp->MajorFunction,
                     IrpSp->MinorFunction
                     ));

   //      UTIL_BreakPoint();
         RC = STATUS_INVALID_DEVICE_REQUEST;
         Irp->IoStatus.Status = RC;
         Irp->IoStatus.Information = ReturnedInformation;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);

         return( RC );
      }

      //
      // Copy Contents Of Current Stack Location To Next Stack Location
      //
      IoCopyCurrentIrpStackLocationToNext( Irp );

      //
      // Setup Our Completion Routine
      // ============================
      // We will specify a default completion routine. This provides us
      // with the opportunity to do whatever we like once the function
      // processing has been completed.
      //
      // Specify that our completion routine be invoked regardless of how
      // the IRP is completed/cancelled.
      //
      IoSetCompletionRoutine(
         Irp,
         TDIH_InternalDeviceControlCompletion,
         pTDIH_DeviceExtension,
         TRUE,
         TRUE,
         TRUE
         );

      // Increment the count of outstanding I/O requests. The count will
      // be decremented in the completion routine.
      // Acquire a special end-resource spin-lock to synchronize access.
      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));

      // Forward the request. Note that if the target does not
      // wish to service the function, the request will get redirected
      // to IopInvalidDeviceRequest() (a routine that completes the
      // IRP with STATUS_INVALID_DEVICE_REQUEST).
      // However, we must release our resources before forwarding the
      // request. That will avoid the sort of problems discussed in
      // Chapter 12 of the text.

      RC = IoCallDriver(pLowerDeviceObject, Irp);

      // Note that at this time, the filter driver completion routine
      // does not return STATUS_MORE_PROCESSING_REQUIRED. However, if you
      // do modify this code and use it in your own filter driver and if your
      // completion routine *could* return the STATUS_MORE_PROCESSING_REQUIRED
      // return code, you must not blindly return the return-code obtained from
      // the call to IoCallDriver() above. See Chapter 12 for a discussion of
      // this issue.
      try_return(RC);

      try_exit:   NOTHING;
   }
   finally
   {
      // Complete the IRP only if we must.
      if (CompleteIrp)
      {
         Irp->IoStatus.Status = RC;
         Irp->IoStatus.Information = ReturnedInformation;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
      }
   }

   return(RC);
}


/////////////////////////////////////////////////////////////////////////////
//               D E F A U L T  F U N C T I O N  H A N D L I N G           //
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//// TDIH_DefaultCompletion
//
// Purpose
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
TDIH_DefaultCompletion(
   PDEVICE_OBJECT    pDeviceObject,
   PIRP              Irp,
   void              *Context
   )
{
   PTDIH_DeviceExtension pTDIH_DeviceExtension;
   BOOLEAN           CanDetachProceed = FALSE;
   PDEVICE_OBJECT    pAssociatedDeviceObject = NULL;

   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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -