// 开始设置几个分发例程
wd_drv_set_dispatch(driver,my_disp_default); wd_drv_set_create(driver,my_disp_create);
wd_drv_set_clean_up(driver,my_disp_clean_up);
wd_drv_set_file_sys_control(driver,my_disp_file_sys_ctl); wd_drv_set_close(driver,my_disp_close); wd_drv_set_read(driver,my_disp_read); wd_drv_set_write(driver,my_disp_write);
下面的任务都在写my_xxx系列的这些函数了。但是对于这个DriverObject的设置,还并不是仅仅这么简单。
由于你的驱动将要绑定到文件系统驱动的上边,文件系统除了处理正常的IRP之外,还要处理所谓的FastIo.FastIo是Cache Manager调用所引发的一种没有irp的请求。换句话说,除了正常的Dispatch Functions之外,你还得为DriverObject撰写另一组Fast Io Functions.这组函数的指针在driver->FastIoDispatch.我不知道这个指针留空会不会导致系统崩溃。在这里本来是没有空间的,所以为了保存这一组指针,你必须自己分配空间。
下面是我常用的内存分配函数。
//-----------------wdf.h中的代码---------------------- // 最简单的分配内存的函数,可以指定分页非分页 _inline wd_pvoid wd_malloc(wd_bool paged,wd_size size) {
if(paged)
return ExAllocatePool(PagedPool,size); else
return ExAllocatePool(NonPagedPool,size); }
// 释放内存
_inline wd_void wd_free(wd_pvoid point) {
ExFreePool(point); }
_inline wd_void wd_memzero( wd_pvoid point, wd_size size) {
RtlZeroMemory(point,size); }
有了上边的基础,我就可以自己写一个初始化FastIoDispatch指针的函数。
//-----------------wdf.h中的代码----------------------
wd_bool wd_fio_disp_init(wd_drv *driver,wd_ulong size) {
wd_fio_disp *disp = wd_malloc(wd_false,size); if(disp == wd_null) return wd_false;
wd_memzero((wd_pvoid)disp,size); driver->FastIoDispatch = disp;
driver->FastIoDispatch->SizeOfFastIoDispatch = size; return wd_true; }
这个函数为FastIoDispacth指针分配足够的空间并填写它的大小。下面是再写一系列的函数来设置这个函数指针数组。实际上,FastIo接口函数实在太多了,所以我仅仅写出这些设置函数的几个作为例子:
//-----------------wdf.h中的代码---------------------- _inline wd_void wd_fio_disp_set_query_standard( wd_drv *driver,
wd_fio_query_standard_func func) {
driver->FastIoDispatch->FastIoQueryStandardInfo = func; }
_inline wd_void wd_fio_disp_set_io_lock( wd_drv *driver,
wd_fio_io_lock_func func) {
driver->FastIoDispatch->FastIoLock = func; }
_inline wd_void wd_fio_disp_set_io_unlock_s( wd_drv *driver,
wd_fio_unlock_single_func func) {
driver->FastIoDispatch->FastIoUnlockSingle = func; } ...
好,如果你坚持读到了这里,应该表示祝贺了。我们回顾一下,wd_main中,应该做哪些工作。
a.生成一个控制设备。当然此前你必须给控制设置指定名称。
b.设置Dispatch Functions.
c.设置Fast Io Functions.
// ----------------wd_main 的近况---------------------------- ...
wd_dev *g_cdo = NULL;
wd_stat wd_main(in wd_drv* driver, in wd_ustr* reg_path) {
wd_ustr name;
wd_stat status = wd_stat_suc;
// 然后我生成控制设备,虽然现在我的控制设备什么都不干 wd_ustr_init(&name,L\status = wdff_cdo_create(driver,0,&name,&g_cdo);
if(!wd_suc(status)) {
if(status == wd_stat_path_not_found) {
// 这种情况发生于FileSystemFilters路径不存在。这个路径是 // 在xp上才加上的。所以2000下可能会运行到这里 wd_ustr_init(&name,L\status = wdff_cdo_create(driver,0,&name,&g_cdo); };
if(!wd_suc(status)) {
wd_printf0(\return status; } }
wd_printf0(\
// 开始设置几个分发例程
wd_drv_set_dispatch(driver,my_disp_default); wd_drv_set_create(driver,my_disp_create);
wd_drv_set_clean_up(driver,my_disp_clean_up);
wd_drv_set_file_sys_control(driver,my_disp_file_sys_ctl);
wd_drv_set_close(driver,my_disp_close); wd_drv_set_read(driver,my_disp_read); wd_drv_set_write(driver,my_disp_write);
// 指定fast io处理函数
if(!wd_fio_disp_init(driver,sizeof(wd_fio_disp))) {
wd_dev_del(g_cdo);
wd_printf0(\return wd_stat_insufficient_res; }
// 下面指定的这些函数都定义在wdf_filter_fio.h中,其实这些函数都统 // 一的返回了false wd_fio_disp_set_check( driver,
my_fio_check);
wd_fio_disp_set_read( driver,
my_fio_read);
wd_fio_disp_set_write( driver,
my_fio_write);
wd_fio_disp_set_query_basic( driver,
my_fio_query_basic_info); ... }
FastIo函数个数数量不明,我只觉得很多。因此不打算全部罗列,以\敷衍之。某些读者可能会认为这些代码无法调试安装。其实您可以参考sfilter中的示例自己完成这些代码。
使用Fast I/O
在这里我们将讲述Fast I/O的基本原理,简单描述各种各样的Fast I/O调用,以及得出如何使用此接口来提高程序性能的建议性结论。
Windows NT内核模式开发的标准做法是采用IRP作为基本的与驱动程序通信的手段,它的优点是IRP封装了上下文所需的详细操作并且允许从驱动程序的众多操作细节中分离出来。
这个方法在windos NT的分层设备体系中非常通用,有相当多的上层操作请求需要快速响应,在这种情况下,上层操作生成IRP决定了整个操作的成本并会导致系统性能的下降。鉴于此,NT系统引入的Fast I/O的概念。这种方法被用在文件系统驱动,如NTFS,HPFS,
相关推荐: