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

1.6.4       NPF_Cleanup函数

函数关闭一个驱动程序实例,当一个正在运行的驱动程序实例被用户调用CloseHandle()关闭时,该函数被调用(响应IRP_MJ_CLOSE)。它停止捕获/监视/转储过程,在NPF_CloseBinding函数种调用NdisCloseAdapter函数关闭网络适配器。接着调用NPF_CloseOpenInstance函数释放与该实例相关的内存与资源。
函数原型如下:
NTSTATUS
NPF_Cleanup(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );
参数DeviceObject指向用户使用的设备对象。参数Irp指向包含用户请求的IRP。函数返回操作的状态。
函数的主要代码如下:
NTSTATUS
NPF_Cleanup(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
 
    POPEN_INSTANCE    Open;
    NDIS_STATUS     Status;
    PIO_STACK_LOCATION  IrpSp;
    LARGE_INTEGER ThreadDelay;
    ULONG localNumOpenInstances;
 
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
    Open = IrpSp->FileObject->FsContext;
    ASSERT(Open != NULL);
 
    if (Open->ReadEvent != NULL)
        KeSetEvent(Open->ReadEvent,0,FALSE);
 
/* 释放调用NdisOpenAdapter所建立的绑定与分配的资源*/
    NPF_CloseBinding(Open);
       
    /* 释放所有的资源*/  
    NPF_CloseOpenInstance(Open);
 
    IrpSp->FileObject->FsContext = NULL;
   
    /* 递减记录Open实例的计数器*/
    localNumOpenInstances = InterlockedDecrement(&g_NumOpenedInstances);
 
    if(localNumOpenInstances == 0)
    {  
        // 在下一个NPF_Open中强制一个同步
        // 这是为了避免由休眠或挂起 (hibernation or standby) 导致的同步问题
        TIME_DESYNCHRONIZE(&G_Start_Time);
    }
 
    // 完成该IRP,并且为成功的状态   
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
    TRACE_EXIT();
 
    return(STATUS_SUCCESS);
}

你可能感兴趣的:(职场,休闲,winpcap)