XiangXiangRen
总版主
总版主
  • 注册日期2003-02-22
  • 最后登录2015-09-01
  • 粉丝13
  • 关注0
  • 积分1042分
  • 威望472点
  • 贡献值1点
  • 好评度145点
  • 原创分13分
  • 专家分1分
阅读:2931回复:9

Windows文件系统过滤驱动开发教程(5)

楼主#
更多 发布于:2004-10-21 19:08
Windows文件系统过滤驱动开发教程

5.绑定FS CDO,文件系统识别器,设备扩展

上一节讲到我们打算绑定一个刚刚被激活的FS CDO.前边说过简单的调用wd_dev_attach可以很容易的绑定这个设备。但是,并不是每次my_fs_notify调用发现有新的fs激活,我就直接绑定它。

首先判断是否我需要关心的文件系统类型。我用下面的函数来获取设备类型。

// ------------------wdf.h中的内容-------------------
_inline wd_dev_type wd_dev_get_type(in wd_dev *dev)
{
return dev->DeviceType;
}

文件系统的CDO的设备类型有下边的几种可能,你的过滤驱动可能只对其中某些感兴趣。

enum {
wd_dev_disk_fs = FILE_DEVICE_DISK_FILE_SYSTEM,
wd_dev_cdrom_fs = FILE_DEVICE_CD_ROM_FILE_SYSTEM,
wd_dev_network_fs = FILE_DEVICE_NETWORK_FILE_SYSTEM
};

你应该自己写一个函数来判断该fs是否你所关心的。

// -------------一个函数,判断是否我所关心的fs---------------
wd_bool my_care(wd_ulong type)
{
    return (((type) == wd_dev_disk_fs) ||
((type) == wd_dev_cdrom_fs) ||
((type) == wd_dev_network_fs));
}

下一个问题是我打算跳过文件系统识别器。文件系统识别器是文件系统驱动的一个很小的替身。为了避免没有使用到的文件系统驱动占据内核内存,windows系统不加载这些大驱动,而代替以该文件系统驱动对应的文件系统识别器。当新的物理存储媒介进入系统,io管理器会依次的尝试各种文件系统对它进行“识别”。识别成功,立刻加载真正的文件系统驱动,对应的文件系统识别器则被卸载掉。对我们来说,文件系统识别器的控制设备看起来就像一个文件系统控制设备。但我们不打算绑定它。

分辨的方法是通过驱动的名字。凡是文件系统识别器的驱动对象的名字(注意是DriverObject而不是DeviceObject!)都为“\FileSystem\Fs_Rec”.

//-------------------用这些代码来跳过文件系统识别器----------------------
wd_wchar name_buf[wd_dev_name_max_len];
wd_ustr name,tmp;

wd_ustr_init_em(&name,name_buf,wd_dev_name_max_len);
wd_ustr_init(&tmp,L"\\FileSystem\\Fs_Rec");

// 我不绑定识别器。所以如果是识别器,我直接返回成功。查看是否是识别
// 器的办法是看是否是\FileSystem\Fs_Rec的设备。
wd_obj_get_name(wd_dev_drv(fs_dev),&name);
if(wd_ustr_cmp(&name,&tmp,wd_true) == 0)
{
wd_printf0("attach fs dev:is a recogonizer.\r\n");
return wd_stat_suc;
}

wd_printf0("attach fs dev: not a recogonizer.\r\n");

接下来我将要生成我的设备。这里要提到设备扩展的概念。设备对象是一个数据结构,为了表示不同的设备,里边将有一片自定义的空间,用来给你记录这个设备的特有信息。我们为我们所生成的设备确定设备扩展如下:

// 文件过滤系统驱动的设备扩展
typedef struct _my_dev_ext
{
// 我们绑定的文件系统驱动
  wd_dev * attached_to;
// 上边这个设备的设备名。
wd_ustr dev_name;
// 这是上边的unicode字符串的缓冲区
wd_wchar name_buf[wd_dev_name_max_len];
} my_dev_ext;

之所以如此简单,是因为我们现在还没有多少东西要记录。只要记得自己绑定在哪个设备上就好了。如果以后需要更多的信息,再增加不迟。扩展空间的大小是在wdf_dev_create(也就是这个设备生成)的时候指定的。得到设备对象指针后,我用下面这个函数来获取设备扩展指针:

// --------------wdf.h中的内容------------------
_inline wd_void * wd_dev_ext(wd_dev *dev)
{
return (dev->DeviceExtension);
}


生成设备后,为了让系统看起来,你的设备和原来的设备没什么区别,你必须设置一些该设备的标志位与你所绑定的设备相同。

_inline wd_void wd_dev_copy_flag(wd_dev *new_dev,
wd_dev *old_dev)
{
    if(old_dev->Flags & DO_BUFFERED_IO)
        new_dev->Flags &= DO_BUFFERED_IO;
    if(old_dev->Flags & DO_DIRECT_IO)
        new_dev->Flags &= DO_DIRECT_IO;
    if (old_dev->Characteristics & FILE_DEVICE_SECURE_OPEN)
        new_dev->Characteristics &= FILE_DEVICE_SECURE_OPEN;
}

DO_BUFFERED_IO,DO_DIRECT_IO这两个标志的意义在于外部向这些设备发送读写请求的时候,所用的缓冲地址将有所不同。这点以后在过滤文件读写的时候再讨论。现在一切事情都搞完,你应该去掉你的新设备上的DO_DEVICE_INITIALIZING标志,以表明的的设备已经完全可以用了。

// --------------wdf.h中的内容------------------
_inline wd_void wd_dev_clr_init_flag(wd_dev *dev)
{
dev->Flags &= ~DO_DEVICE_INITIALIZING;
}

现在我写一个函数来完成以上的这个过程。你只要在上一节中提示的位置调用这个函数,就完成对文件系统控制设备的绑定了。

//-----------绑定一个文件系统驱动设备-------------------------
wd_stat my_attach_fs_dev(wd_dev *fs_dev)
{
wd_wchar name_buf[wd_dev_name_max_len];
wd_ustr name,tmp;
wd_dev *new_dev;
wd_stat status;
my_dev_ext *ext;
wd_ustr_init_em(&name,name_buf,wd_dev_name_max_len);
wd_ustr_init(&tmp,L"\\FileSystem\\Fs_Rec");

// 如果不是我关心的类型,我直接返回成功
if(!my_care(wd_dev_get_type(fs_dev)))
{
wd_printf0(("attach fs dev:not a cared type.\r\n"));
return wd_stat_suc;
}

wd_printf0("attach fs dev: is my cared type.\r\n");

// 我不绑定识别器。所以如果是识别器,我直接返回成功。查看是否是识别
// 器的办法是看是否是\FileSystem\Fs_Rec的设备。
wd_obj_get_name(wd_dev_drv(fs_dev),&name);
if(wd_ustr_cmp(&name,&tmp,wd_true) == 0)
{
wd_printf0("attach fs dev:is a recogonizer.\r\n");
return wd_stat_suc;
}

wd_printf0("attach fs dev: not a recogonizer.\r\n");

// 现在来生成一个设备用来绑定
status = wd_dev_create(g_drv,sizeof(my_dev_ext),NULL,
 wd_dev_get_type(fs_dev),
 0,wd_false,&new_dev);
if(!wd_suc(status))
{
wd_printf0("attach fs dev: dev create failed.\r\n");
return status;
}

wd_printf0("attach fs dev: create dev success.\r\n");

// 接着设置设备的各种标志与之要绑定的标志一致
wd_dev_copy_flag(new_dev,fs_dev);

ext = (my_dev_ext *)wd_dev_ext(new_dev);

wd_printf0("begin to attach.\r\n");
status = wd_dev_attach(new_dev,fs_dev,&ext->attached_to);
wd_printf0("attach over.status = %8x\r\n",status);

if(!wd_suc(status))
{
wd_printf0("attach fs dev: dev attach failed.\r\n");
UNREFERENCED_PARAMETER(new_dev);
wd_dev_del(new_dev);
return status;
}

wd_printf0("attach fs dev: attach %wZ succeed.\r\n",&name);

wd_ustr_init_em(&ext->dev_name,ext->name_buf,wd_dev_name_max_len);
wd_ustr_copy(&ext->dev_name,&name);
wd_dev_clr_init_flag(new_dev);

return status;
}

最新喜欢:

yuanycyuanyc forgetalexforget...
king-z
驱动牛犊
驱动牛犊
  • 注册日期2004-10-12
  • 最后登录2008-08-05
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-10-22 17:36
赞 !
XiangXiangRen
总版主
总版主
  • 注册日期2003-02-22
  • 最后登录2015-09-01
  • 粉丝13
  • 关注0
  • 积分1042分
  • 威望472点
  • 贡献值1点
  • 好评度145点
  • 原创分13分
  • 专家分1分
板凳#
发布于:2004-10-23 09:53
谢谢…… 这几天公司又要开始每夜加班了 痛苦中 新章节已经有提纲,近期推出 敬请关注:)
IoriKingdom
驱动小牛
驱动小牛
  • 注册日期2004-06-17
  • 最后登录2010-04-26
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望23点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-10-23 17:43
支持一下
天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。
liyanmei
驱动牛犊
驱动牛犊
  • 注册日期2004-07-20
  • 最后登录2004-11-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-10-25 11:05
帮你顶 :D :cool:
kevin73
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2005-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-10-28 20:23
我喜欢,多谢
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-11-05 10:09
预!
meng20020311
驱动牛犊
驱动牛犊
  • 注册日期2005-01-04
  • 最后登录2005-02-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-01-31 16:29
顶。。。。。。。。。。。
jjw
jjw
驱动牛犊
驱动牛犊
  • 注册日期2001-11-01
  • 最后登录2008-11-05
  • 粉丝0
  • 关注0
  • 积分-6分
  • 威望5点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-04-12 20:22
好文章,再推一把345
jjw
jjw
jjw
驱动牛犊
驱动牛犊
  • 注册日期2001-11-01
  • 最后登录2008-11-05
  • 粉丝0
  • 关注0
  • 积分-6分
  • 威望5点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-04-12 21:10
请问楼主:
// 现在来生成一个设备用来绑定
status = wd_dev_create(g_drv,sizeof(my_dev_ext),NULL,
wd_dev_get_type(fs_dev),
0,wd_false,&new_dev);


此句中的g_drv是如何定义的?
jjw
游客

返回顶部