bcomd
驱动牛犊
驱动牛犊
  • 注册日期2005-07-21
  • 最后登录2005-10-11
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1171回复:5

protocolreceive封装

楼主#
更多 发布于:2005-08-03 22:04
我想在windows CE 4.2 的passthru的protocol.c文件,使用protocolReceive()中做IPIP封装,ping已经通了,但是一段时间后,会出现内存分配不足。也就是出现内存泄露。代码片断如下,那位大侠给指点一下吧,多谢了!


//把数据包内容拷贝到pData

status = NdisAllocateMemory( (PVOID *)&pData, uiLookAheadBufferSize, 0, noMaxAddr);
if(status != NDIS_STATUS_SUCCESS) return 1;

status = NdisAllocateMemory( (PVOID *)&pHeader, uiHeaderBufferSize, 0, noMaxAddr);
if(status != NDIS_STATUS_SUCCESS) return 1;
          
NdisZeroMemory (pHeader, uiHeaderBufferSize);
NdisZeroMemory (pData, uiLookAheadBufferSize);

NdisMoveMemory(pHeader, pvHeaderBuffer, uiHeaderBufferSize);           NdisMoveMemory(pData, pvLookAheadBuffer, uiLookAheadBufferSize);  

。。。。。。 。。。。。。

//用pEncapData构造新的数据包

status = NdisAllocateMemory((PVOID *)&pEncapData, uiLookAheadBufferSize+sizeof(ip_header), 0, noMaxAddr);
if (status!=NDIS_STATUS_SUCCESS ) return 1;
NdisZeroMemory(pEncapData, uiLookAheadBufferSize+sizeof(ip_header));

//把封装好的IP头拷贝进数据包

NdisMoveMemory(pEncapData, pIpHeader, sizeof(ip_header));
NdisMoveMemory(pEncapData+sizeof(ip_header), pData, uiLookAheadBufferSize);

。。。。。。 。。。。。。

//指定包      

NdisMEthIndicateReceive(pBinding->hMPBinding, hMacReceiveContext, HeaderBuffer,  uiHeaderBufferSize, (PVOID)pEncapData, LookAheadBufferSize+20,    uiPacketSize+20);                

//释放内存

NdisFreeMemory(pIpHeader, sizeof(ip_header), 0);
NdisFreeMemory(pEncapData, uiLookAheadBufferSize+20, 0);


如果不封装,只是使用pData代替pLookAheadBuffer,即

NdisMEthIndicateReceive(pBinding->hMPBinding, hMacReceiveContext, pvHeaderBuffer, uiHeaderBufferSize, (PVOID)pData, uiLookAheadBufferSize,uiPacketSize);

就没有内存泄露问题!!!
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-08-04 15:09
时间有点儿长,有点儿记不清了:)

你这儿写得不是很清楚,你是在帮下层释放资源吗?(pIpHeader等等)

如果是,我觉得这里释放资源好像不对,CE的NDIS和桌面系统提供的API和处理流程一样的话,我记得在向上INDICATE包的时候把下层传来的包包存在你自己分配的包的一个域的,而上层返回你会调用NdisReturnPackets,也就是执行ndis IMD的MPReturnPacket,这里你释放你刚才分配的东西,然后把下层传上来的缓冲区归还给miniport驱动,他自己释放。
根据地的兄弟们,团结就是力量
bcomd
驱动牛犊
驱动牛犊
  • 注册日期2005-07-21
  • 最后登录2005-10-11
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-08-04 15:47
我根据protocolreceive()传来的pvLookAheadBuffer指针,做简单的IPIP封装。pIpHeader也是我分配的,用NdisAllocateMemory()分配。我不太清楚为什么不做封装(但用自己的缓冲区替换了pvLookAheadBuffer),可以长时间ping;而一旦封装(解封装),就会发生内存泄露。PB提示的错误是

ERROR: d:\mckendric\private\winceos\coreos\nk\kernel\virtmem.c line 1217:
 248308 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: Failed VirtualAlloc(00003000) of 00000014 bytes
 248309 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: Data Abort: Thread=83c31a9c Proc=829793a8 'device.exe'
 248310 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: AKY=00000009 PC=03fb730c RA=010ca8c0 BVA=08000000 FSR=00000007
 248329 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: NKDispatchException: returning failure. Flags=0
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-08-04 16:32
你自己分配的缓冲区使用了virtualalloc?释放资源的时候有没有free呢?
根据地的兄弟们,团结就是力量
bcomd
驱动牛犊
驱动牛犊
  • 注册日期2005-07-21
  • 最后登录2005-10-11
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-08-07 15:14
我没有使用VirtualAlloc(),另外,保证NdisAllocateMemory()和NdisFreeMemory()成对使用了。
这可能是protocolreceive()函数执行时间过长的原因吗,或者说封装应该在protocolreceiveComplete()中执行。protocolreceive()和protocolreceiveComplete()有什么区别,前者分配的缓冲区如何在后者中释放呢?
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-08-08 13:40
这个函数在2k/nt下面运行时会禁止调度,但在ce下怎么样我不清楚,不过你最好让这个函数尽快结束。

我记得protocolreceiveComplete()这个函数不需要动吧。

你再看看你的ptreceive是否包含了三种完整的情况?(有三条接受路径,具体什么状况你可以到ndis版询问,现成帖子也很多)
根据地的兄弟们,团结就是力量
游客

返回顶部