本帖最后由 YFSafe 于 2022-8-13 22:41 编辑
我们还有许多初始化的工作需要在DriverEntry函数中进行.目前我们还没有一个设备对象,因此还无法打开一个句柄从而达到驱动程序.我们的软件驱动程序只需要一个设备对象和一个符号链接指向它,这样我们就能从用户模式得到驱动程序的句柄了.
创建一个设备对象需要调用IoCreateDevice API.此函数的声明如下:
[C++] 纯文本查看 复制代码 NTSTATUS IoCreateDevice(
PDRIVER_OBJECT DriverObject,
ULONG DeviceExtensionSize,
PUNICODE_STRING DeviceName,
DEVICE_TYPE DeviceType,
ULONG DeviceCharacteristics,
BOOLEAN Exclusive,
PDEVICE_OBJECT *DeviceObject);
参数描述如下:
————DriverObject:驱动程序对象指针,就是DriverEntry传进来的那个.
————DeviceExtensionSize:填0.
————DeviceName:设备名称.
————DeviceType:我们需要使用FILE_DEVICE_UNKNOWN.
————DeviceCharacteristics:太麻烦了,直接写0就行.
————Exclusive:是否允许多个文件对象打开同一设备.多数时候应该使用FALSE.
————DeviceObject:返回的设备对象指针.
在调用IoCreateDevice之前,我们必须先创建一个UNICODE_STRING来存放内部设备名:
[C++] 纯文本查看 复制代码 UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\SetPriority");
现在我们可以调用IoCreateDevice了:)
[C++] 纯文本查看 复制代码 PDEVICE_OBJECT DeviceObject;
NTSTATUS status = IoCreateDevice(
DriverObject,
0,
&devName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&DeviceObject);
if(!NT_SUCCESS(status))
{
DbgPrint("CreateDevice Failed!!!");
return status;
}
如果一切正常,我们就拥有了一个指向一个设备对象的指针.下一步是通过提供符号链接使设备能够被来自用户模式的调用者访问.下面的代码创建了一个符号链接并将它与我们的设备连接起来.
[C++] 纯文本查看 复制代码 UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\?\\SetPriority");
status = IoCreateSymbolicLink(&symLink,&devName);
if(!NT_SUCCESS(status))
{
DbgPrint("Create symLink Failed!!!");
IoDeleteDevice(DeviceObject);
return status;
}
请注意,如果创建失败了,我们需要将迄今为止做过的所有事情恢复原状.在这里就需要用IoDeleteDevice销毁我们创建了的设备对象.
如果DriverEntry返回了任何失败的状态值,Unload例程都不会被调用.
在设备对象和符号链接都创建好后,DriverEntry就可以返回成功,且我们的驱动程序已经准备好接受请求了!
在继续之前,我们不能忘记驱动程序的Unload例程.假设DriverEntry返回成功,Unload例程就需要把在DriverEntry中完成的所有内容全部复原.在这个驱动程序中,我们只做了两件事:创建设备对象与符号链接.因此,我们在Unload例程中将他们复原.
[C++] 纯文本查看 复制代码 void DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\?\\SetPriority");
IoDeleteSymbolicLink(&symLink);
IoDeleteDevice(DriverObject->DeviceObject);
}
本节到此结束,下一节开始动工客户端程序了.
附:到现在的完整源代码
[C++] 纯文本查看 复制代码 #include <ntifs.h>
void DriverUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS SetPriorityCreateClose(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = SetPriorityCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SetPriorityCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SetPriorityDeviceControl;
UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\SetPriority");
PDEVICE_OBJECT DeviceObject;
NTSTATUS status = IoCreateDevice(
DriverObject,
0,
&devName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&DeviceObject);
if(!NT_SUCCESS(status))
{
DbgPrint("CreateDevice Failed!!!");
return status;
}
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\?\\SetPriority");
status = IoCreateSymbolicLink(&symLink,&devName);
if(!NT_SUCCESS(status))
{
DbgPrint("Create symLink Failed!!!");
IoDeleteDevice(DeviceObject);
return status;
}
return STATUS_SUCCESS;
}
void DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\?\\SetPriority");
IoDeleteSymbolicLink(&symLink);
IoDeleteDevice(DriverObject->DeviceObject);
} |