深度剖析WinPcap之(八)——打开与关闭适配器(26)(完)
来源:互联网 发布:建筑拆除优化设计 编辑:程序博客网 时间:2024/05/18 13:08
本文转自 http://eslxf.blog.51cto.com/918801/211973
/*#define BIOCSETBUFFERSIZE 9592
该IOCTL命令码用来设置内核缓冲区大小。
该IOCTL用来设置一个NPF实例的循环缓冲区的大小,当接收到一个BIOCSETBUFFERSIZE命令时,驱动程序释放老的缓冲区,分配一个新的缓冲区,并在OPEN_INSTANCE结构体中复位与该缓冲区相关的所有参数。
当前缓冲的所有数据包都被丢弃。
*/
case BIOCSETBUFFERSIZE:
/*验证输入参数的合法性*/
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(ULONG))
{
SET_FAILURE_BUFFER_SMALL();
break;
}
//获得所需分配缓冲区的字节数
dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
if (dim / g_NCpu < sizeof(struct PacketHeader))
{
dim = 0;
}
else
{
tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA');
if (tpointer == NULL)
{//没有内存
SET_FAILURE_NOMEM();
break;
}
}
/*获得所有缓冲区的锁*/
for (i = 0; i < g_NCpu ; i++)
{
#pragma prefast(suppress:8103,
"There's no Spinlock leak here, as it's released some lines below.")
NdisAcquireSpinLock(&Open->CpuData[i].BufferLock);
}
/*如果有旧的缓冲区,就释放掉*/
if (Open->CpuData[0].Buffer != NULL)
{
ExFreePool(Open->CpuData[0].Buffer);
}
/*在OPEN_INSTANCE结构体中复位相关的所有参数*/
for (i = 0 ; i < g_NCpu ; i++)
{
if (dim > 0)
Open->CpuData[i].Buffer=
(PUCHAR)tpointer + (dim/g_NCpu)*i;
else
Open->CpuData[i].Buffer = NULL;
Open->CpuData[i].Free = dim/g_NCpu;
Open->CpuData[i].P = 0;
Open->CpuData[i].C = 0;
Open->CpuData[i].Accepted = 0;
Open->CpuData[i].Dropped = 0;
Open->CpuData[i].Received = 0;
}
Open->ReaderSN=0;
Open->WriterSN=0;
Open->Size = dim/g_NCpu;
/*释放所有缓冲区的锁*/
i = g_NCpu;
do
{
i--;
#pragma prefast(suppress:8107,
"There's no Spinlock leak here, as it's acquired some lines above.")
NdisReleaseSpinLock(&Open->CpuData[i].BufferLock);
}while(i != 0);
SET_RESULT_SUCCESS(0);
break;
/*#define BIOCSETEVENTHANDLE 7920
该IOCTL命令码用来把用户(packet.dll)所分配的读事件句柄传递给内核层。
参数:HANDLE
参数为size为句柄的大小sizeof(HANDLE)。*/
case BIOCSETEVENTHANDLE:
/*验证输入参数的合法性*/
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength !=
sizeof (hUserEvent))
{
SET_FAILURE_INVALID_REQUEST();
break;
}
hUserEvent = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;
/* 对hUserEvent进行访问授权确认,如果访问被授权,就返回该对象体对应的指针pKernelEvent。*/
Status = ObReferenceObjectByHandle(hUserEvent,
EVENT_MODIFY_STATE, *ExEventObjectType, Irp->RequestorMode,
(PVOID*) &pKernelEvent, NULL);
if (!NT_SUCCESS(Status))
{
// Status = ??? already set
Information = 0;
break;
}
/* 如果&Open->ReadEvent等于NULL,就把Open->ReadEvent赋为pKernelEvent,否则Open->ReadEvent值不改变。*/
if (InterlockedCompareExchangePointer(&Open->ReadEvent,
pKernelEvent, NULL) != NULL)
{ //释放pKernelEvent
ObDereferenceObject(pKernelEvent);
SET_FAILURE_INVALID_REQUEST();
break;
}
//把ReadEvent复位为非激活状态
KeResetEvent(Open->ReadEvent);
SET_RESULT_SUCCESS(0);
break;
…
}
- 深度剖析WinPcap之(八)——打开与关闭适配器(26)(完)
- 深度剖析WinPcap之(八)——打开与关闭适配器(1)
- 深度剖析WinPcap之(八)——打开与关闭适配器(2)
- 深度剖析WinPcap之(八)——打开与关闭适配器(3)
- 深度剖析WinPcap之(八)——打开与关闭适配器(4)
- 深度剖析WinPcap之(八)——打开与关闭适配器(5)
- 深度剖析WinPcap之(八)——打开与关闭适配器(6)
- 深度剖析WinPcap之(八)——打开与关闭适配器(7)
- 深度剖析WinPcap之(八)——打开与关闭适配器(8)
- 深度剖析WinPcap之(八)——打开与关闭适配器(9)
- 深度剖析WinPcap之(八)——打开与关闭适配器(10)
- 深度剖析WinPcap之(八)——打开与关闭适配器(11)
- 深度剖析WinPcap之(八)——打开与关闭适配器(12)
- 深度剖析WinPcap之(八)——打开与关闭适配器(13)
- 深度剖析WinPcap之(八)——打开与关闭适配器(14)
- 深度剖析WinPcap之(八)——打开与关闭适配器(15)
- 深度剖析WinPcap之(八)——打开与关闭适配器(16)
- 深度剖析WinPcap之(八)——打开与关闭适配器(17)
- Spring,struts,hibernate常见的面试笔试题汇总(2)
- SQL Server2005 中的权限管理
- 深度剖析WinPcap之(八)——打开与关闭适配器(25)
- MFC程序简单的实现XP风格(转载)
- 一个挺好的期刊杂志浏览网站
- 深度剖析WinPcap之(八)——打开与关闭适配器(26)(完)
- C# BackGroundWorker 的简单使用
- SQL中的left outer join,inner join,right outer join用法
- C# 实现Smart Device WIFI 的打开/关闭
- volatile的作用
- 深度剖析WinPcap之(九)——数据包的发送过程(1)
- 深度剖析WinPcap之(九)——数据包的发送过程(2)
- FINAL的使用节省时间
- 最大信息熵原理