WindowsXP驅動程序編寫方法.ppt
《WindowsXP驅動程序編寫方法.ppt》由會員分享,可在線閱讀,更多相關《WindowsXP驅動程序編寫方法.ppt(109頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1 WindowsXP驅動程序編寫方法 StepbyStep 東南大學計算機科學與工程學院楊全勝 VS NET WINXPDDK DriverStudio3 2開發(fā)環(huán)境版 2 本電子講義可以作為幾年前本人所寫的 驅動開發(fā) 上 下電子講義的后續(xù)篇 主要是將開發(fā)平臺從Windows98 2000 DriverStudio2 7升級到以下環(huán)境 WindowsXPSP2VisualStudio NET VC NET2002 簡體中文版 WindowsXPDDK DriverStudio3 2 1 驅動程序的開發(fā)環(huán)境 以上四項中 前3項為Microsoft公司產品 可以只用2 3來開發(fā)驅動程序 為了方便起見 也可以使用第三方的開發(fā)工具DriverStudio 它將DDK的內容封裝成類 而且提供一個快速方便地生成驅動框架的工具 3 2版本可能是Compuware公司推出的最后一個版本 3 通常 開發(fā)不同操作系統(tǒng)下的驅動程序需要不同的DDK做支持 Windows2000DDK適合開發(fā)Windows2000 98 Me的WDM驅動程序 Windows2000下NT4型驅動程序 WindowsXPDDK適合開發(fā)IA64下的驅動程序或WindowsXP 2000 Me的WDM驅動程序 WindowsXP下NT4型驅動程序 Windows2003DDK適合開發(fā)AMD64 IA64下的驅動程序或Windows2003 XP 2000 Me的WDM驅動程序 Windows2003 XP 2000下NT4型驅動程序 本電子講義假設大家已經(jīng)會VC 編程及熟悉VSIDE的使用 4 2 驅動程序開發(fā)工具包DriverStudio 2 1DriverStudio3 2所包含的工具 VToolsDVToolsD是一個用來開發(fā)針對Win9X Windows95和Windows98 操作系統(tǒng)下設備驅動程序 VxD 的工具 VToolsD中包括生成驅動程序源代碼的工具 run time和interface庫 以及一些可以用來作為各種類型的設備驅動程序基礎的驅動程序樣本 DriverWorksDriverWorks提供針對WindowsNT4和Win32驅動模型 WDM 的設備驅動程序開發(fā)的完全支持 DriverWorks中包含一個非常完善的源代碼生成工具 DriverWizard 以及相應的類庫和驅動程序樣本 它提供了在C 下進行設備驅動程序開發(fā)的支持 它可以集成到msvc6和中 還需要最新的WindowsDDK的支持 5 DriverNetworksDriverNetworks是針對Windows網(wǎng)絡驅動開發(fā)人員的一個模塊 它的核心部分 是一個針對NDISdrivers和TDIclients DriverSockets 的C 的類庫 DriverNetworks中也有QuickMiniportWizard用來直接開始一個NDISMiniport Intermediate或協(xié)議驅動程序工程 它可以讓你在采用DriverNetworksC 類庫編寫NDIS驅動程序的時候 快速的生成編譯 安裝和調試所需要的所有文件 它可以集成到msvc6和中 還需要最新的WindowsDDK的支持 6 SoftICE系列調試器SoftICE系列調試器包含了可以調試各種代碼的多種工具 它可以調試諸如BIOS代碼 中斷例程以及系統(tǒng)I O 這些工具與強大的硬件調試板一起支持符號級調試 可以顯示源碼 全局或局部數(shù)據(jù) 其中 SoftICE是單機調試器 調試本機代碼 VisualSoftICE是雙機調試器 支持64位和32位平臺上的微軟操作系統(tǒng) 7 DriverMonitorDriverMonitor不僅可以顯示W(wǎng)DM和VxD在操作系統(tǒng)核心層次輸出的調試語句 還可以裝載和卸載VxD驅動和NT4系統(tǒng)的驅動程序 EZDriverInstaller這是一個無需經(jīng)過設備管理器或 添加新硬件 功能就能為Windows2000 XP動態(tài)加載和卸載WDM驅動程序的小實用程序 SetDDKGo用來設置設備驅動程序創(chuàng)建的環(huán)境 當我們用VisualStudio VC 編譯驅動程序源程序的時候 需要用SetDDKGo來設置環(huán)境變量 之后SetDDKGo會自動啟動VisualStudio VC 編譯環(huán)境 8 DriverWorkbench這是DriverStudio以及用戶工具的集成環(huán)境和宿主 DS的大多數(shù)工具全部被集成到這個開發(fā)環(huán)境中 BoundsCheckerDriverEdition它提供了參數(shù)驗證和系統(tǒng)測試來檢測和跟蹤不同的設備驅動程序與其他操作系統(tǒng)模塊之間的交互 配置 TrueTimeDriverEdition這是一個能讓WindowsNT 2000 XP設備驅動程序的編寫者確定驅動程序性能瓶頸的性能分析工具 對于編寫設備驅動程序或核心代碼的程序員 這很有用 TrueCoverageDriverEdition它能幫助程序員檢測其代碼的哪部分被測試過 哪部分還需要測試 可幫助程序員提高程序的穩(wěn)定性 9 2 2DriverStudio3 2的安裝 安裝需要的軟硬件環(huán)境 Intelx86兼容系統(tǒng)或X64系統(tǒng) 包含IA64和AMD64以及Itanium WindowsXP內存 最少256MB 推薦使用512MB硬盤 完全安裝需要大約182MB針對SoftICE的遠程調試 NE2000 兼容網(wǎng)卡或3Com網(wǎng)卡針對DriverWorks MicrosoftXPDDK VisualC NET 10 安裝步驟 在安裝DriverWorks之前 首先要保證你的計算機上已經(jīng)安裝了MicrosoftVisualC NET以及WindowsXPDDK 所有這些包括DriverStudio的安裝都必須以系統(tǒng)管理員身份啟動系統(tǒng) 并且要按照下面的順序安裝 11 第二步 安裝WindowsXPDDK DriverDevelopmentKits 注意 1 在安裝DDK的時候請選擇完全安裝 2 安裝中 不需要安裝64BITIA64Binaries3 安裝好后 對于XPDDK不需要手動配置環(huán)境變量 只需在開始菜單中點擊CheckedBuildEnvirment則DDK會自動調用setenv配置環(huán)境變量 并監(jiān)測相應的SDK以及VisualStudio NETIDE 第一步 安裝VisualStudioC NET 第三步 安裝DriverStudio3 2 按照安裝提示安裝 12 DriverStudio3 2支持單機調試或雙機調試兩種模式 在安裝的時候也有Host和Target兩種模式 單機調試需要在同一個機器中將Host和Target兩種模式都安裝雙機調試的時候需要在一個機器上安裝Host模式 在另一個機器上安裝Target模式 13 DriverStudio安裝后的設置 1 使用DDKBuildSetting工具定義BASEDIR環(huán)境變量并啟動MSVC NET 14 15 16 17 18 2 打開下列地址上的建立庫文件工程VdwLibs2002 sln如果是VS NET2003 則打開VdwLibs2003 sln 19 3 選擇 生成 批生成 打開下面的窗口 從中選則需要編譯的配置 Checked是調試版本 Free是發(fā)布版本 20 4 點擊 重新生成 編譯所選擇的庫文件 注意 庫文件只需在安裝完成后第一次使用前編譯一次即可 以后要使用DriverWorks 只需通過SetDDKGo進入MSVC NET即可 或者直接從MSVC NET中啟動DriverWorks 21 3 DriverWorks的使用 1 生成簡單框架 VS NET中啟動DriverWizard 22 23 工程文件名 工程文件目錄 24 選擇驅動類型 選擇框架類型 25 創(chuàng)建功能驅動程序 創(chuàng)建過濾器驅動程序 26 選擇相應總線 本例不驅動硬件 27 選擇需要處理的消息句柄 28 添加和應用程序之間通信的控制代碼 29 30 31 32 33 34 35 36 37 38 39 驅動類 設備類 隊列管理類 40 驅動類文件 設備類文件 測試用的控制臺程序文件 驅動安裝指導文件 隊列管理類 41 此時已經(jīng)具備了一個驅動程序以及做測試用的應用程序的基本框架 我們可以在VC集成環(huán)境下修改有關程序 增加相關的具體操作代碼 然后就可以編譯和調試了 42 該驅動程序框架包含了幾個最基本的類 這些類是 classSampleDriver publicKDriver 驅動程序類 用于初始化驅動程序 SAFE DESTRUCTORSpublic 以下成員函數(shù)注意和WDM中有關例程聯(lián)系起來看virtualNTSTATUSDriverEntry PUNICODE STRINGRegistryPath virtualNTSTATUSAddDevice PDEVICE OBJECTPdo virtualVOIDUnload VOID voidLoadRegistryParameters PUNICODE STRINGRegistryPath protected 成員數(shù)據(jù)intm Unit 43 classSampleDevice publicKPnpDevice 是設備類KDvice的派生類 用于在WDM環(huán)境下支持即插即用設備 Constructorspublic SAFE DESTRUCTORS SampleDevice PDEVICE OBJECTPdo ULONGUnit SampleDevice VOIDInvalidate void MemberFunctions注意和PNP的次功能代碼聯(lián)系起來看DEVMEMBER DISPATCHERSvirtualNTSTATUSOnStartDevice KIrpI virtualNTSTATUSOnStopDevice KIrpI virtualNTSTATUSOnRemoveDevice KIrpI virtualNTSTATUSOnDevicePowerUp KIrpI virtualNTSTATUSOnDeviceSleep KIrpI virtualNTSTATUSDefaultPnp KIrpI virtualNTSTATUSDefaultPower KIrpI voidLoadRegistryParameters 取注冊表信息 44 voidSerialRead KIrpI voidSerialWrite KIrpI NTSTATUSSAMPLE IOCTL Read Handler KIrpI NTSTATUSSAMPLE IOCTL Write Handler KIrpI NTSTATUSSAMPLE IOCTL ReadWrite Handler KIrpI protected MemberDataKPnpLowerDevicem Lower sampleQueueReadQueue DrivermanagedIRPqueuesampleQueueWriteQueue DrivermanagedIRPqueue ifdef COMMENT ONLYvirtualNTSTATUSCreate KIrpI COMMENT ONLYvirtualNTSTATUSClose KIrpI COMMENT ONLYvirtualNTSTATUSRead KIrpI COMMENT ONLYvirtualNTSTATUSWrite KIrpI COMMENT ONLYvirtualNTSTATUSDeviceControl KIrpI COMMENT ONLYvirtualNTSTATUSSystemControl KIrpI COMMENT ONLY endif COMMENT ONLY 45 由于一個可能是DriverStudio3 2中的BUG 所以及時生成的一個空工程項目也無法編譯通過 需要對生成的工程文件做以下手工修改 把sample項目中的sources文件中的 TARGETLIBS DDK LIB PATH ntstrsafe lib DDK LIB PATH csq lib這一行去掉就可以編譯通過了 46 先編譯驅動程序工程 在VS2002的集成環(huán)境中 下面我們講解編譯 執(zhí)行和調試這個驅動程序 生成目標文件 47 確認生成的是驅動程序 48 在VS2002的集成環(huán)境中 生成目標文件 再編譯測試應用程序工程 49 確認生成的是測試用應用程序 50 下面使用DriverStudio帶的工具加載驅動程序和查看調試信息 驅動程序監(jiān)視 可實時看到驅動程序發(fā)出的調試輸出語句 驅動程序裝載器 可動態(tài)調用驅動程序 51 驅動程序監(jiān)視器界面 52 為了防止其他驅動程序的干擾 在FilterMessage對話框中設置消息過濾規(guī)則 只讓有sample的消息通過 53 驅動程序裝載器界面 54 55 56 57 驅動程序已經(jīng)加載并且啟動 58 YANGQS 59 DriverStudio3 2給出的驅動測試軟件是一個Win32的窗口程序 而不是先前版本的控制臺程序 為了在調試輸出的時候有所區(qū)別我們將測試程序的調試輸出語句的句頭由原來的sample 改成sampleAPP 在sampleAPP cpp文件中 VOIDsampleOutputText LPCTSTRFormat TCHARstr MAX STRING LENGTH va listvaList va start vaList Format vstprintf str Format vaList OutputDebugString T sampleAPP OutputDebugString str OutputDebugString T n va end vaList return 60 運行編譯好的sampleAPP exe 61 62 如果在執(zhí)行sampleAPP exe之前 驅動程序sample sys還沒有加載到內存中 則在DriverMonitor程序中就可以看到以下信息 63 APP中打開與驅動程序聯(lián)系 64 65 結束后一定要卸載驅動程序 66 驅動程序已經(jīng)卸載 67 下面我們來修改有關代碼 以便增加驅動程序和應用程序之間相互通信的內容 需要增加的內容包括 使用Read和Write方式分別從驅動程序讀入字符和向驅動程序寫字符 使用IO控制代碼方式分別從驅動程序讀入字符和向驅動程序寫字符 使用IO控制代碼方式向驅動程序寫字符串再從驅動程序中讀出該字符串 并返回反饋串信息 注意 程序中暗紅色顯示的部分是我們添加或修改過的語句 其他是DriverWorks自動生成的 藍色顯示的部分是要刪除的語句 省略號的部分是不變的 語句中T Trace TraceInfo FUNCTION xxxx 這樣的語句是向調試軟件輸出信息 該信息可在DriverMonitor或其他調試監(jiān)視器中看到 2 完成應用程序和驅動程序之間的信息交換 68 a 1使用Read方式讀SampleDevice cppvoidSampleDevice SerialRead KIrpI T Trace TraceInfo FUNCTION IRP p n I NTSTATUSstatus STATUS SUCCESS PUCHARpBuffer PUCHAR I BufferedReadDest 取得返回數(shù)據(jù)BUFF的指針ULONGreadSize I ReadSize 獲得應用程序希望讀驅動程序信息的字節(jié)數(shù) ULONGbytesRead 0 charbuff 512 intn 512 j n 26 for inti 0 i n i j j 1 26 buff i a j buff readSize 0 指定串尾strcpy char pBuffer buff 把給應用程序的數(shù)據(jù)拷貝給返回BUFFT Trace TraceInfo FUNCTION Thestringyouwillreadis s n buff 輸出調試信息bytesRead strlen buff CountofbytesreadI Information bytesRead 返回給應用程序的信息的字節(jié)個數(shù)I Status status m DriverManagedQueue PnpNextIrp I 69 控件IDC OP TYPE COMBO及其選擇項 我們這次選ReadFile 70 sampleIorw cpp中有關讀數(shù)據(jù)的代碼 ULONGsampleExecuteIo HWNDhDlg PSAMPLE LIST ITEMioItem 獲得需要讀的字節(jié)數(shù)GetDlgItemText hDlg IDC OUT SIZE EDIT str MAX STRING LENGTH ioItem OutSize ttol str 設置控件IDC OP TYPE COMBO的句柄hWnd GetDlgItem hDlg IDC OP TYPE COMBO 獲得當前被選中項目的索引itemIndex DWORD SendMessage hWnd CB GETCURSEL 0 0 獲得被選中的項目的字符串SendMessage hWnd CB GETLBTEXT WPARAM itemIndex LPARAM str if tcscmp str T ReadFile 71 從驅動程序讀數(shù)據(jù)if ReadFile g hDevice 設備句柄ioItem OutBuffer 輸入緩沖地址ioItem OutSize 緩沖大小 字節(jié)數(shù) NULL 實際讀的數(shù)據(jù)字節(jié)數(shù) if tcscmp str T ReadFile 72 VOIDsampleReadCompleteCallback PVOIDContext 讀驅動程序的回調函數(shù)PSAMPLE LIST ITEMioItem PSAMPLE LIST ITEM Context 因VS net隱含采用Unicode編碼 每個字符16位 下面做8位到16位字符轉換charwstr 1025 for ULONGi 0 iOutSize i wstr i 2 ioItem OutBuffer i wstr i 2 1 0 x0 wstr i 2 wstr i 2 1 0 sampleOutputText T ExecutedReadFile buffersize d returnlength d error d ThestringIreadis s ioItem OutSize ioItem ReturnLength ioItem Error wstr 輸出讀到的字符串sampleOutputBuffer ioItem OutBuffer ioItem ReturnLength 釋放緩沖空間free ioItem OutBuffer 關閉重疊事件句柄CloseHandle ioItem IoOverlapped hEvent 釋放ioItem空間free ioItem return 73 74 a 2使用Write方式寫SampleDevice cppvoidSampleDevice SerialWrite KIrpI T Trace TraceInfo FUNCTION IRP p n I NTSTATUSstatus STATUS SUCCESS PUCHARpBuffer PUCHAR I BufferedWriteSource 取得存放應用程序寫給驅動程序的數(shù)據(jù)的BUFF的指針ULONGwriteSize I WriteSize 獲得應用程序寫給驅動程序的信息的字節(jié)數(shù) ULONGbytesSent 0 bytesSent writeSize charbuff 512 strcpy buff char pBuffer 應用程序寫給驅動程序的數(shù)據(jù)在I BufferedWriteSource 返回的指針中 buff bytesSent 0 T Trace TraceInfo FUNCTION Writetodriveris s n buff I Information bytesSent 返回用戶實際寫的字節(jié)數(shù)I Status status m DriverManagedQueue PnpNextIrp I 75 控件IDC OP TYPE COMBO及其選擇項 我們這次選WriteFile 76 sampleIorw cpp中有關寫數(shù)據(jù)的代碼 ULONGsampleExecuteIo HWNDhDlg PSAMPLE LIST ITEMioItem 獲得需要寫的字節(jié)數(shù) GetDlgItemText hDlg IDC IN SIZE EDIT str MAX STRING LENGTH ioItem InSize ttol str 獲得要寫的字符串和要寫的字節(jié)數(shù)GetDlgItemText hDlg IDC IN DATA EDIT str MAX STRING LENGTH VOID stscanf str T x 77 Writedatatodriverif tcscmp str T ReadFile if tcscmp str T WriteFile 78 79 b 1使用IO控制代碼方式讀 SampleDevice cpp NTSTATUSsampleDevice SAMPLE IOCTL Read Handler KIrpI T Trace TraceInfo FUNCTION IRP p n I NTSTATUSstatus STATUS SUCCESS ULONGinputSize I IoctlInputBufferSize ULONGoutputSize I IoctlOutputBufferSize charbuff1 512 ULONGfwLength 0 strcpy buff1 Welcometodriver 這是應用程序將要讀到的字符串fwLength strlen buff1 1 if outputSize fwLength 如果讀入緩沖夠長strcpy PCHAR I IoctlBuffer buff1 將信息拷給應用程序讀入緩沖I Information fwLength 返回信息長度 else I Information 0 否則信息長度為0T Trace TraceInfo FUNCTION buffsizetoosmall n 80 Bufferedioctl usingthesamebuffersoreadthebufferbeforewritingthebuffer PVOIDinputBuffer I IoctlBuffer PVOIDoutputBuffer I IoctlBuffer if FALSE status STATUS INVALID PARAMETER I Information 0 else I Information 0 T Trace NT SUCCESS status TraceInfo TraceWarning FUNCTION IRP p STATUS x n I status returnstatus 81 sampleIorw cpp中有關寫數(shù)據(jù)的代碼 ULONGsampleExecuteIo HWNDhDlg PSAMPLE LIST ITEMioItem if tcscmp str T SAMPLE IOCTL Read 82 if DeviceIoControl g hDevice 設備句柄SAMPLE IOCTL Read IO控制命令ioItem InBuffer 寫緩沖ioItem InSize 寫緩沖大小ioItem OutBuffer 讀緩沖ioItem OutSize 讀緩沖大小NULL 實際讀的字節(jié)數(shù) if tcscmp str T SAMPLE IOCTL Read 83 VOIDsampleSAMPLE IOCTL ReadCompleteCallback PVOIDContext PSAMPLE LIST ITEMioItem PSAMPLE LIST ITEM Context charwstr 1025 for ULONGi 0 iOutSize i wstr i 2 ioItem OutBuffer i wstr i 2 1 0 x0 wstr i 2 wstr i 2 1 0 sampleOutputText T ExecutedSAMPLE IOCTL Readrequest inbuffersize d outbuffersize d nreturnlength d error d ThestringIreadedis s ioItem InSize ioItem OutSize ioItem ReturnLength ioItem Error wstr 84 85 b 2使用IO控制代碼方式寫 SampleDevice cpp NTSTATUSsampleDevice SAMPLE IOCTL Write Handler KIrpI T Trace TraceInfo FUNCTION IRP p n I NTSTATUSstatus STATUS SUCCESS ULONGinputSize I IoctlInputBufferSize ULONGoutputSize I IoctlOutputBufferSize charbuff 512 strcpy buff char I IoctlBuffer 應用程序寫給驅動程序的數(shù)據(jù)在I BufferedWriteSource 返回的指針中 buff inputSize 0 T Trace TraceInfo FUNCTION Writetodriveris s n buff I Information 0 86 Bufferedioctl usingthesamebuffersoreadthebufferbeforewritingthebuffer PVOIDinputBuffer I IoctlBuffer PVOIDoutputBuffer I IoctlBuffer if FALSE status STATUS INVALID PARAMETER I Information 0 else I Information 0 T Trace NT SUCCESS status TraceInfo TraceWarning FUNCTION IRP p STATUS x n I status returnstatus 87 sampleIorw cpp中有關寫數(shù)據(jù)的代碼 ULONGsampleExecuteIo HWNDhDlg 本頁的修改實際上前面Write時已經(jīng)改好 PSAMPLE LIST ITEMioItem 獲得需要寫的字節(jié)數(shù) GetDlgItemText hDlg IDC IN SIZE EDIT str MAX STRING LENGTH ioItem InSize ttol str 獲得要寫的字符串和要寫的字節(jié)數(shù)GetDlgItemText hDlg IDC IN DATA EDIT str MAX STRING LENGTH VOID stscanf str T x 88 if tcscmp str T SAMPLEIOCTL Write if tcscmp str T SAMPLEIOCTL Write 89 90 c 使用IO控制代碼方式寫并且讀 SampleDevice cpp NTSTATUSsampleDevice IOCTL ReadWrite Handler KIrpI Trace TraceInfo FUNCTION IRP p n I NTSTATUSstatus STATUS SUCCESS ULONGinputSize I IoctlInputBufferSize ULONGoutputSize I IoctlOutputBufferSize Bufferedioctl usingthesamebuffersoreadthebufferbeforewritingthebuffer PVOIDinputBuffer I IoctlBuffer PVOIDoutputBuffer I IoctlBuffer charbuff 512 strcpy buff char I IoctlBuffer 取應用程序寫給驅動程序的數(shù)據(jù)buff inputSize 0 T Trace TraceInfo FUNCTION Applicationwritetodriveris s n buff charbuff1 512 ULONGfwLength 0 strcpy buff1 Thisisfeedbackfromdriver Feedbackstringis strcat buff1 buff strcat buff1 n fwLength strlen buff1 1 91 if outputSize fwLength 如果讀入緩沖夠長strcpy PCHAR I IoctlBuffer buff1 將信息拷給應用程序讀入緩沖I Information fwLength 返回信息長度 else I Information 0 否則信息長度為0T Trace TraceInfo FUNCTION buffsizetoosmall n if FALSE status STATUS INVALID PARAMETER I Information 0 else I Information 0 T Trace NT SUCCESS status TraceInfo TraceWarning FUNCTION IRP p STATUS x n I status returnstatus 92 sampleIorw cpp中有關讀寫數(shù)據(jù)的代碼 ULONGsampleExecuteIo HWNDhDlg 本頁的修改實際上前面Write時已經(jīng)改好 PSAMPLE LIST ITEMioItem 獲得需要寫的字節(jié)數(shù) GetDlgItemText hDlg IDC IN SIZE EDIT str MAX STRING LENGTH ioItem InSize ttol str 獲得要寫的字符串和要寫的字節(jié)數(shù)GetDlgItemText hDlg IDC IN DATA EDIT str MAX STRING LENGTH VOID stscanf str T x 93 if tcscmp str T IOCTL ReadWrite if tcscmp str T SAMPLEIOCTL Write 94 VOIDsampleIOCTL ReadWriteCompleteCallback PVOIDContext PSAMPLE LIST ITEMioItem PSAMPLE LIST ITEM Context 因VS net隱含采用Unicode編碼 每個字符16位 下面做8位到16位字符轉換charwstr 1025 for ULONGi 0 iOutSize i wstr i 2 ioItem OutBuffer i wstr i 2 1 0 x0 wstr i 2 wstr i 2 1 0 sampleOutputText T ExecutedIOCTL ReadWriterequest inbuffersize d outbuffersize d nreturnlength d error d ThestringIreadedis s ioItem InSize ioItem OutSize ioItem ReturnLength ioItem Error wstr 95 96 3 直接對端口寄存器讀寫 DriverStudio提供了KIoRange類來將外部總線的I O地址空間范圍映射到處理器總線的地址空間范圍 該類的成員函數(shù)主要有KIoRange構造函數(shù) 4種格式 Initialize初始化和重新初始化一個實例 3種格式 KIoRange析構函數(shù)Invalidate從已初始化狀態(tài)刪除該對象IsValid測試該對象是否已經(jīng)初始化inb讀一個或多個字節(jié) 2種形式 Outb寫一個或多個字節(jié) 2種形式 Inw讀一個或多個字 2種形式 Outw寫一個或多個字 2種形式 ind讀一個或多個雙字 2種形式 outd寫一個或多個雙字 2種形式 97 KIoRange KIoRange 只介紹WDM形式 FORM3 WDM KIoRange ULONGLONGCpuPhysicalAddress 轉換成外圍設備地址的CPU總線上的物理地址BOOLEANInCpuIoSpace 如果IO范圍是在CPU總線的IO空間中為TRUE 否則為FALSEULONGCount 以字節(jié)計的區(qū)域的大小BOOLEANMapToSystemVirtual TRUE 指定是否需要構造函數(shù)創(chuàng)建一個非頁系統(tǒng)空間的地址空間映射 如果驅動程序讀寫設備中的數(shù)據(jù) 就需要這種映射 FORM4 WDM 注意 這種形式不被DriverStudio2 0支持 KIoRange PCM RESOURCE LISTpTranslatedResourceList 指向轉換資源表的指針ULONGOrdinal 0 指定pTranslatedResourceList指向的資源列表中的一個特殊端口資源BOOLEANMapToSystemVirtual TRUE FORM5 WDM KIoRange PCM RESOURCE LISTpTranslatedResourceList 可通過KIrp TranslatedResources獲得PCM RESOURCE LISTpRawResourceList 指向原始資源表的指針ULONGOrdinal 0 BOOLEANMapToSystemVirtual TRUE 構造KIoRange類 98 KIoRange Initialize 只介紹WDM形式 FORM2 WDM NTSTATUSInitialize ULONGLONGCpuPhysicalAddress BOOLEANInCpuIoSpace ULONGCount BOOLEANMapToSystemVirtual TRUE FORM3 WDM 注意 這種形式不被DriverStudio2 0支持 NTSTATUSInitialize PCM RESOURCE LISTpTranslatedResourceList ULONGOrdinal 0 BOOLEANMapToSystemVirtual TRUE FORM4 WDM Initialize PCM RESOURCE LISTpTranslatedResourceList PCM RESOURCE LISTpRawResourceList ULONGOrdinal 0 BOOLEANMapToSystemVirtual TRUE 初始化或重新初始化KIoRange的實例 99 KIoRange inbFORM1 UCHARinb ULONGByteOffset FORM2 VOIDinb ULONGByteOffset PUCHARBuffer ULONGCount 從映射空間讀一個或多個字節(jié) 100 KIoRange outbFORM1 VOIDoutb ULONGByteOffset 以字節(jié)為單位的目標位置到IO空間開始位置的偏移值UCHARData 要寫的一個字節(jié)數(shù)據(jù) FORM2 VOIDoutb ULONGByteOffset PUCHARBuffer 指向包含要寫數(shù)據(jù)的緩沖的指針ULONGCount 緩沖中要寫數(shù)據(jù)的字節(jié)數(shù) 寫一個或多個字節(jié)到映射的IO空間 101 寫端口 索引信息 地址70H m ParPortIos outb 0 0 x02 準備讀分鐘信息讀端口 讀分鐘信息 地址71H UCHARdata m ParPortIos inb 1 下面我們來訪問CMOS的數(shù)據(jù) 首先定義類KIoRange的一個實例 以定義相關地址空間 KIoRangem ParPortIos 初始化實例 指定CMOS的端口首地址 并映射 status m ParPortIos Initialize 0 x70 CMOS端口首地址是70HTRUE 在CPUI O空間內8 設備讀寫數(shù)據(jù)的字節(jié)寬度TRUE 映射到系統(tǒng)空間 102 4 截獲中斷和掛接中斷服務例程 DriverStudio提供了KInterrupt類來截獲和掛接中斷 該類的成員函數(shù)主要有KInterrupt構造函數(shù) 3種格式 Initialize在無效狀態(tài)下初始化一個對象 3種格式 Connect綁定ISR 中斷服務例程 到中斷InitializeAndConnect一步完成初始化與綁定工作 要用資源列表作為輸入 KInterrupt析構函數(shù)Invalidate在初始化狀態(tài)下刪除對象IsValid檢查對象是否初始化Disconnect使中斷和ISR與中斷分離Synchronize當?shù)玫揭粋€中斷自旋鎖時請求同步功能 103 KInterrupt KInterrupt 只介紹WDM形式 FORM3 WDM KInterrupt KIRQLirql 即插即用設備提供的IRQL值ULONGvector 即插即用設備提供的向量值KINTERRUPT MODEMode LevelSensitive或Latched中選一 BOOLEANbShareVector FALSE 該向量是否被幾個設備共享KAFFINITYaffinity 1 thisistheprocessoraffinitymask BOOLEANbSaveFloat FALSE 是否需要在中斷到來使保存浮點處理器上下文 X86平臺下必須使FALSE 構造類Kinterrupt的實例 104 KInterrupt Initialize 只介紹WDM形式 FORM2 WDM VOIDInitialize KIRQLirql ULONGvector KINTERRUPT MODEMode BOOLEANbShareVector FALSE KAFFINITYaffinity 1 BOOLEANbSaveFloat FALSE 初始化對象 只在對象沒有初始化的時候使用 105 KInterrupt ConnectFORM1 NTSTATUSConnect PKSERVICE ROUTINEIsr 作為ISR服務的函數(shù)的地址PVOIDContext 當系統(tǒng)調用ISR的時候傳遞給他的無類型的參數(shù) FORM2 NTSTATUSConnect PKSERVICE ROUTINEIsr PVOIDContext PKSPIN LOCKpSpin KIRQLSynchIrql 綁定一個中斷到ISR 中斷處理程序 106 KInterrupt InitializeAndConnectNTSTATUSInitializeAndConnect PCM RESOURCE LISTpResourceList 指向資源列表的指針PKSERVICE ROUTINEIsr PVOIDIsrContext ULONGOrdinal 0 BOOLEANbSaveFloat FALSE 初始化一個中斷并綁定到一個ISR上 對于WDM驅動程序 pResourceList必須是一個轉換資源表 例如是KIrp TranslatedResources的返回值 107 下面我們來舉例說明 首先定義類KInterrupt的一個實例KInterruptm TheInterrupt 在設備類中聲明一個成員函數(shù)TheIsr作為中斷服務例程ISR classSampleDevice publicKPnpDevice public MEMBER ISR SampleDevice TheIsr ifdef COMMENT ONLYBOOLEANTheIsr void returnTRUE endif 108 在OnStartDevice例程中獲取包括中斷的設備資源并初始化中斷和掛接ISRSampleDevice OnStartDevice KIrpI PCM RESOURCE LISTpResList I TranslatedResources 獲取設備資源 初始化中斷并掛接中斷服務例程TheIsrstatus m TheInterrupt InitializeAndConnect pResList LinkTo TheIsr this 109 本講義參考了DriverStudio有關文檔- 配套講稿:
如PPT文件的首頁顯示word圖標,表示該PPT已包含配套word講稿。雙擊word圖標可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設計者僅對作品中獨創(chuàng)性部分享有著作權。
- 關 鍵 詞:
- WindowsXP 驅動程序 編寫 方法
裝配圖網(wǎng)所有資源均是用戶自行上傳分享,僅供網(wǎng)友學習交流,未經(jīng)上傳用戶書面授權,請勿作他用。
鏈接地址:http://m.hcyjhs8.com/p-6569653.html