阅读:2118回复:7
请教Passthru中间层 驱动 发包蓝屏问题
代码如下:
VOID SendArpPacket(PARPHeader apPacket) { PNDIS_PACKET ArpPacket ; NDIS_STATUS Status; PNDIS_BUFFER buffer; //分配一段 长度为60的内存 Status = NdisAllocateMemory( &pPacketContent, 60, 0,HighestAcceptableMax); if(Status!=NDIS_STATUS_SUCCESS ) { return ; } //对他进行清0操作 NdisZeroMemory(pPacketContent,60); //把ARP头拷贝到 分配的内存中 NdisMoveMemory(pPacketContent,apPacket,sizeof(PARPHeader)); //从池中分配 包描述符 ArpPacket NdisDprAllocatePacket(&Status,&ArpPacket,hSendPool); //设置缓冲区描述符等 NdisAllocateBuffer(&Status,&buffer,hSendPool,pPacketContent,60); //联接上 NdisChainBufferAtFront( ArpPacket, buffer); ArpPacket->Private.Head->Next =NULL; ArpPacket->Private.Tail =NULL; NdisSetPacketFlags(ArpPacket, NDIS_FLAGS_DONT_LOOPBACK); NdisSend(&Status, pUnderAdapt->BindingHandle, ArpPacket); KdPrint(("发送Arp包完毕")); } 按照ddk上面写的发包 步骤写的程序,,,谁帮忙看看为什么蓝屏 我程序是接到DeviceIoControl请求后,调用函数发送数据包。 上层应用程序一传递DeviceIoControl 请求这边就蓝屏了 问题肯定出在这个函数里 大家帮忙看看吧 |
|
沙发#
发布于:2007-08-09 23:22
就是按照ddk改的。.这个函数加上 发包就蓝屏..
|
|
板凳#
发布于:2007-08-10 00:18
测试中,路过
|
|
|
地板#
发布于:2007-08-10 00:19
调试靠猜?
|
|
|
地下室#
发布于:2007-08-10 09:55
主要是不会调试 驱动。。只会用kdprint......感觉没问题了。。跟ddk里的例子差不多
|
|
5楼#
发布于:2007-08-10 12:04
NdisSetPacketFlags(ArpPacket, NDIS_FLAGS_DONT_LOOPBACK);
NdisSend(&Status, pUnderAdapt->BindingHandle, ArpPacket); 拿softice调试 就在这2句 出问题了 可是softice刚才又坏了。。一ctrl+d就蓝屏 显示模式改了半天也不成 |
|
6楼#
发布于:2008-11-11 11:23
新火(18089752) 10:57:08
经历2周 终于把passthru发包问题弄明白了现在把一点小小体会和大家分享一下 XXx(39034666) 10:57:56 passthru发包,是什么东西 新火(18089752) 10:58:23 //这是应用的接口不是重点 case IOCTL_PTUSERIO_SENDPACKET: { if(uInSize>0) { if(PassthruSendPacket(pAdapt,pIoBuffer,uInSize)) { status = STATUS_SUCCESS; } else status = STATUS_INVALID_DEVICE_REQUEST; } else status = STATUS_INVALID_PARAMETER; } break; 新火(18089752) 11:00:48 //这是PassthruSendPacket的代码 这个代码曾经蓝屏无数次 BOOLEAN PassthruSendPacket(PADAPT pAdapt,UCHAR* pPacket,UINT uLength) { PNDIS_PACKET pNdisPacket; PNDIS_BUFFER pNdisBuffer; PVOID pPacketContent = NULL; NDIS_PHYSICAL_ADDRESS phyaddr = {-1}; NDIS_STATUS Status; //判断下层适配器是否可用 if(pAdapt->MPDeviceState > NdisDeviceStateD0) { return FALSE; } //分配内存存放包内容 Status = NdisAllocateMemory(&pPacketContent,uLength,0,phyaddr); if(Status!=NDIS_STATUS_SUCCESS ) { return FALSE; } //对他进行清0操作 NdisZeroMemory(pPacketContent,uLength); //复制包内容到分配的内存中 NdisMoveMemory(pPacketContent,pPacket,uLength); //从池中分配 包描述符 ArpPacket NdisDprAllocatePacket(&Status,&pNdisPacket,MySendPacketPool); if(NDIS_STATUS_SUCCESS != Status) { NdisFreeMemory(pPacketContent, uLength, 0); return FALSE; } //设置缓冲区 NdisAllocateBuffer(&Status,&pNdisBuffer,MySendBufferPool,pPacketContent,uLength); if(NDIS_STATUS_SUCCESS != Status) { NdisDprFreePacket(pNdisPacket); NdisFreeMemory(pPacketContent, uLength, 0); return FALSE; } pNdisBuffer->Next = NULL; //联接上 NdisChainBufferAtFront(pNdisPacket, pNdisBuffer); //设置标志为自己定义的包 NdisSetPacketFlags(pNdisPacket, NDIS_FLAGS_DONT_LOOPBACK); //发送自定义包 一直都卡在这里 一发包就蓝屏。 NdisSend(&Status, pAdapt->BindingHandle, pNdisPacket); KdPrint(("发送自定义包完毕")); if (Status != NDIS_STATUS_PENDING) { NdisFreeBuffer(pNdisBuffer); NdisFreeMemory(pPacketContent,uLength,0); NdisDprFreePacket(pNdisPacket); } return TRUE; } 新火(18089752) 11:07:38 //蓝屏的原因和解决办法 //蓝屏的原因是当我调用NdisSend 发包时 下层驱动发包后会调用PtSendComplete来通知上层驱动发送完毕需要释放包内存。而以前我一直没有在PtSendComplete里添加相关处理代码。只在PassthruSendPacket里找毛病自然不行。 //这是在PtSendComplete里添加的代码 PoolHandle = NdisGetPoolFromPacket(Packet); //判断是否为自身发的包 if (PoolHandle == MySendPacketPool) { NdisDprFreePacket(Packet); return; } 新火(18089752) 11:10:50 //注意到这里有两个全局变量是我新定义的一个是MySendPacketPool另一个是MySendBufferPool它们是在passthru.c里定义在DriverEntry里初始化的 //Myself send pools NDIS_HANDLE MySendBufferPool = NULL; NDIS_HANDLE MySendPacketPool = NULL; 新火(18089752) 11:11:13 // // Allocate myself packet pools. // NdisAllocatePacketPoolEx( &Status, &MySendPacketPool, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, sizeof(SEND_RSVD)); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT(("AllocatePacketPool fails!")); break; } // // Allocate myself send buffer pools // NdisAllocateBufferPool( &Status, &MySendBufferPool, MAX_SEND_PACKET_POOL_SIZE); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT(("AllocateBufferPool fails!")); break; } 新火(18089752) 11:12:28 通过以上的修改就可以发送自定义数据包了。 |
|
7楼#
发布于:2008-11-11 18:04
//这是在PtSendComplete里添加的代码
PoolHandle = NdisGetPoolFromPacket(Packet); //判断是否为自身发的包 if (PoolHandle == MySendPacketPool) { NdisDprFreePacket(Packet); return; } 好像还有其它资源没有释放掉。例如:pNdisBuffer和pPacketContent。 |
|