亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? windows文件系統過濾驅動開發教程.txt

?? 微過濾器驅動開發指南,本文翻譯僅僅用做交流學習。我不打算保留任何版權或者承擔任何責任。不要引用到贏利出版物中給您帶來版權官司。本文的翻譯者是楚狂人
?? TXT
?? 第 1 頁 / 共 4 頁
字號:
Windows文件系統過濾驅動開發教程

0. 作者,楚狂人自述

	我感覺Windows文件系統驅動的開發能找到的資料比較少。為了讓技術經驗不至于遺忘和引起大家交流的興趣我以我的工作經驗撰寫本教程。

	我的理解未必正確,有錯誤的地方望多多指教。有問題歡迎與我聯系。我們也樂于接受各種驅動項目的開發。郵箱為MFC_Tan_Wen@163.com,QQ為16191935。

	對于這本教程,您可以免費獲得并隨意修改,向任何網站轉貼。修改后您可以在作者介紹中署上您的大名,但是請不要去掉其他作者的名字:).另外您不得剽竊任何內容作為任何贏利出版物的全部或者部分。

	本文現在的情況如下:

	作者是杭州楚狂人,首先在驅動開發網連載.此版本比驅網連載版本稍有修改.除了0外,已發1-8節.后繼的章節將在不久后整理推出.您可以隨時發郵件向我索取更新的版本.

	最后更新日期是11月2日.
	

1. 概述,鉆研目的和準備


	我經常在網上碰到同行請求開發文件系統驅動。windows的pc機上以過濾驅動居多。其目的不外乎有以下幾種:

	一是用于防病毒引擎。希望在系統讀寫文件的時候,捕獲讀寫的數據內容,然后檢測其中是否含有病毒代碼。

	二是用于加密文件系統,希望在文件寫過程中對數據進行加密,在讀的過程中進行解密。

	三是設計透明的文件系統加速。讀寫磁盤的時候,合適的cache算法是可以大大提高磁盤的工作效率。windows本身的cache算法未必適合一些特殊的讀寫磁盤操作(如流媒體服務器上讀流媒體文件)。設計自己的cache算法的效果,我已在工作中有所感受。

	如果你剛好有以上此類的要求,你可以閱讀本教程。

	文件系統驅動是windows系統中最復雜的驅動種類之一。不能對ifsddk中的幫助抱太多希望,以我的經驗看來,文件系統相關的ddk幫助極其簡略,很多重要的部分僅僅輕描淡寫的帶過。如果安裝了ifsddk,應該閱讀src\filesys\OSR_docs下的文檔。而不僅僅是ddk幫助。

	文件系統驅動開發方面的書籍很少。中文資料我僅僅見過侯捷翻譯過的一本驅動開發的書上有兩三章涉及,也僅僅是只能用于9x的vxd驅動。NT文件系統我見過一本英文書。我都不記得這兩本書的書名了。

	如果您打算開發9x或者nt文件系統驅動,建議你去網上下載上文提及的書。那兩本書都有免費的電子版本下載。如果你打算開發Windows2000\WindowsXP\Window2003的文件系統驅動,你可以閱讀本教程。雖然本教程僅僅講述文件系統過濾驅動。但是如果您要開發一個全新的文件系統驅動的話,本教程依然對你有很大的幫助。

	學習文件系統驅動開發之前,應該在機器上安裝ifsddk。ddk版本越高級,其中頭文件中提供的系統調用也越多。經常有人詢問如xpddk編譯的驅動能不能在2000上運行等等的問題。我想可以這樣解釋:高級版本的ddk應該總是可以編譯低級驅動的代碼,而且得到的二進制版本也總是可以在低級系統上運行。但是反過來就未必可以了。如果在高級系統上編寫用于低級系統上的驅動,要非常認真的注意僅僅調用低級系統上有的系統調用。

	ifsddk可以在某些ftp上免費下載。

	我的使用的是ifs ddk for xp,但是我實際用來開發的兩臺機器有一臺是windows 2000,另一臺是windows 2003.我盡量使我編譯出來的驅動,可以在2000\xp\2003三種系統上都通過測試。

	安裝配置ddk和在vc中開發驅動的方法網上有很多的介紹。ifsddk安裝之后,src目錄下的filesys目錄下有文件系統驅動的示例。閱讀這些代碼你就可以快速的學會文件系統驅動開發。

	filter目錄下的sfilter是一個文件系統過濾驅動的例子。另一個filespy完全是用這個例子的代碼加工得更復雜而已。

	如何用ddk編譯這個例子請自己查看相關的資料。

	文件系統過濾驅動編譯出來后你得到的是一個擴展名為sys的文件。同時你需要寫一個.inf文件來實現這個驅動的安裝。我這里不討論.inf文件的細節,你可以直接用sfilter目錄下的inf文件修改。

	對inf文件點鼠標右鍵彈出菜單選擇“安裝”,即可安裝這個過濾驅動。但是必須重新啟動系統才生效。

	如果重啟后藍屏無法啟動,可以用其他方式引導系統后到system32\drivers目錄下刪除你的.sys文件再重啟即可。我嘗試這種情況下用安全模式結果還是藍屏。所以我后來不得不在機器上裝了兩個2000系統。雙系統情況下,一個系統崩潰了用另一個系統啟動,刪除原來的驅動即可。

	如果要調試代碼,請安裝softice.

	打開sfilter目錄下的文件sources(這個文件沒有擴展名),加入一行
	BROWSER_INFO=1	

	然后打開Symbol Loader,File->Open選中你編譯出來的xxx.sys,Modul->Load,Modul->Translate,然后就可以調試了。

	打開softice,輸入file *就可以看見代碼。

	如果準備好了,我們就可以開始琢磨windows文件系統過濾驅動的開發了。


2.hello world,驅動對象與設備對象

	這里所說的驅動對象是一種數據結構,在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.當系統用到你的驅動,會向你的DO發送IRP(這是windows所有驅動的共同工作方式)。你的任務是在dispatch function中處理這些請求。你可以讓irp失敗,也可以成功返回,也可以修改這些irp,甚至可以自己發出irp。

	設備對象則是指DEVICE_OBJECT.下邊簡稱DO.

	但是實際上每個irp都是針對DO發出的。只有針對由該驅動所生成的DO的IRP,
才會發給該驅動來處理。

	當一個應用程序打開文件并讀寫文件的時候,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.那么C:,D:則是NTFS的兩個Volume設備對象.

	實際上"C:"是該設備的符號連接(Symbolic Link)名。而不是真正的設備名。可以打開Symbolic Links Viewer,能看到:

	C: “\Device\HarddiskVolume1”
	
	因此該設備的設備名為“\Device\HarddiskVolume1”.

	這里也看出來,文件系統驅動是針對每個Volume來生成一個DeviceObject,而不是針對每個文件的。實際上對文件的讀寫的irp,都發到Volume設備對象上去了。并不會生成一個“文件設備對象”。

	掌握了這些概念的話,我們現在用簡單的代碼來生成我們的CDO,作為我們開發文件系統驅動的第一步牛刀小試。

	我不喜歡用微軟風格的代碼。太長而且難看。我對大部分數據結構和函數進行了重定義。為此我寫了一個名為wdf.h的頭文件幫助我轉換。有興趣的讀者可以發郵件向索取這個文件。沒有也沒有關系,我總是會寫出wd_xxx系列的東西在DDK中的原形。


// -----------------wdf_filter.c中的內容-------------------------

#include "wdf.h"

wd_stat wdff_cdo_create(in wd_drv *driver,
			in wd_size exten_len,
			in wd_ustr *name,
			out wd_dev **device)
{
    return wd_dev_create(
                driver,
                exten_len,
                name,
                wd_dev_disk_fs,
                wdf_dev_secure_open,
                wd_false,
                device);
}

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_filter");
	status = wdff_cdo_create(driver,0,&name,&g_cdo);

	if(!wd_suc(status))
	{
		if(status == wd_stat_path_not_found)
		{
			// 這種情況發生于\FileSystem\Filters路徑不存在。這個路徑是
			// 在xp上才加上的。所以2000下會運行到這里
			wd_ustr_init(&name,L"\\FileSystem\\our_fs_filter");
			status = wdff_cdo_create(driver,0,&name,&g_cdo);
		};
		if(!wd_suc(status))
		{
			wd_printf0("error: create cdo failed.\r\n");
			return status;
		}
	}	

	wd_printf0("success: create cdo ok.\r\n");
	return status;
}			

	為了讓代碼看起來象上邊的那樣,我不得不做了很多轉換。如

	#define wd_main DriverEntry 

	一種爽的感覺,終于可以在寫看起來更象是main()的函數中工作了。 wd_dev_create 這個函數內部調用的是IoCreateDevice.而wd_suc實際上是SUCCESS()這樣的宏。

// ----------------------wdf.h中的內容------------------------------
#include "ntifs.h"

#define in					IN
#define out					OUT
#define optional				OPTIONAL
#define wd_ustr					UNICODE_STRING
#define wdp_ustr				PUNICODE_STRING
#define wd_main					DriverEntry

// 設備、驅動對象類型
typedef DRIVER_OBJECT	wd_drv;
typedef DEVICE_OBJECT	wd_dev;
typedef DRIVER_OBJECT	wd_pdrv;
typedef PDEVICE_OBJECT	wd_pdev;

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
};

// 狀態相關的類型和宏
typedef NTSTATUS wd_stat;

enum {
	wd_stat_suc = STATUS_SUCCESS,
	wd_stat_path_not_found = STATUS_OBJECT_PATH_NOT_FOUND,
	wd_stat_insufficient_res = STATUS_INSUFFICIENT_RESOURCES,
	wd_stat_invalid_dev_req = STATUS_INVALID_DEVICE_REQUEST,
	wd_stat_no_such_dev = STATUS_NO_SUCH_DEVICE,
	wd_stat_image_already_loaded = STATUS_IMAGE_ALREADY_LOADED,
	wd_stat_more_processing = STATUS_MORE_PROCESSING_REQUIRED,
	wd_stat_pending = STATUS_PENDING
};

_inline wd_bool wd_suc(wd_stat state)
{
	return NT_SUCCESS(state);
}

#define wd_printf0				DbgPrint

_inline wd_void wd_ustr_init(in out wd_ustr* str,
					 in const wd_wchar* chars)
{
	RtlInitUnicodeString(str,chars);
};

_inline wd_void wd_ustr_init_em(
				in out wd_ustr*str,
				in wd_wchar *chars,
				in wd_size size)
{
	RtlInitEmptyUnicodeString(str,chars,size);
};


	wdf.h這個文件我僅僅節選了需要的部分。以上您已經擁有了一個簡單的“驅動”的完整的代碼。它甚至可以編譯,安裝(請修改sfilter.inf文件,其方法不過是將多處sfilter改為"our_fs_filter",希望這個過程中您不會出現問題)。然后把wdf.h和wdf_filter.c放在您新建立的目錄下,這個目錄下還應該有另兩個文件。一個是Makefile,請從sfilter目錄下拷貝。另一個是SOURCES,請輸入如下內容:
TARGETNAME=our_fs_filter
TARGETPATH=obj
TARGETTYPE=DRIVER
DRIVERTYPE=FS
BROWSER_INFO=1
SOURCES=wdf_filter.c

	使用ddk編譯之后您將得到our_fs_filter.sys.把這個文件與前所描述的inf文件同一目錄,按上節所敘述方法安裝。

	這個驅動不起任何作用,但是你已經成功的完成了"hello world".


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.我不知道這個指針留空會不會導致系統崩潰。在這里本來是沒有空間的,所以為了保存這一組指針,你必須自己分配空間。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品国模大尺度视频| a亚洲天堂av| 日本成人在线不卡视频| 亚洲综合男人的天堂| 一区二区国产视频| 一区二区三区在线免费视频| 亚洲视频在线观看一区| 成人免费一区二区三区在线观看| 国产精品第四页| 一区二区三区久久| 日韩成人精品视频| 国内欧美视频一区二区| 一区二区三区在线不卡| 色婷婷av久久久久久久| 久久免费视频色| 五月天久久比比资源色| 欧美绝品在线观看成人午夜影视| 欧美精品色一区二区三区| 欧美va亚洲va| 中文av一区二区| 一区二区三区在线视频观看58| 五月开心婷婷久久| 国产在线不卡一区| av男人天堂一区| 777久久久精品| 欧美国产97人人爽人人喊| 亚洲黄一区二区三区| 日韩av成人高清| 岛国av在线一区| 欧美日韩国产首页| xf在线a精品一区二区视频网站| 欧美日韩视频第一区| 奇米777欧美一区二区| 国产剧情av麻豆香蕉精品| 色悠悠亚洲一区二区| 日韩欧美一级在线播放| 亚洲人妖av一区二区| 久久精品国产999大香线蕉| 成人美女视频在线看| 欧美日韩一二三区| 国产精品水嫩水嫩| 日韩电影在线观看电影| 91丝袜呻吟高潮美腿白嫩在线观看| 欧美三级一区二区| 国产精品国产自产拍高清av| 蜜臀av在线播放一区二区三区| 91亚洲国产成人精品一区二三| 欧美日韩在线不卡| 中文字幕制服丝袜一区二区三区| 亚洲成av人综合在线观看| 国产日韩精品一区二区三区| 国产欧美精品一区二区色综合 | 粉嫩蜜臀av国产精品网站| 成人免费视频免费观看| 337p亚洲精品色噜噜噜| 1000精品久久久久久久久| 激情六月婷婷综合| 欧美日韩成人综合在线一区二区| 亚洲欧美怡红院| 国产成人自拍在线| 久久久久免费观看| 国精产品一区一区三区mba桃花| 在线观看成人免费视频| 亚洲欧洲av在线| 99精品黄色片免费大全| 国产精品色噜噜| 国产成人精品影院| 久久理论电影网| 国产在线一区二区| 精品处破学生在线二十三| 蜜臀久久99精品久久久久宅男| 欧美日韩一区二区三区免费看| 一区二区三区色| 91成人在线精品| 亚洲成人在线网站| 欧美精品日韩精品| 天天操天天综合网| 日韩一级黄色大片| 久久99精品国产麻豆婷婷洗澡| 精品日本一线二线三线不卡| 精品一区二区三区影院在线午夜| 日韩欧美在线综合网| 国产呦萝稀缺另类资源| 中文字幕av一区 二区| 波多野结衣在线一区| 国产精品区一区二区三区| 91视视频在线观看入口直接观看www | 一区二区三区免费网站| 欧美色视频在线观看| 蜜桃久久久久久| 久久久久久免费毛片精品| av高清不卡在线| 日精品一区二区| 国产午夜精品一区二区三区四区| 成人福利电影精品一区二区在线观看| 亚洲色图.com| 日韩一区二区三免费高清| 国产精品系列在线播放| 专区另类欧美日韩| 这里只有精品免费| 国产成人精品三级| 亚洲国产精品综合小说图片区| 精品欧美一区二区三区精品久久| 国产成人av网站| 午夜精品久久久久久久| 久久综合九色综合欧美98 | 91麻豆精品91久久久久久清纯| 久久99久久久久久久久久久| 成人免费在线视频观看| 日韩一区二区在线播放| 成人a级免费电影| 免费成人av资源网| 亚洲欧美激情小说另类| 精品盗摄一区二区三区| 色丁香久综合在线久综合在线观看| 美腿丝袜亚洲色图| 亚洲欧美精品午睡沙发| 久久色在线视频| 在线播放视频一区| 91在线观看视频| 国产麻豆9l精品三级站| 午夜国产不卡在线观看视频| 国产精品不卡在线| 欧美精品一区二区三区四区| 欧美特级限制片免费在线观看| 粉嫩高潮美女一区二区三区 | 2020国产精品自拍| 欧美日韩你懂得| 99re热这里只有精品视频| 国产在线日韩欧美| 日韩中文字幕区一区有砖一区| 国产精品成人网| 国产欧美一区二区精品秋霞影院| 91精品国产综合久久福利| 91国产福利在线| 91色.com| av亚洲产国偷v产偷v自拍| 国产精品一区二区在线播放| 日韩电影在线观看电影| 午夜精品久久久久久久久久久| 亚洲美女在线一区| 一区二区三区在线免费观看| 综合中文字幕亚洲| 中文字幕一区二区三区av| 国产欧美日韩视频在线观看| 久久综合九色综合97婷婷女人| 欧美成人video| 精品区一区二区| 久久久久免费观看| 久久久久久久久久电影| 国产女主播一区| 国产精品久久久久久久岛一牛影视| 久久久高清一区二区三区| 精品国产精品一区二区夜夜嗨| 精品三级在线观看| 久久婷婷综合激情| 欧美性色aⅴ视频一区日韩精品| 日韩一级视频免费观看在线| 国产河南妇女毛片精品久久久| 激情五月播播久久久精品| 免费观看一级欧美片| 日本在线不卡视频一二三区| 免费成人美女在线观看| 日本成人中文字幕| 国产福利一区二区三区视频在线 | 一区二区三区丝袜| 国产精品久久久久久久久搜平片| 日韩久久一区二区| 五月婷婷综合在线| 精品亚洲国产成人av制服丝袜| 国产乱对白刺激视频不卡| 国产真实精品久久二三区| 成人污污视频在线观看| 91国模大尺度私拍在线视频| 欧美日韩电影在线| 久久尤物电影视频在线观看| 欧美激情在线观看视频免费| 国产亚洲欧美日韩日本| 一区二区三区四区高清精品免费观看| 亚洲一二三四区| 国模大尺度一区二区三区| 床上的激情91.| 在线观看国产日韩| 日韩欧美国产精品| 日本一区二区高清| 亚洲高清免费视频| 国产不卡在线一区| 欧美日韩小视频| 中文字幕国产精品一区二区| 亚洲国产精品久久久久婷婷884 | 在线免费观看视频一区| 日韩精品一区二区在线| 亚洲啪啪综合av一区二区三区| 日韩影院在线观看| 不卡一区中文字幕| 日韩欧美你懂的| 一区二区三区精品久久久| 国产在线精品免费av| 欧美视频一区二区在线观看| 国产精品视频观看|