深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(5)
2010-06-22 23:20
417 查看
本文转自http://eslxf.blog.51cto.com/918801/198586
st1/:*{behavior:url(#ieooui) }
参数pStr是用户分配的字符串,用来存储适配器的名称。参数BufferSize是pStr所指缓冲区的长度。
如果函数失败,该变量返回存储适配器列表所需的字节数。如果函数成功,返回非0值。
如果返回值为0,BufferSize返回存储适配器列表所需的字节数。
通常,这是第一个与驱动程序通信的函数。它返回系统上所安装的WinPcap能支持的适配器名称。在适配器的名称之后,pStr包含一个字符串用对每一个适配器进行描述。在调用PacketGetAdapterNames函数后,pStr字符串的格式如下所示:
Ø 一些数量的ASCII字符串,每个适配器的名称之间由一个"/0"分开
Ø 两个"/0"
Ø 许多ASCII字符串,之间由一个"/0"分隔,每一个描述一个对应适配器。描述的数量与名称的数量一样。第一个描述对应于第一个名称,以此类推。
Ø 两个"/0"
packetNtx/Dll/Packet32.c:3616-3723
BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize)
{
…
/*创建适配器链表*/
PacketPopulateAdaptersInfoList();
/*获得g_AdaptersInfoMutex互斥信号*/
WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
if(!g_AdaptersInfoList)
{ //失败系统中没有找到适配器,函数返回
…
}
/*
*填充pStr中适配器的名称与描述两个列表
*/
//第一次遍历g_AdaptersInfoList,
//为了计算第二个列表开始的偏移与检查缓冲区的大小
for (TAdInfo = g_AdaptersInfoList; TAdInfo != NULL;
TAdInfo = TAdInfo->Next)
{
if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT)
{
// 更新有关大小的变量值
SizeNeeded += (ULONG)strlen(TAdInfo->Name) +
(ULONG)strlen(TAdInfo->Description) + 2;
SizeNames += (ULONG)strlen(TAdInfo->Name) + 1;
}
}
//检查缓冲区大小,以防缓冲区溢出。
//注意:需要2个额外的分隔符(两个列表间一个’/0’,
//第二个列表结束时的一个’/0’)
if(SizeNeeded + 2 > *BufferSize || pStr == NULL)
{
ReleaseMutex(g_AdaptersInfoMutex);
*BufferSize = SizeNeeded + 2; //报告所需的缓冲区大小
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
OffDescriptions = SizeNames + 1;//第二个列表开始的偏移
//第二次遍历g_AdaptersInfoList,为了复制适配器的信息
for(TAdInfo = g_AdaptersInfoList, SizeNames = 0, SizeDesc = 0;
TAdInfo != NULL; TAdInfo = TAdInfo->Next)
{
if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT)
{
// 复制数据
StringCchCopyA( ((PCHAR)pStr) + SizeNames,
*BufferSize - SizeNames, TAdInfo->Name);
StringCchCopyA( ((PCHAR)pStr) + OffDescriptions + SizeDesc,
*BufferSize - OffDescriptions - SizeDesc,
TAdInfo->Description);
// 更新有关大小的变量值
SizeNames += (ULONG)strlen(TAdInfo->Name) + 1;
SizeDesc += (ULONG)strlen(TAdInfo->Description) + 1;
}
}
//分隔两个列表
((PCHAR)pStr)[SizeNames] = 0;
// 添加一个/0,结束列表
((PCHAR)pStr)[SizeNeeded + 1] = 0;
//释放g_AdaptersInfoMutex互斥信号
ReleaseMutex(g_AdaptersInfoMutex);
return TRUE;
}
函数首先调用PacketPopulateAdaptersInfoList()函数创建适配器链表g_AdaptersInfoList。接着开始给pStr中填充适配器的名称与描述两个列表,在填充的过程中,需要遍历g_AdaptersInfoList两次,第一次遍历是为了计算第二个列表开始的偏移与检查缓冲区的大小,第二次遍历是为了复制适配器的名称与描述信息。复制数据结束后,在两个列表之间加入分隔符’/0’,并在第二个列表之后添加一个’/0’结束列表。
st1/:*{behavior:url(#ieooui) }
1.4.2 PacketGetAdapterNames函数
函数PacketGetAdapterNames获取可用网络适配器的一个列表与它们的描述。参数pStr是用户分配的字符串,用来存储适配器的名称。参数BufferSize是pStr所指缓冲区的长度。
如果函数失败,该变量返回存储适配器列表所需的字节数。如果函数成功,返回非0值。
如果返回值为0,BufferSize返回存储适配器列表所需的字节数。
通常,这是第一个与驱动程序通信的函数。它返回系统上所安装的WinPcap能支持的适配器名称。在适配器的名称之后,pStr包含一个字符串用对每一个适配器进行描述。在调用PacketGetAdapterNames函数后,pStr字符串的格式如下所示:
Ø 一些数量的ASCII字符串,每个适配器的名称之间由一个"/0"分开
Ø 两个"/0"
Ø 许多ASCII字符串,之间由一个"/0"分隔,每一个描述一个对应适配器。描述的数量与名称的数量一样。第一个描述对应于第一个名称,以此类推。
Ø 两个"/0"
packetNtx/Dll/Packet32.c:3616-3723
BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize)
{
…
/*创建适配器链表*/
PacketPopulateAdaptersInfoList();
/*获得g_AdaptersInfoMutex互斥信号*/
WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);
if(!g_AdaptersInfoList)
{ //失败系统中没有找到适配器,函数返回
…
}
/*
*填充pStr中适配器的名称与描述两个列表
*/
//第一次遍历g_AdaptersInfoList,
//为了计算第二个列表开始的偏移与检查缓冲区的大小
for (TAdInfo = g_AdaptersInfoList; TAdInfo != NULL;
TAdInfo = TAdInfo->Next)
{
if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT)
{
// 更新有关大小的变量值
SizeNeeded += (ULONG)strlen(TAdInfo->Name) +
(ULONG)strlen(TAdInfo->Description) + 2;
SizeNames += (ULONG)strlen(TAdInfo->Name) + 1;
}
}
//检查缓冲区大小,以防缓冲区溢出。
//注意:需要2个额外的分隔符(两个列表间一个’/0’,
//第二个列表结束时的一个’/0’)
if(SizeNeeded + 2 > *BufferSize || pStr == NULL)
{
ReleaseMutex(g_AdaptersInfoMutex);
*BufferSize = SizeNeeded + 2; //报告所需的缓冲区大小
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
OffDescriptions = SizeNames + 1;//第二个列表开始的偏移
//第二次遍历g_AdaptersInfoList,为了复制适配器的信息
for(TAdInfo = g_AdaptersInfoList, SizeNames = 0, SizeDesc = 0;
TAdInfo != NULL; TAdInfo = TAdInfo->Next)
{
if(TAdInfo->Flags != INFO_FLAG_DONT_EXPORT)
{
// 复制数据
StringCchCopyA( ((PCHAR)pStr) + SizeNames,
*BufferSize - SizeNames, TAdInfo->Name);
StringCchCopyA( ((PCHAR)pStr) + OffDescriptions + SizeDesc,
*BufferSize - OffDescriptions - SizeDesc,
TAdInfo->Description);
// 更新有关大小的变量值
SizeNames += (ULONG)strlen(TAdInfo->Name) + 1;
SizeDesc += (ULONG)strlen(TAdInfo->Description) + 1;
}
}
//分隔两个列表
((PCHAR)pStr)[SizeNames] = 0;
// 添加一个/0,结束列表
((PCHAR)pStr)[SizeNeeded + 1] = 0;
//释放g_AdaptersInfoMutex互斥信号
ReleaseMutex(g_AdaptersInfoMutex);
return TRUE;
}
函数首先调用PacketPopulateAdaptersInfoList()函数创建适配器链表g_AdaptersInfoList。接着开始给pStr中填充适配器的名称与描述两个列表,在填充的过程中,需要遍历g_AdaptersInfoList两次,第一次遍历是为了计算第二个列表开始的偏移与检查缓冲区的大小,第二次遍历是为了复制适配器的名称与描述信息。复制数据结束后,在两个列表之间加入分隔符’/0’,并在第二个列表之后添加一个’/0’结束列表。
相关文章推荐
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(2)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(6)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(3)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(7)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(4)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(1)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(6)
- 深度剖析WinPcap-获得与释放网络适配器设备列表
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(2)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(7)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(3)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(8)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(8)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(4)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(9)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(1)
- 深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(9)
- 深度剖析WinPcap之(七)――获得与释放网络适配器设备列表(5)
- WinPcap基础知识(第一课:获得设备列表)
- 深度剖析WinPcap之(四)——WinPcap的体系架构(1)