阅读:1395回复:1
关于协议驱动接收报文一问???
下面这段代码是2000DDK中例子packet中文件read.c中的一段,我咋就没看见协议驱动收到数据报后是如何转发到上层的?
大家看看这段程序的功能是啥? 输入参数Packet是下层通知上来的数据报吗?那代码直接的open->RcvList中的数据是啥时候由谁放进去的?为啥能将从irp中取出的数据报文packet和函数输入参数进来的packet进行拷贝操作???????????? INT PacketReceivePacket( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet ) /*++ Routine Description: ReceivePacket handler. Called up by the miniport below when it supports NDIS 4.0 style receives. A ProtocolReceivePacket function should be provided if the protocol driver might be bound to a NIC driver that indicates an array of one or more packets by calling NdisMIndicateReceivePacket. Arguments: ProtocolBindingContext Pointer to our adapter structure. Packet - Pointer to the packet Return Value: == 0 -> We are done with the packet != 0 -> We will keep the packet and call NdisReturnPackets() this many times when done. --*/ { UINT bytesTransfered = 0; POPEN_INSTANCE open; PIRP irp; PNDIS_PACKET myPacket; PLIST_ENTRY packetListEntry; ULONG bufferLength; PPACKET_RESERVED reserved; PIO_STACK_LOCATION irpSp; PMDL mdl; NTSTATUS status = STATUS_SUCCESS; DebugPrint((\"PacketReceivePacket\\n\")); open= (POPEN_INSTANCE)ProtocolBindingContext; // // See if there are any pending read that we can satisfy // packetListEntry=ExInterlockedRemoveHeadList( &open->RcvList, //由谁在啥时候放进去的???????????????? &open->RcvQSpinLock ); if (packetListEntry == NULL) { // // No pending reads so just the dropping the packet // on the floor. // DebugPrint((\"No pending read, dropping packets\\n\")); return 0; } reserved=CONTAINING_RECORD(packetListEntry,PACKET_RESERVED,ListElement); myPacket=CONTAINING_RECORD(reserved,NDIS_PACKET,ProtocolReserved); irp = RESERVED(myPacket)->Irp; irpSp = IoGetCurrentIrpStackLocation(irp); // // We don\'t have to worry about the situation where the IRP is cancelled // after we remove it from the queue and before we reset the cancel // routine because the cancel routine has been coded to cancel an IRP // only if it\'s in the queue. // IoSetCancelRoutine(irp, NULL); // // Following block of code locks the destination packet // MDLs in a safe manner. This is a temporary workaround // for NdisCopyFromPacketToPacket that currently doesn\'t use // safe functions to lock pages of MDL. This is required to // prevent system from bugchecking under low memory resources. // { PVOID virtualAddress; PNDIS_BUFFER firstBuffer, nextBuffer; ULONG totalLength; NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, &totalLength); while( firstBuffer != NULL) { NdisQueryBufferSafe(firstBuffer, &virtualAddress, &totalLength, NormalPagePriority ); if(!virtualAddress) { // // System is running low on memory resources. // So fail the read. // status = STATUS_INSUFFICIENT_RESOURCES; goto CleanExit; } NdisGetNextBuffer(firstBuffer, &nextBuffer); firstBuffer = nextBuffer; } } // // // Attach the actual MDL to the packet // NdisChainBufferAtFront(myPacket, irp->MdlAddress); bufferLength=irpSp->Parameters.Read.Length; NdisCopyFromPacketToPacket(myPacket, 0, bufferLength, Packet, 0, &bytesTransfered); ////////////////////////////////////////////////////////难道数据拷贝完了就发给上层了吗?如果不是,要调用什么函数才能将数据报转发到上层????????????????????? CleanExit: // // Put the packet on the free queue // NdisFreePacket(myPacket); irp->IoStatus.Status = status; irp->IoStatus.Information = bytesTransfered; IoCompleteRequest(irp, IO_NO_INCREMENT); DebugPrint((\"BytesTransfered:%d\\n\", bytesTransfered)); IoDecrement(open); return 0; } |
|
沙发#
发布于:2003-08-12 13:06
他的上层就是packet目录下的testapp,你也可以自己写应用程序和他通信。应用程序是通过调用ReadFile,把请求下传,IO管理器把应用程序的请求打成IRP包,发给驱动,驱动把数据考到IRP包里面的Buffer里,然后IoCompleteRequest。read.c里面的PacketRead是专门处理应用程序的读请求的。
|
|
|