阅读:2138回复:5
关于 serialized 和 deserialized Miniport( 200分)
我做的一个虚拟的Miniport,不发送数据,只提交数据,其数据是由应用程序写入的( 组播数据)。在Win2000、Winxp和win98(第一版)下工作正常,但是在Win98Se下总流量比较大时(如20M) bps,只要启动Meadplayer接收MPEG4数据(该数据流只有1.5Mbps,还有其它数据流)大约几分钟mediaplayer就会死掉,此时整个Socket已死掉(我自己写程序测试过),CPU占用100%,但其它进程都工作正常(比如说浏览某个目录,运行某程序等,只是比较慢),包括网络文件服务等。经过检查我的Miniport代码,我在NdisMSetAttribs中其中一个参数设为deserialized ,此后工作正常。但后来在安装了philips的一个IP CA协议后,每次关机和重启计算机都要等待大约3~5分钟时间,此时系统显示正在关机。如果我的Miniport不设定deserialized,则关机很顺利。我在Sice中进行查看,发现每次在关机等待的时间里,我的miniport总是被频繁调用MiniportSendPackets,该函数实现如下,实际上不做任何事。现在这个问题让我很郁闷,还请版主及其它高手指点一二。
注:当安装了IP CA协议后,我的网卡只同IP CA(Protocol)绑定,同TCP/IP的连接被断开 VOID MiniportSendPackets( IN NDIS_HANDLE MiniportAdapterContext, IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets ) { PADAPTER Adapter = ( PADAPTER )MiniportAdapterContext; UINT Index = 0; PNDIS_PACKET Packet = NULL; NDIS_STATUS Status = STATUS_SUCCESS; TRACE_IN( \"MiniportSendPackets\" ); NdisAcquireSpinLock( &Adapter->Lock ); for( Index = 0; Index < NumberOfPackets; Index++ ) { Packet = PacketArray[ Index ]; if( Packet ) { Adapter->dwSendCount ++; Status = NDIS_STATUS_SUCCESS; NDIS_SET_PACKET_STATUS( Packet, Status ); NdisMSendComplete( Adapter->MiniportAdapterHandle, Packet, Status ); } } NdisReleaseSpinLock( &Adapter->Lock ); TRACE_OUT( \"\", NO_RETURN ); } [编辑 - 5/22/03 by bingjie] |
|
沙发#
发布于:2003-05-23 11:00
把packet声明和NdisAcquireSpinLock NdisReleaseSpinLock都挪到for循环的里面去
|
|
|
板凳#
发布于:2003-05-23 11:02
IPCA是个什么东西?他频繁调用senpacket是不是因为他要获得那个把的应答报文?
|
|
|
地板#
发布于:2003-05-23 12:01
放在循环里外效果应该是一样的吧,IP CA是一个Protocol,它收到我的Miniport提交的数据,再把它转发给另外一个Miniport,它没有使用中间层技术,而是使用了Protocol+Miniport的方式来实现数据解密的
|
|
地下室#
发布于:2003-05-23 12:06
我最想不明白的就是为什么设置为deserialized就需要等待很长时间,而设为serialized就不会,以下是我的提交数据的部分
BOOL NCReceiveData( IN NDIS_HANDLE MiniportAdapterContext ) { PADAPTER Adapter = ( PADAPTER )MiniportAdapterContext; PNDIS_PACKET NdisPacket; PNDIS_BUFFER NdisBuffer; PUCHAR Buffer; ULONG Length; NDIS_STATUS Status; UCHAR MacAddress[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; PUCHAR DataBuffer; ULONG DataLength = 0; // // 从Packet指针列表中取得Packet描述符 // NdisPacket = (PNDIS_PACKET)ListRemove(&Adapter->PacketsList); if( NdisPacket == NULL ) { TRACE( \"No Packet\" ); return FALSE; } // // 从Buffer指针列表中取得Buffer描述符 // NdisBuffer = (PNDIS_BUFFER)ListRemove(&Adapter->BuffersList); if( NdisBuffer == NULL ) { TRACE0( \"No Buffer\" ); ListInsert(&Adapter->PacketsList, (PVOID)NdisPacket); return FALSE; } DataBuffer = QueueRemove( &Adapter->DataQueue, &DataLength ); if( DataBuffer == NULL || DataLength == 0 || DataLength > MAX_PACKET_SIZE ) { // 归还Buffer和Packet ListInsert( &Adapter->BuffersList, NdisBuffer ); ListInsert( &Adapter->PacketsList, NdisPacket ); return FALSE; } //TRACE2( \"The %d bytes data at 0x%x will be Indicated\", // DataLength, DataBuffer ); // // 填充Buffer // NdisAdjustBufferLength( NdisBuffer, DataLength ); NdisQueryBuffer( NdisBuffer, (PVOID*)&Buffer, &Length ); ASSERT( Buffer ); NdisMoveMemory( Buffer, DataBuffer, DataLength ); // 将Buffer链接到Packet的后面 // NdisAdjustBufferLength(NdisBuffer, DataLength); NdisChainBufferAtBack(NdisPacket, NdisBuffer); // // 设置Packet属性 // NDIS_SET_PACKET_HEADER_SIZE(NdisPacket, 14); NDIS_SET_PACKET_STATUS(NdisPacket, NDIS_STATUS_SUCCESS ); // 向Ndis提交 NdisMIndicateReceivePacket( Adapter->MiniportAdapterHandle, &NdisPacket, 1 ); #if !DESERIALIZED // deserialized driver, ndis will return all packet by miniportreturnpacket Status = NDIS_GET_PACKET_STATUS( NdisPacket ); if( Status != NDIS_STATUS_PENDING ) { //TRACE1( \"The IndicateReceive status is 0x%x\", Status ); MiniportReturnPacket( Adapter, NdisPacket ); } #endif Adapter->dwRcvCount ++; return TRUE; } |
|
5楼#
发布于:2003-05-23 15:27
版主能将一下这其中的区别吗
|
|