深度剖析WinPcap之(六)——驱动程序的初始化与清除 (3)
2009-09-11 00:00:00 来源:WEB开发网1.3.3 NPF_CreateDevice函数
函数NPF_CreateDevice对一个给定的MAC创建一个设备。NPF驱动程序也调用NPF_CreateDevice函数,通过IoCreateDevice系统接口把Open/close,read/write与IOCTL请求的句柄地址传递给操作系统。
函数原型如下:
BOOLEAN
NPF_CreateDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP
)
参数adriverObjectP是用来与设备相关联的驱动对象,例如NPF的一个实例。参数 amacNameP是所创建设备将要指向的网络接口名称。
如果函数成功,返回非0值。
NPF对每一个可用的网络适配器只创建一个设备。该新设备指向该NPF驱动程序,但包含关于原始设备的信息。通过这种方式,当用户打开该新设备时,NPF将能够确定使用正确的适配器。
函数的主要代码如下:
BOOLEAN NPF_CreateDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP)
{
NTSTATUS status;
PDEVICE_OBJECT devObjP;
UNICODE_STRING deviceName;
UNICODE_STRING deviceSymLink;
/*检查amacNameP->Buffer是否包含合法的 “\\Device\\”子字符串*/
if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
devicePrefix.Length) < devicePrefix.Length)
{
return FALSE;
}
/*分配设置设备对象的名称的内存空间*/
deviceName.Length = 0;
deviceName.MaximumLength = (USHORT)(amacNameP->Length +
g_NPF_Prefix.Length + sizeof(UNICODE_NULL));
deviceName.Buffer = ExAllocatePoolWithTag(PagedPool,
deviceName.MaximumLength, '3PWA');
if (deviceName.Buffer == NULL)
return FALSE;
/*分配用户可见的设备名称的内存空间*/
deviceSymLink.Length = 0;
deviceSymLink.MaximumLength=
(USHORT)(amacNameP->Length-devicePrefix.Length
+ symbolicLinkPrefix.Length
+ g_NPF_Prefix.Length
+ sizeof(UNICODE_NULL));
deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool,
deviceSymLink.MaximumLength, '3PWA');
if (deviceSymLink.Buffer == NULL)
{
ExFreePool(deviceName.Buffer);
return FALSE;
}
/*生成设置设备对象的名称*/
RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
RtlAppendUnicodeStringToString(&deviceName, &g_NPF_Prefix);
RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
devicePrefix.Length / sizeof(WCHAR));
/*生成用户可见的设备名称*/
RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
RtlAppendUnicodeStringToString(&deviceSymLink, &g_NPF_Prefix);
RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
devicePrefix.Length / sizeof(WCHAR));
/*为驱动程序的使用者分配内存,并初始化一个设备对象*/
status = IoCreateDevice(adriverObjectP,
sizeof(DEVICE_EXTENSION),
&deviceName,
FILE_DEVICE_TRANSPORT,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&devObjP);
if (NT_SUCCESS(status))
{
PDEVICE_EXTENSION devExtP =
(PDEVICE_EXTENSION)devObjP->DeviceExtension;
devObjP->Flags |= DO_DIRECT_IO;
//设置适配器的名称
RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);
/*在一个设备对象名称与一个用户可见的名称之间建立一个符号连接*/
if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) !=
STATUS_SUCCESS)
{//创建连接失败,函数返回
ExFreePool(deviceName.Buffer);
ExFreePool(deviceSymLink.Buffer);
devExtP->ExportString = NULL;
return FALSE;
}
/*设置应用程序可见的设备名称*/
devExtP->ExportString = deviceSymLink.Buffer;
ExFreePool(deviceName.Buffer);
return TRUE;
}
else
{ //IoCreateDevice调用失败,函数返回
ExFreePool(deviceName.Buffer);
ExFreePool(deviceSymLink.Buffer);
return FALSE;
}
}
- ››深度解释攻击linux服务器的四种级别
- ››剖析java.util.concurrent锁
- ››剖析Android智能手机系统的更多功能
- ››深度分析地方社区网站的内容定位
- ››剖析Windows Azure Platform框架与组成
- ››剖析使用 ObjectOutputStream 可能引起的内存泄漏...
- ››剖析EWebEditor编辑器漏洞攻击案例
- ››剖析开源云:构建 Infrastructure as a Service 块...
- ››深度剖析 Android 和 iPhone OS
- ››深度分析:HTML5能否成为Flash终结者
- ››深度挖掘 更多Windows 7快捷模式
- ››深度挖掘 Windows 7快捷模式
更多精彩
赞助商链接