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

📄 tcpclient.c

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

NTSTATUS TCPC_ReceiveEventHandler(
   IN PVOID TdiEventContext,     // Context From SetEventHandler
    IN CONNECTION_CONTEXT ConnectionContext,
    IN ULONG ReceiveFlags,
    IN ULONG BytesIndicated,
    IN ULONG BytesAvailable,
    OUT ULONG *BytesTaken,
    IN PVOID Tsdu,				// pointer describing this TSDU, typically a lump of bytes
    OUT PIRP *IoRequestPacket	// TdiReceive IRP if MORE_PROCESSING_REQUIRED.
	)
{
//   KdPrint(("TCPC_ReceiveEventHandler: Entry...\n") );

   KdPrint(("  Bytes Indicated: %d; BytesAvailable: %d; Flags: 0x%8.8x\n",
      BytesIndicated, BytesAvailable, ReceiveFlags));

   return( STATUS_SUCCESS );
}

/////////////////////////////////////////////////////////////////////////////
//// TCPC_ReceiveExpeditedEventHandler
//
// Purpose
//
// Parameters
//   TdiEventContext - Pointer to TCPC_SESSION structure for the session.
//
// Return Value
//
// Remarks
// This indication is delivered if expedited data is received on the connection.
// This will only occur in providers that support expedited data.
//

NTSTATUS TCPC_ReceiveExpeditedEventHandler(
   IN PVOID TdiEventContext,     // Context From SetEventHandler
   IN CONNECTION_CONTEXT ConnectionContext,
   IN ULONG ReceiveFlags,          //
   IN ULONG BytesIndicated,        // number of bytes in this indication
   IN ULONG BytesAvailable,        // number of bytes in complete Tsdu
   OUT ULONG *BytesTaken,          // number of bytes used by indication routine
   IN PVOID Tsdu,                  // pointer describing this TSDU, typically a lump of bytes
   OUT PIRP *IoRequestPacket        // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
   )
{
   KdPrint(("TCPC_ReceiveExpeditedEventHandler: Entry...\n") );

   KdPrint(("  Bytes Indicated: %d; BytesAvailable: %d; Flags: 0x%8.8x\n",
      BytesIndicated, BytesAvailable, ReceiveFlags));

   return( STATUS_SUCCESS );
}

VOID
TCPC_SendCompletion(
    PVOID UserCompletionContext,
    PIO_STATUS_BLOCK IoStatusBlock,
    ULONG Reserved
    )
{
   PTCPC_SESSION  pSession = (PTCPC_SESSION )UserCompletionContext;
   NTSTATUS       Status = STATUS_SUCCESS;

   if( NT_SUCCESS( IoStatusBlock->Status ) )
   {
//      KdPrint(( "TCPC_SendBuffer: Sent %d Bytes\n", IoStatusBlock->Information ));
   }
   else
   {
      KdPrint(( "TCPC_SendBuffer: Status 0x%8.8X\n", IoStatusBlock->Status ));

      KeSetEvent( &pSession->m_FinalSendEvent, 0, FALSE );

      return;
   }

   --pSession->m_nNumBuffersToSend;    // Sent One

   if( pSession->m_nNumBuffersToSend )
   {
      // ATTENTION!!!
      // ------------
      // Do not call KS_SendOnEndpoint (which eventually calls
      // IoCallDriver) directly from this completion routine. Use a
      // worker thread, running at IRQL = PASSIVE_LEVEL, to make the
      // call.
      //

      //
      // Start Another Asynchronous Send On The Connection
      //
      (pSession->m_pPatternMdl)->Next = NULL;   // IMPORTANT!!!

      Status = KS_SendOnEndpoint(
                     &pSession->m_KS_Endpoint,
                     NULL,       // User Completion Event
                     TCPC_SendCompletion,       // User Completion Routine
                     pSession,   // User Completion Context
                     &pSession->m_PatternIoStatus,
                     pSession->m_pPatternMdl,
                     0           // Send Flags
                     );

      if( !NT_SUCCESS( Status ) )
      {
         if( Status != STATUS_PENDING )
         {
            KdPrint(( "TCPC_SendBuffer: Status 0x%8.8X\n", IoStatusBlock->Status ));
   
            KeSetEvent( &pSession->m_FinalSendEvent, 0, FALSE );

            return;
         }
      }
   }
   else
   {
      KeSetEvent( &pSession->m_FinalSendEvent, 0, FALSE );
   }
}


/////////////////////////////////////////////////////////////////////////////
//// DoQueryAddressInfoTest
//
// Purpose
// Demonstrate TD_ADDRESS_INFO TDI Query
//
// Parameters
//
// Return Value
//
// Remarks
//

VOID
DoQueryAddressInfoTest(
   PTCPC_SESSION  pSession
   )
{
   NTSTATUS    Status = STATUS_SUCCESS;
   ULONG       nInfoBufferSize = sizeof( pSession->m_InfoBuffer );

   //
   // Query TDI Address Info On Transport Address
   //
   Status = KS_QueryAddressInfo(
               pSession->m_KS_Address.m_pFileObject,  // Address Object
               pSession->m_InfoBuffer,
               &nInfoBufferSize
               );

   KdPrint(( "Query Address Info Status: 0x%8.8x\n", Status ));

   if( NT_SUCCESS( Status ) )
   {
      DEBUG_DumpAddressInfo( (PTDI_ADDRESS_INFO )pSession->m_InfoBuffer );
   }

   //
   // Query TDI Address Info On Connection Endpoint
   //
   Status = KS_QueryAddressInfo(
               pSession->m_KS_Endpoint.m_pFileObject,  // Connection Object
               pSession->m_InfoBuffer,
               &nInfoBufferSize
               );

   KdPrint(( "Query Address Info Status: 0x%8.8x\n", Status ));

   if( NT_SUCCESS( Status ) )
   {
      DEBUG_DumpAddressInfo( (PTDI_ADDRESS_INFO )pSession->m_InfoBuffer );
   }
}


/////////////////////////////////////////////////////////////////////////////
//// DoQueryConnectionInfoTest
//
// Purpose
// Demonstrate TD_CONNECTION_INFO TDI Query
//
// Parameters
//
// Return Value
//
// Remarks
//

VOID
DoQueryConnectionInfoTest(
   PTCPC_SESSION  pSession
   )
{
   NTSTATUS    Status = STATUS_SUCCESS;
   ULONG       nInfoBufferSize = sizeof( pSession->m_InfoBuffer );

   //
   // Query TDI Connection Info
   //
   Status = KS_QueryConnectionInfo(
               &pSession->m_KS_Endpoint,  // Connection Endpoint
               pSession->m_InfoBuffer,
               &nInfoBufferSize
               );

   KdPrint(( "Query Connection Info Status: 0x%8.8x\n", Status ));

   if( NT_SUCCESS( Status ) )
   {
      DEBUG_DumpConnectionInfo( (PTDI_CONNECTION_INFO )pSession->m_InfoBuffer );
   }
}

/////////////////////////////////////////////////////////////////////////////
//// TCPC_TestThread
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//

VOID
TCPC_TestThread(
   IN PVOID pContext
   )
{
   NTSTATUS             Status = STATUS_SUCCESS;
   NDIS_STATUS          nNdisStatus;
   PTTCP_TEST_START_CMD pStartCmd = NULL;
   PTCPC_SESSION        pSession = (PTCPC_SESSION )pContext;
   LARGE_INTEGER        DelayTime;
   IO_STATUS_BLOCK      IoStatusBlock;

   KdPrint(("TCPC_TestThread: Starting...\n") );

   //
   // Initialize Default Settings
   //
   Status = STATUS_SUCCESS;      // Always Indicate I/O Success

   //
   // Locate Test Session Parameter Buffer
   //
   pSession = (PTCPC_SESSION )pContext;

   //
   // Allocate The Pattern Buffer
   //
   pSession->m_PatternBufferSize = pSession->m_TestParams.m_nBufferSize;
   pSession->m_nNumBuffersToSend = pSession->m_TestParams.m_nNumBuffersToSend;

   nNdisStatus = NdisAllocateMemory(
                  &pSession->m_pPatternBuffer,
                  pSession->m_PatternBufferSize,
                  0,       // Allocate non-paged system-space memory
                  HighestAcceptableMax
                  );

   if( !NT_SUCCESS( nNdisStatus ) )
   {
      pSession->m_pPatternBuffer = NULL;

      goto ExitTheThread;
   }

   TDITTCP_FillPatternBuffer( 
      pSession->m_pPatternBuffer,
      pSession->m_PatternBufferSize
      );

   pSession->m_pPatternMdl = KS_AllocateAndProbeMdl(
                              pSession->m_pPatternBuffer,   // Virtual Address
                              pSession->m_PatternBufferSize,
                              FALSE,
                              FALSE,
                              NULL
                              );

   if( !pSession->m_pPatternMdl )
   {
      goto ExitTheThread;
   }

   //
   // Setup Local TDI Address
   //
   KS_InitIPAddress(
      &pSession->m_LocalAddress,
      INADDR_ANY,    // Any Local Address
      0              // Any Local Port
      );

   //
   // Open Transport Address
   //
   Status = KS_OpenTransportAddress(
                  TCP_DEVICE_NAME_W,
                  (PTRANSPORT_ADDRESS )&pSession->m_LocalAddress,
                  &pSession->m_KS_Address
                  );

   if( !NT_SUCCESS( Status ) )
   {
      //
      // Address Object Could Not Be Created
      //
      goto ExitTheThread;
   }

   //
   // Create The Connection Endpoint
   //
   Status = KS_OpenConnectionEndpoint(
                  TCP_DEVICE_NAME_W,
                  &pSession->m_KS_Address,
                  &pSession->m_KS_Endpoint,
                  &pSession->m_KS_Endpoint    // Context
                  );

   if( !NT_SUCCESS( Status ) )
   {
      //
      // Connection Endpoint Could Not Be Created
      //
      KS_CloseConnectionEndpoint( &pSession->m_KS_Endpoint );
      KS_CloseTransportAddress( &pSession->m_KS_Address );

      goto ExitTheThread;
   }

   KdPrint(("TCPC_TestThread: Created Local TDI Connection Endpoint\n") );

   KdPrint(("  pSession: 0x%8.8X; pAddress: 0x%8.8X; pConnection: 0x%8.8X\n",
      (ULONG )pSession,
      (ULONG )&pSession->m_KS_Address,
      (ULONG )&pSession->m_KS_Endpoint
      ));

   //
   // Setup Event Handlers On The Address Object
   //
   Status = KS_SetEventHandlers(
                  &pSession->m_KS_Address,
                  pSession,      // Event Context
                  NULL,          // ConnectEventHandler
                  TCPC_DisconnectEventHandler,
                  TCPC_ErrorEventHandler,
                  TCPC_ReceiveEventHandler,
                  NULL,          // ReceiveDatagramEventHandler
                  TCPC_ReceiveExpeditedEventHandler
                  );

   if( !NT_SUCCESS( Status ) )
   {
      //
      // Event Handlers Could Not Be Set
      //
      KS_CloseConnectionEndpoint( &pSession->m_KS_Endpoint );
      KS_CloseTransportAddress( &pSession->m_KS_Address );

      goto ExitTheThread;
   }

   KdPrint(("TCPC_TestThread: Set Event Handlers On The Address Object\n") );

   //
   // Setup Remote TDI Address
   //
   KS_InitIPAddress(
      &pSession->m_RemoteAddress,
      pSession->m_TestParams.m_RemoteAddress.s_addr,
      pSession->m_TestParams.m_Port
      );

   //
   // Request Connection To Remote Node
   //
   Status = KS_Connect(
               &pSession->m_KS_Endpoint,
               (PTRANSPORT_ADDRESS )&pSession->m_RemoteAddress
               );

   KdPrint(( "Connect Status: 0x%8.8x\n", Status ));

   if( NT_SUCCESS( nNdisStatus ) )
   {
      //
      // Specify NODELAY Send Option On The Connection Endpoint
      // ------------------------------------------------------
      // Returns successfully, BUT does not appear to effect TCP stream.
      //
      if( pSession->m_TestParams.m_nNoDelay )

⌨️ 快捷键说明

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