您的位置:首页 > 数据库

关于写pl/sql的编程的经验总结

2013-11-07 00:12 330 查看

1.5 packet.dll对应的函数接口

下面对各函数在packet.dll中的实现进行详细分析。

1.5.1 关键结构体

[align=left]结构体_ADAPTER描述了一个打开的适配器,该结构体对packet.dll的函数非常重要,不过大部分成员对用户而言都可不用关心,因为该库原本就是为了避免用户处理底层的参数而设计的。该结构体的定义如下:[/align]

[align=left]typedef struct _ADAPTER { [/align]

[align=left] HANDLE hFile; //指向一个NPF驱动程序实例的句柄[/align]
[align=left] CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; //保存当前打开网络适配器的名称[/align]
[align=left] int NumWrites; //对每个数据包重复发送的次数[/align]
[align=left] HANDLE ReadEvent; //与适配器上读调用关联的通知事件[/align]
[align=left] UINT ReadTimeOut; //读超时时间[/align]
[align=left] CHAR Name[ADAPTER_NAME_LENGTH];[/align]
[align=left] PWAN_ADAPTER pWanAdapter;[/align]
[align=left] UINT Flags; //适配器标识[/align]

[align=left]} ADAPTER, *LPADAPTER;[/align]

[align=left]结构体_PACKET包含了从驱动程序来的一组数据包。该结构体定义了与每个递送给应用程序的数据包相关联的包头。结构体的定义如下:[/align]

[align=left]typedef struct _PACKET { [/align]

[align=left] PVOID Buffer; //存储数据包的缓冲区。参见PacketReceivePacket()了解缓冲区中的数据组织形式。[/align]
[align=left] UINT Length; //缓冲区的长度[/align]
[align=left] DWORD ulBytesReceived; //缓冲区中的有效字节数,如最后调用PacketReceivePacket所接收的数据量[/align]

[align=left]} PACKET, *LPPACKET;[/align]

[align=left]结构体_PACKET_OID_DATA包含一个OID请求。它被PacketRequest函数使用来发送一个OID请求给接口卡驱动程序。它也能被用来获取诸如适配器的错误计数、MAC地址、多播列表,等信息。结构体的定义如下:[/align]

[align=left]struct _PACKET_OID_DATA {[/align]

[align=left] ULONG Oid; //OID码。 参见Microsoft DDK文档或文件 ntddndis.h获得一个有效编码的完整列表。[/align]
[align=left] ULONG Length; //Data成员的长度。[/align]
[align=left]UCHAR Data[1]; //变长成员,包含传递到适配器或从适配器接收的信息[/align]
[align=left]}; [/align]

[align=left]typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;[/align]

1.5.2 PacketOpenAdapter函数

在库wpcap.dll中pcap_activate_win32()函数调用PacketOpenAdapter()函数打开适配器。函数PacketOpenAdapter()的作用就是打开一个适配器。函数原型如下:

[align=left]LPADAPTER PacketOpenAdapter(PCHAR AdapterNameWA);[/align]

[align=left]参数AdapterNameWA字符串包含待打开设备的名称。函数调用PacketOpenAdapterNPF()函数获取可用的设备列表。[/align]
[align=left]函数如果成功,返回一个已经正确初始化的ADAPTER对象的指针。否则返回NULL。[/align]
[align=left]函数的主要代码如下:[/align]

[align=left]LPADAPTER PacketOpenAdapter(PCHAR AdapterNameWA)[/align]

[align=left]{[/align]
[align=left] … [/align]
[align=left] /*检查适配器的名称是否为ASCII码字符串,如果不是,执行转换*/[/align]
[align=left] if(AdapterNameWA[1]!=0)[/align]
[align=left] { //是ASCII码字符串[/align]
[align=left] bFreeAdapterNameA = FALSE;[/align]
[align=left] AdapterNameA = AdapterNameWA;[/align]
[align=left] } [/align]
[align=left] else [/align]
[align=left] { //是Unicode码字符串,转换为ASCII码字符串[/align]
[align=left] size_t bufferSize = wcslen((PWCHAR)AdapterNameWA) + 1;[/align]
[align=left] AdapterNameA = GlobalAllocPtr(GPTR, bufferSize);[/align]
[align=left] [/align]
[align=left] if (AdapterNameA == NULL)[/align]
[align=left] {//分配错误,函数返回[/align]
[align=left] SetLastError(ERROR_NOT_ENOUGH_MEMORY);[/align]
[align=left] return NULL;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] StringCchPrintfA(AdapterNameA, bufferSize, "%ws", [/align]
[align=left] (PWCHAR)AdapterNameWA);[/align]
[align=left] bFreeAdapterNameA = TRUE;[/align]
[align=left] }[/align]
[align=left]/*获得g_AdaptersInfoMutex互斥信号*/[/align]
[align=left] WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);[/align]
[align=left] [/align]
[align=left]/*查找适配器,并打开它*/[/align]
[align=left] do[/align]
[align=left] { [/align]
[align=left] //第一次查找给定适配器的PADAPTER_INFO结构体[/align]
[align=left] TAdInfo = PacketFindAdInfo(AdapterNameA);[/align]
[align=left] if(TAdInfo == NULL)[/align]
[align=left] {//没有找到,更新链表,然后执行第二次查找[/align]
[align=left] PacketUpdateAdInfo(AdapterNameA);[/align]
[align=left] TAdInfo = PacketFindAdInfo(AdapterNameA);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] if(TAdInfo == NULL)[/align]
[align=left] {//出错处理,跳出do…while循环[/align]
[align=left]…[/align]
[align=left] break;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]//找到适配器,检查适配器的类型,查看它是否被正确的支持,[/align]
[align=left]//此处我们只考虑正常的NPF适配器[/align]
[align=left]#ifdef HAVE_WANPACKET_API[/align]
[align=left] if(TAdInfo->Flags == INFO_FLAG_NDISWAN_ADAPTER)[/align]
[align=left] {[/align]
[align=left] …[/align]
[align=left] break;[/align]
[align=left] }[/align]
[align=left]#endif //HAVE_WANPACKET_API[/align]
[align=left]…[/align]
[align=left] [/align]
[align=left] if(TAdInfo->Flags == INFO_FLAG_DONT_EXPORT)[/align]
[align=left] {[/align]
[align=left] //该适配器不允许被导出,跳出循环[/align]
[align=left]… [/align]
[align=left]break;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] if (TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER)[/align]
[align=left] {//打开不明标识的适配器,跳出循环[/align]
[align=left]…[/align]
[align=left] break;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] //正常的NPF适配器,试图打开它 [/align]
[align=left] lpAdapter = PacketOpenAdapterNPF(AdapterNameA);[/align]
[align=left] if (lpAdapter == NULL)[/align]
[align=left] {//打开失败[/align]
[align=left] dwLastError = GetLastError();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] }while(FALSE);[/align]
[align=left] [/align]
[align=left]/*释放g_AdaptersInfoMutex互斥信号*/[/align]
[align=left] ReleaseMutex(g_AdaptersInfoMutex);[/align]
[align=left] [/align]
[align=left] /*如果执行了Unicode转换,释放所用的内存*/[/align]
[align=left] if (bFreeAdapterNameA) [/align]
[align=left]GlobalFree(AdapterNameA);[/align]
[align=left] [/align]
[align=left] /*函数返回*/[/align]
[align=left] if (dwLastError != ERROR_SUCCESS)[/align]
[align=left] {//函数失败,返回NULL[/align]
[align=left] SetLastError(dwLastError);[/align]
[align=left] return NULL;[/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {//函数成功,返回所打开的适配器关联的结构体指针[/align]
[align=left] return lpAdapter;[/align]
[align=left] }[/align]

[align=left]}[/align]

函数首先检查适配器的名称是否为ASCII码字符串,如果不是,执行Unicode码到ASCII码的转换。
[align=left]然后获得g_AdaptersInfoMutex互斥信号,调用PacketFindAdInfo()函数开始在g_AdaptersInfoList链表中查找适配器。如果第一次没有查到,调用PacketUpdateAdInfo()函数更新该链表,执行第二次查找。[/align]
[align=left]如果找到适配器,检查适配器的类型,查看它是否被正确的支持,我们只考虑正常的NPF适配器。[/align]
如果是正常的NPF适配器,调用PacketOpenAdapterNPF()函数打开它。
然后释放g_AdaptersInfoMutex互斥信号,如果执行了Unicode转换,释放所用的内存。
最后,如果函数成功,则返回与打开适配器关联的结构体指针lpAdapter,否则返回NULL。
本文出自 “千江月” 博客,请务必保留此出处http://eslxf.blog.51cto.com/918801/205042
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: