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

📄 ksutil.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
{
   PDEVICE_OBJECT    pDeviceObject;

   pKS_Endpoint->m_pKS_Address = NULL;
   pKS_Endpoint->m_nAssociateStatus = STATUS_UNSUCCESSFUL;

   pDeviceObject = IoGetRelatedDeviceObject( pKS_Address->m_pFileObject );

   //
   // Associate the local endpoint with the address object.
   //
   TdiBuildAssociateAddress(
      pKS_Address->m_pAtomicIrp,
      pDeviceObject,
      pKS_Endpoint->m_pFileObject,
      NULL,
      NULL,
      pKS_Address->m_hAddress
      );

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

   if( NT_SUCCESS( pKS_Endpoint->m_nAssociateStatus ) )
   {
      pKS_Endpoint->m_pKS_Address = pKS_Address;

      _I_KS_RefTransportAddress( pKS_Endpoint->m_pKS_Address );
   }

   return( pKS_Endpoint->m_nAssociateStatus );
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_DisassociateAddress (INTERNAL/PRIVATE)
//
// Purpose
//
// Parameters
//
// Return Value
// Status
//
// Remarks
//

NTSTATUS
_I_KS_DisassociateAddress(
   PKS_ENDPOINT   pKS_Endpoint
   )
{
   NTSTATUS       Status = STATUS_SUCCESS;
   PDEVICE_OBJECT pDeviceObject;

   pDeviceObject = IoGetRelatedDeviceObject( pKS_Endpoint->m_pFileObject );
   
   // Disassociate the local endpoint with the address object.
   if( pKS_Endpoint->m_pKS_Address )
   {
      TdiBuildDisassociateAddress(
         (pKS_Endpoint->m_pKS_Address)->m_pAtomicIrp,
         pDeviceObject,
         pKS_Endpoint->m_pFileObject,
         NULL,
         NULL
         );

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

   if( NT_SUCCESS( Status ) )
   {
      if( pKS_Endpoint->m_pKS_Address )
      {
         _I_KS_DerefTransportAddress( pKS_Endpoint->m_pKS_Address );
      }
   }

   return( Status );
}


/////////////////////////////////////////////////////////////////////////////
//// KS_OpenConnectionEndpoint
//
// Purpose
// Open a new TDI connection endpoint and associate it with a specified
// transport address object.
//
// Parameters
//   TransportDeviceNameW
//      Pointer to a zero-terminated wide character string that specifies
//      the transport device. An example would be: L"\\Device\\Tcp"
//
//   pKS_Address
//      Pointer to the KS_ADDRESS structure previously opened using the
//      LS_OpenTransportAddress function. The KS_ADDRESS pointer specifies
//      the transport address object to be used with the new connection
//      endpoint.
//
//   pKS_Endpoint
//      Pointer to a caller-provided KS_ENDPOINT structure that will be
//      initialized as the connection endpoint is opened.
//
//   pContext
//      This is actually an arbitrary value provided by the caller. The value
//      passed as pContext here will simply be returned as TdiEventContex when
//      TDI event handlers are called. Typically pContext is actually a pointer
//      to a structure of interest to the caller.
//
// Return Value
// Status
//
// Remarks
// This function combines several of the steps involved in opening a connection
// endpoint into one convenient function.
//
// Before calling this function the caller must have already opened a transport
// address object using  KS_OpenTransportAddress.
//
// This function performs most of the mechanics of opening a TDI connection endpoint
// object. It builds the extended attributes (EA) buffer, calls ZwCreateFile and
// obtains a pointer to the connection endpoint object file pointer by calling
// ObReferenceObjectByHandle. If these operations are successful, the function calls
// an internal function called _I_KS_AssociateAddress to associate the new connection
// endpoint with the specified transport address.
//
// The connection endpoint object handle and its file pointer are stored in the
// KS_ENDPOINT structure. A pointer to a KS_ENDPOINT structure that has been successfully
// initialized by KS_OpenConnectionEndpoint is used by subsequent calls that operate
// on a connection endpoint.
//
// It is important to note that KS_OpenConnectionEndpoint will call ZwCreateFile in the
// process of opening a connection endpoint. The call to ZwCreateFile creates a
// client-process-specific file object that represents the connection endpoint object.
// This means that the m_hContext handle is only valid in the same client process that
// the ZwCreateFile call was made in.
//
// Fortunately, most TDI operations actually reference the file object pointer - not
// the handle. Operations that do not reference the connection handle can be performed
// in arbitrary context unless there are other restrictions.
//
// The client process dependency of the connection endpoint handle does affect the design
// of a TDI Client to some extent. In particular, the client process that was used to 
// create an connection endpoint object must continue to exist until the connection endpoint
// object is eventually closed.
//
// There are several ways to insure that the client process continues to exist while
// the connection endpoint object is in use. The most common is to create a thread that
// is attached to the system process. As long as the system process continues to exist,
// the connection endpoint object handle will remain valid.
//
// See the NT DDK documentation topic "5.2 Opening a Connection Endpoint" for more
// information.
//
// Callers of KS_OpenConnectionEndpoint must be running at IRQL PASSIVE_LEVEL.
//

NTSTATUS
KS_OpenConnectionEndpoint(
   IN PWSTR       TransportDeviceNameW,// Zero-terminated String
   PKS_ADDRESS    pKS_Address,
   PKS_ENDPOINT   pKS_Endpoint,
   PVOID          pContext
   )
{
   NTSTATUS Status;

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

   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

   //
   // Initialize KS_CONTEXT Structure
   //
   NdisZeroMemory( pKS_Endpoint, sizeof( KS_ENDPOINT ) );

   pKS_Endpoint->m_ReferenceCount = 1;

   pKS_Endpoint->m_pKS_Address = NULL;

   //
   // Open Connection Context
   //
   Status = _I_KS_OpenConnectionContext(
                  TransportDeviceNameW,
                  pKS_Endpoint,
                  pContext
                  );

   if( !NT_SUCCESS( Status ) )
   {
      return( pKS_Endpoint->m_nOpenStatus );
   }

   KdPrint(("KS_OpenConnectionEndpoint: Opened Connection Context\n") );

   //
   // Associate Address
   //
   Status = _I_KS_AssociateAddress( pKS_Address, pKS_Endpoint );

   if( NT_SUCCESS( Status ) )
   {
      KdPrint(("KS_OpenConnectionEndpoint: Associated Address\n") );

      //
      // Add The Connection To The Address Object's Connection List
      //
      InsertTailList(
         &pKS_Address->m_ConnectionList,
         &pKS_Endpoint->m_ListElement
         );
   }

   return( pKS_Endpoint->m_nAssociateStatus );
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_RefConnectionEndpoint (INTERNAL/PRIVATE)
//
// Purpose
// This routine increments the reference count on the connection endpoint.
//
// Parameters
//
// Return Value
// None.
//
// Remarks
//

VOID
_I_KS_RefConnectionEndpoint(
   PKS_ENDPOINT   pKS_Endpoint
   )
{
   InterlockedIncrement( &pKS_Endpoint->m_ReferenceCount );
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_DestroyConnection (INTERNAL/PRIVATE)
//
// Purpose
//
// Parameters
//
// Return Value
// Status
//
// Remarks
//

NTSTATUS
_I_KS_DestroyConnection(
   PKS_ENDPOINT   pKS_Endpoint
   )
{
   NTSTATUS Status;

   //
   // About Disassociate Address
   // --------------------------
   // Logically one would think it appropriate to call _I_KS_DisassociateAddress
   // at this point. However, the NT DDK TDI documentation states that when
   // closing a connection endpoint it is unnecessary "to disassociate
   // the connection endpoint from from its associated transport address
   // before making a close-connection-endpoint request".
   //
   // Further, on TCP it appears that a call to _I_KS_DisassociateAddress
   // will often fail with STATUS_CONNECTION_ACTIVE (0xC000023B).
   //
   // So, instead of calling _I_KS_DisassociateAddress we just remove
   // the reference counts to the transport address and connection context
   // objects that was created by _I_KS_AssociateAddress.
   //
   _I_KS_DerefTransportAddress( pKS_Endpoint->m_pKS_Address );

   //
   // Remove The Connection To The Address Object's Connection List
   //
   RemoveEntryList( &pKS_Endpoint->m_ListElement );

   //
   // Close Connection Context
   //
   Status = _I_KS_CloseConnectionContext( pKS_Endpoint );

#ifdef DBG
   if( NT_SUCCESS( Status ) )
   {
      KdPrint(("KS_DestroyConnection: Closed Connection Context\n") );
   }
#endif // DBG

   return( Status );
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_DerefConnectionEndpoint (INTERNAL/PRIVATE)
//
// Purpose
// This routine decrements the reference count on the connection endpoint.
//
// Parameters
//
// Return Value
// None.
//
// Remarks
//

VOID
_I_KS_DerefConnectionEndpoint(
   PKS_ENDPOINT   pKS_Endpoint
   )
{
   LONG  Result;

   Result = InterlockedDecrement( &pKS_Endpoint->m_ReferenceCount );

   if( !Result )
   {
      //
      // Destroy The Connection
      //
      _I_KS_DestroyConnection( pKS_Endpoint );
   }
}


/////////////////////////////////////////////////////////////////////////////
//// KS_CloseConnectionEndpoint
//
// Purpose
// KS_CloseConnectionEndpoint closes the connection endpoint specified by
// pKS_ENDPOINT.
//
// Parameters
// pKS_Endpoint
//    Pointer to the KS_ENDPOINT structure that specifies the connection endpoint
//    object pointer and handle to be closed.
//
// Return Value
// Status
//
// Remarks
// This function calls the internal function _I_KS_DerefConnectionEndpoint to
// decrement the reference count for the KS_ENDPOINT structure. If the reference
// count is decremented to zero by this call, the connection endpoint object
// specified by pKS_ENDPOINT will actually be closed.
//
// Callers of KS_CloseConnectionEndpoint must be running at IRQL PASSIVE_LEVEL.
//

NTSTATUS
KS_CloseConnectionEndpoint(
   PKS_ENDPOINT   pKS_Endpoint
   )
{
   KdPrint(("KS_CloseConnectionEndpoint: Entry...\n"));

   _I_KS_DerefConnectionEndpoint( pKS_Endpoint );

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// KS_Connect
//
// Purpose
// This routine establishes a connection between a local connection endpoint
// and a remote transport address.
//
// Parameters
//   pKS_Endpoint
//      Pointer to the KS_ENDPOINT structure that specifies the local connection
//      endpoint object pointer to be used.
//   pTransportAddress
//      Pointer to a TRANSPORT_ADDRESS structure that specifies the remote
//      connection address for the connection.
//
// Return Value
//
// Remarks
// For a local-node client to establish an endpoint-to-endpoint connection
// with a remote-node peer process, it must first associate an idle local
// connection endpoint with a local-node address. A client cannot initiate a
// connection attempt to a remote-node peer until it has made a successful
// TDI_ASSOCIATE_ADDRESS request, which it set up with TdiBuildAsociateAddress,
// to its underlying transport.
//
// It terms of the KS library functions, this means that the KS_ENDPOINT
// structure pointed to by pKS_Endpoint must have been successfully initialized
// by calling KS_OpenConntectionEndpoint.
//
// See the NT DDK documentation topic "5.5 Making an Endpoint-to-Endpoint
// Connection" for more information.
//
// As currently written, callers of KS_Connect must be running at
// IRQL PASSIVE_LEVEL.
//

NTSTATUS
KS_Connect(
   PKS_ENDPOINT            pKS_Endpoint,
   IN PTRANSPORT_ADDRESS   pTransportAddress // Remote Transport Address
   )
{
   NTSTATUS                   Status = STATUS_SUCCESS;
	TDI_CONNECTION_INFORMATION RequestConnectionInfo;
//	TDI_CONNECTION_INFORMATION ReturnConnectionInfo;
   LARGE_INTEGER              ConnectionTimeOut = {0,0};

⌨️ 快捷键说明

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