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

📄 udpecho.c

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

   //
   // Make the next stack location current. Normally IoCallDriver would
   // do this, but for this IRP it has been bypassed.
   //
   IoSetNextIrpStackLocation( pUDPS_Packet->Reserved.m_pReceiveIrp );

   //
   // Tell TDI To Transfer The Data
   //
   *IoRequestPacket = pUDPS_Packet->Reserved.m_pReceiveIrp;

   return( STATUS_MORE_PROCESSING_REQUIRED );
}

#else

/////////////////////////////////////////////////////////////////////////////
//// UDPS_ReceiveDatagramCompletion
//
// Purpose
//
// Parameters
//
// Return Value
// 
// Remarks
//

VOID
UDPS_ReceiveDatagramCompletion(
   PVOID UserCompletionContext,
   PIO_STATUS_BLOCK IoStatusBlock,
   ULONG Reserved
   )
{
   PUDPS_PACKET      pUDPS_Packet;
   PNDIS_BUFFER      pNdisBuffer;
   ULONG             nDataSize, nBufferCount;
   NTSTATUS          nFinalStatus = IoStatusBlock->Status;
   ULONG             nByteCount = IoStatusBlock->Information;

#if DBG
   DbgPrint( "UDPS_ReceiveDatagramCompletion: FinalStatus: 0x%8.8x; Bytes Transfered: %d\n",
      nFinalStatus, nByteCount );
#endif

   pUDPS_Packet = (PUDPS_PACKET )UserCompletionContext;

   //
   // Sanity Check On Passed Parameters
   //
   ASSERT( pUDPS_Packet );

   if( !pUDPS_Packet )
   {
      return;
   }

   //
   // Verify The Packet Signature
   //
   ASSERT( pUDPS_Packet->Reserved.m_Signature == UDPS_PACKET_SIGN );

   if( pUDPS_Packet->Reserved.m_Signature != UDPS_PACKET_SIGN )
   {
#if DBG
      DbgPrint( "UDPS_ReceiveDatagramCompletion: Invalid Packet Signature\n" );
#endif

      return;
   }

   DEBUG_DumpTransportAddress(
      (PTRANSPORT_ADDRESS )&pUDPS_Packet->Reserved.m_RemoteAddress
      );

   //
   // Handle Transfer Failure
   //
   if( !NT_SUCCESS( nFinalStatus ) )
   {
      //
      // Recycle The Packet And Buffers
      //
      UDPS_FreePacketAndBuffers( pUDPS_Packet );

      // ATTENTION!!! Update Statistics???

      return;
   }

   // ATTENTION!!! Update Statistics???

   //
   // Query The NDIS_PACKET
   //
   NdisQueryPacket(
      (PNDIS_PACKET )pUDPS_Packet,
      (PULONG )NULL,
      (PULONG )&nBufferCount,
      &pNdisBuffer,
      &nDataSize
      );

   ASSERT( pNdisBuffer );

   if( !pNdisBuffer )
   {
      //
      // Recycle The Packet And Buffers
      //
      UDPS_FreePacketAndBuffers( pUDPS_Packet );

      return;
   }

   //
   // Save The Byte Count
   // -------------------
   // In this implementation, the NDIS_BUFFER Length field is adjusted
   // to the amount of data that was copied into the buffer. This has
   // the added benefit of insuring that when the packet is sent later
   // the NDIS_BUFFER Length field and the length parameter passed to
   // TdiSend are the same.
   //
   NdisAdjustBufferLength( pNdisBuffer, nByteCount );

   // ATTENTION!!! Check Flags???
   //
   // Put The Packet In The Received UDP PacketList
   //
   InsertTailList(
      &g_ReceivedUdpPacketList,
      &pUDPS_Packet->Reserved.m_ListElement
      );

   //
   // Possibly Send Another Packet
   //
   UDPS_EchoUdpPackets( FALSE);

   return;
}

#endif // USE_RECEIVE_EVENT_HANDLER

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

NTSTATUS
UDPS_Startup( PDEVICE_OBJECT pDeviceObject )
{
   NTSTATUS          nTdiStatus;
   NDIS_STATUS       nNdisStatus;
   TA_IP_ADDRESS     ECHOAddress;
   int               i;
   PUDPS_PACKET      pUDPS_Packet;
   PNDIS_BUFFER      pNdisBuffer;

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

   g_bAddressOpen = FALSE;

   //
   // Initialize The Received UDP Packet List
   //
   InitializeListHead( &g_ReceivedUdpPacketList );

   //
   // Allocate The Packet Pool
   //
   NdisAllocatePacketPool(
      &nNdisStatus,
      &g_hPacketPool,
      UDPS_PACKET_POOL_SIZE,
      sizeof( UDPS_PACKET_RESERVED )
      );

   ASSERT( NT_SUCCESS( nNdisStatus ) );

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

      return( STATUS_INSUFFICIENT_RESOURCES );
   }

   g_bPacketPoolAllocated = TRUE;

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

   ASSERT( NT_SUCCESS( nNdisStatus ) );

   if( !NT_SUCCESS( nNdisStatus ) )
   {
#if DBG
      DbgPrint( "UDPS_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,
      INADDR_ANY,                   // Any Local Address
      KS_htons( IPPORT_ECHO )       // ECHO Port
      );

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

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

   ASSERT( NT_SUCCESS( nTdiStatus ) );

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

   g_bAddressOpen = TRUE;

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

   ASSERT( NT_SUCCESS( nTdiStatus ) );

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


#ifndef USE_RECEIVE_EVENT_HANDLER

   //
   // Allocate The Receive Packet Descriptor
   // --------------------------------------
   // Use of this structure is adopted from it's use in lower-level
   // NDIS protocol drivers. It is simply a convienient way to allocate
   // the space needed to handle packet reception.
   //
   NdisAllocatePacket(
      &nNdisStatus,
      &(PNDIS_PACKET )pUDPS_Packet,
      g_hPacketPool
      );

   if( nNdisStatus != NDIS_STATUS_SUCCESS || !pUDPS_Packet )
   {
      // ATTENTION!!! Update Statistics???

#if DBG
      DbgPrint( "UDPS_Startup Could Not Allocate Packet\n" );
#endif

      return( STATUS_MORE_PROCESSING_REQUIRED );
   }

   //
   // Initialize The Packet Signature
   //
   pUDPS_Packet->Reserved.m_Signature = UDPS_PACKET_SIGN;

   //
   // Initialize The Space For Remote Address To Be Returned
   //
   KS_InitIPAddress(
      &pUDPS_Packet->Reserved.m_RemoteAddress,
      INADDR_ANY,                   // Any Local Address
      0                             // Any Port
      );

   //
   // Setup Return Connection Info In Packet Reserved Area
   //
   NdisZeroMemory(
      &pUDPS_Packet->Reserved.m_RemoteConnectionInfo,
      sizeof( TDI_CONNECTION_INFORMATION )
      );

   pUDPS_Packet->Reserved.m_RemoteConnectionInfo.RemoteAddress = &pUDPS_Packet->Reserved.m_RemoteAddress;
   pUDPS_Packet->Reserved.m_RemoteConnectionInfo.RemoteAddressLength = sizeof( TA_IP_ADDRESS );

   //
   // Allocate An NDIS Buffer Descriptor For The Receive Data
   //
   NdisAllocateBuffer(
      &nNdisStatus,
      &pNdisBuffer,
      g_hBufferPool,
      pUDPS_Packet->Reserved.m_DataBuffer,   // Private Buffer
      UDPS_BUFFER_SIZE                       // Private Buffer's Size
      );

   if( nNdisStatus != NDIS_STATUS_SUCCESS || !pNdisBuffer )
   {
      // ATTENTION!!! Update Statistics???

      NdisFreePacket( (PNDIS_PACKET )pUDPS_Packet );

#if DBG
      DbgPrint( "UDPS_Startup Could Not Allocate Buffer\n" );
#endif

      return( STATUS_MORE_PROCESSING_REQUIRED );
   }

   NdisChainBufferAtFront( (PNDIS_PACKET )pUDPS_Packet, pNdisBuffer );

   //
   // Start A Receive On The Connection
   //
   KS_ReceiveDatagramOnAddress(
      &g_KS_Address,
      NULL,       // User Completion Event
      UDPS_ReceiveDatagramCompletion, // User Completion Routine
      pUDPS_Packet,   // User Completion Context
      &pUDPS_Packet->Reserved.m_PacketIoStatus,
      pNdisBuffer,   // MdlAddress
      NULL,          // ReceiveDatagramInfo
      &pUDPS_Packet->Reserved.m_RemoteConnectionInfo, // ReturnInfo
      TDI_RECEIVE_NORMAL   // InFlags
      );

#endif // USE_RECEIVE_EVENT_HANDLER

   return( STATUS_SUCCESS );
}


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

VOID UDPS_Shutdown( PDEVICE_OBJECT pDeviceObject )
{
   TDI_STATUS        nTdiStatus;

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

   //
   // Empty the ReceivedUdpPacketList
   // ----------------------------
   // UDPS_EchoUdpPackets will empty the list if bShutdown is TRUE.
   //
   UDPS_EchoUdpPackets( TRUE );

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

   return;
}

⌨️ 快捷键说明

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