您的位置:首页 > 理论基础 > 计算机网络

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

2010-06-22 23:29 441 查看
本文转自http://eslxf.blog.51cto.com/918801/198589



st1/:*{behavior:url(#ieooui) }


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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐