📄 udpecho.c
字号:
//
// 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 + -