驱动对象与设备对象

news/2024/7/5 10:47:53

 驱动对象与设备对象(转)

这里所说的 驱动对象 是一种数据结构, 在DDK 中名为 DRIVER_OBJECT。任何驱动程序都对应一个
DRIVER_OBJECT.如何获得本人所写的驱动对应的 DRIVER_OBJECT 呢?驱动程序的入口函数为 DriverEntry,因
此,当你写一个驱动的开始,你会写下如下的代码:

NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING
RegistryPath )
{
}

这个函数就相当与喜欢c 语言的你所常用的main().IN 是 无意义的宏,仅仅表明后边的参数是一种输入,而对应的
OUT 则代表这个参数是一种返回。这里没有使用引用,因此如果想在参数中返回结果,一律传入指针。
DriverObject 就是你所写的驱动对应的 DRIVER_OBJECT, 是系统在加载你的驱动时候所分配的
RegisteryPath专用于你记录你的驱动相关参数的注册表路径这两者都由系统分配并通过这两个参数传递给你
DriverObject 重要之处,在于它 拥有一组函数指针,称为 dispatch functions.

开发驱动的 主要任务就是 亲手撰写这些dispatch functions. 当系统用到你的驱动会向你的驱动发送IRP(这是
windows 所有驱动的共同工作方式)。你的任务是 在dispatch function 中处理这些请求你可以让irp 失败,也可以
成功返回
也可以修改这些irp,甚至可以自己发出irp。


设备对象则是指 DEVICE_OBJECT.下边简称DO.
但是实际上每个 irp 都是针对 DO 发出的。只有针对由该驱动所生成的 DOIRP, 才会发给该驱动来处理。具体的
分发函数,决定于 DO 下的 DriverObject 域。
当一个应用程序打开文件并读写文件的时候, windows 系统将这些请求变成irp 发送给文件系统驱动
文件系统过滤驱动可以过滤这些irp.这样,你就拥有了 捕获和改变文件系统操作能力
Fat32,NTFS 这样的 文件系统(File System,简称FS),可能生成好几种设备。首先文件系统驱动本身往往生成
一个 控制设备(CDO).这个设备的主要任务是 修改整个驱动的内部配置。因此一个 Driver对应一个 CDO.
另一种设备是被这个文件系统 Mount Volume。一个 FS 可能有多个 Volume,也 可能一个都没有。解释一下,如
果你有 C:,D:,E:,F:四个分区。 C:,D:为 NTFS, E:,F:为 Fat32.那么 E:,F:则是 Fat 的两个 Volume 设备对象.
实际上"C:"是该设备的符号连接(Symbolic Link)名而不是真正的设备名可以打开Symbolic Links Viewer,
能看到:
C: /Device/HarddiskVolume1
因此该设备的 设备名为“/Device/HarddiskVolume1”.
这里也看出来,文件系统驱动是针对每个 Volume 来生成一个 DeviceObject,而不是针对每个文件的。实际上对文
件的读写的 irp,都 发到Volume 设备对象上去了。并不会生成一个“文件设备对象”。
掌握了这些概念的话,我们现在用简单的代码来生成我们的CDO,作为我们开发文件系统驱动的第一步牛刀小试。


NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
// 定义一个Unicode 字符串。
UNICODE_STRING nameString;
RtlInitUnicodeString( &nameString, L"//FileSystem//Filters//SFilter" );

// 生成控制设备
status = IoCreateDevice( DriverObject,
0, //has no device extension
&nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gSFilterControlDeviceObject );

// 如果因为路径没找到而生成失败
if (status == STATUS_OBJECT_PATH_NOT_FOUND) {
// 这是因为一些低版本的操作系统没有/FileSystem/Filters/这个目录

// 如果没有,我们则改变位置,生成到/FileSystem/下.
RtlInitUnicodeString( &nameString, L"//FileSystem//SFilterCDO" );

status = IoCreateDevice( DriverObject,
0,&nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gSFilterControlDeviceObject );

// 成功后,用KdPrint 打印一个log.
if (! NT_SUCCESS( status )) {
KdPrint(( "SFilter!DriverEntry: Error creating control device object /"%wZ/",
status=%08x/n", &nameString, status ));
return status;
}
} else if (! NT_SUCCESS( status )) {
// 失败也打印一个。并直接返回错误
KdPrint(( "SFilter!DriverEntry: Error creating control device object /"%wZ/",
status=%08x/n", &nameString, status ));
}
return status;
}
sfilter.sys.把这个文件与前所描述的inf 文件同一目录,按上节所叙述方法安装。
这个驱动不起任何作用,但是你已经成功的完成了"hello world".
初次看这些代码可能有一些慌乱。但是只要注意了以下几点,你就会变得轻松了:

1) 习惯使用UNICODE_STRING 字符串。这些字符串用Rtl…系列的函数来操作。你应该阅读DDK 帮助,然
后熟悉这些字符串的用法。
2) 用KdPrint(())来代替printf 输出信息。这些信息可以在DbgView 中看到。KdPrint(())自身是一个宏,
为了完整传入参数所以使用了两重括弧。这个比DbgPrint 调用要稍好。因为在free 版不被编译。
3) 查看DDK 帮助了解生成设备对象IoCreateDevice 的用法。
请注意CDO 生成后,保存在gSFilterControlDeviceObject 中。这样以后我们得到一个DEVICE_OBJECT 时,
就很容易判断是否是我们的控制设备。

http://www.niftyadmin.cn/n/3102310.html

相关文章

基于C++语言开发的Windows环境微型操作系统

一 需求分析 用高级语言编写程序,模拟实现一个简单功能的操作系统。 实现作业调度(先来先服务)、进程调度功能(时间片轮转) 实现内存管理功能(连续分配) 实现文件系统功能(选做内…

驱动对象 设备对象 设备栈 乱杂谈

驱动对象 设备对象 设备栈 乱杂谈 作者: JIURL 主页: http://jiurl.yeah.net -------------------------------------------------------------------------------- 用有限的几句话就舒舒服服的建立起对驱动对象和设备对象的概念是不可能的。刚开始是…

基于VC++的MFC框架实现的飞机大战小游戏

一、类介绍 1.1 程序使用到的MFC类库中主要的类 CDC类 CRect类 CBitmap类 CImageList类 mfc框架:app类、wnd类、doc类、view类 1.2 项目包含的对象类 8个游戏类: enemy(敌人) bomb(敌人子弹) miss…

(WSS)WSS3.0安装文档库组件后恢复默认安全设置,上下文菜单消失了,想请教下各位老大是咋回事(问题有了突破)...

最近装了WSS3.0并且安装了文档库这个模板,原本我windows 2003的机器在鼠标移动到文档项目的名称列下某行的空白处会出现一个显亮的方框,左键单击后会出现一个上下文菜单,如下图: 后来因为其他机器(有win7的&#xff0c…

基于C语言的Linux环境下socket编程

一 需求分析 柏克莱套接字,又称为BSD 套接字是一种应用程序接口,用于网际插座与Unix域套接字,包括了一个用C语言写成的应用程序开发库,主要用于实现进程间通讯,在计算机网络通讯方面被广泛使用。 使用Berkeley套接字…

Windows下使用标准Shell接口遍历文件和文件夹

Windows下使用标准Shell接口遍历文件和文件夹(1) 在Windows中我们经常需要遍历一个文件夹或者遍历一个磁盘。本文介绍如何使用标准的Shell接口进行遍历。在介绍过程中会逐步的实现一个类似FileZilla的TreeViewListView的界面。我最近为psftp做界面的时候简单了解了一下这方面的…

基于Qt和OpenCV实现彩色图和灰度图的转换

一、实验目的与要求 1.1 目的 熟悉Qt可视化开发,理解C的面向对象思想 熟悉Qt和Opencv开发环境搭建 了解Qt消息机制 初步理解Opencv的用法 学会使用c异常处理 1.2 要求 使用Qt编写一程序,点击按钮从电脑目录选择jpg图片,显示在界面上 再…

VC++中如何判断当前用户是否具有管理员权限

代码一: BOOL CRSysInfo::IsUserAdminPrivilege(const CString & strUserName,BOOL & bAdminPrivilege) { bAdminPrivilege FALSE; PSID pSid NULL; DWORD cbSid 0; LPTSTR bufDomain NULL; …