(二)、windows驱动开发的重要数据结构

一、DRIVER_OBJECT与DEVICE_OBJECT

DRIVER_OBJECT结构体
0
Major Function指的是分发函数
DriverUnload指的是卸载函数
DriverStart 驱动对象的起始地址 
DriverName驱动名字
FastloDispatch快速IO分发函数
DeviceObject设备对象,设备对象链表的开始
Type 结构的类型
Size 结构的大小
 
 
DeviceObject
 
0
 
Characteristic: 设备特征
DeviceType:设备类型
CurrentIrp:当前Irp
NextDevice:下一个设备对象(一个驱动可能会创建多个设备对象)
DriverObject:指示该设备对象隶属于哪个驱动对象
DeviceExtension:符号扩展
Attach Device:上一个设备的指针(操作系统 采用使用成员)
 
0
 
ServiceKeyName:注册表项目名称
0

二、函数返回类型

 
0
 

三、创建设备对象

 
0
Exclusive:设置设备为互斥设备(即无法同时打开两个设备)
 

四、用代码创建设备对象

#include<ntddk.h>

VOID DriverUnload(PDRIVER_OBJECT driver)
{
    IoDeleteDevice(driver->DeviceObject);//删除驱动设备//
    KdPrint(("设备删除"));
    DbgPrint("Driver is unloading ...\r\n");
}


NTSTATUS
DriverEntry(
    PDRIVER_OBJECT  driver,
    PUNICODE_STRING RegistryPath
)
{
    UNREFERENCED_PARAMETER(RegistryPath);   //该表明该变量未使用//
 
    NTSTATUS status;
    PDEVICE_OBJECT DeviceObject; //创建设备对象//
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK"); //用宏来初始化字符串//注意这里必须是\\Device\\不然会蓝屏
    KdPrint(("驱动加载"));
    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);//非分页池//
    DbgPrint("设备创建\r\n");

    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;//设备已初始化完毕//


    driver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

 

 
0
这里,注意设备路径名中的\\Device\\不能变,不然就蓝//
0
 

五、创建符号连接对象

下面借助微软提供的winobj工具
0
winobj中的Symboliclink符号连接相当于别名
比如图中懂得HardddiskVolumeShadow{}那一大串字符串就是起的别名
我们只能通过符号链接对象来找到设备对象
 
 
 
 
 
0
 
0
目前还没有符号链接
 
创建链接
#include<ntddk.h>

VOID DriverUnload(PDRIVER_OBJECT driver)
{
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\Global??\\HelloDDK");
    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(driver->DeviceObject);//删除驱动设备//
    KdPrint(("删除符号链接"));
    KdPrint(("设备删除"));
    DbgPrint("Driver is unloading ...\r\n");
}


NTSTATUS
DriverEntry(
    PDRIVER_OBJECT  driver,
    PUNICODE_STRING RegistryPath
)
{
    UNREFERENCED_PARAMETER(RegistryPath);   //该表明该变量未使用//
 
    NTSTATUS status;
    PDEVICE_OBJECT DeviceObject; //创建设备对象//
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK"); //用宏来初始化字符串//注意这里设备路径名中的\\Device\\不能变不然会蓝屏//
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\Global??\\HelloDDK"); //Global可以省略

    KdPrint(("驱动加载"));
    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);//非分页池//
    if (!NT_SUCCESS(status)) {
        KdPrint(("设备创建失败\r\n"));
        return status;
    }
    DbgPrint("设备创建\r\n");
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);  //创建符号连接//两个参数都是PUNICODE_STRING,所以需要取地址//
    
    if (!NT_SUCCESS(status))
    {
        KdPrint(("符号链接创建失败\n"));
        IoDeleteDevice(DeviceObject);//删除设备对象//
        return status;
    }
    KdPrint(("符号链接创建成功\n"));


    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;//设备已初始化完毕//


    driver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

 

符号链接创建成功
0
注意,代码中符号链接的名字中 Global可以省略,只写??即可,微软会自动在Global下去创建符号链接
 

六、设备的层次结构

这里我们介绍一个新工具 DeviceTree
他能查看驱动与设备对象中的信息
0
IRP命令从上到下分配分发
0

七、打印一下驱动结构

VOID EnumDriver(PDRIVER_OBJECT DriverObject) { KdPrint(("Driver:%p\n", DriverObject)); KdPrint(("Device:%p\n", DriverObject->DeviceObject)); KdPrint(("驱动对象名:%wZ\n", &DriverObject->DriverName));////打印字符串结构用%Z表示%wZ表示是宽字符// KdPrint(("服务名:%wZ\n", &DriverObject->DriverExtension->ServiceKeyName));//服务名// KdPrint(("%wZ\n", DriverObject->HardwareDatabase));//数据库// }
 
0
 
posted @ 2022-04-03 23:14  TLSN  阅读(105)  评论(0编辑  收藏  举报