Windows驅動開發技術詳解 筆記1

1.Windows驅動程序分爲兩類:NT式驅動程序,WDM式驅動程序。
2.驅動程序的入口函數DriverEntry,它有兩個參數DriverObject 和RegistryPath。
    DriverEntry函數由IO管理器負責調度,這兩個函數也是由IO管理器負責分配和指定的。第一個代表IO管理器傳遞進來的驅動程序對象,第二個指向此驅動程序負責的註冊表。
3.設備類型FILE_DEVICE_UNKNOWN此種設備爲獨佔設備,即設備只能被一個應用程序所使用。
4.設備對內存的操作有兩種方式:DO_BUFFERED_IO和 DO_DIRECT_IO
5.驅動卸載例程
    VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
    {
        PDEVICE_OBJECT    pNextObj;
        pNextObj = pDriverObject->DeviceObject;
       //遍歷設備對象鏈表,刪除設備
       while (pNextObj != NULL)
       {
            PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
            //刪除符號鏈接
            UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
            IoDeleteSymbolicLink(&pLinkName);
            pNextObj = pNextObj->NextDevice;
            IoDeleteDevice( pDevExt->pDevice );
        }
     }
6.在VS2005中配置驅動開發環境參考:http://blog.sina.com.cn/s/blog_5371d2790100bsy2.html
  在visual c++ 6.0 中配置驅動開發環境參考《windows驅動程序開發技術詳解》--1.3.2節
7.NT或WDM式的驅動程序在默認情況下是隱藏的,但也可以通過設備管理器來查看,路徑如下:
  設備管理器--->查看---->顯示隱藏的設備----->非即插即用設備
8.有些代碼中會看到這樣的字段,比如:
  #pragma INITCODE
  NTSTATUS DriverEntry().........
  其中的#pragma 指明函數是加載到INIT內存區域中的。INIT標誌指明該函數只是在加載的時候需要裝入內存,當程序被卸載以後,該函數可以從內存區域中卸載掉。

  可以通過以下方式定義分頁內存,非分頁內存,初始化內存等:
   #define PAGEDCODE code_seg("PAGE")//分頁內存
   #define LOCKEDCODE code_seg()     //非分頁內存
   #define INITCODE code_seg("INIT")//初始化內存
   #define PAGEDDATA data_seg("PAGE")//分頁內存
   #define LOCKEDDATA data_seg()     //非分頁內存
   #define INITDATA data_seg("INIT")//初始化內存

8.WDM驅動程序中有一個dispatch 例程:AddDevice,該dispatch routine是用來創建設備對象並由PNP管理器調用的。
    DriverObject->DriverExtension->AddDevice = DriverAddDeviceRoutine;
9.俄從去年就開始研究WDM驅動程序,到現在才發現俺寫的一直都是NT式的驅動程序。唉..........
10.WDM和NT式驅動的一個重要區別就是要對IRP_MJ_PNP請求進行處理。還有一個就是AddDevice例程。
11.PAGED_CODE()
   這是一個DDK提供的宏,只在check版中有效。當此例程所在的中斷請求級別超過APC_LEVEL時,會產生一個斷言,斷言會使程序終止,並報告出錯的地址。
12.WDM 驅動程序的加載
   WDM驅動程序不能像NT式驅動程序一樣以服務的形式加載到系統中,需要自己編寫一個inf文件,可以使用由DriverStufio自帶的EzDriverInstaller工具。
   還可以才用如下的方式:
   控制面板--->添加硬件--->"是,我已經連接了此硬件"--->“添加新的硬件設備”--->“安裝我手動從列表中選擇的硬件(高級)”--->顯示所有設備--->從磁盤安裝。
   這種方式比較繁瑣,而且需要等待系統枚舉所有的設備,可能要等很長時間,所以還是推薦使用EzDriverInstaller安裝、啓動、關閉、卸載、重啓。
13.科普知識
   Windows 9X系列:Windows95、Windows98、Windows ME
   Windows NT系列:Windows NT3.1(93年7)、Windows NT3.5(94年9)、Windows NT4.0(96年7)
                   Windows 2000(99年12)、Windows XP(01年8)、Windows Server 2003(03年3)

14.Windows驅動程序和普通win32的應用程序一樣,也是PE格式的文件。C語言中對變量的聲明必須在函數的首部,而C++則沒有這個限制。但是C++的許多高級特性是不適合用來開發驅動程序的,所以可以使用C++的簡單特性來寫驅動程序。但最好還是用C。

15.當一個函數被調用的時候,首先壓入函數的各個參數,然後壓入函數的返回地址。當函數退出的時候以相反的順序依次退出堆棧,從而保持了堆棧的平衡。

   C語言調用約定:(__cdecl)從右到左參數入棧,調用者恢復堆棧。

   標準調用約定:(__stdcall)從右向左參數入棧,函數本身負責恢復堆棧

   Windows驅動程序的編譯需要使用標準調用約定,尤其是入口函數。所以用VC編譯器的時候應該將VC的C語言調用約定更改爲標準調用約定。(Vs2005中我沒有更改,編寫的驅動也是照樣可以運行,所以此說法有待驗證。)如果用DDK編譯則可以忽略這個環節。

16.在C++中添加C語言的程序,需要用extern "C"來修飾

   有時候 出現下面的錯誤,可以考慮在代碼前面加上以上修飾符。

   :error LNK2001:unresolved external symbol "unsigned long __cdecl 。。。。"

17.Windows操作系統規定,在內核模式的程序無法調用用戶模式的程序,而用戶模式的程序可以調用內核態的程序。

18.WDM驅動程序加載

   (1)Windows在安裝的時候會提供很多INF文件,根據不同的VernderID何ProductID,會找出合適這個設備的INF文件,如果系統中沒有合適的INF文件,系統會向用戶詢問是否可以提供這個INF文件,如果不能則嘗試到微軟網站去尋找。找到INF文件後,系統會根據INF文件上的指示,將驅動程序(.sys文件)和相關文件複製到系統指定目錄下,並且修改註冊表。同時通知PNP管理器和I/O管理器,創建新設備,並運行驅動程序的入口程序DriverEntry。

   (2)INF文件剖析:INF文件是一個文本文件,由若干個節(Section)組成。每個節的名稱用一個方括號指示,緊接着方括號後面的就是節的內容。每一行就是一項內容,其形式都是類似SomeEntry = SomeValue。每個項的順序是可以顛倒的,但系統分析INF文件的時候,是順序解析的。INF中註釋語句是用分號開頭的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章