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

----------------------------------续前节-------------------------------------- 
// 内存清零
    ZeroMemory(lpAdapter->SymbolicLink, sizeof(lpAdapter->SymbolicLink));
 
    // 看可否直接打开适配器  
lpAdapter->hFile=CreateFileA(SymbolicLinkA,
GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
    if (lpAdapter->hFile != INVALID_HANDLE_VALUE)
    {// 打开成功
 
// 分配与该捕获实例相关联的读事件信号,
// 并把它创地给内核驱动,
// 并存储在该_ADAPTER 结构体中(lpAdapter所指的结构体).
        if(PacketSetReadEvt(lpAdapter)==FALSE){
            // 失败,函数返回NULL
           
            return NULL;
        }      
        // 为驱动程序Packet_tap()(NPF_tap())函数设置最大可能的前视缓冲区
        PacketSetMaxLookaheadsize(lpAdapter);
 
        // 指明这是一个由NPF.sys管理的设备
        lpAdapter->Flags = INFO_FLAG_NDIS_ADAPTER;
        StringCchCopyA(lpAdapter->Name, ADAPTER_NAME_LENGTH,
                            AdapterNameA);
        // 成功打开适配器,返回一个已经正确初始化的ADAPTER对象的指针
        return lpAdapter;
    }
    // 设置错误信息
   
    return NULL;
}
函数首先调用系统函数OpenSCManager()连接到服务控制管理器( service control manager ) ,以检查NPF驱动程序是否已经存在,服务是否正在运行。如果NPF驱动程序不存在,则调用PacketInstallDriver()函数安装驱动程序。如果服务没有运行,则调用StartService()系统函数启动服务。
接下来就可以分配并初始化ADAPTER对象了。设置单个数据包发送的次数为一次,NPF驱动程序依据该值决一个数据包重复发送的次数。
接着从原始的设备名创建NPF设备的名称,并尝试看可否直接打开该适配器,如果打开成功,则分配与该捕获实例相关联的读事件信号,为驱动程序 Packet_tap()(NPF_tap()) 函数设置最大可能的前视缓冲区,然后指明这是一个由NPF.sys管理的设备。
最后返回一个已经正确初始化的ADAPTER对象的指针。
 
注意:前视缓冲区(lookahead buffer)tap()程序能从NIC驱动程序中访问的一部分内存,而不用执行一次内存复制。

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