设备与符号链接
驱动程序和系统其他组件之间的交互是通过给设备发送或者接受发给设备的请求来交互的。换句话说,一个没有任何设备的驱动是不能按规范方式和系统交互的。当然也不会收到任何IRP,分发函数也失去了意义。
但并不意味着这样的驱动程序不存在。如果一个驱动程序只是想写写日志文件、Hook某些内核函数或者是做一些其他的小动作,也可以不生成任何设备,也不需要关心分发函数的设置。
如果驱动程序要和应用程序之间通信,则应该生成设备。此外还必须为设备生成应用程序可以访问的符号链接。下面的驱动程序生成了一个设备,并设置了分发函数:
#include <ntifs.h> // 之所以用ntifs.h而不是ntddk.h是因为我习惯开发文件
// 系统驱动,实际上目前对读者来说这两个头文件没区别。
NTSTATUS DriverEntry(
PDRIVER_OBJECT driver,
PUNICODE_STRING reg_path)
{
NTSTATUS status;
PDEVICE_OBJECT device;
// 设备名
UNICODE_STRING device_name =
RTL_CONSTANT_STRING("\\Device\\MyCDO");
// 符号链接名
UNICODE_STRING symb_link =
RTL_CONSTANT_STRING("\\DosDevices\\MyCDOSL");
// 生成设备对象
status = IoCreateDevice(
driver,
0,
device_name,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&device);
// 如果不成功,就返回。
if(!NT_SUCCESS(status))
return status;
// 生成符号链接
status = IoCreateSymbolicLink(
&symb_link,
&device_name);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(device);
return status;
}
// 设备生成之后,打开初始化完成标记
device->Flags &= ~DO_DEVICE_INITIALIZING;
return status;
}
这个驱动成功加载之后,生成一个名叫“\Device\MyCDO”的设备。然后在给这个设备生成了一个符号链接名字叫做“\DosDevices\MyCDOSL”。应用层可以通过打开这个符号链接来打开设备。应用层可以调用CreateFile就像打开文件一样打开。只是路径应该是“”\.\ MyCDOSL”。前面的“\.\”意味后面是一个符号链接名,而不是一个普通的文件。请注意,由于C语言中斜杠要双写,所以正确的写法应该是“\\.\”。与应用层交互的例子在下一节“IRP和IO_STACK_LOCATION”中。