檔案過濾驅動之一

來源:互聯網
上載者:User

終於到了禮拜天,抓緊時間寫了段文檔。
由於不是一次兩次就能說的清楚,所以我分塊來說明,這篇希望能講解出一個驅動的架構,以後的講解就在這個架構的基礎上深入展

開。
對於檔案過濾驅動的整體描述,我認為下面這個文章裡codewarrior(會思考的草) 說的很不錯,在次感謝
http://community.csdn.net/Expert/topic/4849/4849948.xml?temp=.1946985

這裡先對ddk裡面幾個基礎的東東大概說明下:

入口函數:
和win32編程一樣,驅動也有一個入口函數DriverEntry(相當於main WinMain),這裡注意他們之間的運行方式是不同的,win32入口

函數後是進入訊息迴圈,驅動DriverEntry的主要功能是註冊一些IRP的相當於回調處理方式的函數,也就是我們所說的派遣函數。。
IRP:
IRP(I/O 請求包),驅動編程裡十分重要的概念,說白了它就是一個資料結構,裡面有對應操作需要的資料,比如我們應用程式層調用了

CreateFile函數,在驅動層可能就構建一個IRP(IRP_MJ_CREATE),通過這個IRP的處理完成對應操作,如果我們對使用者開啟,建立檔案

等操作有興趣(比只允許指定程式開啟對應檔案),就可以通過掛接的方式讓系統將這個IRP發送到我們指定的函數(就是

DriverEntry裡面指定的),然後...
CDO:
CDO(ontrol Device Object),控制裝置物件,這個對象代表這個驅動,它是供我們應用程式層的程式使用的,在DriverEntry裡面建立

它,注意它沒有裝置擴充。這裡有必要說一下一般見到說的DO(device object),DO是用來綁定到檔案系統驅動的FDO上的,和CDO

不同。他們都使用IoCreateDevice函數建立,注意區別。
Device Extension:
Device Extension(裝置擴充),使用IoCreateDevice建立DO等時通過第2個參數來指定,其實它就是一塊儲存有用資料的記憶體,這

裡一般就是一個結構體。請注意它會隨DO一起傳遞,這就是它的關鍵好處所在。
就講這幾個了,還有很多,用到的時候再說,下面先從DriverEntry說起。
DriverEntry一般都下面這樣的形式,2個參數的類型都帶了P,相信大家一看就知道是指標形式,加下注釋
NTSTATUS
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,//指向系統建立的我們的驅動對象
    IN PUNICODE_STRING RegistryPath//驅動註冊key的路徑
    )
首先需要做的是申明一個全域的PDRIVER_OBJECT變數,儲存我們的DriverObject,因為我們在其他地方可能會用到它,然後就是取得

一些需要使用函數的地址,存放在全域變數中,這裡不說這個。接著就可以建立我們的控制裝置物件了,就是前面說的CDO,建立它

使用函數IoCreateDevice,如下:

DEVICE_OBJECT   * ourCDO = NULL;//注意這個變數是全域,為了看的清楚我才放在這裡!!!!!!!!
                //我們的CDO控制裝置物件,前面有說到它
    
NTSTATUS                    status = STATUS_SUCCESS;//傳回值我讓它預設為成功
UNICODE_STRING     Name_2k;//請注意我這裡加了個2k,是為了引起大家的注意,因為XP系統裡下面那個串會不   

                     //一樣
RtlInitUnicodeString(&Name_2k,L"//FileSystem//OurFilter_Cdo");//就是這個串,xp下是                                  

                                   

//L"//FileSystem//Filters//OurFilter_Cdo"
status  =  IoCreateDevice(DriverObject,//我們的驅動程式對象
  0,//擴充裝置的大小,就是前面說的Device Extension,還記得前面說的CDO沒有裝置擴充嗎      

                 //?,所以置0
  &Name_2k,//裝置名稱
  FILE_DEVICE_DISK_FILE_SYSTEM,//裝置的類型
  FILE_DEVICE_SECURE_OPEN,//指出裝置所允許的操作
  FALSE,//TRUE表示只能有一個線程使用該裝置,FALSE則沒有1個使用的限制
  &ourCDO //返回的控制裝置物件CDO
  );
if(!NT_SUCCESS(status))//如果建立控制裝置物件失敗,退出
 return status;

接下來我們可以建立一個Win32可見的符號串連
UNICODE_STRING     Link_2k;
RtlInitUnicodeString(&Link_2k,L"//DosDevices//OurFilter");
status = IoCreateSymbolicLink(&Link_2k ,&Name_2k);
if(!NT_SUCCESS(status))
 return status;

到這裡後我們就可以設定我們的派遣函數了,前面說過了,就是能處理到IRP的函數,具體怎麼設定,我先以一個簡單的為了動態禦

載而設定的DriverUnload函數為例子來說明,該函數會在禦載的時候調用,設定這個函數的代碼大致如下:

先聲明函數,為了使DriverEntry可見,所以一般是在對應的標頭檔裡面聲明
void DriverUnload(IN PDRIVER_OBJECT DriverObject);
接著在DriverEntry裡添加
//設定Unload
DriverObject->DriverUnload = DriverUnload;
至於DriverUnload函數都需要做些什麼,主要就是一些DO ,CDO等的刪除,資源的釋放,取消掛接等等,這裡由於我們上面的操作比

較簡單,所以需要釋放的東東也就不多
void DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
                UNICODE_STRING uniNameString;
               
                RtlInitUnicodeString(&uniNameString, L"//FileSystem//OurFilter_Cdo");
                IoDeleteSymbolicLink(&uniNameString);        //刪除win32可見
                IoDeleteDevice(pDriverObject->DeviceObject);        //刪除裝置
               
                return ;
}

到這裡,一個最基本的驅動架構也就出來了,加入DbgPrint()調試資訊,編譯得到XX.sys後裝載調試完全可以看到輸出的調試資訊
,由於DriverUnload的設定使其能支援動態禦載,如何編譯調試等這裡就不說了。以後的資料就在這個架構的基礎上擴充。

再次說明一下,由於是在網吧匆忙寫的,加上水平很菜,沒說清楚或有錯誤請大家指出,有時間我會把後面的都寫出來,希望對大家

有協助

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.