久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

windows WDM驅(qū)動程序設(shè)計

 阿鼎的圖書館 2011-12-18

windows WDM驅(qū)動程序設(shè)計

分類: windows 驅(qū)動編程 25人閱讀 評論(3) 收藏 舉報

      回顧微軟10年,,驅(qū)動開發(fā)模型從VxD->WDM->WDF,開發(fā)工具從VtoolsD-->DDK-->WDK,在這個過程中,,出現(xiàn)了一些優(yōu)秀的開發(fā)工具,,windriver,driver studio 3.2 等,。其中windriver適合用來調(diào)試硬件,driver studio 3.2 采用C++開發(fā)框架,用戶只要簡單的寫幾個回調(diào)函數(shù)就可以完成驅(qū)動的編寫,,但是該軟件又微軟新的驅(qū)動模型WDF的沖擊,不在對它進行開發(fā)了,,將最終版本定格在3.2,,我最先學(xué)習(xí)驅(qū)動程序就是通過driver studio學(xué)習(xí)的。

     從windows 2000開始,,開發(fā)驅(qū)動程序以WDM為基礎(chǔ),,但開發(fā)難度大,為了改善這種局面,,微軟推出WDF,,它以WDM為基礎(chǔ)進行建模和封裝,降低了開發(fā)的難道,。

    (一)WDF驅(qū)動模型到windows WDF驅(qū)動程序設(shè)計中進行講解:下面主要講講WDM驅(qū)動模型和WDF驅(qū)動模型的區(qū)別,;

    1)WDF采用基于對象的技術(shù)對WDM進行封裝,對象包括,,屬性,,方法和事件,屬性好比C++中類中的成員變量,,而方法好比C++類中的成員函數(shù),,事件就是回調(diào)函數(shù);

    2)無論內(nèi)核模式的驅(qū)動程序或者用戶模式的驅(qū)動程序,,都采用同一套對象模型構(gòu)建,,采用同一個基礎(chǔ)承載。這個基礎(chǔ)就是WDF。 WDF包括KMDF和UMDF,,兩者都是繼承了WDF,,無論哪種框架,內(nèi)部封裝的方法還是WDM,。

    3)WDF驅(qū)動模型封裝了很多通用的功能,,比如Pnp管理和電源管理,在WDM驅(qū)動模型下,,Pnp和電源管理是很復(fù)雜的,,最多有300種狀態(tài),但是WDF驅(qū)動模型下,,WDF框架實現(xiàn)了Pnp和電源管理的功能,,驅(qū)動開發(fā)者幾乎不要寫一行代碼就可以實現(xiàn)Pnp和電源管理,舉個不恰當?shù)睦?,WDF驅(qū)動框架就是對WDM驅(qū)動的一次抽象,,好像C++中抽象類,其中以純虛函數(shù)的形式實現(xiàn)了PNp和電源管理,,如果用戶沒有特殊的要求直接使用框架提供的電源管理和Pnp管理就行了,。如果要實現(xiàn)特殊的功能,框架提供了回調(diào)函數(shù),,驅(qū)動開發(fā)者實現(xiàn)回調(diào)函數(shù)的功能就可以了,,這個回調(diào)函數(shù)就好比C++中的override,將基類提供的虛函數(shù)覆蓋掉,,實現(xiàn)自己的函數(shù),;

    4)WDF 采用了基于隊列的I/O派遣隊列,這樣的好處是可以指定哪些IO在哪個隊列上使用,;這樣我個人認為 好處就是,,會減少IO同步操作,減少系統(tǒng)資源的占用,,比如說鎖的占用,;

 

  (二) 講了WDM驅(qū)動模型和WDF驅(qū)動模型的區(qū)別后,我們下面講解WDM驅(qū)動模型,,首先從WDM驅(qū)動模型中重要的數(shù)據(jù)結(jié)構(gòu)談起:

   1)驅(qū)動對象(DRIVER_OBJECT)

     每個驅(qū)動程序會有唯一的驅(qū)動對象與之對應(yīng),,它作為驅(qū)動的一個實例在內(nèi)核的I/O管理器負責(zé)加載。
 typedef struct
  {
  PDEVICE_OBJECT DeviceObject;
  PUNICODE_STRING HardwareDatabase;
  PFAST_IO_DISPATCH FastIoDispatch;
  PDRIVER_INITIALIZE DriverInit;
  PDRIVER_STARTIO DriverStartIo;
  PDRIVER_UNLOAD DriverUnload;
  PDRIVER_DISPATCH MajorFunction[IRP_MJ_NUM+1];
  } DRIVER_OBJECT,*PDRIVER_OBJECT;
DeviceObject:指向驅(qū)動程序創(chuàng)建的設(shè)備對象,。這個驅(qū)動程序調(diào)用IoCreateDevice的時候會自動賦予正確的設(shè)備對象指針,。每個驅(qū)動程序會有一個或多個設(shè)備對象。其中,,每個設(shè)備對象都有一個指針指向下一個驅(qū)動對象,,最后一個設(shè)備對象指向空,。此處的 DeviceObject指向驅(qū)動對象的第一個設(shè)備對象。通過 DeviceObject,,就可以遍歷驅(qū)動對象里的所有設(shè)備對象,。
MajorFunction[IRP_MJ_NUM+1]:函數(shù)指針的數(shù)組 ,每一個指針指向一個函數(shù),這個函數(shù)就是處理IRP的派遣函數(shù),。
 
對于驅(qū)動程序來說,,每個驅(qū)動都有唯一的驅(qū)動對象與之對應(yīng),驅(qū)動對象由IO管理器負責(zé)加載,;
 
 
       將完驅(qū)動對象后,,另外一個重要的數(shù)據(jù)結(jié)構(gòu)就是設(shè)備對象了,,在DRIVER_OBJECT中也包含DeviceObject對象的一項成員,,一般在驅(qū)動的DriverEntry中調(diào)用IoCreateDevice創(chuàng)建設(shè)備對象,然后將設(shè)備對象和驅(qū)動對象聯(lián)系起來,,下面先看看設(shè)備對象的數(shù)據(jù)結(jié)構(gòu)吧,。
     
2)設(shè)備對象(DEVICE_OBJECT)
typedef struct _DEVICE_OBJECT {
.....
  struct _DRIVER_OBJECT *  DriverObject;
  struct _DEVICE_OBJECT *  NextDevice;
  struct _DEVICE_OBJECT *  AttachedDevice;
....
  PVOID                       DeviceExtension;
.....
} DEVICE_OBJECT, *PDEVICE_OBJECT;
DriverObject:指向驅(qū)動程序中的驅(qū)動對象;
NextDevice:指向下一個設(shè)備對象,,這里指的下一個設(shè)備對象是同屬于一個驅(qū)動對象的設(shè)備,,每個設(shè)備對象根據(jù)NextDevice域形成鏈表,從而可以枚舉每個設(shè)備對象,;
AttachedDevice:指向下一個設(shè)備對象,,如果有更高層的驅(qū)動附加到這個驅(qū)動的時候, AttachedDevice指向那個更高層的驅(qū)動,。
DeviceExtension:指向的是設(shè)備的擴展對象,,也就是程序員自己定義的結(jié)構(gòu)體。
 
通過AttachedDevice可以將上層的驅(qū)動附加到下層驅(qū)動,;而DeviceExtension數(shù)據(jù)結(jié)構(gòu)也是很重要的數(shù)據(jù)結(jié)構(gòu),,一般保存全局的信息,這樣這些信息便于管理,,比如同步加鎖管理等等;增加驅(qū)動的可重入性,。在DeviceExtension 結(jié)構(gòu)中可以提供一個指向下層設(shè)備的指針,這樣從可以從上層設(shè)備找到下層設(shè)備,,同時也可以通過AttachedDevice從下層設(shè)備找到上層設(shè)備,。這樣方便查找設(shè)備
 
 
(三)介紹完WDM驅(qū)動模型重要的數(shù)據(jù)結(jié)構(gòu)后,我們下面來看看,,Windows應(yīng)用程序怎么和驅(qū)動程序進行通信,,對于windows 平臺來說,應(yīng)用程序和驅(qū)動程序進行通信,,就是通過windows提供的api,,如:CreateFile,,ReadFile,WriteFile,DeviceIoControl,CloseFile等等,。  那么這些api是怎么聯(lián)系到驅(qū)動程序的呢,,舉個簡單的例子來說吧,CreateFile,,當應(yīng)用程序調(diào)用這個函數(shù)時,,通過注冊表,進入內(nèi)核調(diào)用NtCreateFile,,然后在內(nèi)核用系統(tǒng)的IO管理器創(chuàng)建和發(fā)送IRP,,對于IRP,就是輸入輸出請求包,,驅(qū)動程序都是IRP驅(qū)動的,,對于IO管理,Pnp管理,,電源管理,,都會轉(zhuǎn)化成對應(yīng)的IRP,然后轉(zhuǎn)發(fā)給驅(qū)動程序,,而相對驅(qū)動程序,,主要的功能就是實現(xiàn)這些IRP的回調(diào)函數(shù),而在WDF驅(qū)動模型下,,IO是由IO管理器的IRP和隊列共同作用的,。這一點在WDM驅(qū)動模型和WDF驅(qū)動的差別中進行了講解。
 
同樣對于ReadFile和WriteFile的流程和CreateFile相似,,都是通過IRP轉(zhuǎn)發(fā)給驅(qū)動的,。
 
 
(四)對于驅(qū)動人員來說,最關(guān)心的就是IO操作了,,在WDM和WDF驅(qū)動中,,驅(qū)動程序所創(chuàng)建的設(shè)備一般有2種讀寫方式:1)緩沖區(qū)方式;2)Direct方式 ,;3)Neither
緩沖區(qū)方式:在系統(tǒng)內(nèi)核中創(chuàng)建和用戶模式相同的緩沖區(qū),,用于發(fā)送或接收硬件的數(shù)據(jù),然后將緩沖區(qū)的數(shù)據(jù)copy給應(yīng)用程序,;
Direct方式:和緩沖區(qū)方式讀寫設(shè)備不同,,直接方式讀寫設(shè)備,操作系統(tǒng)會將用戶模式下得緩沖區(qū)鎖住,,然后操作系統(tǒng)將這段緩沖區(qū)在內(nèi)核模式地址再次映射一遍,。這樣用戶模式的緩沖區(qū)和內(nèi)核模式的緩沖區(qū)指向的是同一區(qū)域的物理內(nèi)存。
Neither讀寫方式在此不在進行介紹,。
   對于windows驅(qū)動開發(fā)的難點,,在于在驅(qū)動程序中減少緩沖區(qū)的copy,,因為memcpy是很耗時間和cpu的。
 
 
(五)Irp派遣函數(shù),,派遣函數(shù)是windows驅(qū)動程序中的一個重要概念,,驅(qū)動程序的主要功能是負責(zé)處理I/O請求,其中大部分I/O請求是在派遣函數(shù)中處理的,。
用戶模式下所有對驅(qū)動程序的I/O請求,,全部由操作系統(tǒng)轉(zhuǎn)換為IRP的數(shù)據(jù)結(jié)構(gòu),不同的IRP數(shù)據(jù)會被派遣到不同的派遣函數(shù),。
IRP定義:
    在windows內(nèi)核中,,有一種數(shù)據(jù)結(jié)構(gòu)叫做IRP(I/O Request Package),即輸入輸出請求包。它是與輸入輸出相關(guān)的重要數(shù)據(jù)結(jié)構(gòu),,上層應(yīng)用程序與底層驅(qū)動程序通信時,,應(yīng)用程序會發(fā)出I/O請求,操作系統(tǒng)將I/O請求轉(zhuǎn)換為相應(yīng)的IRP數(shù)據(jù),,不同類型的IRP會根據(jù)類型傳遞到不同的派遣函數(shù)中,。
 
 
(六)驅(qū)動的同步處理:和windows應(yīng)用程序多線程同步類似,內(nèi)核也有信號量,,互斥,自旋鎖,,事件等同步機制,,而這些同步機制 的函數(shù)就是在應(yīng)用程序的函數(shù)前面加一個ke,比如對于事件來說:SetEvent對于KeSetEvent,,WaitForSingleObject對應(yīng) KeWaitForSingleObject,。我們知道應(yīng)用程序多線程怎么同步,驅(qū)動程序內(nèi)部怎么同步,,那么驅(qū)動程序和應(yīng)用程序之間如果同步呢,,有一種方法,在應(yīng)用程序中調(diào)用DeviceIoControl傳遞一個Event句柄給驅(qū)動程序,,在驅(qū)動程序中鎖定這個句柄,,然后在驅(qū)動中調(diào)用KeSetEvent,在應(yīng)用程序中通過WaitForSingleObject就可以同步了,。其實對于DDK和WDK里面提供的函數(shù)也是這樣操作的,;下面在講解下DeviceIoControl的流程:
 
DeviceIoControl 分為同步和異步操作2種,主要是看最后一個參數(shù),,這個參數(shù)和CreateFile中一個參數(shù)配合使用,,就可以實現(xiàn)同步操作和異步操作,對于DeviceIoControl同步操作而言,,當應(yīng)用程序調(diào)用DeviceIoControl時,,其實里面會有一個等待的函數(shù),,當驅(qū)動程序通過 IoCompleteRequest 完成對應(yīng)的這個Irp時,其實他就是發(fā)送一個信號給應(yīng)用程序,,基本原理和上面講的應(yīng)用程序和驅(qū)動程序同步類似,。
 
同理當DeviceIoControl 異步調(diào)用時,也是類似的,。
 
 
(七)在驅(qū)動程序中有分層的概念,,比如說過濾驅(qū)動程序,在Ndis驅(qū)動中,,過濾驅(qū)動是很重要的,,比如你要實現(xiàn)一個防火墻或殺毒軟件,最可靠的方法就是實現(xiàn)一個Ndis中間層驅(qū)動程序,,在多層驅(qū)動程序框架下,,RP請求一般會被傳送到設(shè)備棧的最頂層的設(shè)備對象,頂層的設(shè)備對象可以選擇直接結(jié)束IRP(IoCompleteRequest),也可以選擇將IRP請求向下層的設(shè)備對象轉(zhuǎn)發(fā)(IoCallDriver),,如果是向下層設(shè)備對象轉(zhuǎn)發(fā)IRP請求,,IRP結(jié)束時,IRP會順著設(shè)備棧的反方向原路返回,。當?shù)弥聦域?qū)動程序已經(jīng)結(jié)束IRP請求時,,本層設(shè)備對象可以選擇繼續(xù)講IRP向上返回,或者選擇將IRP再次傳遞給底層設(shè)備驅(qū)動,。
 
這樣防火墻原理就是做一個過濾驅(qū)動,,將惡意程序過濾掉,不然它提交給驅(qū)動程序,;殺毒軟件也類似,,在內(nèi)核就講病毒識別出來,在殺掉,!
 
 
(八)Pnp即插即用
即插即用體系結(jié)構(gòu)的主要目標是不需要用戶介入,,而直接對設(shè)備安裝、拆除操作進行自動配置,。
(1)系統(tǒng)能夠檢測到新設(shè)備的插入,,也能檢測到設(shè)備被拔出;
(2)如果總線接口容許,,設(shè)備可以實現(xiàn)熱插拔,,并保證系統(tǒng)可以正常工作,如usb設(shè)備,,當設(shè)備插入時,,系統(tǒng)會自動加載其驅(qū)動,并且保證usb總線上其它設(shè)備能正常工作,,另外當系統(tǒng)運行時,,拔掉usb設(shè)備不會引起系統(tǒng)的崩潰,。
狀態(tài)轉(zhuǎn)換圖:
1)當一個設(shè)備被添加到系統(tǒng)時,Windows查找正確的驅(qū)動程序,,并調(diào)用它的DriverEntry例程,;
2)Pnp管理器然后調(diào)用驅(qū)動程序的AddDevice例程,告訴它要添加一個新設(shè)備,,此時驅(qū)動程序創(chuàng)建自己的設(shè)備對象,;即FDO。
3)在處理的過程中,,驅(qū)動程序會收到IRP_MN_START_DEVICE的IRP,,開始與硬件進行合適的對話;
4)如果一個設(shè)備要被拔出,,Windows使用IRP_MN_REMOVE的IRP查詢驅(qū)動程序設(shè)備,。如果驅(qū)動程序不希望設(shè)備被刪除,它將拒絕刪除請求,,然后發(fā)送IRP_MN_CANCEL_REMOVE的IRP,,使它回到開始狀態(tài);
5)如果用戶突然拔掉一個設(shè)備,,在Windows中會發(fā)送IRP_MN_SUPPRISE_REMOVE的IRP,,驅(qū)動必須處理好中斷了的傳輸。
 
 
(九)電源管理 (省略)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多