windowsNT4.0下設備驅動程序的開發與應用
摘要: 介紹了Windows NT4.0內核模式設備驅動程序開發中的一般性過程。通過提供一個最小化驅動程序的核心代碼,解釋各組成部分的結構功能和使用方法。在實踐中,結合自身的開發需要,可編寫出具有實用價值的驅動程序。
本文引用地址:http://www.104case.com/article/201609/304725.htm關鍵詞:Win32子系統 設備驅動 系統注冊表 I/O請求包
Windows NT 以其安全、穩定及界面友好等特性逐漸成為工業控制領域的前臺操作系統。面對工業控制中大量采用的串/并行通信及總線控制等技術,要求用戶不斷開發出滿足自身需要的硬件設備,同時又要求用戶應用程序與這些硬件設備進行通信,發送控制命令,讀取狀態信息等等。Windows NT出于安全性、穩定性等考慮,不允許用戶應用程序對物理硬件進行直接訪問,這就需要使用設備驅動程序跨越操作系統邊界對物理硬件進行操作,并向上提供客戶應用程序控制接口以供調用。
1 分層結構與設備驅動程序
Windows NT分層結構(如圖1所示)包括運行于用戶模式及內核模式的各種部件,設備驅動程序在圖1的左下角,處于內核模式下I/O管理器之中。
2 驅動程序工作方式
內核模式驅動程序與應用程序之間的最大差別之一是驅動程序的控制結構。內核模式驅動程序沒有main或WinMain,而是由I/O管理器根據需要調用一個驅動程序例程:
· 驅動程序被裝入時;
· 驅動程序被卸出或系統關閉時;
· 用戶程序發出I/O系統服務調用時;
· 共享硬件資源對驅動程序可用時;
· 設備操作過程中的任何時候。
3 初始化過程
3.1 系統注冊表中有關設備驅動程序的項目是系統加載設備驅動程序的入口點
系統注冊表中用于系統加載設備驅動程序的項目如下:
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDriverName]
″Type″ = dword00000001
″Start″ = dword00000002
″Group″ = ″Extended Base″
″ErrorControl″ = dword∶00000001
其中Start含義如下:
SERVICE_BOOT_START (0×0) 操作系統裝入時
SERVICE_SYSTEM_START (0×01) 操作系統初始化時
SERVICE_AUTO_START (0×02) 服務控制管理器啟動時
SERVICE_DEMAND_START (0×03) 服務控制管理器手工啟動
SERVICE_DISABLED (0×04) 不啟動
Type含義如下:
SERVICE_KERNEL_DRIVER (0×1)
SERVICE_FILE_SYSTEM_DRIVER (0×2)
SERVICE_ADAPTER (0×4)
系統注冊表中用于設備驅動程序加載后讀取的項目如下:
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDriverNameParameters]
″Parameter1″ = dword∶00000001
″Parameter2″ = dword∶00000004
3.2 加載驅動程序的裝入例程
I/O管理器調用驅動程序的DriverEntry例程,執行初始化。該例程完成:
· 初始化其它例程的入口;
· 創建命名設備對象;
· 讀取系統注冊表中相關項目并聲明必要的資源;
· 設置內核驅動程序名與Win32子系統名的聯接;
· 創建或初始化任意驅動程序使用的對象、類型和資源;
· 返回狀態值。
I/O管理器建立與設備關聯的Driver對象,并將其傳遞給DriverEntry例程。實際上Driver對象基本上是一個目錄,含有指向各個驅動程序服務例程函數的指針,其結構如表1所示。
表1 Driver對象域說明
I/O管理器能夠找到DriverEntry例程,是因為它有一個公認的名字,而其他的例程則通過下列兩種方法查找:
·在Driver對象中有明確槽的函數如DirverObject->DriverUnload;
·在Driver對象的MajorFunction數組中——Driver對象的MajorFunction支持兩種類型的功能代碼。一種為標準的功能代碼,如IRP_MJ_CREATE。另一種是用戶自定義的功能代碼,如IRP_MJ_DEVICE_CONTROL。
所有驅動程序必須支持IRP_MJ_CREATE功能代碼,這是因為Win32子系統下的用戶程序調用CreateFile函數創建設備時,產生該功能代碼。如果不處理這個功能代碼,Win32程序就不能得到設備句柄。
用戶自定義的功能代碼IRP_MJ_DEVICE_CONTROL只有在用戶模式下的客戶程序執行自定義的功能時可用。
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
//聲明設備對象
PDEVICE_OBJECT DeviceObject,
//生成函數接口指針
DriverObject->MajorFunction[IRP_MJ_CREATE]=XxSelfDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE]=
XxSelfDispatch;
DriverObject->MajorFunction[IRP_MJ_READ]=
XxReadDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE]=
XxWriteDispatch
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=XxSelfDispatch
DriverObject->DriverUnload=XxUnload
//生成Windows NT Executive知道的設備名
RtlInitUnicodeString(NtDeviceName, SelfDeviceName);
//生成自己的設備
Status=IoCreateDevice(
DriverObject, // Driver對象
sizeof(SELF_DEVICE_INFO), // Device對象
Extension結構大小
NtDeviceName,
DeviceType,
0,
FALSE, // 不執行
DeviceObject //Device對象指針
);
//生成Win32子系統下的用戶程序可識別的設備名
評論