深度剖析WinPcap之(八)——打开与关闭适配器(24)

本文转自http://eslxf.blog.51cto.com/918801/211969

 

1.6.4.1        NPF_CloseBinding函数
函数主要释放调用NdisOpenAdapter所建立的绑定与分配的资源。
函数代码实现如下:
VOID NPF_CloseBinding(IN POPEN_INSTANCE pOpen)
{
    NDIS_EVENT Event;
    NDIS_STATUS Status;
 
    ASSERT(pOpen != NULL);
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
 
    NdisInitializeEvent(&Event);
    NdisResetEvent(&Event);
 
    NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
 
    while(pOpen->AdapterHandleUsageCounter > 0)
    {
        NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
        NdisWaitEvent(&Event,1);
        NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
    }
 
    /*现在使用计数为0*/
    while(pOpen->AdapterBindingStatus == ADAPTER_UNBINDING)
    {
        NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
        NdisWaitEvent(&Event,1);
        NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
    }
 
    /*现在绑定状态可能为绑定也可能为未绑定*/
    if (pOpen->AdapterBindingStatus == ADAPTER_UNBOUND)
    {
        NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
        return;
    }
 
    ASSERT(pOpen->AdapterBindingStatus == ADAPTER_BOUND);
 
    pOpen->AdapterBindingStatus = ADAPTER_UNBINDING;
    NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
   
    /*执行释放过程*/
    NdisResetEvent(&pOpen->NdisOpenCloseCompleteEvent);
 
    //释放调用NdisOpenAdapter所建立的绑定与分配的资源
    NdisCloseAdapter(
        &Status,
        pOpen->AdapterHandle
        );
 
    //检测是否为挂起状态
    if (Status == NDIS_STATUS_PENDING)
       { //挂起,等待NdisOpenCloseCompleteEvent事件,
//在完成函数NPF_CloseAdapterComplete中设置该事件
        NdisWaitEvent(&pOpen->NdisOpenCloseCompleteEvent, 0);
    }
    else
    {
        ;
    }
 
    /*设置绑定状态为未绑定*/
    NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
    pOpen->AdapterBindingStatus = ADAPTER_UNBOUND;
    NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
}
 
1.6.4.2 NPF_CloseAdapterComplete
函数结束适配器的关闭,为NDIS函数NdisCloseAdapter关联的回调函数,当NIC驱动程序完成一个关闭操作(在NPF_CloseBinding中调用NdisCloseAdapter启动关闭操作)后被NDIS调用。
函数原型如下:
VOID
NPF_CloseAdapterComplete(
    IN NDIS_HANDLE  ProtocolBindingContext,
    IN NDIS_STATUS  Status
    );
参数ProtocolBindingContext为函数的上下文,包含一个指向与当前实例关联的OPEN_INSTANCE结构体指针。参数StatusNDIS执行关闭操作的状态。
函数的主要代码如下:
VOID NPF_CloseAdapterComplete(IN NDIS_HANDLE  ProtocolBindingContext,
IN NDIS_STATUS  Status)
{
    POPEN_INSTANCE    Open;
    PIRP              Irp;
 
    Open = (POPEN_INSTANCE)ProtocolBindingContext;
     ASSERT(Open != NULL);
/*设置NdisOpenCloseCompleteEvent事件,*/
     NdisSetEvent(&Open->NdisOpenCloseCompleteEvent);
     TRACE_EXIT();
     return;
}
 
1.6.4.3        NPF_CloseOpenInstance函数
//释放调用NdisOpenAdapter所建立的绑定与分配的资源
函数的主要代码如下:
VOID NPF_CloseOpenInstance(POPEN_INSTANCE pOpen)
{
        PKEVENT pEvent;
        UINT i;    
 
        ASSERT(pOpen != NULL);
        ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
 
        TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", pOpen);
/*释放为数据包接收与发送所分配的内存缓冲池*/
        NdisFreePacketPool(pOpen->PacketPool);
 
        /*释放过滤器,如果存在*/
        if(pOpen->bpfprogram != NULL)
            ExFreePool(pOpen->bpfprogram);
 
// Jitted 过滤器仅仅被x86(32)架构支持//
#ifdef _X86_
        /*释放jitted过滤器,如果存在*/
        if(pOpen->Filter != NULL)
            BPF_Destroy_JIT_Filter(pOpen->Filter);
#endif //_X86_
 
        /*递减ReadEvent事件对象的引用计数,并执行保留状态检查*/
        if (pOpen->ReadEvent != NULL)
            ObDereferenceObject(pOpen->ReadEvent);
 
        /*释放缓冲区*/
        // 注意:该缓冲区在各CPU间被分割成片,但是所分配的大块内存的基地址仍然存储在第一个位置(pOpen->CpuData[0])
        if (pOpen->Size > 0)
            ExFreePool(pOpen->CpuData[0].Buffer);
 
        /* 释放CPU自旋锁*/
        for (i = 0; i < g_NCpu; i++)
        {
            NdisFreeSpinLock(&Open->CpuData[i].BufferLock);
        }
 
        /*释放存储转储文件名的字符串*/
        if(pOpen->DumpFileName.Buffer!=NULL)
            ExFreePool(pOpen->DumpFileName.Buffer);
       
        /*释放open实例的内存空间*/
        ExFreePool(pOpen);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值