本文转自http://eslxf.blog.51cto.com/918801/209118
1.5.2.1.4 PacketAllocatePacket 与PacketFreePacket函数
函数PacketAllocatePacket分配一个_ADAPTER结构体内存空间,函数原型如下:
LPPACKET PacketAllocatePacket(void)
函数成功就放回所指向所分配的_ADAPTER结构体指针。函数主要由下面的代码实现:
lpPacket=(LPPACKET)GlobalAllocPtr( GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(PACKET) );
返回的结构体传递给PacketReceivePacket()从驱动程序接收数据包。
注意:_PACKET 结构体的Buffer成员不是由该函数设置的,该缓冲区必须由应用程序分配,并调用PacketInitPacket函数把该缓冲区与该_PACKET结构体相关联。
而函数PacketFreePacket释放一个_ADAPTER结构体内存空间,函数原型如下:
VOID PacketFreePacket(LPPACKET lpPacket);
参数lpPacket为所要释放的结构体的指针。
函数主要由下面的代码实现:
GlobalFreePtr(lpPacket);
注意:用户层所分配的与该_PACKET结构体相关联的缓冲区,并不在该函数中释放,该缓冲区必须显式的由程序员释放。
下面来看看在wpcap.dll中的实际使用情况:
static int pcap_activate_win32(pcap_t *p){//pcap_open最终会调用该函数
…
/*设置缓冲区大小*/
p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
/*分配在捕获过程中使用的数据包结构体*/
if((p->Packet = PacketAllocatePacket())==NULL)
{
}
/*分配在捕获过程中使用的缓冲区*/
p->buffer = (u_char *)malloc(p->bufsize);
/*初始化捕获过程中使用的数据包结构体,并把缓冲区与该_PACKET结构体相关联*/
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
…
}
static void pcap_cleanup_win32(pcap_t *p) //pcap_close最终会调用该函数
{
…
if (p->Packet) {
PacketFreePacket(p->Packet); /*释放捕获过程中使用的数据包结构体*/
p->Packet = NULL;
}
pcap_cleanup_live_common(p);
}
void pcap_cleanup_live_common(pcap_t *p)
{
if (p->buffer != NULL) {
free(p->buffer);//释放该缓冲区
…
}