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

📄 addr.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
         );

      // 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 + -