![windows xp驅(qū)動(dòng)程序編寫方法【課件】_第1頁(yè)](http://file4.renrendoc.com/view/9ef401af2e3945fac5ffa2cd06191eda/9ef401af2e3945fac5ffa2cd06191eda1.gif)
![windows xp驅(qū)動(dòng)程序編寫方法【課件】_第2頁(yè)](http://file4.renrendoc.com/view/9ef401af2e3945fac5ffa2cd06191eda/9ef401af2e3945fac5ffa2cd06191eda2.gif)
![windows xp驅(qū)動(dòng)程序編寫方法【課件】_第3頁(yè)](http://file4.renrendoc.com/view/9ef401af2e3945fac5ffa2cd06191eda/9ef401af2e3945fac5ffa2cd06191eda3.gif)
![windows xp驅(qū)動(dòng)程序編寫方法【課件】_第4頁(yè)](http://file4.renrendoc.com/view/9ef401af2e3945fac5ffa2cd06191eda/9ef401af2e3945fac5ffa2cd06191eda4.gif)
![windows xp驅(qū)動(dòng)程序編寫方法【課件】_第5頁(yè)](http://file4.renrendoc.com/view/9ef401af2e3945fac5ffa2cd06191eda/9ef401af2e3945fac5ffa2cd06191eda5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
WindowsXP驅(qū)動(dòng)程序編寫方法——StepbyStep東南大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院楊全勝VS.NET+WINXPDDK+DriverStudio3.2開(kāi)發(fā)環(huán)境版1WindowsXP驅(qū)動(dòng)程序編寫方法東南大學(xué)計(jì)算機(jī)科學(xué)與工程本電子講義可以作為幾年前本人所寫的《驅(qū)動(dòng)開(kāi)發(fā)》上、下電子講義的后續(xù)篇,主要是將開(kāi)發(fā)平臺(tái)從Windows98/2000,DriverStudio2.7升級(jí)到以下環(huán)境:WindowsXPSP2VisualStudio.NET(VC++.NET2002)簡(jiǎn)體中文版*WindowsXPDDK**DriverStudio3.21.驅(qū)動(dòng)程序的開(kāi)發(fā)環(huán)境以上四項(xiàng)中,前3項(xiàng)為Microsoft公司產(chǎn)品,可以只用2,3來(lái)開(kāi)發(fā)驅(qū)動(dòng)程序。為了方便起見(jiàn),也可以使用第三方的開(kāi)發(fā)工具Driver
Studio,它將DDK的內(nèi)容封裝成類,而且提供一個(gè)快速方便地生成驅(qū)動(dòng)框架的工具。3.2版本可能是Compuware公司推出的最后一個(gè)版本。2本電子講義可以作為幾年前本人所寫的《驅(qū)動(dòng)開(kāi)發(fā)》上、下**通常,開(kāi)發(fā)不同操作系統(tǒng)下的驅(qū)動(dòng)程序需要不同的DDK做支持:Windows2000DDK適合開(kāi)發(fā)Windows2000/98/Me的WDM驅(qū)動(dòng)程序,Windows2000下NT4型驅(qū)動(dòng)程序。WindowsXPDDK適合開(kāi)發(fā)IA64下的驅(qū)動(dòng)程序或WindowsXP/2000/Me的WDM驅(qū)動(dòng)程序,WindowsXP下NT4型驅(qū)動(dòng)程序。Windows2003DDK適合開(kāi)發(fā)AMD64/IA64下的驅(qū)動(dòng)程序或Windows2003/XP/2000/Me的WDM驅(qū)動(dòng)程序,Windows2003/XP/2000下NT4型驅(qū)動(dòng)程序。*本電子講義假設(shè)大家已經(jīng)會(huì)VC++編程及熟悉VSIDE的使用。3**通常,開(kāi)發(fā)不同操作系統(tǒng)下的驅(qū)動(dòng)程序需要不同的DDK做支持2.驅(qū)動(dòng)程序開(kāi)發(fā)工具包DriverStudio2.1DriverStudio3.2所包含的工具
VToolsD
VToolsD是一個(gè)用來(lái)開(kāi)發(fā)針對(duì)Win9X(Windows95和Windows98)操作系統(tǒng)下設(shè)備驅(qū)動(dòng)程序(VxD)的工具。VToolsD中包括生成驅(qū)動(dòng)程序源代碼的工具,run-time和interface庫(kù),以及一些可以用來(lái)作為各種類型的設(shè)備驅(qū)動(dòng)程序基礎(chǔ)的驅(qū)動(dòng)程序樣本。
DriverWorks
DriverWorks提供針對(duì)WindowsNT4和Win32驅(qū)動(dòng)模型(WDM)的設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)的完全支持。DriverWorks中包含一個(gè)非常完善的源代碼生成工具(DriverWizard)以及相應(yīng)的類庫(kù)和驅(qū)動(dòng)程序樣本,它提供了在C++下進(jìn)行設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)的支持。它可以集成到msvc6和中,還需要最新的WindowsDDK的支持。42.驅(qū)動(dòng)程序開(kāi)發(fā)工具包DriverStudio2.1DrDriverNetworks
DriverNetworks是針對(duì)Windows網(wǎng)絡(luò)驅(qū)動(dòng)開(kāi)發(fā)人員的一個(gè)模塊。它的核心部分,是一個(gè)針對(duì)NDISdrivers和TDIclients(DriverSockets)的C++的類庫(kù)。DriverNetworks中也有QuickMiniportWizard用來(lái)直接開(kāi)始一個(gè)NDISMiniport,Intermediate或協(xié)議驅(qū)動(dòng)程序工程。它可以讓你在采用DriverNetworksC++類庫(kù)編寫NDIS驅(qū)動(dòng)程序的時(shí)候,快速的生成編譯、安裝和調(diào)試所需要的所有文件。它可以集成到msvc6和中,還需要最新的WindowsDDK的支持。
5DriverNetworks
DriverNetwoSoftICE系列調(diào)試器
SoftICE系列調(diào)試器包含了可以調(diào)試各種代碼的多種工具。它可以調(diào)試諸如BIOS代碼、中斷例程以及系統(tǒng)I/O。這些工具與強(qiáng)大的硬件調(diào)試板一起支持符號(hào)級(jí)調(diào)試,可以顯示源碼、全局或局部數(shù)據(jù)。其中:SoftICE是單機(jī)調(diào)試器,調(diào)試本機(jī)代碼。VisualSoftICE是雙機(jī)調(diào)試器,支持64位和32位平臺(tái)上的微軟操作系統(tǒng)。6SoftICE系列調(diào)試器
SoftICE系列調(diào)試器DriverMonitor
DriverMonitor不僅可以顯示W(wǎng)DM和VxD在操作系統(tǒng)核心層次輸出的調(diào)試語(yǔ)句,還可以裝載和卸載VxD驅(qū)動(dòng)和NT4系統(tǒng)的驅(qū)動(dòng)程序。EZDriverInstaller
這是一個(gè)無(wú)需經(jīng)過(guò)設(shè)備管理器或“添加新硬件”功能就能為Windows2000/XP動(dòng)態(tài)加載和卸載WDM驅(qū)動(dòng)程序的小實(shí)用程序。SetDDKGo
用來(lái)設(shè)置設(shè)備驅(qū)動(dòng)程序創(chuàng)建的環(huán)境。當(dāng)我們用VisualStudio(VC++)編譯驅(qū)動(dòng)程序源程序的時(shí)候,需要用SetDDKGo來(lái)設(shè)置環(huán)境變量,之后SetDDKGo會(huì)自動(dòng)啟動(dòng)VisualStudio(VC++)編譯環(huán)境。7DriverMonitor
DriverMonitoDriverWorkbench
這是DriverStudio以及用戶工具的集成環(huán)境和宿主。DS的大多數(shù)工具全部被集成到這個(gè)開(kāi)發(fā)環(huán)境中。BoundsCheckerDriverEdition
它提供了參數(shù)驗(yàn)證和系統(tǒng)測(cè)試來(lái)檢測(cè)和跟蹤不同的設(shè)備驅(qū)動(dòng)程序與其他操作系統(tǒng)模塊之間的交互。配置TrueTimeDriverEdition
這是一個(gè)能讓W(xué)indowsNT/2000/XP設(shè)備驅(qū)動(dòng)程序的編寫者確定驅(qū)動(dòng)程序性能瓶頸的性能分析工具。對(duì)于編寫設(shè)備驅(qū)動(dòng)程序或核心代碼的程序員,這很有用。TrueCoverageDriverEdition
它能幫助程序員檢測(cè)其代碼的哪部分被測(cè)試過(guò),哪部分還需要測(cè)試??蓭椭绦騿T提高程序的穩(wěn)定性。8DriverWorkbench
這是DriverSt2.2DriverStudio3.2的安裝安裝需要的軟硬件環(huán)境Intelx86兼容系統(tǒng)或X64系統(tǒng)(包含IA64和AMD64以及Itanium)WindowsXP內(nèi)存:最少256MB,推薦使用512MB硬盤:完全安裝需要大約182MB針對(duì)SoftICE的遠(yuǎn)程調(diào)試:NE2000-兼容網(wǎng)卡或3Com網(wǎng)卡針對(duì)DriverWorks:MicrosoftXPDDK,
VisualC++.NET92.2DriverStudio3.2的安裝安裝需要的軟硬安裝步驟:在安裝DriverWorks之前,首先要保證你的計(jì)算機(jī)上已經(jīng)安裝了MicrosoftVisualC++.NET以及WindowsXPDDK。所有這些包括DriverStudio的安裝都必須以系統(tǒng)管理員身份啟動(dòng)系統(tǒng)。并且要按照下面的順序安裝。10安裝步驟:10第二步:安裝WindowsXPDDK(DriverDevelopmentKits)。注意:1)在安裝DDK的時(shí)候請(qǐng)選擇完全安裝。2)安裝中,不需要安裝64BITIA64Binaries
3)安裝好后,對(duì)于XPDDK不需要手動(dòng)配置環(huán)境變量,只需在開(kāi)始菜單中點(diǎn)擊CheckedBuildEnvirment則DDK會(huì)自動(dòng)調(diào)用setenv配置環(huán)境變量,并監(jiān)測(cè)相應(yīng)的SDK以及VisualStudio.NETIDE第一步:安裝VisualStudioC++.NET第三步:安裝DriverStudio3.2(按照安裝提示安裝)。11第二步:第一步:第三步:11DriverStudio3.2支持單機(jī)調(diào)試或雙機(jī)調(diào)試兩種模式。在安裝的時(shí)候也有Host和Target兩種模式。單機(jī)調(diào)試需要在同一個(gè)機(jī)器中將Host和Target兩種模式都安裝雙機(jī)調(diào)試的時(shí)候需要在一個(gè)機(jī)器上安裝Host模式,在另一個(gè)機(jī)器上安裝Target模式。12DriverStudio3.2支持單機(jī)調(diào)試或雙機(jī)調(diào)試兩種DriverStudio安裝后的設(shè)置:1)使用DDKBuildSetting工具定義BASEDIR環(huán)境變量并啟動(dòng)MSVC.NET,13DriverStudio安裝后的設(shè)置:1314141515161617172)打開(kāi)下列地址上的建立庫(kù)文件工程VdwLibs2002.sln如果是VS.NET2003,則打開(kāi)VdwLibs2003.sln182)打開(kāi)下列地址上的建立庫(kù)文件工程VdwLibs2002.s3)選擇“生成->批生成”,打開(kāi)下面的窗口,從中選則需要編譯的配置。
Checked是調(diào)試版本,F(xiàn)ree是發(fā)布版本193)選擇“生成->批生成”,打開(kāi)下面的窗口,從中選則需要編譯4)點(diǎn)擊“重新生成”編譯所選擇的庫(kù)文件。注意:庫(kù)文件只需在安裝完成后第一次使用前編譯一次即可。以后要使用DriverWorks,只需通過(guò)SetDDKGo進(jìn)入MSVC.NET即可?;蛘咧苯訌腗SVC.NET中啟動(dòng)DriverWorks。204)點(diǎn)擊“重新生成”編譯所選擇的庫(kù)文件。注意:庫(kù)文件只需在安3.DriverWorks的使用1)生成簡(jiǎn)單框架(VS.NET中啟動(dòng)DriverWizard)213.DriverWorks的使用1)生成簡(jiǎn)單框架(VS.N2222工程文件名工程文件目錄23工程文件名工程文件目錄23選擇驅(qū)動(dòng)類型選擇框架類型24選擇驅(qū)動(dòng)類型選擇框架類型24創(chuàng)建功能驅(qū)動(dòng)程序創(chuàng)建過(guò)濾器驅(qū)動(dòng)程序25創(chuàng)建功能驅(qū)動(dòng)程序創(chuàng)建過(guò)濾器驅(qū)動(dòng)程序25選擇相應(yīng)總線本例不驅(qū)動(dòng)硬件26選擇相應(yīng)總線本例不驅(qū)動(dòng)硬件26選擇需要處理的消息句柄27選擇需要處理的消息句柄27添加和應(yīng)用程序之間通信的控制代碼28添加和應(yīng)用程序之間通信的控制代碼282929303031313232333334343535363637373838驅(qū)動(dòng)類設(shè)備類隊(duì)列管理類39驅(qū)動(dòng)類設(shè)備類隊(duì)列管理類39驅(qū)動(dòng)類文件設(shè)備類文件測(cè)試用的控制臺(tái)程序文件驅(qū)動(dòng)安裝指導(dǎo)文件隊(duì)列管理類40驅(qū)動(dòng)類文件設(shè)備類文件測(cè)試用的控制臺(tái)程序文件驅(qū)動(dòng)安裝指導(dǎo)文件隊(duì)此時(shí)已經(jīng)具備了一個(gè)驅(qū)動(dòng)程序以及做測(cè)試用的應(yīng)用程序的基本框架,我們可以在VC集成環(huán)境下修改有關(guān)程序,增加相關(guān)的具體操作代碼,然后就可以編譯和調(diào)試了。41此時(shí)已經(jīng)具備了一個(gè)驅(qū)動(dòng)程序以及做測(cè)試用的應(yīng)用程序的基該驅(qū)動(dòng)程序框架包含了幾個(gè)最基本的類,這些類是:classSampleDriver:publicKDriver//驅(qū)動(dòng)程序類,用于初始化驅(qū)動(dòng)程序{SAFE_DESTRUCTORSpublic:
//以下成員函數(shù)注意和WDM中有關(guān)例程聯(lián)系起來(lái)看virtualNTSTATUSDriverEntry(PUNICODE_STRINGRegistryPath);virtualNTSTATUSAddDevice(PDEVICE_OBJECTPdo);virtualVOIDUnload(VOID);voidLoadRegistryParameters(PUNICODE_STRINGRegistryPath);protected:
//成員數(shù)據(jù)intm_Unit;};42該驅(qū)動(dòng)程序框架包含了幾個(gè)最基本的類,這些類是:42classSampleDevice:publicKPnpDevice//是設(shè)備類KDvice的派生類,用于在WDM環(huán)境下支持即插即用設(shè)備{
//Constructorspublic: SAFE_DESTRUCTORS; SampleDevice(PDEVICE_OBJECTPdo,ULONGUnit); ~SampleDevice(); VOIDInvalidate(void);
//MemberFunctions注意和PNP的次功能代碼聯(lián)系起來(lái)看 DEVMEMBER_DISPATCHERS virtualNTSTATUSOnStartDevice(KIrpI); virtualNTSTATUSOnStopDevice(KIrpI); virtualNTSTATUSOnRemoveDevice(KIrpI); virtualNTSTATUSOnDevicePowerUp(KIrpI); virtualNTSTATUSOnDeviceSleep(KIrpI); virtualNTSTATUSDefaultPnp(KIrpI); virtualNTSTATUSDefaultPower(KIrpI);
voidLoadRegistryParameters();//取注冊(cè)表信息43classSampleDevice:publicKP voidSerialRead(KIrpI); voidSerialWrite(KIrpI); NTSTATUSSAMPLE_IOCTL_Read_Handler(KIrpI); NTSTATUSSAMPLE_IOCTL_Write_Handler(KIrpI); NTSTATUSSAMPLE_IOCTL_ReadWrite_Handler(KIrpI);protected://MemberData KPnpLowerDevice m_Lower; sampleQueue ReadQueue; //DrivermanagedIRPqueue sampleQueue WriteQueue; //DrivermanagedIRPqueue#ifdef__COMMENT_ONLY virtualNTSTATUSCreate(KIrpI); //COMMENT_ONLY virtualNTSTATUSClose(KIrpI); //COMMENT_ONLY virtualNTSTATUSRead(KIrpI); //COMMENT_ONLY virtualNTSTATUSWrite(KIrpI); //COMMENT_ONLY virtualNTSTATUSDeviceControl(KIrpI);//COMMENT_ONLY virtualNTSTATUSSystemControl(KIrpI);//
COMMENT_ONLY#endif//__COMMENT_ONLY};44 voidSerialRead(KIrpI);44由于一個(gè)可能是DriverStudio3.2中的BUG,所以及時(shí)生成的一個(gè)空工程項(xiàng)目也無(wú)法編譯通過(guò),需要對(duì)生成的工程文件做以下手工修改:把sample項(xiàng)目中的sources文件中的:
TARGETLIBS=$(DDK_LIB_PATH)\ntstrsafe.lib$(DDK_LIB_PATH)\csq.lib
這一行去掉就可以編譯通過(guò)了
45由于一個(gè)可能是DriverStudio3.2中的BUG,所先編譯驅(qū)動(dòng)程序工程在VS2002的集成環(huán)境中下面我們講解編譯、執(zhí)行和調(diào)試這個(gè)驅(qū)動(dòng)程序。生成目標(biāo)文件46先編譯驅(qū)動(dòng)程序工程在VS2002的集成環(huán)境中下面我們講解編譯確認(rèn)生成的是驅(qū)動(dòng)程序47確認(rèn)生成的是驅(qū)動(dòng)程序47在VS2002的集成環(huán)境中生成目標(biāo)文件再編譯測(cè)試應(yīng)用程序工程48在VS2002的集成環(huán)境中生成目標(biāo)文件再編譯測(cè)試應(yīng)用程序工程確認(rèn)生成的是測(cè)試用應(yīng)用程序49確認(rèn)生成的是測(cè)試用應(yīng)用程序49下面使用DriverStudio帶的工具加載驅(qū)動(dòng)程序和查看調(diào)試信息。驅(qū)動(dòng)程序監(jiān)視,可實(shí)時(shí)看到驅(qū)動(dòng)程序發(fā)出的調(diào)試輸出語(yǔ)句驅(qū)動(dòng)程序裝載器,可動(dòng)態(tài)調(diào)用驅(qū)動(dòng)程序50下面使用DriverStudio帶的工具加載驅(qū)動(dòng)程序驅(qū)動(dòng)程序監(jiān)視器界面51驅(qū)動(dòng)程序監(jiān)視器界面51為了防止其他驅(qū)動(dòng)程序的干擾,在FilterMessage對(duì)話框中設(shè)置消息過(guò)濾規(guī)則,只讓有sample的消息通過(guò)。52為了防止其他驅(qū)動(dòng)程序的干擾,在FilterMessage對(duì)驅(qū)動(dòng)程序裝載器界面53驅(qū)動(dòng)程序裝載器界面53545455555656驅(qū)動(dòng)程序已經(jīng)加載并且啟動(dòng)57驅(qū)動(dòng)程序已經(jīng)加載并且啟動(dòng)57YANGQS58YANGQS58DriverStudio3.2給出的驅(qū)動(dòng)測(cè)試軟件是一個(gè)Win32的窗口程序,而不是先前版本的控制臺(tái)程序。為了在調(diào)試輸出的時(shí)候有所區(qū)別我們將測(cè)試程序的調(diào)試輸出語(yǔ)句的句頭由原來(lái)的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;}59DriverStudio3.2給出的驅(qū)動(dòng)測(cè)試軟件是一個(gè)Wi運(yùn)行編譯好的sampleAPP.exe60運(yùn)行編譯好的sampleAPP.exe606161如果在執(zhí)行sampleAPP.exe之前,驅(qū)動(dòng)程序sample.sys還沒(méi)有加載到內(nèi)存中,則在DriverMonitor程序中就可以看到以下信息:62如果在執(zhí)行sampleAPP.exe之前,驅(qū)動(dòng)程序samplAPP中打開(kāi)與驅(qū)動(dòng)程序聯(lián)系63APP中打開(kāi)與驅(qū)動(dòng)程序聯(lián)系636464結(jié)束后一定要卸載驅(qū)動(dòng)程序65結(jié)束后一定要卸載驅(qū)動(dòng)程序65驅(qū)動(dòng)程序已經(jīng)卸載66驅(qū)動(dòng)程序已經(jīng)卸載66下面我們來(lái)修改有關(guān)代碼,以便增加驅(qū)動(dòng)程序和應(yīng)用程序之間相互通信的內(nèi)容。需要增加的內(nèi)容包括:使用Read和Write方式分別從驅(qū)動(dòng)程序讀入字符和向驅(qū)動(dòng)程序?qū)懽址J褂肐O控制代碼方式分別從驅(qū)動(dòng)程序讀入字符和向驅(qū)動(dòng)程序?qū)懽址?。使用IO控制代碼方式向驅(qū)動(dòng)程序?qū)懽址購(gòu)尿?qū)動(dòng)程序中讀出該字符串,并返回反饋串信息。
注意:程序中暗紅色顯示的部分是我們添加或修改過(guò)的語(yǔ)句,其他是DriverWorks自動(dòng)生成的。藍(lán)色顯示的部分是要?jiǎng)h除的語(yǔ)句。省略號(hào)的部分是不變的。語(yǔ)句中T.Trace(TraceInfo,__FUNCTION__“xxxx”)這樣的語(yǔ)句是向調(diào)試軟件輸出信息,該信息可在DriverMonitor或其他調(diào)試監(jiān)視器中看到。2)完成應(yīng)用程序和驅(qū)動(dòng)程序之間的信息交換67下面我們來(lái)修改有關(guān)代碼,以便增加驅(qū)動(dòng)程序和應(yīng)用程序之a(chǎn).1使用Read方式讀SampleDevice.cppvoidSampleDevice::SerialRead(KIrpI){ T.Trace(TraceInfo,__FUNCTION__"++.IRP%p\n",I); NTSTATUSstatus =STATUS_SUCCESS; PUCHAR pBuffer =(PUCHAR)I.BufferedReadDest();//取得返回?cái)?shù)據(jù)BUFF的指針 ULONGreadSize=I.ReadSize();//獲得應(yīng)用程序希望讀驅(qū)動(dòng)程序信息的字節(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); //把給應(yīng)用程序的數(shù)據(jù)拷貝給返回BUFFT.Trace(TraceInfo,__FUNCTION__"Thestringyouwillreadis%s\n",buff);//輸出調(diào)試信息 bytesRead=strlen(buff); //Countofbytesread
I.Information()=bytesRead;
//返回給應(yīng)用程序的信息的字節(jié)個(gè)數(shù)
I.Status()=status; m_DriverManagedQueue.PnpNextIrp(I);}68a.1使用Read方式讀68控件IDC_OP_TYPE_COMBO及其選擇項(xiàng),我們這次選ReadFile69控件IDC_OP_TYPE_COMBO及其選擇項(xiàng),我們這次選sampleIorw.cpp中有關(guān)讀數(shù)據(jù)的代碼:ULONGsampleExecuteIo(HWNDhDlg){PSAMPLE_LIST_ITEMioItem;……//獲得需要讀的字節(jié)數(shù)
GetDlgItemText(hDlg,IDC_OUT_SIZE_EDIT,str,MAX_STRING_LENGTH);
ioItem->OutSize=_ttol(str);//設(shè)置控件IDC_OP_TYPE_COMBO的句柄hWnd=GetDlgItem(hDlg,IDC_OP_TYPE_COMBO);//獲得當(dāng)前被選中項(xiàng)目的索引itemIndex=(DWORD)SendMessage(hWnd,CB_GETCURSEL,0,0);//獲得被選中的項(xiàng)目的字符串SendMessage(hWnd,CB_GETLBTEXT,(WPARAM)itemIndex,(LPARAM)str);
if((!_tcscmp(str,_T(“ReadFile”)))&&(ioItem->OutSize>0))//如是讀端口{
//設(shè)置讀的緩沖區(qū)ioItem->OutBuffer=(PCHAR)malloc(ioItem->OutSize); ……
70sampleIorw.cpp中有關(guān)讀數(shù)據(jù)的代碼:ULONG//從驅(qū)動(dòng)程序讀數(shù)據(jù)if((!ReadFile( g_hDevice, //設(shè)備句柄 ioItem->OutBuffer, //輸入緩沖地址 ioItem->OutSize, //緩沖大小(字節(jié)數(shù)) NULL, //實(shí)際讀的數(shù)據(jù)字節(jié)數(shù) &ioItem->IoOverlapped))&&//覆蓋結(jié)構(gòu)指針,表示異步讀 (GetLastError()!=ERROR_IO_PENDING)){//如果讀出錯(cuò),給出出錯(cuò)的調(diào)試信息 error=GetLastError();
sampleOutputText(_T("ReadFilefailedwitherror(%d)"),error); break;}//設(shè)置回調(diào)函數(shù),因?yàn)槭钱惒阶x,所以讀出數(shù)據(jù)后回調(diào)函數(shù)會(huì)啟動(dòng)ioItem->Callback=sampleReadCompleteCallback; ……}//if((!_tcscmp(str,_T(“ReadFile”)……
}71//從驅(qū)動(dòng)程序讀數(shù)據(jù)71VOIDsampleReadCompleteCallback(PVOIDContext){//讀驅(qū)動(dòng)程序的回調(diào)函數(shù)PSAMPLE_LIST_ITEMioItem=(PSAMPLE_LIST_ITEM)Context;
//因VS.net隱含采用Unicode編碼,每個(gè)字符16位,下面做8位到16位字符轉(zhuǎn)換
charwstr[1025];for(ULONGi=0;i<ioItem->OutSize;i++){wstr[i*2]=ioItem->OutBuffer[i];wstr[i*2+1]=0x0;}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);
//關(guān)閉重疊事件句柄CloseHandle(ioItem->IoOverlapped.hEvent);
//釋放ioItem空間free(ioItem);return;}72VOIDsampleReadCompleteCallbac7373a.2使用Write方式寫SampleDevice.cppvoidSampleDevice::SerialWrite(KIrpI){ T.Trace(TraceInfo,__FUNCTION__"++.IRP%p\n",I); NTSTATUSstatus=STATUS_SUCCESS; PUCHARpBuffer=(PUCHAR)I.BufferedWriteSource();//取得存放應(yīng)用程序?qū)懡o驅(qū)動(dòng)程序的數(shù)據(jù)的BUFF的指針 ULONGwriteSize=I.WriteSize();//獲得應(yīng)用程序?qū)懡o驅(qū)動(dòng)程序的信息的字節(jié)數(shù)。 ULONGbytesSent=0;
bytesSent=writeSize;
charbuff[512]; strcpy(buff,(char*)pBuffer); //應(yīng)用程序?qū)懡o驅(qū)動(dòng)程序的數(shù)據(jù)在I.BufferedWriteSource()返回的指針中。
buff[bytesSent]='\0'; T.Trace(TraceInfo,__FUNCTION__"Writetodriveris%s\n",buff);
I.Information()=bytesSent;
//返回用戶實(shí)際寫的字節(jié)數(shù) I.Status()=status; m_DriverManagedQueue.PnpNextIrp(I);}74a.2使用Write方式寫74控件IDC_OP_TYPE_COMBO及其選擇項(xiàng),我們這次選WriteFile75控件IDC_OP_TYPE_COMBO及其選擇項(xiàng),我們這次選sampleIorw.cpp中有關(guān)寫數(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"),&inPattern);
charinstr[MAX_STRING_LENGTH];//TCHAR轉(zhuǎn)換成char*for(inti=0;i<MAX_STRING_LENGTH;i++) instr[i]=(char)str[i];ioItem->InSize=strlen(instr);//設(shè)置控件IDC_OP_TYPE_COMBO的句柄hWnd=GetDlgItem(hDlg,IDC_OP_TYPE_COMBO);//獲得當(dāng)前被選中項(xiàng)目的索引itemIndex=(DWORD)SendMessage(hWnd,CB_GETCURSEL,0,0);//獲得被選中的項(xiàng)目的字符串SendMessage(hWnd,CB_GETLBTEXT,(WPARAM)itemIndex,(LPARAM)str);76sampleIorw.cpp中有關(guān)寫數(shù)據(jù)的代碼:ULONG
//Writedatatodriverif((!_tcscmp(str,_T(“ReadFile”)))&&(ioItem->OutSize>0))//如是讀端口{
//設(shè)置寫的緩沖區(qū)ioItem->InBuffer=(PCHAR)malloc(ioItem->InSize);……
strcpy((char*)ioItem->InBuffer,instr);//for(ii=0;ii<ioItem->InSize;ii+=sizeof(DWORD))//{//CopyMemory(ioItem->InBuffer+ii,&inPattern,//min(sizeof(DWORD),ioItem->InSize-ii));//}
if((!WriteFile(g_hDevice,ioItem->InBuffer,ioItem->InSize,NULL,&ioItem->IoOverlapped))&&(GetLastError()!=ERROR_IO_PENDING)){//如果讀出錯(cuò),給出出錯(cuò)的調(diào)試信息error=GetLastError();sampleOutputText(_T("WriteFilefailedwitherror(%d)"),error);break;}//設(shè)置回調(diào)函數(shù),因?yàn)槭钱惒阶x,所以讀出數(shù)據(jù)后回調(diào)函數(shù)會(huì)啟動(dòng)ioItem->Callback=sampleWriteCompleteCallback; ……}//if((!_tcscmp(str,_T(“WriteFile”)……
}77 //Writedatatodriver777878b.1使用IO控制代碼方式讀SampleDevice.cppNTSTATUSsampleDevice::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!”);//這是應(yīng)用程序?qū)⒁x到的字符串
fwLength=strlen(buff1)+1; if(outputSize>=fwLength) {//如果讀入緩沖夠長(zhǎng)strcpy((PCHAR)I.IoctlBuffer(),buff1);//將信息拷給應(yīng)用程序讀入緩沖I.Information()=fwLength; //返回信息長(zhǎng)度} else {I.Information()=0; //否則信息長(zhǎng)度為0T.Trace(TraceInfo,__FUNCTION__"buffsizetoosmall\n");}79b.1使用IO控制代碼方式讀SampleDevice.cp//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;}80//Bufferedioctl-usingthesampleIorw.cpp中有關(guān)寫數(shù)據(jù)的代碼:ULONGsampleExecuteIo(HWNDhDlg){PSAMPLE_LIST_ITEMioItem;……if((!_tcscmp(str,_T("SAMPLE_IOCTL_Read")))&&((ioItem->OutSize>0)||(ioItem->InSize>0))){……//Setuptheoutbufferifspecifiedif(ioItem->OutSize>0){ioItem->OutBuffer=(PCHAR)malloc(ioItem->OutSize);……}……81sampleIorw.cpp中有關(guān)寫數(shù)據(jù)的代碼:ULONGif((!DeviceIoControl(g_hDevice, //設(shè)備句柄SAMPLE_IOCTL_Read, //IO控制命令ioItem->InBuffer, //寫緩沖ioItem->InSize, //寫緩沖大小ioItem->OutBuffer, //讀緩沖ioItem->OutSize, //讀緩沖大小NULL, //實(shí)際讀的字節(jié)數(shù)&ioItem->IoOverlapped))&& //覆蓋結(jié)構(gòu)指針(GetLastError()!=ERROR_IO_PENDING)){error=GetLastError();sampleOutputText(_T("SAMPLE_IOCTL_Readfailedwitherror(%d)"),error);break;}
//SetuptheentryioItem->Callback=sampleSAMPLE_IOCTL_ReadCompleteCallback;……}//if((!_tcscmp(str,_T("SAMPLE_IOCTL_Read")……
}82if((!DeviceIoContrVOIDsampleSAMPLE_IOCTL_ReadCompleteCallback(PVOIDContext){PSAMPLE_LIST_ITEMioItem=(PSAMPLE_LIST_ITEM)Context;
charwstr[1025];for(ULONGi=0;i<ioItem->OutSize;i++){ wstr[i*2]=ioItem->OutBuffer[i]; wstr[i*2+1]=0x0;}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);……}83VOIDsampleSAMPLE_IOCTL_ReadCo8484b.2使用IO控制代碼方式寫SampleDevice.cppNTSTATUSsampleDevice::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());
//應(yīng)用程序?qū)懡o驅(qū)動(dòng)程序的數(shù)據(jù)在I.BufferedWriteSource()返回的指針中。
buff[inputSize]='\0';T.Trace(TraceInfo,__FUNCTION__"Writetodriveris%s\n",buff);I.Information()=0;
85b.2使用IO控制代碼方式寫SampleDevice.cp//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;}86//Bufferedioctl-usingthesampleIorw.cpp中有關(guān)寫數(shù)據(jù)的代碼:ULONGsampleExecuteIo(HWNDhDlg)//本頁(yè)的修改實(shí)際上前面Write時(shí)已經(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"),&inPattern);
charinstr[MAX_STRING_LENGTH];//TCHAR轉(zhuǎn)換成char*for(inti=0;i<MAX_STRING_LENGTH;i++) instr[i]=(char)str[i];ioItem->InSize=strlen(instr);//設(shè)置控件IDC_OP_TYPE_COMBO的句柄hWnd=GetDlgItem(hDlg,IDC_OP_TYPE_COMBO);//獲得當(dāng)前被選中項(xiàng)目的索引itemIndex=(DWORD)SendMessage(hWnd,CB_GETCURSEL,0,0);//獲得被選中的項(xiàng)目的字符串SendMessage(hWnd,CB_GETLBTEXT,(WPARAM)itemIndex,(LPARAM)str);……87sampleIorw.cpp中有關(guān)寫數(shù)據(jù)的代碼:ULONGif((!_tcscmp(str,_T(“SAMPLEIOCTL_Write”)))&&((ioItem->OutSize>0)||(ioItem->InSize>0)))//如是寫端口,本頁(yè)的部分需要修改{
//設(shè)置寫的緩沖區(qū)ioItem->InBuffer=(PCHAR)malloc(ioItem->InSize);……
strcpy((char*)ioItem->InBuffer,instr);//for(ii=0;ii<ioItem->InSize;ii+=sizeof(DWORD))//{//CopyMemory(ioItem->InBuffer+ii,&inPattern,//min(sizeof(DWORD),ioItem->InSize-ii));//}……
if((!DeviceIoControl(g_hDevice,SAMPLE_IOCTL_Write,ioItem->InBuffer,ioItem->InSize,ioItem->OutBuffer,ioItem->OutSize,NULL,&ioItem->IoOverlapped))&&(GetLastError()!=ERROR_IO_PENDING)){……}//設(shè)置回調(diào)函數(shù),因?yàn)槭钱惒阶x,所以讀出數(shù)據(jù)后回調(diào)函數(shù)會(huì)啟動(dòng)ioItem->Callback=sampleSAMPLEIOCTL_WriteCompleteCallback; ……}//if((!_tcscmp(str,_T("SAMPLEIOCTL_Write")))……
}88if((!_tcscmp(str,_T(“SAMPLEI8989c.使用IO控制代碼方式寫并且讀SampleDevice.cppNTSTATUSsampleDevice::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());//取應(yīng)用程序?qū)懡o驅(qū)動(dòng)程序的數(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; 90c.使用IO控制代碼方式寫并且讀SampleDevice.if(outputSize>=fwLength) {//如果讀入緩沖夠長(zhǎng)strcpy((PCHAR)I.IoctlBuffer(),buff1);//將信息拷給應(yīng)用程序讀入緩沖I.Information()=fwLength; //返回信息長(zhǎng)度} else{ I.Information()=0; //否則信息長(zhǎng)度為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;}91if(outputSize>=fwLength) {sampleIorw.cpp中有關(guān)讀寫數(shù)據(jù)的代碼:ULONGsampleExecuteIo(HWNDhDlg)//本頁(yè)的修改實(shí)際上前面Write時(shí)已經(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"),&inPattern);
charinstr[MAX_STRING_LENGTH];//TCHAR轉(zhuǎn)換成char*for(inti=0;i<MAX_STRING_LENGTH;i++) instr[i]=(char)str[i];ioItem->InSize=strlen(instr);//設(shè)置控件IDC_OP_TYPE_COMBO的句柄hWnd=GetDlgItem(hDlg,IDC_OP_TYPE_COMBO);//獲得當(dāng)前被選中項(xiàng)目的索引itemIndex=(DWORD)SendMessage(hWnd,CB_GETCURSEL,0,0);//獲得被選中的項(xiàng)目的字符串SendMessage(hWnd,CB_GETLBTEXT,(WPARAM)itemIndex,(LPARAM)str);……92sampleIorw.cpp中有關(guān)讀寫數(shù)據(jù)的代碼:ULONGif((!_tcscmp(str,_T(“IOCTL_ReadWrite”)))&&((ioItem->OutSize>0)||(ioItem->InSize>0)))//如是讀寫端口,本頁(yè)的的內(nèi)容需要對(duì)照著修改,注意if語(yǔ)句的條件{
//設(shè)置寫的緩沖區(qū)ioItem->InBuffer=(PCHAR)malloc(ioItem->InSize);……
strcpy((char*)ioItem->InBuffer,instr);//for(ii=0;ii<ioItem->InSize;ii+=sizeof(DWORD))//{//CopyMemory(ioItem->InBuffer+ii,&inPattern,//min(sizeof(DWORD),ioItem->InSize-ii));//}……
if((!DeviceIoControl(g_hDevice,IOCTL_ReadWrite,ioItem->InBuffer,ioItem->InSize,ioItem->OutBuffer,ioItem->OutSize,NULL,&ioItem->IoOverlapped))&&(GetLastError()!=ERROR_IO_PENDING)){……}//設(shè)置回調(diào)函數(shù),因?yàn)槭钱惒阶x,所以讀出數(shù)據(jù)后回調(diào)函數(shù)會(huì)啟動(dòng)ioItem->Callback=sampleIOCTL_ReadWriteCompleteCallback; ……}//if((!_tcscmp(str,_T("SAMPLEIOCTL_Write")))……
}93if((!_tcscmp(str,_T(“IOCTL_RVOIDsampleIOCTL_ReadWriteCompleteCallback(PVOIDContext){PSAMPLE_LIST_ITEMioItem=(PSAMPLE_LIST_ITEM)Context;//因VS.net隱含采用Unicode編碼,每個(gè)字符16位,下面做8位到16位字符轉(zhuǎn)換
charwstr[1025];for(ULONGi=0;i<ioItem->OutSize;i++){wstr[i*2]=ioItem->OutBuffer[i];wstr[i*2+1]=0x0;}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);……}94VOIDsampleIOCTL_ReadWriteComp95953)直接對(duì)端口寄存器讀寫DriverStudio提供了KIoRange類來(lái)將外部總線的I/O地址空間范圍映射到處理器總線的地址空間范圍。該類的成員函數(shù)主要有KIoRange
構(gòu)造函數(shù)(4種格式)Initialize 初始化和重新初始化一個(gè)實(shí)例(3種格式)~KIoRange析構(gòu)函數(shù)Invalidate 從已初始化狀態(tài)刪除該對(duì)象IsValid
測(cè)試該對(duì)象是否已經(jīng)初始化inb
讀一個(gè)或多個(gè)字節(jié)(2種形式)Outb
寫一個(gè)或多個(gè)字節(jié)(2種形式)Inw
讀一個(gè)或多個(gè)字(2種形式)Outw
寫一個(gè)或多個(gè)字(2種形式)ind
讀一個(gè)或多個(gè)雙字(2種形式)outd 寫一個(gè)或多個(gè)雙字(2種形式)
963)直接對(duì)端口寄存器讀寫DriverStudio提供KIoRange::KIoRange(只介紹WDM形式)FORM3(WDM):KIoRange(
ULONGLONGCpuPhysicalAddress,//轉(zhuǎn)換成外圍設(shè)備地址的CPU總線上的物理地址
BOOLEANInCpuIoSpace,//如果IO范圍是在CPU總線的IO空間中為TRUE,否則為FALSE
ULONGCount,//以字節(jié)計(jì)的區(qū)域的大小
BOOLEANMapToSystemVirtual=TRUE//指定是否需要構(gòu)造函數(shù)創(chuàng)建一個(gè)非頁(yè)系統(tǒng)空間的地址空間映射,如果驅(qū)動(dòng)程序讀寫設(shè)備中的數(shù)據(jù),就需要這種映射);FORM4(WDM):(注意:這種形式不被
DriverStudio2.0支持。)KIoRange(
PCM_RESOURCE_LISTpTranslatedResourceList,//指向轉(zhuǎn)換資源表的指針
ULONGOrdinal=0,//指定pTranslatedResourceList指向的資源列表中的一個(gè)特殊端口資源
BOOLEANMapToSystemVirtual=TRUE
);FORM5(WDM):KIoRange(
PCM_RESOURCE_LIST
pTranslatedResourceList,//可通過(guò)KIrp::TranslatedResources獲得
PCM_RESOURCE_LIST
pRawResourceList,//指向原始資源表的指針
ULONG
Ordinal=0,
BOOLEAN
MapToSystemVirtual=TRUE
);構(gòu)造KIoRange類。97KIoRange::KIoRange(只介紹WDM形式)97KIoRange::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_LIST
pTranslatedResourceList,
PCM_RESOURCE_LIST
pRawResourceList,
ULONG
Ordinal=0,
BOOLEAN
MapToSystemVirtual=TRUE);初始化或重新初始化KIoRange的實(shí)例。98KIoRange::Initialize(只介紹WDM形式KIoRange::inbFORM1:UCHARinb(ULONGByteOffset);FORM2:VOIDinb(
ULONGByteOffset,
PUCHARBuffer,
ULONGCount
);從映射空間讀一個(gè)或多個(gè)字節(jié)。99KIoRange::inb99KIoRange::outbFORM1:VOIDoutb(
ULONGByteOffset,//以字節(jié)為單位的目標(biāo)位置到IO空間開(kāi)始位置的偏移值
UCHARData//要寫的一個(gè)字節(jié)數(shù)據(jù));FORM2:VOIDoutb(
ULONGByteOffset,
PUCHARBuffer,//指向包含要寫數(shù)據(jù)的緩沖的指針
ULONGCount//緩沖中要寫數(shù)據(jù)的字節(jié)數(shù));寫一個(gè)或多個(gè)字節(jié)到映射的IO空間。100KIoRange::outb100寫端口(索引信息,地址70H)m_ParPortIos.outb(0,0x02);//準(zhǔn)備讀分鐘信息讀端口(讀分鐘信息,地址71H)
UCHARdata=m_ParPortIos.inb(1);下面我們來(lái)訪問(wèn)CMOS的數(shù)據(jù)。首先定義類KIoRange的一個(gè)實(shí)例,以定義相關(guān)地址空間。
KIoRangem_ParPortIos;初始化實(shí)例(指定CMOS的端口首地址,并映射)
status=m_ParPortIos.Initialize(
0x70, //CMOS端口首地址是70H
TRUE, //在CPUI/O空間內(nèi)
8, //設(shè)備讀寫數(shù)據(jù)的字節(jié)寬度
TRUE //映射到系統(tǒng)空間
);101寫端口(索引信息,地址70H)m_ParPortIos4)截獲中斷和掛接中斷服務(wù)例程
DriverStudio提供了KInterrupt類來(lái)截獲和掛接中斷。
該類的成員函數(shù)主要有KInterrupt構(gòu)造函數(shù)(3種格式)Initialize在無(wú)效狀態(tài)下初始化一個(gè)對(duì)象(3種格式)Connect
綁定ISR(中斷服務(wù)例程)到中斷InitializeAndConnect一步完成初始化與綁定工作,要用資源列表作為輸入。~KInterrupt析構(gòu)函數(shù)Inva
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 胸外科護(hù)士工作心得
- 2025年全球及中國(guó)單擺銑頭行業(yè)頭部企業(yè)市場(chǎng)占有率及排名調(diào)研報(bào)告
- 2025-2030全球倒置行星滾柱絲杠行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 2025年全球及中國(guó)虛擬試穿平臺(tái)行業(yè)頭部企業(yè)市場(chǎng)占有率及排名調(diào)研報(bào)告
- 2025年全球及中國(guó)汽車天線定位器行業(yè)頭部企業(yè)市場(chǎng)占有率及排名調(diào)研報(bào)告
- 2025年全球及中國(guó)重載有軌穿梭小車(RGV)行業(yè)頭部企業(yè)市場(chǎng)占有率及排名調(diào)研報(bào)告
- 2025年全球及中國(guó)絲素蛋白敷料行業(yè)頭部企業(yè)市場(chǎng)占有率及排名調(diào)研報(bào)告
- 2025-2030全球直線式桁架機(jī)器人行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 2025-2030全球裝運(yùn)前檢驗(yàn)(PSI)服務(wù)行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 2025年全球及中國(guó)電子鑰匙柜行業(yè)頭部企業(yè)市場(chǎng)占有率及排名調(diào)研報(bào)告
- 江西省部分學(xué)校2024-2025學(xué)年高三上學(xué)期1月期末英語(yǔ)試題(含解析無(wú)聽(tīng)力音頻有聽(tīng)力原文)
- GA/T 2145-2024法庭科學(xué)涉火案件物證檢驗(yàn)實(shí)驗(yàn)室建設(shè)技術(shù)規(guī)范
- 2024年中考語(yǔ)文試題分類匯編:非連續(xù)性文本閱讀(學(xué)生版)
- 2024年度窯爐施工協(xié)議詳例細(xì)則版B版
- 第一屆山東省職業(yè)能力大賽濟(jì)南市選拔賽制造團(tuán)隊(duì)挑戰(zhàn)賽項(xiàng)目技術(shù)工作文件(含樣題)
- 尿毒癥替代治療
- 【課件】2025屆高考英語(yǔ)一輪復(fù)習(xí)小作文講解課件
- 基底節(jié)腦出血護(hù)理查房
- 工程公司總經(jīng)理年終總結(jié)
- 2024年海南省高考地理試卷(含答案)
- 【企業(yè)盈利能力探析的國(guó)內(nèi)外文獻(xiàn)綜述2400字】
評(píng)論
0/150
提交評(píng)論