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

📄 ksutil.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
// the _I_KS_DestroyTransportAddress function is finally called to destroy
// the transport address object.
//

VOID
_I_KS_DerefTransportAddress(
   PKS_ADDRESS pKS_Address
   )
{
   LONG  Result;

   ASSERT( pKS_Address );

   if( pKS_Address )
   {
      if( pKS_Address->m_ReferenceCount ) // ATTENTION!!! Is this test OK on SMP???
      {
         Result = InterlockedDecrement( &pKS_Address->m_ReferenceCount );

         if( !Result )
         {
            //
            // Destroy The Transport Address
            //
            _I_KS_DestroyTransportAddress( pKS_Address );
         }
      }
   }
}


/////////////////////////////////////////////////////////////////////////////
//// KS_CloseTransportAddress
//
// Purpose
// This routine closes the transport address object specified by pKS_ADDRESS.
//
// Parameters
//   pKS_Address
//      Pointer to the KS_ADDRESS structure that specifies the transport
//      address object pointer and handle to be closed.
//
// Return Value
// Status
//
// Remarks
// This function calls _I_KS_DerefTransportAddress to decrement the reference
// count for the KS_ADDRESS structure. If the reference count is decremented
// to zero by this call, the transport address object specified by pKS_ADDRESS
// will actually be closed.
//
// Callers of KS_TransportAddress must be running at IRQL PASSIVE_LEVEL.
//

NTSTATUS
KS_CloseTransportAddress(
   PKS_ADDRESS pKS_Address
   )
{
   KdPrint(("KS_CloseTransportAddress: Entry...\n"));

   ASSERT( pKS_Address );

   if( pKS_Address )
   {
      _I_KS_DerefTransportAddress( pKS_Address );
   }

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// KS_SetEventHandlers
//
// Purpose
// Setup event handlers on the address object.
//
// Parameters
//   pKS_Address
//      Pointer to the KS_ADDRESS structure that specifies the transport
//      address object pointer and handle that the event handlers will
//      be set on.
//   pEventContext
//      Points to caller-determined context to be passed in to the ClientEventXxx
//      routine as TdiEventContext when it is called by the transport.
//   ConnectEventHandler
//      ConnectEventHandler is an event handler the TDI driver calls in response
//      to an incoming endpoint-to-endpoint connection offer from a remote node.
//   DisconnectEventHandler
//      DisconnectEventHandler is an event handler that the underlying TDI
//      transport calls in response to an incoming disconnection notification
//      from a remote node.
//   ErrorReceiveHandler
//      ErrorReceiveHandler is an event handler that the underlying TDI transport
//      calls in response to an error, either in the transport itself or in a
//      still lower network driver, that makes I/O on a particular local
//      transport address unreliable or impossible.
//   ReceiveEventHandler
//      ReceiveEventHandler is an event handler that the underlying TDI transport
//      calls in response to an incoming receive from a remote node with which
//      the client has an established endpoint-to-endpoint connection. Usually,
//      this is a normal TSDU unless the client has not registered a
//      ReceiveExpeditedEventHandler handler.
//   ReceiveDatagramEventHandler
//      ReceiveDatagramEventHandler is an event handler that the underlying TDI
//      transport calls in response to an incoming receive from a remote node
//      that was directed to a local-node transport address that the client has
//      opened.
//   ReceiveExpeditedEventHandler
//      ReceiveExpeditedEventHandler is an event handler that the underlying
//      TDI transport calls in response to an incoming expedited receive from a
//      remote node with which the client has an established endpoint-to-endpoint
//      connection.
//
// Return Value
// Status
//
// Remarks
// Understand that TDI event handlers are setup on a transport address, not a
// connection endpoint.
//
// In general terms, "context" is simply some piece of information that you
// provide in one place and is given back to you when you need it most. For example,
// you pass a pEventContext value to KS_SetEventHandlers; this value is simply
// given back to you as TdiEventContext when your event handler is called.
//
// Often a context value is a pointer to a data structure that you have
// defined that contains the information that you will need when the event
// handler of callback is called. It doesn't have to be a pointer, however; it
// could be an index number into a table that you maintain, or anything else that
// will help you in your callback.
//
// See the NT DDK documentation topic "5.1 Opening a Transport Address"
// for more information.
//
// Callers of KS_SetEventHandlers must be running at IRQL PASSIVE_LEVEL.
//

NTSTATUS
KS_SetEventHandlers(
   PKS_ADDRESS                pKS_Address,
   PVOID                      pEventContext,
   PTDI_IND_CONNECT           ConnectEventHandler,
   PTDI_IND_DISCONNECT        DisconnectEventHandler,
   PTDI_IND_ERROR             ErrorEventHandler,
   PTDI_IND_RECEIVE           ReceiveEventHandler,
   PTDI_IND_RECEIVE_DATAGRAM  ReceiveDatagramEventHandler,
   PTDI_IND_RECEIVE_EXPEDITED ReceiveExpeditedEventHandler
   )
{
   NTSTATUS       Status;
   PDEVICE_OBJECT pDeviceObject;

   KdPrint(("KS_SetEventHandlers: Entry...\n") );

   pDeviceObject = IoGetRelatedDeviceObject( pKS_Address->m_pFileObject );

   //
   // Set The Specified Event Handlers
   //
   do
   {
      //
      // Set The Connect Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_CONNECT,
         ConnectEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }

      //
      // Set The Disconnect Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_DISCONNECT,
         DisconnectEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }

      //
      // Set The Error Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_ERROR,
         ErrorEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }

      //
      // Set The Receive Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_RECEIVE,
         ReceiveEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }

      //
      // Set The Receive Datagram Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_RECEIVE_DATAGRAM,
         ReceiveDatagramEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }

      //
      // Set The Receive Expedited Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_RECEIVE_EXPEDITED,
         ReceiveExpeditedEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }

#ifdef ZNEVER // Not Currently Supported By TDI
      //
      // Set The Send Possible Event Handler
      //
      TdiBuildSetEventHandler(
         pKS_Address->m_pAtomicIrp,
         pDeviceObject,
         pKS_Address->m_pFileObject,
         NULL,
         NULL,
         TDI_EVENT_SEND_POSSIBLE,
         SendPossibleEventHandler,
         pEventContext
         );

      //
      // Submit The Request To The Transport
      //
      Status = KS_MakeSimpleTdiRequest(
                  pDeviceObject,
                  pKS_Address->m_pAtomicIrp
                  );

      if (!NT_SUCCESS(Status))
      {
         break;
      }
#endif // ZNEVER

      //
      // All Event Handlers Have Been Set
      //
   }
      while(0);   

   return( Status );
}

/////////////////////////////////////////////////////////////////////////////
//// _I_KS_AddressRequestComplete (INTERNAL/PRIVATE)
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//

static NTSTATUS
_I_KS_AddressRequestComplete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
    IN PVOID Context
    )
{
   PKS_ADDRESS_REQUEST_CONTEXT   pKS_RequestContext;
   PKEVENT                       pEvent;

   pKS_RequestContext = (PKS_ADDRESS_REQUEST_CONTEXT )Context;

   if( pKS_RequestContext != NULL )
   {
      //
      // Fill IoStatusBlock With Final Status And Information
      //
      (pKS_RequestContext->m_pIoStatusBlock)->Status = pIrp->IoStatus.Status;
      (pKS_RequestContext->m_pIoStatusBlock)->Information = pIrp->IoStatus.Information;

      //
      // Set The Completion Event, If Specified
      //
      if( pKS_RequestContext->m_CompletionEvent )
      {
         KeSetEvent( pKS_RequestContext->m_CompletionEvent, 0, FALSE);
      }

      //
      // Call The Completion Routine, If Specified
      //
      if( pKS_RequestContext->m_CompletionRoutine )
      {
         (pKS_RequestContext->m_CompletionRoutine)(
               pKS_RequestContext->m_CompletionContext,
               pKS_RequestContext->m_pIoStatusBlock,
               pKS_RequestContext->m_Reserved
               );
      }

      //
      // Dereference The Address Object
      //
      _I_KS_DerefTransportAddress( pKS_RequestContext->m_pKS_Address );

      //
      // Free Memory Allocated For Private Completion Context
      //
      NdisFreeMemory(
         pKS_RequestContext,
         sizeof( KS_ADDRESS_REQUEST_CONTEXT ),
         0
         );
   }

⌨️ 快捷键说明

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