深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(8)

来源:互联网 发布:信封制作软件 编辑:程序博客网 时间:2024/05/20 08:42

本文转自http://eslxf.blog.51cto.com/918801/198593

 

1.4.3  PacketGetNetInfoEx函数

函数PacketGetNetInfoEx获得一个适配器的所有地址信息,函数使用结构体npf_if_addr返回与一个适配器相关联的地址信息。函数原型如下:
BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName,
npf_if_addr* buffer, PLONG NEntries)
参数AdapterName字符串是适配器的名称;参数buffer是一个用户分配的npf_if_addr结构体类型的数组,该函数将填充此数组;参数NEntries是数组的大小(npf_if_addr类型计算大小),也就是所存储的npf_if_addr结构体的个数。
如果函数成功返回非0值,否则返回0值。
函数从注册表中获得一个接口的信息,诸如IP地址、网络掩码地址与广播地址。该buffer参数以npf_if_addr结构体来填充,每个结构体都含有一个单独地址的数据。如果buffer满了,余下的地址信息将被丢弃,因此如果只需第一个网络地址,把buffer的大小设为sizeof(npf_if_addr)即可。
函数首先对适配器的名称AdapterName考虑兼容性,必要时提供Unicode字符串到ASCII码字符串的转换。接着在一个类型为ADAPTER_INFO的全局链表g_AdaptersInfoList中更新该适配器的信息。然后在该链表中查找与该适配器关联的PADAPTER_INFO结构体,如果查找成功,则给buffer存储npf_if_addr类型的数据,并返回。
函数的主要代码实现如下:
BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries)
{
    PADAPTER_INFO TAdInfo;
    PCHAR Tname;
    BOOLEAN Res, FreeBuff;
   
    /*提供字符串转换,为了后向兼容。
*WChar2SChar函数把一个Unicode字符串转换为一个ASCII码字符串, *WChar2SChar函数为执行转换分配了新的内存空间,内存需要释放
*/
    if(AdapterName[1] != 0)
    //ASCII字符串
        Tname = AdapterName;
        FreeBuff = FALSE;
    }
    else
    {
        Tname = WChar2SChar((PWCHAR)AdapterName);
        FreeBuff = TRUE; //内存需要释放
    }
 
/*
    *更新该适配器的信息。
    *PacketUpdateAdInfo函数在一个全局ADAPTER_INFO类型的链表*g_AdaptersInfoList中更新一个适配器的信息。
*/
    if(!PacketUpdateAdInfo(Tname))
    {
        //更新失败,函数返回
        if(FreeBuff)
            GlobalFreePtr(Tname);
        return FALSE;
    }
 
/*获得g_AdaptersInfoMutex互斥信号*/
    WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
    /*
*在全局的ADAPTER_INFO链表查找与适配器关联的PADAPTER_INFO结构体
*/
TAdInfo = PacketFindAdInfo(Tname);
    if(TAdInfo != NULL)
    {//查找成功
        LONG numEntries = 0, i;
        PNPF_IF_ADDRESS_ITEM pCursor;
 
        //获取该适配器的npf_if_addr类型的地址链表
        pCursor = TAdInfo->pNetworkAddresses;
        //计算地址链表的元素个数numEntries,
        while(pCursor != NULL)
        {
            numEntries ++;
            pCursor = pCursor->Next;
        }
//且NEntries=min(numEntries, NEntries)
        if (numEntries < *NEntries)
        {
            *NEntries = numEntries;
        }
//给buffer存储npf_if_addr类型的数据
        pCursor = TAdInfo->pNetworkAddresses;
        for (i = 0; (i < *NEntries) && (pCursor != NULL); i++)
        {
            buffer[i] = pCursor->Addr;
            pCursor = pCursor->Next;
        }
 
        Res = TRUE;
    }
    else
    {//查找失败
        TRACE_PRINT("PacketGetNetInfoEx: Adapter not found");
        Res = FALSE;
    }
 
/*释放g_AdaptersInfoMutex互斥信号*/
    ReleaseMutex(g_AdaptersInfoMutex);
   
    if(FreeBuff)
GlobalFreePtr(Tname);
   
    return Res;
}

原创粉丝点击