1.6.4 NPF_Cleanup函数
函数关闭一个驱动程序实例,当一个正在运行的驱动程序实例被用户调用CloseHandle()关闭时,该函数被调用(响应IRP_MJ_CLOSE)。它停止捕获/监视/转储过程,在NPF_CloseBinding函数种调用NdisCloseAdapter函数关闭网络适配器。接着调用NPF_CloseOpenInstance函数释放与该实例相关的内存与资源。
函数原型如下:
NPF_Cleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
参数DeviceObject指向用户使用的设备对象。参数Irp指向包含用户请求的IRP。函数返回操作的状态。
函数的主要代码如下:
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);