📄 receive.cpp
字号:
//////////////////////////////////////////////////////////////////////////
// Copyright @2003 Peng He,Information Science Insititute,XiDian University
// MyNdis_Wdm example
//Abstract:
// Receive Module
//Environment:
// kernel mode only
// Version history:
//
///////////////////////////////////////////////////////////////////////////
#define BINARY_COMPATIBLE 1 // 对win9x兼容
#define DOBREAKS // 设置调试断点
#include "ndis.h"
#include "ntddndis.h"
#include "debug.h"
#include "common.h"
#include "USBNDIS.h"
/*****************************************************************************
// ProcessData
//
// 数据处理例程序,把数据考贝到相应的缓冲区
//
//
*****************************************************************************/
NTSTATUS
ProcessData(
IN PUSB_DEVICE Adapter,
IN PRCV_BUFFER PRecBuf)
{
NTSTATUS status=NDIS_STATUS_SUCCESS;
USB_DUMP( DBG_BUF,( pRecBuf->dataBuf, pRecBuf->dataLen ) );
status=DeliverBuffer(
Adapter,
PRecBuf);
DEBUGMSG(DBG_FUNC, ("-ProcessData\n"));
return status;
}
/*****************************************************************************
// MiniportReturnPacket
//
// 从上层协议驱动程序返回一个数据包,该包是以前通过调用NdisMIndicateReceivePacket
// 函数传上去的,它保留了包描述符所描述的资源
//
*****************************************************************************/
NDIS_STATUS
MiniPortReturnPacket(
IN NDIS_HANDLE MiniPortAdapterContext,
IN PNDIS_PACKET PReturnPacket)
{
PUSB_DEVICE Adapter;
PNDIS_BUFFER PBuffer;
PRCV_BUFFER PRecBuffer;
UINT Index;
BOOLEAN found = FALSE;
DEBUGONCE(DBG_FUNC, ("+MiniportReturnPacket\n"));
//
// 将指向适配器环境区的指针指向Adapter
//
Adapter=CONTEX_TO_DEV(MiniportAdapterContext);
//
// 用一个原子操作把调用者提供的LONG类型的变量加1
//
NdisInterlockedIncrement( (PLONG) &Adapter->packetsReceived);
//
// 搜索包队列,确定正确的接收包
//
for (Index=0;Index<NUM_RCV_BUFS;Index++)
{
PRecBuffer=&(Adapter->rcvBufs[Index]);
if ( ((PNDIS_PACKET)PRecBuffer->Packet)== pReturnedPacket )
{
ProcessReturnPacket(Adapter, pRecBuffer); // 处理返回包
found=TRUE; // 已发现返回包
break;
}
}
//
// 确认返回包已经找到
//
ASSERT(found);
DEBUGMSG(DBG_FUNC, ("-MiniportReturnPacket\n"));
return;
}
/*****************************************************************************
// ProcessReturnPacket
//
// 返回包处理函数
//
*****************************************************************************/
VOID ProcessReturnPacket(PUSB_DEVICE Adapter,
PRCV_BUFFER pReceiveBuffer)
{
PNDIS_BUFFER PBuffer;
DEBUGONCE(DBG_FUNC, ("+ProcessReturnPacket\n"));
//
// 从给定包缓冲区描述符链表中删除链表的表头,并且返回指向这个缓冲区描述符的指针
//
NdisUnchainBufferAtFront( (PNDIS_PACKET) pReceiveBuffer->packet, &pBuffer);
ASSERT( pBuffer ); // 如果指向缓冲区描述符的指针不为空
if (pBuffer) {
NdisFreeBuffer( pBuffer );
}
InterlockedExchange( &(pReceiveBuffer->dataLen), 0);
InterlockedExchange( (PULONG)&(pReceiveBuffer->state), STATE_FREE);
DEBUGMSG(DBG_FUNC, ("-ProcessReturnPacket\n"));
}
PRCV_BUFFER GetRcvBuf(
PUSB_DEVICE Adapter,
OUT UINT *PIndex,
IN rcvBufferState state) // 输入缓冲区状态参数
{
UINT Index;
PRCV_BUFFER PBuf=NULL;
DEBUGMSG(DBG_FUNC, (" +GetRcvBuf()\n"));
for (Index=0;Index<NUM_RCV_BUFS;Index++)
{
if (Adapter->rcvBufs[Index].state == STATE_FREE )
{
InterlockedExchange((PULONG)&Adapter->rcvBufs[Index].state, (ULONG)state ); // 设置缓冲区输入状态
*PIndex=Index; // 得到缓冲区号
InterlockedExchange( &(Adapter->RcvBuffersInUse), Index+1); // 将已用的缓冲区数加1
PBuf=&(Adapter->rcvBufs[*PIndex]);
break;
}
}
DEBUGMSG(DBG_FUNC, (" -GetRcvBuf()\n"));
return PBuf;
}
/*****************************************************************************
// DeliverBuffer
//
// 通过调用NdisMIndicateReceivePacket函数,向上层协议驱动程序传递接收缓冲区
//
*****************************************************************************/
NTSTATUS DeliverBuffer(
IN PUSB_DEVICE Adapter,
IN PRCV_BUFFER pRecBuf)
{
PNDIS_BUFFER PBuffer;
NTSTATUS status=NDIS_STATUS_SUCCESS;
PNDIS_BUFFER Buffer;
NDIS_STATUS Status;
NdisAllocateBuffer( // 在指定的已分配但不分页的内存块中创建一个映射虚存范围的缓冲区描述符
&status, // 返回的状态
&Buffer,
Adapter->BufferPoolHandle,
PRecBuf->databuf, // 接收缓冲区映射的虚拟内存地址
PRecBuf->dataLen) // 虚拟内存中的数据字节数
NdisChainBufferAtFront( (PNDIS_PACKET) pRecBuf->packet, Buffer); // 将给定缓冲区描述符链到一个给定包的缓冲区描述符链表的表头
NDIS_SET_PACKET_STATUS((PNDIS_PACKET) pRecBuf->packet, NDIS_STATUS_SUCCESS); // 从一个与给定的包描述符相关联的OOB数据块中返回状态值
NdisMIndicateReceivePacket( // 向相关的上层指示一个或多个包
Adapter->MiniportHandle, // 逻辑适配器句柄
&((PNDIS_PACKET) pRecBuf->packet), // 接收包的包描述符指针
1 // 接收包数目
);
DEBUGMSG(DBG_FUNC, ("-DeliverBuffer\n"));
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -