基于Windows2000的過(guò)濾器驅動(dòng)程序設計

發(fā)布時(shí)間:2010-6-30 17:56    發(fā)布者:我芯依舊
WDM(Windows Driver Mode)是微軟公司為Windows的驅動(dòng)程序設計的一種通用的驅動(dòng)程序模型。相比以前的KDM和VXD來(lái)說(shuō),他的性能更高、系統之間移植更加方便。所以,隨著(zhù)系統的升級,WDM已經(jīng)成為Windows 2000系統下驅動(dòng)程序開(kāi)發(fā)的主流。作為WDM模型之中一類(lèi)特殊的驅動(dòng)程序,過(guò)濾器驅動(dòng)程序(Filter driver)可以在不更改現有驅動(dòng)程序的情況下,方便地修改、增加現有驅動(dòng)程序的功能。特別是對于Windows 2000已經(jīng)提供了通用驅動(dòng)程序的硬件設備,通過(guò)編寫(xiě)過(guò)濾器驅動(dòng)程序,可以以較小的代價(jià)擴展硬件現有的功能。因此具有很強的實(shí)際應用價(jià)值。

1 Windows 2000 I/O請求處理結構

如圖1所示,Windows 2000是分態(tài)的操作系統。用戶(hù)應用程序運行在用戶(hù)態(tài),操作系統代碼(如系統服務(wù)和設備驅動(dòng)程序)在核心態(tài)下運行。用戶(hù)態(tài)程序只能調用Win32子系統提供的API來(lái)同設備交互,當請求傳遞到I/O管理器時(shí),他進(jìn)行必要的參數匹配和操作安全性檢查,然后由這個(gè)請求構造出合適的IRP(IO Request Package,I/O請求包),并把此IRP傳遞到適當的驅動(dòng)程序去,并給應用程序一個(gè)消息,通知這次I/O操作還沒(méi)完成。驅動(dòng)程序一般通過(guò)硬件抽象層來(lái)和硬件交互,從而完成I/O請求工作。驅動(dòng)程序完成I/O操作后,他將調用一個(gè)特殊的內核服務(wù)例程來(lái)完成IRP。這時(shí),I/O管理器把數據和結果返回給Win32和用戶(hù)應用程序。



2 WDM驅動(dòng)程序模型體系結構

Windows驅動(dòng)程序模型重新定義驅動(dòng)程序分層使用了如圖2的層次結構。圖中左邊是一個(gè)設備對象堆棧。設備對象是系統為幫助軟件管理硬件而創(chuàng )建的數據結構。一個(gè)物理硬件可以有多個(gè)這樣的數據結構。處于堆棧最底層的設備對象稱(chēng)為物理設備對象PDO(Physical Device Object),代表了設備和總線(xiàn)之間的連接。在設備對象堆棧的中間的對象稱(chēng)為功能設備對象FDO(Functional Device Object),代表了設備的功能。在FDO的上面和下面還會(huì )有一些過(guò)濾器設備對象FIDO(Filter Device Object)。位于FDO上面的過(guò)濾器設備對象稱(chēng)為上層過(guò)濾器,位于FDO下面(但仍在PDO之上)的過(guò)濾器設備對象稱(chēng)為下層過(guò)濾器。


總線(xiàn)驅動(dòng)程序負責枚舉他的總線(xiàn),這意味著(zhù)發(fā)現總線(xiàn)上的全部設備和檢測設備何時(shí)被添加或刪除并為每個(gè)設備創(chuàng )建一個(gè)PDO。功能驅動(dòng)程序知道如何控制設備的主要功能,他分層在總線(xiàn)驅動(dòng)程序的上面。功能驅動(dòng)程序創(chuàng )建一個(gè)功能設備對象,放在設備棧中。對總線(xiàn)上的所有設備,總線(xiàn)過(guò)濾驅動(dòng)程序被加在總線(xiàn)驅動(dòng)程序之上;設備過(guò)濾驅動(dòng)程序僅對特定的設備添加。上層的過(guò)濾驅動(dòng)程序在功能驅動(dòng)程序之上,而下層過(guò)濾驅動(dòng)程序在功能驅動(dòng)程序之下。這種層次結構可以使I/O請求過(guò)程更加明了。I/O管理器發(fā)送的IRP,先被送到設備堆棧的上層過(guò)濾器驅動(dòng)程序(FIDO),他可以根據要求決定IRP的處理方式,是沿著(zhù)設備棧繼續向下傳,或者是做一些額外的處理。依次,每一層驅動(dòng)程序都可以決定如何處理IRP。高層的驅動(dòng)程序可以把請求劃分成更簡(jiǎn)單的請求并傳遞給下層驅動(dòng)程序。中間層次的驅動(dòng)程序進(jìn)一步處理請求,將一個(gè)IRP中的請求劃分為若干個(gè)小的請求并傳給下層驅動(dòng)程序。最后,最低層的驅動(dòng)程序與硬件打交道。因此一些IRP在到達總線(xiàn)程序之前,在設備棧傳遞過(guò)程中可能就被過(guò)濾掉了。

3 過(guò)濾器驅動(dòng)程序

過(guò)濾驅動(dòng)程序是一種中間驅動(dòng)程序,他位于其他的驅動(dòng)程序層次之間。過(guò)濾驅動(dòng)程序可以監視、攔截和修改IRP流,在不影響其他驅動(dòng)程序的前提下提供一些附加的功能。他的功能可分為:

(1)利用過(guò)濾器驅動(dòng)程序修改現有功能驅動(dòng)程序的行為而不必重新編寫(xiě)功能驅動(dòng)程序。

(2)上層過(guò)濾器驅動(dòng)程序在功能驅動(dòng)程序之前看到IRP,可以很方便地為用戶(hù)提供額外的特征。還可以修正功能驅動(dòng)程序或硬件存在的毛病或缺陷。

(3)下層過(guò)濾器驅動(dòng)程序在功能驅動(dòng)程序要向總線(xiàn)驅動(dòng)程序發(fā)送IRP時(shí)看到IRP?梢员O視、攔截、修改功能驅動(dòng)程序要執行的總線(xiàn)操作流,截獲數據,進(jìn)行必要的數據處理,再將處理過(guò)的數據傳遞下去,實(shí)現一定的數據處理功能。

(4)下層過(guò)濾器驅動(dòng)程序可以實(shí)現驅動(dòng)程序的總線(xiàn)無(wú)關(guān)性,使功能驅動(dòng)程序完全獨立于總線(xiàn)結構而不直接與設備對話(huà)。針對不同的總線(xiàn)編寫(xiě)不同的下層過(guò)濾器,每個(gè)下層過(guò)濾器對應一個(gè)總線(xiàn)類(lèi)型。當功能驅動(dòng)程序需要與硬件對話(huà)時(shí),他只需向相應的下層過(guò)濾器驅動(dòng)程序發(fā)送IRP即可。

4 過(guò)濾器驅動(dòng)程序設計

過(guò)濾器驅動(dòng)程序設計與功能驅動(dòng)程序相似。這里限于篇幅主要討論一下過(guò)濾器驅動(dòng)程序設計中與功能驅動(dòng)程序相區別的幾個(gè)關(guān)鍵的技術(shù)要點(diǎn)。

4.1 DriverEntry例程

DriverEntry例程是驅動(dòng)程序的人口點(diǎn)。當I/O管理器裝入驅動(dòng)程序時(shí),他調用DriverEntry例程用來(lái)初始化驅動(dòng)程序范圍的數據結構和資源,包括輸出該驅動(dòng)程序的其他人口點(diǎn),初始化該驅動(dòng)程序使用的特定對象,并設置驅動(dòng)程序系統資源。與功能驅動(dòng)程序相區別的是:他必須為每種類(lèi)型的IRP都安裝派遣函數,而不僅僅只是其希望處理的IRP。

4.2 AddDevice例程

AddDevice函數的基本職責是創(chuàng )建一個(gè)設備對象并把他連接到以物理設備對象PDO為底的設備堆棧中,并負責設備對象初始化。與功能驅動(dòng)程序相區別的是:過(guò)濾驅動(dòng)程序創(chuàng )建的設備對象可能是2種,一種是不命名的過(guò)濾設備對象,過(guò)濾器工作時(shí)把這個(gè)無(wú)名的設備對象連接到以物理設備對象PDO為底的設備堆棧中。一種是為了和用戶(hù)程序通信而創(chuàng )建的命名的設備對象并不連接到以物理設備對象PDO為底的設備堆棧中。命名可以采用2種方法:第一種方法是采用可顯示的"硬編碼"符號鏈接名,用戶(hù)態(tài)程序必須把設備名硬編碼到源代碼中;另外一種方法是使用設備接口,每個(gè)設備接口是由一個(gè)全局惟一標志符GUID標志。設備注冊為一個(gè)特定的設備接口就創(chuàng )建了一個(gè)符號鏈接。

相關(guān)步驟如下:

(1)調用IoCreateDevke創(chuàng )建過(guò)濾設備對象,并建立一個(gè)私有的設備擴展對象。
(2)寄存一個(gè)或多個(gè)設備接口,以便應用程序能知道設備的存在。另外,還可以給出設備名并創(chuàng )建符號連接。
(3)初始化設備擴展和設備對象的F1ag成員。
(4)調用IOAttachDevkeToDeviceStack函數把新設備對象放到堆棧上。

具體實(shí)現程序如下:

NTSTATUS AddDevice (PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
{
PDEVICE_OBJECT fido=NULL;
//創(chuàng )建沒(méi)有設備名的過(guò)濾設備對象
NTSTATUS status=IoCreateDevice (DriverObjeot,sizeof (DEVICE-EXTENSION),
NULL,FILE_DEVICE_UNKNOWN,0,FALSE,&fido);
if(!NT_SUCCESS(status)) return status;
//初始化設備擴展和設備對象的Flag成員
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fido->DeviceExtension;
pdx->DeviceObject=fido;
pdx->Pdo=pdo;
pdx->eDeviceType =FILTER;
//把沒(méi)有設備名的設備對象放到堆棧上
PDEVICE- OBJECT fdo =
IoAttachDeviceToDeviceStack (fido,pdo);
pdx->TopDevObj=fdo;
fido->Flags ︱=pdo->F1ags&(DO_DIRECT-IO ︱DO-BUFFERED-IO ︱ DO_POWER_PAGABLE ︱DO_POWER_INRUSH);
………
//建立一個(gè)命名的設備對象創(chuàng )建符號鏈接
CreateSymbOlicLink (DriverObject,pdo);
return STATUS_SUCCESS;
}

4.3 派遣例程

派遣例程處理來(lái)自應用程序的打開(kāi)、關(guān)閉、讀、寫(xiě)等I/O請求命令。與功能驅動(dòng)程序的區別是:過(guò)濾器驅動(dòng)程序不能影響其他驅動(dòng)程序接受IRP。對于未知的IRP或不處理的IRP過(guò)濾驅動(dòng)程序的原則是必須沿設備棧傳遞下去。因此他必須為每種類(lèi)型的IRP都安裝派遣函數,而不僅僅只是其希望處理的IRP。對于希望處理的IRP必須指定特殊的派遣函數,直接用CompleteIRP來(lái)完成接收到的這類(lèi)IRP,不往下層傳送。

這里由DispatchDeviceControl處理來(lái)自應用程序的所有希望處理的I/O操作命令。通常采用給予所有自定義的I/O請求代碼的SWITCH語(yǔ)句,而對于每個(gè)命令使用相應的處理函數。下面列出了主要的代碼框架:

NTSTATUS DispatchDeviceControl (PDEVICE_OBJECT fido,PIRP Irp)
{
NTSTATUS status;
PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)fido->DeviceExtension;
PlO_STACK_LOCATION IrpStack =
IoGetCurrentlrpStackLocation(1rp);
//取I/O控制命令代碼
ULONG IoControlCode = IrpStack >
Parameters.DeviceloContr01.IoControlCode;
switch(IoControlCode)
{
case IOCTL-XXX:
…… //處理I/O控制命令代碼
case IOCTL-XXX:
……
default:
……
break;
}
//完成接收到的IRP
IoCompleteRequest(Irp,IO_NO_INCREMENT);
……
return status;
}
對于不需要處理的IRP則交由DispatchAny例程處理,將IRP沿著(zhù)設備棧直接傳遞下去:
NTSTATUS DispatchAny(PDEVICE_OBJECT fido,PIRP Irp)
{
PDEVICE_ EXTENSION pdx=(PDEVICE-EXTENSION)
fido->DeviceExtension
//使堆棧指針少前進(jìn)一步。
IoSkipCurrentlrpStackLocation(hp);
Status=IoCallDriver(pdx->LowerDeviceObject,Irp);
……
return status;

4.4 Unload例程功能

在Unload例程中,驅動(dòng)程序必須釋放所有創(chuàng )建的對象和所有分配給驅動(dòng)程序的資源。

5 結 語(yǔ)

筆者就采用在Windows提供的USB聲卡驅動(dòng)程序下方插入自己編寫(xiě)的下層過(guò)濾器驅動(dòng)程序實(shí)現了對USB聲卡輸出的數據流的截獲并進(jìn)行語(yǔ)音信號處理,取得了不錯的效果,現已投入實(shí)際應用?梢(jiàn)過(guò)濾器驅動(dòng)程序作為一類(lèi)特殊的驅動(dòng)程序,它可以以較小的代價(jià)實(shí)現對驅動(dòng)數據流的截獲,修改、增加現有驅動(dòng)常需的功能,具有很強的實(shí)用性。
本文地址:http://selenalain.com/thread-14193-1-1.html     【打印本頁(yè)】

本站部分文章為轉載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀(guān)點(diǎn)和對其真實(shí)性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問(wèn)題,我們將根據著(zhù)作權人的要求,第一時(shí)間更正或刪除。
nuaachu 發(fā)表于 2010-7-1 09:39:43
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页