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

 /*如果成功,则给全局记录打开实例的计数器原子操作加一,然后获取设备的最大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实例。

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