Windows檔案系統過濾驅動開發教程(3)

來源:互聯網
上載者:User
Windows檔案系統過濾驅動開發教程

3.分發常式,fast io

上一節僅僅產生了控制裝置物件。但是不要忘記,驅動開發的主要工作是撰寫分發常式(dispatch functions.).接上一接,我們已經知道自己的DriverObject儲存在上文代碼的driver中。現在我寫如下一個函數來指定一個預設的 dispatch function給它。

//-----------------wdf.h中的代碼----------------------
typedef PDRIVER_DISPATCH wd_disp_fuc;
_inline wd_void wd_drv_set_dispatch(in wd_drv* driver,
in wd_disp_fuc disp)
{
wd_size i;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
driver->MajorFunction[i] = disp;
}

在前邊的wd_main中,我只要加

wd_drv_set_dispatch(driver,my_dispatch_func);

就為這個驅動指定了一個預設的Dispatch Function.所有的irp請求,都會被發送到這個函數。但是,我可能不希望這個函數處理過於複雜,而希望把一些常見的請求獨立出來,如Read, Write,Create,Close,那我又寫了幾個函數專門用來設定這幾個Dispatch Functions.

//-----------------wdf.h中的代碼----------------------
_inline wd_void wd_drv_set_read(
in wd_drv* driver,
in wd_disp_fuc read)
{
driver->MajorFunction[IRP_MJ_READ] = read;
}
_inline wd_void wd_drv_set_write(
in wd_drv* driver,
in wd_disp_fuc write)
{
driver->MajorFunction[IRP_MJ_WRITE] = write;
}

wd_void wd_drv_set_create(in wd_drv* driver,
in wd_disp_fuc create)
{
driver->MajorFunction[IRP_MJ_CREATE] = create;
driver->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = create;
driver->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = create;
}

wd_void wd_drv_set_file_sys_control(in wd_drv* driver,
in wd_disp_fuc control)
{
driver->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = control;
}

wd_void wd_drv_set_clean_up(in wd_drv* driver,
in wd_disp_fuc clean_up)
{
driver->MajorFunction[IRP_MJ_CLEANUP] = clean_up;
}

wd_void wd_drv_set_close(in wd_drv* driver,
in wd_disp_fuc close)
{
driver->MajorFunction[IRP_MJ_CLOSE] = close;
}

別看我羅列n多代碼,其實就是在設定driver->MajorFunction這個數組而已。因此在wd_main對dispatch functions的設定,就變成了下邊這樣的:

// 開始設定幾個分發常式
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\"\\FileSystem\\Filters\\our_fs_filters\");
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\"\\FileSystem\\our_fs_filters\");
status = wdff_cdo_create(driver,0,&name,&g_cdo);
};
if(!wd_suc(status))
{
wd_printf0(\"error: create cdo failed.rn\");
return status;
}
}

wd_printf0(\"success: create cdo ok.rn\");

// 開始設定幾個分發常式
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(\"error: fast io disp init failed.rn\");
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中的樣本自己完成這些代碼。

現在我們的my_xxx系列的函數還沒有開始寫,因此驅動也不能編譯通過。在後邊的內容中再逐步介紹。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.