/*如果成功,则给全局记录打开实例的计数器原子操作加一,然后获取设备的最大MTU*/

    if (returnStatus == STATUS_SUCCESS)

    { //完成打开网络设备

        ULONG localNumOpenedInstances; 

        //给全局记录打开实例的计数器原子操作加一

localNumOpenedInstances = InterlockedIncrement(&g_NumOpenedInstances);

        //获得系统启动以来的时间绝对值,用于时间装换

        TIME_SYNCHRONIZE(&G_Start_Time);

        //获取设备的最大MTU

        returnStatus = NPF_GetDeviceMTU(Open, Irp, &Open->MaxFrameSize);

 

        if (!NT_SUCCESS(returnStatus))

        {//获取失败,关闭绑定

            NPF_CloseBinding(Open);

        }

    }

    /*如果成功,则把Open实例保存到IrpSp->FileObject->FsContext*/

    if (!NT_SUCCESS(returnStatus))

    {

        NPF_CloseOpenInstance(Open);

    }

    else

    {

        //  此处保存Open

        IrpSp->FileObject->FsContext=Open;

    }

 

    Irp->IoStatus.Status = returnStatus;

    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

 

    return returnStatus;

}

函数NPF_open首先获得_DEVICE_EXTENSION结构体指针,在后面赋给Open->DeviceExtension接着获得IRP中的调用者栈的位置。然后分配内存空间给Open结构体,并对所分配的内存清零,接着为数据包的接收与发送分配一个数据包内存缓冲池。

开始初始化Open结构体的各种事件,与各种自旋锁,初始化设置open实例的其它成员。

然后试图打开网络设备,在调用的协议与一个特定底层NIC驱动程序或NDIS中间层驱动程序之间建立绑定。检查NdisOpenAdapter函数返回是否为挂起状态,如果是,则等待打开完成事件。如果绑定成功,则给全局记录打开实例的计数器原子操作加一,然后调用NPF_GetDeviceMTU函数获取设备的最大MTU。如果该调用成功,则把Open实例保存到IrpSp->FileObject->FsContext,以便其它函数调用。比如在NPF_Cleanup函数中使用Open = IrpSp->FileObject->FsContext;语句获得Open实例。

本文出自 “千江月” 博客,请务必保留此出处http://eslxf.blog.51cto.com/918801/210887