首页
社区
课程
招聘
[求助]关于ndis的问题
发表于: 2009-6-2 21:34 9211

[求助]关于ndis的问题

2009-6-2 21:34
9211
这几天在学习ndis,从网上下了个例子改的驱动,结果自然是BSOD,可是小弱我看了半天也没能理解为什么,各位大牛帮忙给看看:

!analyze -v执行后的部分结果:

DEBUG_FLR_IMAGE_TIMESTAMP:  4a25159a

READ_ADDRESS:  fffffffc

CURRENT_IRQL:  2

FAULTING_IP:
NDIS!NdisReturnPackets+2a
f83dc82a 8b47fc          mov     eax,dword ptr [edi-4]

DEFAULT_BUCKET_ID:  DRIVER_FAULT

BUGCHECK_STR:  0xD1

LAST_CONTROL_TRANSFER:  from 804f93fa to 80527da8

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
f6bf8fc8 804f93fa 00000003 fffffffc f83dc82a nt!DbgBreakPointWithStatus+0x4
f6bf93a8 80540853 0000000a fffffffc 00000002 nt!KeRegisterBugCheckReasonCallback+0x77c
f6bf9454 f89a7355 f6bf9464 00000001 00000000 nt!Kei386EoiHelper+0x27db
f6bf9470 f83dc87f 8215eb08 820acf30 821e5950 passthru!MPReturnPacket+0x55 [d:\winddk\3790.1830\src\network\ndis\passthru\driver\miniport.c @ 1145]
f6bf9498 f8260061 f6bf94bc 00000001 820acf78 NDIS!NdisReturnPackets+0x7f
f6bf94b0 f83e9d09 8207a2e0 820acf30 f8265b40 psched!RegisterPsComponent+0x6d33
f6bf9504 f826001d 00140220 821318f0 00000001 NDIS!FddiFilterDprIndicateReceive+0xb11
f6bf9518 f82601b4 821e5950 821318f0 00000001 psched!RegisterPsComponent+0x6cef
f6bf953c f82605f9 8207a2e8 00000000 821e5950 psched!RegisterPsComponent+0x6e86
f6bf9554 f83e9d40 8207a2e0 8209b156 82282226 psched!RegisterPsComponent+0x72cb
f6bf95a4 f89a9557 00140220 f6bf95dc 00000001 NDIS!FddiFilterDprIndicateReceive+0xb48
f6bf960c f83e9ff2 8215eb08 82282040 822820d0 passthru!PtReceive+0x1e7 [d:\winddk\3790.1830\src\network\ndis\passthru\driver\protocol.c @ 1150]
f6bf9674 f83dcec4 c000009a f6bf9694 00000001 NDIS!FddiFilterDprIndicateReceive+0xdfa
f6bf969c f83c799d 82232fb8 82375f60 81e33130 NDIS!NdisRequest+0x559
f6bf96b8 f83df986 8218f6b8 82232f58 f6bf9710 NDIS!NdisDprFreePacketNonInterlocked+0x1c8
f6bf96c8 f89a6a65 f6bf9700 8218f6b8 82232f58 NDIS!NdisSend+0xf
f6bf9710 f83c9f86 8215eb08 f6bf9744 00000001 passthru!MPSendPackets+0x325 [d:\winddk\3790.1830\src\network\ndis\passthru\driver\miniport.c @ 545]
f6bf9738 f8261528 821bd608 82375ed8 82375ea0 NDIS!NdisInitializeString+0x6d1
f6bf9774 f83c7985 8207a2e0 82375ed8 00000002 psched!RegisterPsComponent+0x81fa
f6bf979c f6ea5122 82094428 82375ed8 820dbb58 NDIS!NdisDprFreePacketNonInterlocked+0x1b0
f6bf97c0 f6ea51c6 000dbb0e ffffffff 82375ed8 tcpip!IPTransmit+0x24df
f6bf97ec f6ea370a 820dbb58 f6bf9800 00000001 tcpip!IPTransmit+0x2583
f6bf981c f6eb3910 81dc48e8 ffffffff 82375ed8 tcpip!IPTransmit+0xac7
f6bf9850 f6eaeb9f ffffffff 82375ed8 82099020 tcpip!IPTransmit+0x10ccd
f6bf9988 f6ebd09a f6ee14d4 820cc148 82099020 tcpip!IPTransmit+0xbf5c
f6bf9a28 f6ebce61 820df558 820cc148 8206b8c0 tcpip!IPRegisterProtocol+0x4673
f6bf9a4c f6ebcec7 00bf9a70 8206bfa0 82099060 tcpip!IPRegisterProtocol+0x443a
f6bf9a84 f6ebc713 8206b8c0 8206b978 8206bfa0 tcpip!IPRegisterProtocol+0x44a0
f6bf9aa0 804eedf9 820655d0 8206b8c0 821a22a0 tcpip!IPRegisterProtocol+0x3cec
f6bf9b08 f6e58bce 05d4fb34 f6e58bce 821a22a0 nt!IoBuildPartialMdl+0xed
f6bf9c50 8057564b 820db028 00000001 05d4fa04 afd+0x2bce
f6bf9d00 8056e33c 00001368 0000124c 00000000 nt!NtWriteFile+0x3595
f6bf9d34 8053d808 00001368 0000124c 00000000 nt!NtDeviceIoControlFile+0x2a
f6bf9ddc 80541fa2 f83cdb85 82134a38 00000000 nt!KeReleaseInStackQueuedSpinLockFromDpcLevel+0xb14
f6bf9e54 7c930732 00000002 000906e8 00090000 nt!KiDispatchInterrupt+0x5a2
f6bf9e80 7c930732 7c9306ab 7c9306eb 00000000 ntdll!RtlAllocateHeap+0x15e
f6bf9e84 7c9306ab 7c9306eb 00000000 00100290 ntdll!RtlAllocateHeap+0x15e
f6bf9e88 7c9306eb 00000000 00100290 76d6a140 ntdll!RtlAllocateHeap+0xd7
f6bf9e9c 7c930551 00090778 7c93056d 000b8238 ntdll!RtlAllocateHeap+0x117
f6bf9ea4 7c93056d 000b8238 000b8218 000a35bc ntdll!RtlFreeHeap+0x114
f6bf9ebc 7c9305c8 000b8280 0086fd90 7c930551 ntdll!RtlFreeHeap+0x130
00000000 00000000 00000000 00000000 00000000 ntdll!RtlFreeHeap+0x18b

STACK_COMMAND:  kb

FOLLOWUP_IP:
passthru!MPReturnPacket+55 [d:\winddk\3790.1830\src\network\ndis\passthru\driver\miniport.c @ 1145]
f89a7355 8be5            mov     esp,ebp

FAULTING_SOURCE_CODE:  
No source found for 'd:\winddk\3790.1830\src\network\ndis\passthru\driver\miniport.c'

// miniport.c

VOID
MPReturnPacket(
    IN NDIS_HANDLE             MiniportAdapterContext,
    IN PNDIS_PACKET            Packet
    )
/*++

Routine Description:

    NDIS Miniport entry point called whenever protocols are done with
    a packet that we had indicated up and they had queued up for returning
    later.

Arguments:

    MiniportAdapterContext    - pointer to ADAPT structure
    Packet    - packet being returned.

Return Value:

    None.

--*/
{
    PADAPT            pAdapt = (PADAPT)MiniportAdapterContext;

#ifdef NDIS51
    //
    // Packet stacking: Check if this packet belongs to us.
    //
    if (NdisGetPoolFromPacket(Packet) != pAdapt->RecvPacketPoolHandle)
    {
        //
        // We reused the original packet in a receive indication.
        // Simply return it to the miniport below us.
        //
        NdisReturnPackets(&Packet, 1);
    }
    else
#endif // NDIS51
    {
        //
        // This is a packet allocated from this IM's receive packet pool.
        // Reclaim our packet, and return the original to the driver below.
        //

        PNDIS_PACKET    MyPacket;
        PRECV_RSVD      RecvRsvd;
   
        RecvRsvd = (PRECV_RSVD)(Packet->MiniportReserved);
        MyPacket = RecvRsvd->OriginalPkt;
   
        NdisFreePacket(Packet);
        NdisReturnPackets(&MyPacket, 1);
    }
}      //这里就是1145行

//protocol.c

NDIS_STATUS   
PtReceive(   
    IN NDIS_HANDLE  ProtocolBindingContext,   
    IN NDIS_HANDLE  MacReceiveContext,   
    IN PVOID        HeaderBuffer,           // 包头   
    IN UINT         HeaderBufferSize,       // 包头大小,以太网环境下为14   
    IN PVOID        LookAheadBuffer,        // 前视缓冲   
    IN UINT         LookAheadBufferSize,    //   
    IN UINT         PacketSize              // 数据包总大小(不包括包头)   
)   
/*-----------------------------------------------------------------------------------  
ProtocolReceive这个函数是在低层面向无连接的NIC驱动程序调用NdisMXxxIndicateReceive 函  
  
数向上Indicate数据包时被 NDIS 调 用 的。 同 时 传 递 了 一 个 LookAheadBuffer,但 这  
  
个LookAheadBuffer 里 面 可 能 不 是 数 据 包 的 全 部 内 容, 如  果  不  是  的  话  
  
(LookAheadBufferSize < PacketSize)则需要调用NdisTransferData来获得这个数据包其余的内  
  
容,NdisTransferData只是传递在LookaheadBuffer中没有出现的数据内容, 不是传递整个数据  
  
包。  
-----------------------------------------------------------------------------------*/   
{   
    PADAPT OutAdapt, pAdapt =(PADAPT)ProtocolBindingContext;   
    PNDIS_PACKET MyPacket, Packet, MyPacket1;   
    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;   
   
    PNDIS_BUFFER pPacketBuffer, pBakBuffer;   
    PUCHAR pPacketContent, pBakContent;   
    UINT PacketLen;   
   
    UINT OffsetSize;   
    UINT BytesTransferred;   
   
    PRSVD Rsvd = NULL;   
    PVOID MediaSpecificInfo = NULL;   
    ULONG MediaSpecificSize= 0;   
   
    DBGPRINT(("In PtReceive\n"));   
   
    if(!pAdapt->MiniportHandle)   
    {   
        Status = NDIS_STATUS_FAILURE;   
    }   
    else do   
    {   
  
        // Fall through if the miniport below us has either not indicated a packet or we could not   
        // allocate one   
  
        */   
           
        if(FALSE){}   
        else if(PacketSize <= LookAheadBufferSize)  // 如果 LookAheadBuffer 中包含了全部数据   
        {   
            // 分配内存   
            Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax);   
            if(Status != NDIS_STATUS_SUCCESS)   
            {   
                DbgPrint("PTReceive:NdisAllocateMemory Failed\n");   
                return(NDIS_STATUS_NOT_ACCEPTED);   
            }   
            if(pPacketContent == NULL)   
            {   
                DbgPrint("PTReceive:pPacketContent==NULL\n");   
                return(NDIS_STATUS_NOT_ACCEPTED);   
            }   
            // 将包头和 LookAheadBuffer 复制到新分配的内存中   
            NdisZeroMemory(pPacketContent, BUFFER_SIZE);   
            NdisMoveMemory(pPacketContent, HeaderBuffer, HeaderBufferSize);   
            NdisMoveMemory(pPacketContent+ HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);   
            PacketLen = PacketSize+HeaderBufferSize;   
   
            //if(Monitor_flag)   
            //{   
            //    if(Check_Packet((char*)pPacketContent))   
            //    {   
            //        return NDIS_STATUS_NOT_ACCEPTED;   
            //    }   
            //}   
            //else {}   
   
            // 在包池中分配包描述符   
            NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);   
   
            if(Status == NDIS_STATUS_SUCCESS)   
            {   
                // 在缓冲池中分配缓冲描述符,将包描述符与缓冲描述符关联。   
                NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketLen);   
                NdisChainBufferAtFront(MyPacket, pPacketBuffer);   
   
                MyPacket->Private.Head->Next = NULL;   
                MyPacket->Private.Tail = NULL;   
                Rsvd=(PRSVD)(MyPacket->MiniportReserved);   
                Rsvd->OriginalPkt = NULL;   
                NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);   
   
                // 向上层协议驱动指示数据包,防真网卡行为。   
                NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);   
                if(NDIS_GET_PACKET_STATUS(MyPacket) != NDIS_STATUS_PENDING)       //这里就是1150行
                {   
                    DBGPRINT(("In PtReceive And Free Memory\n"));   
                    NdisFreeBuffer(pPacketBuffer);   
                    NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0);   
                    NdisDprFreePacket(MyPacket);   
                }   
            }   
            break;   
        }   
        else // 如果 LookAheadBuffer 中没有包含全部数据   
        {   
            // 分配内存 pPacketContent,存放要传输的除 LookAheadBuffer 之外的数据。   
            Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax);   
            if(Status != NDIS_STATUS_SUCCESS)   
            {   
                DbgPrint("PtReceive:NdisAllocateMemory Failed.\n");   
                return(NDIS_STATUS_NOT_ACCEPTED);   
            }   
            if(pPacketContent==NULL)   
            {   
                DbgPrint("PTReceive:pPacketContent==NULL\n");   
                return(NDIS_STATUS_NOT_ACCEPTED);   
            }   
            NdisZeroMemory(pPacketContent,BUFFER_SIZE);   
            // 分配包描述符 MyPacket。   
            NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);   
            // 分配内存 pBakContent,存放HeaderBuffer + LookAheadBuffer。   
            Status = NdisAllocateMemory(&pBakContent, BUFFER_SIZE, 0, HighestAcceptableMax);   
            if(Status != NDIS_STATUS_SUCCESS)   
            {   
                DbgPrint("PtReceive:NdisAllocateMemory Failed.\n");   
                return(NDIS_STATUS_NOT_ACCEPTED);   
            }   
            if(pBakContent == NULL)   
            {   
                DbgPrint("PTReceive:pPacketContent==NULL\n");   
                return(NDIS_STATUS_NOT_ACCEPTED);   
            }   
            // 将 HeaderBuffer + LookAheadBuffer 复制到 pBakContent 指向的内存中。   
            NdisZeroMemory(pBakContent, BUFFER_SIZE);   
            NdisMoveMemory(pBakContent, HeaderBuffer, HeaderBufferSize);   
            NdisMoveMemory(pBakContent+HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);            
   
            PacketLen = HeaderBufferSize + PacketSize;   
               
            // 为要传输的除 LookAheadBuffer 之外的数据分配缓冲描述符(该缓冲描述符与 pPacketContent 指向的内存关联)。   
            NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketSize-LookAheadBufferSize);   
            // 关联包描述符 MyPacket 与缓冲描述符 pPacketBuffer。   
            NdisChainBufferAtFront(MyPacket, pPacketBuffer);   
            MyPacket->Private.Head->Next=NULL;   
            MyPacket->Private.Tail=NULL;   
   
            OffsetSize = HeaderBufferSize + LookAheadBufferSize;   
               
            // 分配包描述符 MyPacket1。   
            NdisDprAllocatePacket(&Status, &MyPacket1, pAdapt->RecvPacketPoolHandle);   
            // 分配缓冲描述符 pBakBuffer,与 pBakContent 指向的内存关联。   
            NdisAllocateBuffer(&Status, &pBakBuffer, pAdapt->RecvBufferPoolHandle, pBakContent, OffsetSize);   
            // 关联包描述符 MyPacket1 与缓冲描述符 pBakBuffer。   
            NdisChainBufferAtFront(MyPacket1, pBakBuffer);   
   
            Rsvd = (PRSVD)(MyPacket->MiniportReserved);   
            Rsvd->OriginalPkt = (PNDIS_PACKET)MyPacket1;   
   
            NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);   
               
            // 取得 LookAheadBuffer 之后的数据   
            NdisTransferData(&Status,   
                            pAdapt->BindingHandle,   
                            MacReceiveContext,   
                            LookAheadBufferSize,            // 数据起始地址   
                            PacketSize-LookAheadBufferSize, // 字节数   
                            MyPacket,   
                            &BytesTransferred);   
   
            if(Status != NDIS_STATUS_PENDING)   
            {   
                PtTransferDataComplete((NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred);   
            }   
            break;   
        }   
   
        pAdapt->IndicateRcvComplete = TRUE;   
   
    } while(FALSE);   
   
    return Status;   
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 0
活跃值: (984)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
楼主自己调试下看看!看BSOD 后的数据。。
2009-6-4 14:36
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼上的,我已经调过了, 给出的结果就在上面,PtReceive的伪代码哪位大侠能给一下?
2009-6-9 23:11
0
游客
登录 | 注册 方可回帖
返回