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

📄 tcpecho.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:
      &pTCPS_Packet->Reserved.m_ListElement
      );

   //
   // Possibly Send Another Packet
   //
   TCPS_EchoTcpPackets( pConnection );

   return;
}

#endif // USE_RECEIVE_EVENT_HANDLER


/////////////////////////////////////////////////////////////////////////////
//                    D I S C O N N E C T  R O U T I N E S                 //
/////////////////////////////////////////////////////////////////////////////


VOID
TCPS_DisconnectCallback(
   PVOID UserCompletionContext,
   PIO_STATUS_BLOCK IoStatusBlock,
   ULONG Reserved
   )
{
   PTCPS_Connection   pConnection = (PTCPS_Connection )UserCompletionContext;
   NTSTATUS          nFinalStatus = IoStatusBlock->Status;

#if DBG
   DbgPrint( "TCPS_DisconnectCallback: FinalStatus: %d\n", nFinalStatus );
#endif

   //
   // Mark As Not Connected
   //
   pConnection->m_bIsConnected = FALSE;

   //
   // Empty the ReceivedTcpPacketList
   // ----------------------------
   // TCPS_EchoTcpPackets will empty the list if pConnection->m_bIsConnected
   // is FALSE.
   //
   TCPS_EchoTcpPackets( pConnection );

   if( pConnection->m_pWaitEvent )
   {
#if DBG
      DbgPrint( "TCPS_DisconnectCallback: Setting Wait Event\n" );
#endif

      KeSetEvent( pConnection->m_pWaitEvent, 0, FALSE );
      pConnection->m_pWaitEvent = NULL;
   }

   //
   // Return Connection To Free List
   //
   TCPS_FreeConnection( pConnection );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_DisconnectEventHandler
//
// Purpose
// Called by the TDI to indicate that a remote client is closing a
// connection.
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
TCPS_DisconnectEventHandler(
   IN PVOID TdiEventContext,                  // Context From SetEventHandler
   IN CONNECTION_CONTEXT ConnectionContext,   // As passed to TdiOpenConnection
   IN LONG DisconnectDataLength,
   IN PVOID DisconnectData,
   IN LONG DisconnectInformationLength,
   IN PVOID DisconnectInformation,
   IN ULONG DisconnectFlags
   )
{
   PTCPS_Connection   pConnection;
   TDI_STATUS        nTdiStatus;

#if DBG
   DbgPrint( "TCPS_DisconnectEventHandler Entry...\n" );
#endif

   pConnection = (PTCPS_Connection )ConnectionContext;

   //
   // Remove From Open Connection List
   //
   RemoveEntryList( &pConnection->m_ListElement );

   switch( DisconnectFlags )
   {
      case TDI_DISCONNECT_WAIT:      // Used For Disconnect Notification
#if DBG
         DbgPrint( "Disconnect: Wait\n" );
#endif
         //
         // Return Connection To Free List
         //
         TCPS_FreeConnection( pConnection );

         break;

      case TDI_DISCONNECT_ABORT:      // Immediately Terminate Connection
#if DBG
         DbgPrint( "Disconnect: Abort\n" );
#endif
         //
         // Return Connection To Free List
         //
         TCPS_FreeConnection( pConnection );

         break;

      case TDI_DISCONNECT_RELEASE:   // Initiate Graceful Disconnect
#if DBG
         DbgPrint( "Disconnect: Release\n" );
#endif

         nTdiStatus = KS_Disconnect(
                        &pConnection->m_KS_Endpoint,
                        NULL,       // UserCompletionEvent
                        TCPS_DisconnectCallback,
                        pConnection,
                        NULL,
                        0
                        );

         break;

      default:
#if DBG
         DbgPrint( "Unexpected Flags: 0x%X\n", DisconnectFlags );
#endif
         break;
   }

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_Startup
//
// Purpose
// Startup the ECHO server.
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
TCPS_Startup( PDEVICE_OBJECT pDeviceObject )
{
   NTSTATUS          nTdiStatus;
   NDIS_STATUS       nNdisStatus;
   TA_IP_ADDRESS     ECHOAddress;
   int               i;

#if DBG
   DbgPrint( "TCPS_Startup Entry...\n" );
   DbgPrint( "pDeviceObject: 0x%X\n", pDeviceObject );
#endif

   if( g_nTCPS_UseCount > 0 )
   {
      ++g_nTCPS_UseCount;

      return( STATUS_SUCCESS );
   }

   g_bAddressOpen = FALSE;

   //
   // Initialize Connection Lists
   //
   InitializeListHead( &g_FreeConnectionList );
   InitializeListHead( &g_OpenConnectionList );

   //
   // Allocate The Packet Pool
   //
   NdisAllocatePacketPool(
      &nNdisStatus,
      &g_hPacketPool,
      TCPS_PACKET_POOL_SIZE,
      sizeof( TCPS_PACKET_RESERVED )
      );

   ASSERT( NT_SUCCESS( nNdisStatus ) );

   if( !NT_SUCCESS( nNdisStatus ) )
   {
#if DBG
      DbgPrint( "TCPS_Startup: Failed To Allocate Packet Pool\n" );
#endif

      return( STATUS_INSUFFICIENT_RESOURCES );
   }

   g_bPacketPoolAllocated = TRUE;

   //
   // Allocate The Buffer Pool
   //
   NdisAllocateBufferPool(
      &nNdisStatus,
      &g_hBufferPool,
      TCPS_BUFFER_POOL_SIZE
      );

   ASSERT( NT_SUCCESS( nNdisStatus ) );

   if( !NT_SUCCESS( nNdisStatus ) )
   {
#if DBG
      DbgPrint( "TCPS_Startup: Failed To Allocate Buffer Pool\n" );
#endif

      NdisFreePacketPool( g_hPacketPool );

      g_bPacketPoolAllocated = FALSE;
      g_bBufferPoolAllocated = FALSE;

      return( STATUS_INSUFFICIENT_RESOURCES );
   }

   g_bBufferPoolAllocated = TRUE;

   //
   // Initialize The Local IP Address
   //
   KS_InitIPAddress(
      &g_LocalAddress,              // Pointer To A TA_IP_ADDRESS
      INADDR_ANY,                   // Any Local Internet Address
      KS_htons( IPPORT_ECHO )       // ECHO Port
      );

   //
   // Open The Local TDI Address Object
   //
   nTdiStatus = STATUS_REQUEST_ABORTED;

   nTdiStatus = KS_OpenTransportAddress(
                  TCP_DEVICE_NAME_W,
                  (PTRANSPORT_ADDRESS )&g_LocalAddress,
                  &g_KS_Address
                  );

   ASSERT( NT_SUCCESS( nTdiStatus ) );

   if ( !NT_SUCCESS( nTdiStatus ) )
   {
      return( nTdiStatus );
   }

   //
   // Initialize And Link Up The Free Connections Pool
   //
   for( i = 0; i < MAX_CONNECTIONS ; i++ )
   {
      PTCPS_Connection            pConnection = &g_ConnectionSpace[i];
      OBJECT_ATTRIBUTES          TcpObjectAttributes;
      PVOID                      *contextAddress;
      PFILE_FULL_EA_INFORMATION  eaBuffer;
      ULONG                      eaLength;
      UNICODE_STRING             TcpDeviceName;
      IO_STATUS_BLOCK            IoStatus;

      //
      // Zero The Connection Memory
      //
      NdisZeroMemory( pConnection, sizeof( TCPS_Connection ) );

      InitializeListHead( &pConnection->m_ReceivedTcpPacketList );

      //
      // Create The Connection Endpoint
      //
      nTdiStatus = KS_OpenConnectionEndpoint(
                     TCP_DEVICE_NAME_W,
                     &g_KS_Address,
                     &pConnection->m_KS_Endpoint,
                     pConnection    // Context
                     );

      ASSERT( NT_SUCCESS( nTdiStatus ) );

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

      pConnection->m_bIsConnectionObjectValid = TRUE;

      InsertTailList(
         &g_FreeConnectionList,
         &g_ConnectionSpace[i].m_ListElement
         );
   }

   g_bAddressOpen = TRUE;

   //
   // Setup Event Handlers On The Server Address Object
   //
   nTdiStatus = KS_SetEventHandlers(
                  &g_KS_Address,
                  pDeviceObject,       // Event Context
                  TCPS_ConnectEventHandler,  // ConnectEventHandler
                  TCPS_DisconnectEventHandler,  // DisconnectEventHandler
                  NULL,                // ErrorEventHandler,
#ifdef USE_RECEIVE_EVENT_HANDLER
                  TCPS_ReceiveEventHandler,  // ReceiveEventHandler
#else
                  NULL,                // ReceiveEventHandler
#endif
                  NULL,                // ReceiveDatagramEventHandler
                  NULL                 // ReceiveExpeditedEventHandler
                  );

   ASSERT( NT_SUCCESS( nTdiStatus ) );

   if( !NT_SUCCESS( nTdiStatus ) )
      return( nTdiStatus );

   g_nTCPS_UseCount = 1;

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_Shutdown
//
// Purpose
// Shutdown the ECHO server.
//
// Parameters
//
// Return Value
// 
// Remarks
//

VOID TCPS_Shutdown( PDEVICE_OBJECT pDeviceObject )
{
   TDI_STATUS        nTdiStatus;

#if DBG
   DbgPrint( "TCPS_Shutdown Entry...\n" );
#endif

   if( --g_nTCPS_UseCount <= 0 )
   {
      PTCPS_Connection   pConnection;

      //
      // Destroy All Connections
      //
      while( !IsListEmpty( &g_OpenConnectionList ) )
      {
         pConnection = (PTCPS_Connection )RemoveHeadList( &g_OpenConnectionList );

#if DBG
         DbgPrint( "Destroying Connection; ConnectionContext: 0x%X\n",
            pConnection );
#endif

         if( pConnection->m_bIsConnected )
         {
            //
            // Perform Synchronous Disconnect
            //
            nTdiStatus = KS_Disconnect(
                           &pConnection->m_KS_Endpoint,
                           NULL,    // UserCompletionEvent
                           NULL,    // UserCompletionRoutine
                           NULL,    // UserCompletionContext
                           NULL,    // pIoStatusBlock
                           0        // Disconnect Flags
                           );
         }

         //
         // Mark As Not Connected
         //
         pConnection->m_bIsConnected = FALSE;

         //
         // Empty the ReceivedTcpPacketList
         // ----------------------------
         // TCPS_EchoTcpPackets will empty the list if pConnection->m_bIsConnected
         // is FALSE.
         //
         TCPS_EchoTcpPackets( pConnection );

         //
         // Return Connection To Free List
         //
         TCPS_FreeConnection( pConnection );
      }

      //
      // Release Connections In The Free Connection List
      //
      while( !IsListEmpty( &g_FreeConnectionList ) )
      {
         pConnection = (PTCPS_Connection )RemoveHeadList( &g_FreeConnectionList );

#if DBG
         DbgPrint( "Destroying Connection; ConnectionContext: 0x%X\n",
            pConnection );
#endif

         //
         // Close The TDI Connection Object, If Necessary
         //
         if( pConnection->m_bIsConnectionObjectValid )
         {
            KS_CloseConnectionEndpoint( &pConnection->m_KS_Endpoint );
         }

         pConnection->m_bIsConnectionObjectValid = FALSE;
      }

      //
      // Close The TDI Address Object, If Necessary
      //
      if( g_bAddressOpen )
      {
         KS_CloseTransportAddress( &g_KS_Address );
      }

      g_bAddressOpen = FALSE;

      //
      // Free Packet And Buffer Pools
      //
      if( g_bBufferPoolAllocated )
         NdisFreeBufferPool( g_hBufferPool );

      g_bBufferPoolAllocated = FALSE;

      if( g_bPacketPoolAllocated )
         NdisFreePacketPool( g_hPacketPool );

      g_bPacketPoolAllocated = FALSE;

      g_nTCPS_UseCount = 0;

      return;
   }
}

⌨️ 快捷键说明

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