对 Windows驱动开发技术详解 第四章的(驱动程序的基本结构)自我理解
BY:ALALMN—飞龙 QQ:316118740 BLOG:http://hi.baidu.com/alalmn
个人感觉NT式驱动和WDM驱动 可以说基本上没变化入口点 创建设备对象 创建符号链接 正果过程都还是一样的
NT式驱动的基本结构
驱动程序入口点DriverEntry
驱动对象DRIVER_OBJECT
typedef struct _DRIVER_OBJECT {
CSHORT Type; //应该是IO_TYPE_DRIVER
CSHORT Size;
PDEVICE_OBJECT DeviceObject; //指向驱动的第一个设备对象
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension; //指向扩充部
UNICODE_STRING DriverName; //驱动程序名字
PUNICODE_STRING HardwareDatabase; //设备的硬件数据库键名。
PFAST_IO_DISPATCH FastIoDispatch; //文件驱动中用到的派遣函数。
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo; //记录StartIO例程的函数地址,用于串行话操作。
PDRIVER_UNLOAD DriverUnload; //指定驱动卸载时所用的回调函数地址。
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; //是一个数组,数组中的每个成员记录着一个指针
,每个指针指向的是一个函数。这个函数就是处理IRP的派遣函数。
} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;
驱动对象DEVICE_OBJECT
typedef struct _DEVICE_OBJECT {
CSHORT Type;
USHORT Size;
LONG ReferenceCount;
struct _DRIVER_OBJECT *DriverObject; //指向驱动程序中的驱动对象。
struct _DEVICE_OBJECT *NextDevice; //指向下一个设备对象。下层驱动
struct _DEVICE_OBJECT *AttachedDevice; //指向下一个设备对象。高层驱动
struct _IRP *CurrentIrp; //指向当前IRP结构。
ULONG Flags; //设备对象
//DO_BUFFERED_IO 读写操作使用缓冲方式(系统复制缓冲区)访问用户模式数据
//DO_BUS_ENUMERATED_DEVICE 一次只允许一个线程打开设备句柄
//DO_DEVICE_INITIALIZING 读写操作使用直接方式(内存描述符表)访问用户模式
数据
//DO_POWER_INRUSH 设备对象正在初始化
//DO_POWER_PAGABLE 必须在PASSIVE_LEVEL级上处理IRP_MJ_PNP请求
//DO_VERIFY_VOLUME 设备上电期间需要大电流
ULONG Characteristics;
PVPB Vpb;
PVOID DeviceExtension;
DEVICE_TYPE DeviceType; //指明设备的类型。
CCHAR StackSize; //在多层驱动情况下,驱动与驱动之间会形成类似堆栰的结构。StackSize描述的
就是这个层数。
struct _DEVOBJ_EXTENSION *DeviceObjectExtension; //指向设备扩展对象
} DEVICE_OBJECT;
typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT;
DEVICE_TYPE DeviceType; //指明设备的类型。 常用的类型
#define FILE_DEVICE_8042_PORT 0x00000027 8042端口设备对象
#define FILE_DEVICE_ACPI 0x00000032 ACPI设备对象
#define FILE_DEVICE_BATTERY 0x00000029 电池设备对象
#define FILE_DEVICE_BEEP 0x00000001 蜂鸣器设备对象
#define FILE_DEVICE_BUS_EXTENDER 0x0000002a 总线扩展设备对象
#define FILE_DEVICE_CD_ROM 0x00000002 CD光驱设备对象
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 CD光驱文件系统设备对象
#define FILE_DEVICE_CHANGER 0x00000030 充电设备对象
#define FILE_DEVICE_CONTROLLER 0x00000004 控制器设备对象
#define FILE_DEVICE_DATALINK 0x00000005 数据链设备对象
#define FILE_DEVICE_DFS 0x00000006 DFS设备对象
#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
#define FILE_DEVICE_DFS_VOLUME 0x00000036
#define FILE_DEVICE_DISK 0x00000007 磁盘设备对象
#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 磁盘文件系统设备对象
#define FILE_DEVICE_DVD 0x00000033 DVD设备对象
#define FILE_DEVICE_FILE_SYSTEM 0x00000009 文件系统设备对象
#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
#define FILE_DEVICE_INPORT_PORT 0x0000000a 输入端口设备对象
#define FILE_DEVICE_KEYBOARD 0x0000000b 键盘设备对象
#define FILE_DEVICE_KS 0x0000002f 内核流设备对象
#define FILE_DEVICE_KSEC 0x00000039
#define FILE_DEVICE_MAILSLOT 0x0000000c 邮件槽设备对象
#define FILE_DEVICE_MASS_STORAGE 0x0000002d 大容量储存设备对象
#define FILE_DEVICE_MIDI_IN 0x0000000d MIDI输入设备对象
#define FILE_DEVICE_MIDI_OUT 0x0000000e MIDI输出设备对象
#define FILE_DEVICE_MODEM 0x0000002b 调制解调器设备对象
#define FILE_DEVICE_MOUSE 0x0000000f 鼠标设备对象
#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 多UNC设备对象
#define FILE_DEVICE_NAMED_PIPE 0x00000011 命名管道设备对象
#define FILE_DEVICE_NETWORK 0x00000012 网络设备对象
#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 网络浏览器设备对象
#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 网络文件系统设备对象
#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 网卡设备对象
#define FILE_DEVICE_NULL 0x00000015 空设备对象
#define FILE_DEVICE_PARALLEL_PORT 0x00000016 并口设备对象
#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 物理网卡设备对象
#define FILE_DEVICE_PRINTER 0x00000018 打印机设备对象
#define FILE_DEVICE_SCANNER 0x00000019 扫描仪设备对象
#define FILE_DEVICE_SCREEN 0x0000001c 屏幕设备对象
#define FILE_DEVICE_SERENUM 0x00000037
#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a 串口鼠标设备对象
#define FILE_DEVICE_SERIAL_PORT 0x0000001b 串口设备对象
#define FILE_DEVICE_SMARTCARD 0x00000031 智能卡设备对象
#define FILE_DEVICE_SMB 0x0000002e SMB设备对象
#define FILE_DEVICE_SOUND 0x0000001d 声音设备对象
#define FILE_DEVICE_STREAMS 0x0000001e 流设备对象
#define FILE_DEVICE_TAPE 0x0000001f 磁带设备对象
#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 磁带文件系统设备对象
#define FILE_DEVICE_TERMSRV 0x00000038
#define FILE_DEVICE_TRANSPORT 0x00000021 传输设备对象
#define FILE_DEVICE_UNKNOWN 0x00000022 未知设备对象
#define FILE_DEVICE_VDM 0x0000002c VDM设备对象
#define FILE_DEVICE_VIDEO 0x00000023 视频设备对象
#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 虚拟磁盘设备对象
#define FILE_DEVICE_WAVE_IN 0x00000025 声音输入设备对象
#define FILE_DEVICE_WAVE_OUT 0x00000026 声音输出设备对象
该UNICODE_STRING结构是用来定义UNICODE字符串。
typedef struct _UNICODE_STRING {
USHORT Length; //记录这个字符串用多少字节记录。如果字符串有N个字符,那么Length将会是N的2倍。
USHORT MaximumLength; //记录Buffer的大小,也就是这个结构最大能记录的字节数。MaximumLength要大于等于Length.
PWSTR Buffer; //记录字符串的指针。与ASCII字符串不同,这里的字符串每个都是16位
} UNICODE_STRING *PUNICODE_STRING;
创建设备对象IoCreateDevice
NTSTATUS
IoCreateDevice(
IN PDRIVER_OBJECT DriverObject, //指向驱动对象对象的指针。
IN ULONG DeviceExtensionSize, //指向设备扩展的大小,I/O管理器会根据这个大小,在内存中创建设备扩展,并
与驱动对象关联。
IN PUNICODE_STRING DeviceName OPTIONAL, //设置对象的名字
IN DEVICE_TYPE DeviceType,
IN ULONG DeviceCharacteristics, //设置设备对象的特征
IN BOOLEAN Exclusive, //设置设备对象是否为内核模式下使用,一般设置为TRUE
OUT PDEVICE_OBJECT *DeviceObject //I/O管理器负责创建创建这个设备对象,并返回设备对象的地址。
);
建立符号链接是否成功IoCreateSymbolicLink
NTSTATUS
IoCreateSymbolicLink(
IN PUNICODE_STRING SymbolicLinkName, //符号链接的字符串。
IN PUNICODE_STRING DeviceName //设备对象名的字符串。
);
删除设备对象函数IoDeleteDevice
VOID
IoDeleteDevice(
IN PDEVICE_OBJECT DeviceObject //设备结构
);
删除符号链接函数IoDeleteSymbolicLink
NTSTATUS
IoDeleteSymbolicLink(
IN PUNICODE_STRING SymbolicLinkName //表示已经被注册了的符号链接
);
///
///
WDM式驱动的基本结构
NT式驱动需要用户自动加载
WDM式驱动 插入设备后,系统会自动创建出PDO,并提示请求用户安装FDO。