1.4.2.1     PacketPopulateAdaptersInfoList函数

函数PacketPopulateAdaptersInfoList()创建适配器的链表g_AdaptersInfoList。该函数先释放掉g_AdaptersInfoList中旧的内容,然后调用PacketGetAdaptersNPF()函数用新的信息填充该链表。

其主要代码如下所示:

void PacketPopulateAdaptersInfoList()

{

    …

/*获得g_AdaptersInfoMutex互斥信号*/

    WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);

 

    /*释放g_AdaptersInfoList中旧的内容*/

    if(g_AdaptersInfoList)

    {

        TAdInfo = g_AdaptersInfoList;

        while(TAdInfo != NULL) //遍历链表

        {

            PNPF_IF_ADDRESS_ITEM pItem, pCursor;

            Mem2 = TAdInfo;

           

            pCursor = TAdInfo->pNetworkAddresses;

            TAdInfo = TAdInfo->Next;

           

            while(pCursor != NULL)

            {

                pItem = pCursor->Next;

                GlobalFreePtr(pCursor); //释放内存

                pCursor = pItem;

            }

            GlobalFreePtr(Mem2);  //释放内存

        }

       

        g_AdaptersInfoList = NULL;

    }

 

   

    /*用新的信息填充链表*/

    if(!PacketGetAdaptersNPF())

    {   //失败

       

    }

//释放g_AdaptersInfoMutex互斥信号

    ReleaseMutex(g_AdaptersInfoMutex);

}

 

1.4.2.2     PacketGetAdaptersNPF函数

函数PacketGetAdaptersNPF()通过查询注册表的"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"条目获得适配器的名称,并调用PacketAddAdapterNPF()函数来更新适配器链表g_AdaptersInfoList的内容。如果函数成功则返回非0值。

其主要代码如下所示:

static BOOLEAN PacketGetAdaptersNPF()

{

    … 

    /*打开注册表*/

    Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,     TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),

        0,

        KEY_READ,

        &AdapKey);

   

    if ( Status != ERROR_SUCCESS ){

//打开注册表{4D36E972-E325-11CE-BFC1-08002BE10318}条目失败

        goto tcpip_linkage;

    }

 

    i = 0;

   

    /*遍历{4D36E972-E325-11CE-BFC1-08002BE10318}键,获取适配器的名称*/

    while((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2))

== ERROR_SUCCESS)

    {

        i++;

        FireWireFlag = 0;

       

        //从注册表键中获取适配器的名称

        Status=RegOpenKeyEx(AdapKey, AdapName, 0, KEY_READ, &OneAdapKey);

        if ( Status != ERROR_SUCCESS )

        {//失败

            continue;          

        }

 

        /*

*检查该适配器是否为火线(FireWire)适配器,

*通过在ComponentId中查找“ 1394” 字符串判断。防止列出火线适配器,

*因为WinPcap能够打开它们,但是它们与操作系统的接口被断开了,

*打开它们会导致蓝屏。

*/

        dim = sizeof(TName);

        Status = RegQueryValueEx(OneAdapKey,

            TEXT("ComponentId"),

            NULL,

            NULL,

            (PBYTE)TName,

            &dim);

 

        if(Status == ERROR_SUCCESS)

        {

            if(IsFireWire(TName))

            {

                FireWireFlag = INFO_FLAG_DONT_EXPORT;//设置不导出标志

            }

        }

 

        Status=RegOpenKeyEx(OneAdapKey, TEXT("Linkage"), 0, KEY_READ,

 &LinkageKey);

        if (Status != ERROR_SUCCESS)

        { //失败

            RegCloseKey(OneAdapKey);           

            continue;

        }

       

        dim = sizeof(DeviceGuidName);

        Status=RegQueryValueExA(LinkageKey,

            "Export",

            NULL,

            NULL,

            (PBYTE)DeviceGuidName,

            &dim);

 

        if(Status != ERROR_SUCCESS)

        {

            RegCloseKey(OneAdapKey);

            RegCloseKey(LinkageKey);

            continue;

        }

 

        if (strlen(DeviceGuidName) >= strlen("\\Device\\"))

        {

            // 把\Device\NPF_ 字符串放置到名称的开始

            StringCchPrintfA(TAName, sizeof(TAName), "%s%s",

                            npfCompleteDriverPrefix,

                            DeviceGuidName + strlen("\\Device\\"));

        }

        else

            continue;

 

        //给TAName最后一个字符设为结束符’\ 0’ ,为了以防万一

        TAName[sizeof(TAName) - 1] = '\0';

 

       

//成功获取适配器的信息,把给适配器的信息添加到全局适配器链表

        PacketAddAdapterNPF(TAName, FireWireFlag);

 

        RegCloseKey(OneAdapKey);

        RegCloseKey(LinkageKey);       

    }

 

    RegCloseKey(AdapKey);

 

/*

*如果在{4D36E972-E325-11CE-BFC1-08002BE10318}没找到适配器,

*这在Windows NT 4下可能性很大,

*因此试图查找tcpip绑定来获得适配器的信息

*/

tcpip_linkage:

    … 

    return TRUE;

}

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