深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(3)
2009-09-11 00:00:00 来源:WEB开发网1.4.2.3 PacketAddAdapterNPF函数
函数PacketAddAdapterNPF()向适配器链表g_AdaptersInfoList中添加一个节点。参数AdName是要添加的链表节点的适配器名称。如果函数成功则返回非0值。
其主要代码如下所示:
static BOOLEAN PacketAddAdapterNPF(PCHAR AdName, UINT flags)
{
LONG Status;
LPADAPTER adapter = NULL;
PPACKET_OID_DATA OidData = NULL;
PADAPTER_INFO TmpAdInfo;
PADAPTER_INFO TAdInfo;
/*
*检查ADAPTER_INFO::Name成员是否有足够的空间存储适配器名称
*如果没有,函数返回失败
*/
if (strlen(AdName) + 1 > sizeof(TmpAdInfo->Name))
{
return FALSE;
}
/*获得g_AdaptersInfoMutex互斥信号*/
WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
/*查看适配器的名称是否已在适配器链表中,如是,则函数返回*/
for(TAdInfo = g_AdaptersInfoList; TAdInfo != NULL;
TAdInfo = TAdInfo->Next)
{
if(strcmp(AdName, TAdInfo->Name) == 0)
{// AdName已存在链表中,函数返回
ReleaseMutex(g_AdaptersInfoMutex);
return TRUE;
}
}
//此处不能释放g_AdaptersInfoMutex互斥信号
//如此时有两个线程试图添加同一个适配器,链表中将存在一个适配器的副本
if(flags != INFO_FLAG_DONT_EXPORT)
{ //试图打开NPF适配器,查看它是否可用
//试图打开适配器
adapter = PacketOpenAdapterNPF(AdName);
if(adapter != NULL)
{
//分配一个缓冲区,从驱动程序获得厂商的描述
OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
if (OidData == NULL)
{ //分配失败
PacketCloseAdapter(adapter);
ReleaseMutex(g_AdaptersInfoMutex);
TRACE_EXIT("PacketAddAdapterNPF");
return FALSE;
}
}
else
{
//NPF适配器不可用,不添加到链表中
ReleaseMutex(g_AdaptersInfoMutex);
TRACE_EXIT("AddAdapter");
return FALSE;
}
}
/*
*获得该适配器的PADAPTER_INFO结构体中各成员的值
*/
// PacketOpenAdapter成功,认为这是一个可用的适配器,
//为它在适配器链表中分配一个条目。
TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
if (TmpAdInfo == NULL)
{//内存分配失败,函数返回
…
}
// 复制适配器名称AdName到TmpAdInfo->Name中
strncpy(TmpAdInfo->Name, AdName,
sizeof(TmpAdInfo->Name)/ sizeof(TmpAdInfo->Name[0]) - 1);
//无需给TmpAdInfo->Name添加结束符,
//既然在尾部预留了一个字节,同时分配TmpAdInfo内存时已设为0。
if(flags != INFO_FLAG_DONT_EXPORT)
{
PNPF_IF_ADDRESS_ITEM pAddressesFromRegistry;
//对NIC驱动的查询,获得适配器的描述
OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
OidData->Length = 256;
ZeroMemory(OidData->Data, 256);
Status = PacketRequest(adapter, FALSE, OidData);
if(Status==0 || ((char*)OidData->Data)[0]==0)
{
//不能从NIC驱动程序获得适配器的描述信息
}
//复制设备的描述
strncpy(TmpAdInfo->Description, (PCHAR)OidData->Data,
sizeof(TmpAdInfo->Description)/ sizeof(TmpAdInfo->Description[0]) - 1);
//无需给TmpAdInfo->Name添加结束符,既然在尾部预留了一个
//字节,同时分配TmpAdInfo内存时已设为0。
//从注册表获得一个适配器的NetType结构体,
//该结构体包含适配器的链接类型与速度
Status = PacketGetLinkLayerFromRegistry(adapter, &(TmpAdInfo->LinkLayer));
if (Status == FALSE)
{//失败,函数返回
…
}
//查询NIC驱动程序,获取适配器的MAC地址
// 现在只支持以太网,等待补丁程序支持其它的链路层.
OidData->Oid = OID_802_3_CURRENT_ADDRESS;
OidData->Length = 256;
ZeroMemory(OidData->Data, 256);
Status = PacketRequest(adapter, FALSE, OidData);
if(Status)
{//成功获取MAC地址,地址长度设为6
memcpy(TmpAdInfo->MacAddress, OidData->Data, 6);
TmpAdInfo->MacAddressLen = 6;
}
else
{//获取MAC地址失败,设为00:00:00:00:00:00,长度设为0。
memset(TmpAdInfo->MacAddress, 0, 6);
TmpAdInfo->MacAddressLen = 0;
}
//获取网络地址项PNPF_IF_ADDRESS_ITEM
TmpAdInfo->pNetworkAddresses = NULL;
//从注册表中获取一个适配器的网络地址项
if(!PacketGetAddressesFromRegistry(TmpAdInfo->Name,
&pAddressesFromRegistry))
{
}
else
{
PNPF_IF_ADDRESS_ITEM pCursor;
//把pAddressesFromRegistry追加到链表
//TmpAdInfo->pNetworkAddresses的尾部
if (TmpAdInfo->pNetworkAddresses == NULL)
{
TmpAdInfo->pNetworkAddresses =
pAddressesFromRegistry;
}
else
{
pCursor = TmpAdInfo->pNetworkAddresses;
while(pCursor->Next != NULL)
pCursor = pCursor->Next;
pCursor->Next = pAddressesFromRegistry;
}
}
TmpAdInfo->Flags = INFO_FLAG_NDIS_ADAPTER;
// NdisWan适配器不会被NPF驱动程序导出,
//因此此处不可能见到它们
//释放内存
PacketCloseAdapter(adapter);
GlobalFreePtr(OidData);
}
else
{
//是火线适配器,设置该标识,使后续调用将阻止它
TmpAdInfo->Flags = INFO_FLAG_DONT_EXPORT;
}
/*更新g_AdaptersInfoList 链表*/
TmpAdInfo->Next = g_AdaptersInfoList;
g_AdaptersInfoList = TmpAdInfo;
/*释放g_AdaptersInfoMutex互斥信号*/
ReleaseMutex(g_AdaptersInfoMutex);
return TRUE;
}
- ››深度解释攻击linux服务器的四种级别
- ››剖析java.util.concurrent锁
- ››剖析Android智能手机系统的更多功能
- ››深度分析地方社区网站的内容定位
- ››剖析Windows Azure Platform框架与组成
- ››剖析使用 ObjectOutputStream 可能引起的内存泄漏...
- ››剖析EWebEditor编辑器漏洞攻击案例
- ››剖析开源云:构建 Infrastructure as a Service 块...
- ››深度剖析 Android 和 iPhone OS
- ››深度分析:HTML5能否成为Flash终结者
- ››深度挖掘 更多Windows 7快捷模式
- ››深度挖掘 Windows 7快捷模式
更多精彩
赞助商链接