2011年微機原理與接口技術(shù)_第1頁
2011年微機原理與接口技術(shù)_第2頁
2011年微機原理與接口技術(shù)_第3頁
2011年微機原理與接口技術(shù)_第4頁
2011年微機原理與接口技術(shù)_第5頁
已閱讀5頁,還剩145頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第十一章Windows輸入/輸出程序設(shè)計11.1Windows9x和虛擬設(shè)備驅(qū)動程序11.2設(shè)備驅(qū)動程序的編寫

11.3Win32應(yīng)用程序和VxD之間的通信

11.4Windows9x的輸入/輸出

11.5Windows9x的中斷處理

11.6VxD實例

11.7WDM設(shè)備驅(qū)動程序

11.1Windows9x和虛擬設(shè)備驅(qū)動程序

11.1.1

Windows9x的分層結(jié)構(gòu) Windows9x是一個分層結(jié)構(gòu)的操作系統(tǒng),由兩個不同的層構(gòu)成。頂層(ring3層):給應(yīng)用程序的運行提供Win32API服務(wù),包括所有的由USER、GDI、和KERNEL提供的服務(wù)。Windows9x應(yīng)用程序和Win32API服務(wù)一起構(gòu)成操作系統(tǒng)的頂層,運行在一個單一的虛擬機中,統(tǒng)稱為系統(tǒng)VM。每一個DOS應(yīng)用程序都在一個獨立的虛擬機中運行。操作系統(tǒng)允許多個虛擬機同時處于運行狀態(tài)。底層(ring0層):Windows9x操作系統(tǒng)的底層就是虛擬機管理器。對于應(yīng)用程序而言,虛擬機管理器是透明的,應(yīng)用程序感覺不到管理器的存在。Windows9x虛擬機管理器由一個內(nèi)核服務(wù)集和許多虛擬設(shè)備驅(qū)動程序(VxDs)組成。許多VxDs是由Microsoft公司隨操作系統(tǒng)提供的,如鍵盤和顯示器等。其他VxDs由第三方提供或者由用戶自行編寫,它們用來支持特殊的硬件或軟件,完成特定的功能。VxDs中的程序運行在ring0層,可以執(zhí)行所有的指令,可以完成任何的軟硬件的操作。11.1.2虛擬設(shè)備虛擬設(shè)備(VxD)是一些程序,它們通過對計算機的各種硬件設(shè)備和支撐軟件進行虛擬化,實現(xiàn)對設(shè)備無關(guān)的虛擬機管理器(VMM)的支持。VxDs可以虛擬一臺計算機上的所有硬件設(shè)備,如時鐘、串行通信口、并行通信口等。VxDs也能對軟件提供支持,它們并不一定有相應(yīng)的硬設(shè)備。Windows9x中,用戶自己也可以安裝新的設(shè)備驅(qū)動程序來對新增硬件提供支持,或者在系統(tǒng)范圍內(nèi)提供某種軟件服務(wù)。VxDs通過VMM或其他虛擬設(shè)備向上層提供任何類型的服務(wù)。對Windows9x應(yīng)用程序來講,虛擬設(shè)備就是真實設(shè)備,換句話講,應(yīng)用程序是分不清哪個設(shè)備是由真實硬件支持的真實設(shè)備,哪個設(shè)備是由虛擬設(shè)備驅(qū)動程序模擬的虛擬設(shè)備。11.1.3設(shè)備驅(qū)動程序Windows設(shè)備驅(qū)動程序是Windows用來同各種硬件設(shè)備進行交互的一些程序。Windows并不直接對硬件設(shè)備進行訪問,而是通過加載該設(shè)備的驅(qū)動程序,調(diào)用其中的某些接口函數(shù)來完成對硬件設(shè)備的操作。每個設(shè)備驅(qū)動程序都有一組完成各種功能的函數(shù)輸出,Windows通過調(diào)用這些函數(shù)來對某一設(shè)備完成特定的操作。在Windows9x操作系統(tǒng)中,各種硬件設(shè)備,如通信端口、鼠標、鍵盤和顯示器等,都有相應(yīng)的設(shè)備驅(qū)動程序。用戶往系統(tǒng)中安裝其他可選設(shè)備時,需要提供和安裝其相應(yīng)的設(shè)備驅(qū)動程序。11.2設(shè)備驅(qū)動程序的編寫11.2.1VxD程序結(jié)構(gòu)

VToolsD提供了三個基本框架類:VDevice類提供了眾多的成員函數(shù)來處理從虛擬機(VMM)或其他VxDs發(fā)來的控制消息;VVirtualMachine類及其派生類用來處理一些針對虛擬機的特殊的控制消息;VThread類處理與線程有關(guān)的控制消息。若所建的VxD對特定的控制消息感興趣,則要重載其相應(yīng)的成員函數(shù)。1.VxD的控制消息VToolsD提供的三個基本框架類可以處理50多條控制消息,大多數(shù)的VxD則僅僅處理其中的一部分消息。動態(tài)安裝的VxD在安裝時會收到Sys_Dynamic_Device_Init消息,卸載時會收到Sys_Dynamic_Device_Exit消息。靜態(tài)安裝的VxD安裝時第一個消息是Windows初始化時發(fā)出Sys_Critical_Init消息,然后是Device_Init消息,最后是plete消息。Windows關(guān)閉時首先發(fā)出Sys_VM_Terminate消息,而后是System_Exit消息,最后為Sys_Critical_Exit消息。2.VDevice類用VtoolsD開發(fā)VxD首先要從派生VDevice類開始。加載VxD時系統(tǒng)會自動生成一個VDevice類的實例。在開發(fā)VxD時一般只用到VDevice類,只有處理VDevice類不能響應(yīng)的消息時才用到VVirtualMachine類和VThread類。派生VDevice類的方法:#defineDEVICE_CLASS MyDeviceclassMyDevice:publicVDevice{virtualBOOLOnDeviceInit(VMHANDLEhSysVM,PCHARpszCmdTail); //其他感興趣的成員函數(shù)。};BOOLOnDeviceInit(VMHANDLEhSysVM,PCHARpszCmdTail){ //具體初始化程序。

if初始化成功return(TRUE)elsereturn(FALSE);}11.2.2開發(fā)工具的使用

安裝VtoolsD之前,首先必須安裝VC++6.0。1.VxD設(shè)備參數(shù)(DeviceParameters)

圖11-1為QuickVxD設(shè)備參數(shù)定義欄,主要設(shè)備參數(shù)有:DeviceName:所建VxD的設(shè)備名。每一個VxD都應(yīng)有它的設(shè)備名字,設(shè)備名不多于8個字符。DeviceID:所建VxD的設(shè)備標識。如果將要建立的VxD提供了對其他VxD的調(diào)用入口,或提供了對其他虛擬8086模式程序的API調(diào)用入口,或保護模式程序API調(diào)用入口,則DeviceID是必須要具備的。DeviceID是一個16位的無符號整型數(shù),不能任意取值,以免與其他VxD相沖突。圖11-1DeviceInitializationOrder:確定Windows系統(tǒng)啟動時對該VxD的裝載順序。如果將要建立的VxD不依賴于其他VxD是否裝載,則此項可以使用VtoolsD提供的缺省值:UNDEFINED_INIT_ORDER。否則該參數(shù)必須設(shè)置為在某個已知VxD之前裝載。DeviceInitializationOrder常數(shù)的形式為:xxxx_INIT_ORDER,其中xxxx表示某個已知VxD的設(shè)備名。C/C++Framework:決定生成的VxD源程序的代碼類別是基于C語言的還是C++語言的。DynamicallyLoadable:決定將建立的VxD是否可以被操作系統(tǒng)動態(tài)加載。Version:建立的VxD的版本號,包括MajorVersion和MinorVersion兩項。2.應(yīng)用程序調(diào)用入口(ApplicationInterfaces)

QuickVxD采用下面幾種方式為應(yīng)用程序提供調(diào)用接口:V86EntryPoint為虛擬8086模式程序調(diào)用VxD服務(wù)提供了調(diào)用入口點。PMEntryPoint為保護模式程序調(diào)用VxD服務(wù)提供調(diào)用入口點。DOS保護模式程序調(diào)用入口(Vendorv86API)3.VxD服務(wù)(VxDServices)

VxDServices是提供給其他VxD的服務(wù)函數(shù)。4.VxD的控制消息(ControlMessages)

QuickVxD提供兩類控制消息:ControlMessage:支持Win3.1和Windows9xWindows95ControlMessage:只支持Windows9x5.產(chǎn)生C/C++源文件,工程文件按下GenerateNow按鈕,QuickVxD將在校驗所有選擇項和填寫項無誤的情況下自動生成輸出文件若檢驗有誤,QuickVxD會提供出錯信息圖11-2圖11-36.編譯生成VxD文件 有兩種方式編譯生成VxD文件采用命令行的方式編譯: MICROSOFTC++: nmake/fVXDNAME.MAK BORLANDC++: make/fVXDNAME.MAK采用MSVC++6.0的集成環(huán)境生成VxD:(1)啟動MSVC++6.0。(2)從File菜單選擇OpenWorkspace,打開相應(yīng)的

.mak文件。(3)在接下的兩個對話框中按“是(Y)”或“OK"按鈕。(4)保存相應(yīng)的.dsp文件。(5)在當前工程中添加所有的.cpp和.h文件。11.3Win32應(yīng)用程序和VxD之間的通信11.3.1Win32應(yīng)用程序?qū)xD的通信1.Win32應(yīng)用程序的編程 Win32應(yīng)用程序調(diào)用VxD,首先必須獲取VxD的設(shè)備句柄,可以用CreateFile來獲取VxD的設(shè)備句柄:HANDLEhDevice=CreateFile("\\\\.\\VxDName.vxd",0,0,0,CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0);假設(shè)VxD的文件名為VxDName.vxd\\\\.\\VxDName.vxd為VxD的路徑和文件名格式加載VxD時先搜索當前目錄,然后搜索C:\Windows\System目錄。CreateFile函數(shù)實際是動態(tài)加載了VxD。 成功獲取VxD的設(shè)備句柄后,可以在Win32應(yīng)用程序中調(diào)用DeviceIoControl來傳遞參數(shù)或使用VxD:DeviceIoControl( HANDLE hDevice, //VxD句柄 DWORD dwIoControlCode, //VxD控制代碼 LPVOID lpInBuf, //輸入數(shù)據(jù)塊指針 DWORD cbInBuf, //輸入數(shù)據(jù)塊大小 LPVOID lpOutBuf, //輸出的數(shù)據(jù)塊指針 DWORD cbOutBuf, //輸出數(shù)據(jù)塊大小 LPDWORDlpBytesReturned,//返回的字節(jié)數(shù)長度指針 NULL )hDevice是CreateFile獲取的VxD設(shè)備句柄dwIoControlCode是應(yīng)用程序向VxD發(fā)出的命令碼lpInBuf和cbInBuf是Win32應(yīng)用程序向VxD傳送的數(shù)據(jù)塊的地址及大小LpOutBuf、cbOutBuf和lpBytesReturned是VxD返回給Win32應(yīng)用程序的數(shù)據(jù)塊的地址、大小以及實際返回的字節(jié)數(shù)完成通信后,Win32應(yīng)用程序應(yīng)調(diào)用CloseHandle(hDevice)關(guān)閉VxD,即動態(tài)卸載VxD。2.VxD的編程Win32應(yīng)用程序調(diào)用DeviceIoControl函數(shù)向VxD發(fā)出命令后,系統(tǒng)即向VxD發(fā)出W32_DEVICEIoCONTROL控制消息。VxD的VDevice類的成員函數(shù)OnW32DeviceIoControl函數(shù)被觸發(fā)來響應(yīng)此控制消息OnW32DeviceIoControl函數(shù)定義為: VDevice::OnW32DeviceIoControl(PIOCTLPARAMSpParams)參數(shù)pParams為指向PIOCTLPARAMS結(jié)構(gòu)的指針。PIOCTLPARAMS結(jié)構(gòu)定義如下(部分):typedefstructtagIOCTLParams( ...DWORD dioc_IOCtlCode; //應(yīng)用程序發(fā)出的VxD控制代碼PVOID dioc_InBuf, //輸入數(shù)據(jù)塊指針DWORD dioc_cbInBuf, //輸入數(shù)據(jù)塊大小PVOID dioc_OutBuf, //輸出的數(shù)據(jù)塊指針DWORD dioc_cbOutBuf, //輸出數(shù)據(jù)塊大小PDWORD dioc_bytesret, //返回的字節(jié)數(shù)長度指針...)IOCTLPARAMS,*PIOCTLPARAMS;這些參數(shù)分別與DeviceIOControl函數(shù)的參數(shù)相對應(yīng)。OnW32DeviceIoControl函數(shù)定義如下:DWORDXYZDevice::OnW32DeviceIoControl(PIOCTLPARAMSp){switch(p->dioc_IOCtlCode){ caseDIOC_OPEN://Win32應(yīng)用程序調(diào)用CreateFile時產(chǎn)生。

return(0); caseDIOC_CLOSEHANDLE://Win32應(yīng)用程序調(diào)用CloseHandle時或退出時產(chǎn)生。 return(0); caseCMD1://CMD1命令對應(yīng)的處理程序,由DeviceIOControl發(fā)出。

return(0); //其他命令的相應(yīng)程序。

default://非法命令。

returnERROR_INVALID_PARAMETER; } }11.3.2VxD對Win32應(yīng)用程序的通信一般情況下都是Win32應(yīng)用程序調(diào)用VxD提供的服務(wù)。發(fā)生中斷時,有一些特定的事件發(fā)生時,需要由VxD通知Win32應(yīng)用程序,也就是VxD要首先發(fā)起對Win32應(yīng)用程序的通信。VxD對Win32應(yīng)用程序的通信有如下三種方法:(1)異步過程調(diào)用(APC,asynchronousprocedurecall)(2)Win32事件(3)向Win32應(yīng)用程序發(fā)送消息異步過程調(diào)用要用到的函數(shù):1.Win32應(yīng)用程序回調(diào)函數(shù)DWORDWINAPICallBackAPC(PVOIDparam) { //具體處理程序

return(0); }參數(shù)param為VxD傳遞給應(yīng)用程序的參數(shù)指針,函數(shù)名可任取。2.向處于警覺等待狀態(tài)的Win32線程發(fā)送消息的函數(shù)VWIN32_QueueUserApc(PVOIDpR3Proc,DWORDParam,THREADHANDLEhThread)pR3Proc為Win32應(yīng)用程序回調(diào)函數(shù)的入口地址Param為VxD傳遞給Win32應(yīng)用程序回調(diào)函數(shù)的參數(shù)指針hThread為當前線程的句柄3.使線程處于警覺等待狀態(tài)的函數(shù)SleepEx(DWORDdwMilliseconds,BOOLbAlertable)

dwMilliseconds為等待時間(毫秒),使用INFINITE則為無限等待。Balertable在此可設(shè)為TRUE。//以下是VxD中的程序片斷PVOIDCallBackApc=0;THREADHANDLETheThread=0;intparams=0; //某一消息處理函數(shù)BOOLXYZDevice::XXX(VMHANDLEhVM){ //具體處理程序//下面的函數(shù)調(diào)用向處于警覺等待狀態(tài)的Win32線程發(fā)送消息,//即異步過程調(diào)用Win32應(yīng)用程序回調(diào)函數(shù)CallBAckApc。 VWIN32_QueueUserApc(CallBAckApc,(DWORD)¶m,TheThread) }DWORDXYZDevice::OnW32DeviceIoControl(PIOCTLPARAMSp){switch(p->dioc_IOCtlCode){ //其他命令的相應(yīng)程序。

caseCMD1: //CMD1命令是向VxD傳送Win32回調(diào)函數(shù)入口地址。

CallBackApc=p->dioc_InBuf;TheThread=Get_Cur_Thread_Handle(); return(0); //其他命令的相應(yīng)程序。

}}//以下是Win32應(yīng)用程序的片斷DWORDWINAPICallBackAPC(PVOIDparam){//具體處理程序

return(0);}voidmain(){HANDLEhDevice;hDevice=CreateFile("\\\\.\\XYZDevice.VxD",0,0,0,CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0); if(hDevice==INVALID_HANDLE_VALUE) {printf("無法打開XYZDevice.VxD!"); exit(1); } printf("按Ctrl-C鍵退出程序\n"); while(TRUE)SleepEx(INFINITE,TRUE); CloseHandle(hDevice);}11.4Windows9x的輸入/輸出11.4.1訪問I/O端口硬件設(shè)備對I/O地址空間的訪問采用inp和outp命令:int_inp(unsignedshortport);unsignedshort_inpw(unsignedshortport);unsignedlong_inpd(unsignedshortport);int_outp(unsignedshortport,intdatabyte);unsignedshort_outpw(unsignedshortport,unsignedshortdataword);unsignedlong_outpd(unsignedshortport,unsignedlongdataword);11.4.2訪問內(nèi)存映射硬件設(shè)備Windows9x采用虛擬內(nèi)存的工作方式,內(nèi)存中的某些頁完全有可能被交換到磁盤上,因此程序在訪問硬件端口映射的線性內(nèi)存時,要采取相應(yīng)的措施來阻止這種交換的發(fā)生。有3個函數(shù)來完成內(nèi)存映射過程:1.PvoidPageResever(DWORDipage,DWORDnpages,DWORDflags)

功能:分配指定頁數(shù)的線性空間。 參數(shù):ipage:線性頁開始的范圍??梢匀∠铝兄担? PR_PRIVATE在ring3層私有區(qū)域的任意位置。 PR_SHARED在ring3層共享區(qū)域的任意位置。 PR_SYSTEM在系統(tǒng)的任意位置。 npages:保留的線性頁數(shù)(一頁為4K) flags:0或下列值: PR_FIXED:固定的 PR_STATIC:拒絕委托,直到靜態(tài)標志被指定

才釋放操作。 PR_4MEG:強迫地址在4M邊界。返回值:如果成功返回線性地址,返回0,否則返回-1。2.BOOLmitPhys(DWORDipage,Dwordnpages,DWORDphyspage,DWORDflags); 功能:將指定的物理空間聯(lián)系到線性空間。 參數(shù):ipage:被聯(lián)系的第一個物理頁的線性頁號 npage:被聯(lián)系的頁數(shù)。 physpage:第一個物理頁的物理頁號。 flags:取下列值: PC_INCR:線性頁被映射到物理上鄰接的

物理頁上。 PC_USER:這些頁可在ring3層被訪問。 PC_0USER:此些頁可被讀寫。 返回值:如果成功返回TRUE,否則返回FALSE。3.DWORDLinPageLock(DWORDHlinPgNum,DWORDnPages,DWORDflags); 功能:線性頁面鎖定。 參數(shù):HlinPgNum:要鎖定的線性頁面的第一頁。 npages:被鎖定的頁數(shù)。 flags:可以是0或取下列值之一: PAGELOCKEDIFDP:僅當該虛擬頁交換設(shè)備使用

MS-DOS或BIOS函數(shù)去寫硬件頁時被鎖定。 PAGEMAPGLOBAL:映射的一個全局線性地址被

鎖定。 PAGEMARKDIRTY:如果此些頁被寫,標上標志。返回值:當PAGEMAPGLOBAL被指定時,如果成功,返回

的是線性基地址,否為返回0。 PAGEMAPGLOBAL未指定時,成功則返回TRUE,

否則返回FALSE。映射處理的最后還需進行線性地址+物理地址偏移的處理。這是因為要處理的物理空間首地址不一定正好是物理頁(一頁是4KB)的首地址。釋放映射空間只要調(diào)用LinPageUnLock、mit和PageFree即可。11.5Windows9x的中斷處理11.5.1VPICD(虛擬可編程中斷控制器)在多任務(wù)環(huán)境里,硬件中斷管理程序是重要的系統(tǒng)級功能。它不僅要把硬件發(fā)生的中斷事件傳遞給相應(yīng)的驅(qū)動程序和應(yīng)用程序,還要允許某些設(shè)備驅(qū)動程序提供它們特殊的中斷服務(wù)處理。在Windows9X平臺下,VPICD就是這樣的硬件設(shè)備管理程序,它負責(zé)管理所有的硬件中斷事件VPICD通過一個缺省機制觸發(fā)駐留在虛擬機內(nèi)的中斷處理函數(shù)。并且它可以允許其他VxD重載中斷處理函數(shù)。11.5.2VHardwareInt類

VHardwareInt類可以實現(xiàn)對某個中斷請求(IRQ)號的虛擬化,重載其成員函數(shù)OnHardwareInt便可響應(yīng)該中斷的請求。VHardwareInt類的主要成員函數(shù)有:(1)VHardwareInt::VHardwareInt(intirq,DWORD

flags,DWORDtimeout,PVOIDrefdata) 構(gòu)造函數(shù),irq是要虛擬化的中斷號,其值為0到15,其余參數(shù)一般設(shè)為0。(2)VOIDVHardwareInt::OnHardwareInt(VMHANDLE

hVM) 中斷發(fā)生時,本成員函數(shù)被調(diào)用。一定要重載此函數(shù)才能響應(yīng)中斷。(3)BOOLVHardwareInt::hook()此成員函數(shù)將虛擬irq和VHardwareInt類中的五個成員函數(shù)相連,它們是OnHardwareInt,OnVirtualInt,OnVirtualRET,OnVirtualEOI和OnVirtualMask。只有調(diào)用hook后,這五個成員函數(shù)才會在中斷響應(yīng)時被調(diào)用。hook返回TRUE表示成功,返回FALSE表示失敗。(4)BOOLVHardwareInt::unhook() 此成員函數(shù)將取消本irq的虛擬化。11.5.3VSharedHardwareInt類VSharedHardwareInt是VHardwareInt的派生類。與VHardwareInt類的不同之處是,VSharedHardwareInt類允許一個IRQ被多個VxD虛擬化。如果需要響應(yīng)PCI卡的中斷時,一般使用VSharedHardwareInt類。VSharedHardwareInt類的成員函數(shù)有:(1)VHardwareInt::VhardwareInt (intirq,DWORDflags,DWORDtimeout,PVOIDrefdata) 構(gòu)造函數(shù),irq是要虛擬化的中斷號,其值為0到15,其余參數(shù)一般設(shè)為0。(2)BOOLVSharedHardwareInt::

OnSharedHardwareInt(VMHANDLEhVM)中斷發(fā)生時,本成員函數(shù)被調(diào)用。返回值通知VPICD是否處理了本次中斷。VSharedHardwareInt類允許一個IRQ被多個VxD虛擬化。因此,當中斷發(fā)生時,VPICD將依次調(diào)用虛擬化了這個中斷的VxD的OnSharedHardwareInt函數(shù)。如果某個OnSharedHardwareInt函數(shù)處理了這次中斷,則返回TRUE告知VPICD中斷已被處理,VPICD不再調(diào)用余下的VxD的OnSharedHardwareInt函數(shù)。函數(shù)認為不應(yīng)該處理該次中斷,它就要返回FALSE,VPICD將調(diào)用下一個VxD的OnSharedHardwareInt函數(shù)。一直到中斷被處理或所有VxD的OnSharedHardwareInt函數(shù)被調(diào)用為止。下面是VxD中虛擬化IRQ的一個例子:classXMyIRQ:publicVSharedHardwareInt{public: XMyIRQ(intnIRQ); //構(gòu)造函數(shù)。 virtualBOOLOnSharedHardwareInt(VMHANDLE); //必須有的函數(shù) virtualVOIDOnVirtualInt(VMHANDLE); virtualVOIDOnVirtualEOI(VMHANDLE); virtualVOIDOnVirtualIRET(VMHANDLE);}; //在構(gòu)造函數(shù)中調(diào)用類VSharedHardwareInt的構(gòu)造函數(shù),//nIRQ指定要虛擬(處理)的中斷號XMyIRQ::XMyIRQ(intnIRQ):VSharedHardwareInt(nIRQ,0,0,0) {}//OnSharedHardwareInt成員函數(shù)就是中斷處理程序,當相應(yīng)中斷發(fā)生時,該函數(shù)被調(diào)用BOOLXMyIRQ::OnSharedHardwareInt(VMHANDLEhVM) {assert(hVM);//向hVM標識的VM申請?zhí)摂M中斷。 //下面是處理中斷的具體代碼 ... }VOIDXMyIRQ::OnVirtualEOI(VMHANDLEhVM) {deassert(hVM);//VM中斷返回,撤消虛擬中斷申請。 SendPhysicalEOI();//請求VPICD向PPIC發(fā)送中斷結(jié)束指令 } //以下代碼放在VxD初始化代碼區(qū)內(nèi)。 //生成XMyIRQ類實例對象,該對象虛擬(處理)硬件中斷05HXMyIRQmIRQ(5); //調(diào)用成員函數(shù)hook,完成虛擬化(中斷處理程序的掛接)if(mIR.hook()){ //IRQ虛擬化成功。 }

else{ //IRQ虛擬化失敗。 }11.5.4VGlobalEvent類硬件中斷處理通常要利用異步事件類。VMM被中斷轉(zhuǎn)而執(zhí)行中斷處理,在中斷處理中不能調(diào)用同步VMM服務(wù),否則VMM會因重入而崩潰。所以,在中斷處理中只能安排一個異步事件函數(shù),以允許系統(tǒng)在中斷處理結(jié)束后返回到正常狀態(tài)時調(diào)用這個異步事件函數(shù)。異步事件類的類別較多,它們都是從類VEvent派生而來,共有五個:VEvent,VGlobalEvent,VThreadEvent,VPriorityVMEvent,VVMEvent。其中,VEvent是其他異步事件類的基類。除了VGlobalEvent類外,其他類與中斷無關(guān)。全局異步事件類VGlobalEvent是受限制最少的異步事件類。一旦所有的中斷處理執(zhí)行完畢,VMM就將回調(diào)全局異步事件類的handler成員函數(shù)。VGlobalEvent類的主要成員函數(shù)(1)VGlobalEvent::VglobalEvent(PVOIDrefData)refData:傳遞給handler成員函數(shù)的參考數(shù)據(jù)。VGlobalEvent函數(shù)創(chuàng)建一個VGlobalEvent類實例。在該函數(shù)之后應(yīng)該調(diào)用call或者schedule成員函數(shù)以安排異步函數(shù)的回調(diào)。當VMM調(diào)用handler函數(shù)時,refData也傳遞給handler函數(shù).(2)BOOLVGlobalEvent::call()call函數(shù)視具體情況或者立即調(diào)用handler函數(shù)或者只是調(diào)度(schedule)一個全局事件。當VMM處在非中斷狀態(tài)時,call函數(shù)立即調(diào)用handler函數(shù);否則call函數(shù)將調(diào)度一個異步事件,即當中斷結(jié)束返回時再調(diào)用handler函數(shù)。call函數(shù)返回TRUE表示調(diào)度異步事件,返回FALSE表示handler函數(shù)立即被調(diào)用。(3)VOIDVGlobaleEvent::schedule()schedule函數(shù)調(diào)度一個異步事件。一旦中斷處理完畢,系統(tǒng)就調(diào)用handler成員函數(shù)。(4)VOIDVGlobalEvent::cancel()cancel成員函數(shù)取消對一個異步事件的調(diào)度,該函數(shù)與schedule函數(shù)相對。handler函數(shù)被調(diào)用時,不能使用cancel函數(shù)。(5)VOIDVGlobalEvent::handler(VMHANDLEhVM,

CLIENT_STRUCT*pRegs,PVOIDrefData)hVM當前活動VM的句柄;pRegs指向VM寄存器組的指針;refData由構(gòu)造函數(shù)傳來的參數(shù)。Handler成員函數(shù)在中斷處理完畢后被系統(tǒng)觸發(fā)。在該函數(shù)里可安全的調(diào)用同步VMM服務(wù)。在中斷中使用VGlobalEvent類的例子://中斷處理類classMyINT:publicVSharedHardwareInt {public: MyINT(); virtualBOOLOnSharedHardwareInt(VMHANDLEhVM); };//全局異步事件類classGEvent:publicVGlobalEvent {public: GEvent(); virtualVOIDhandler(VMHANDLEhVM,

CLIENT_STRUCT*pRegs,PVOIDrefData); };//中斷處理程序,其中安排了一全局異步事件BOOLMyINT::OnSharedHardwareInt(VMHANDLEhVM) {pEvent=newGEvent(); if(pEvent){ //具體中斷處理,但不能調(diào)用同步VMM服務(wù) //在中斷處理完成后調(diào)用GEvent::handler. pEvent->schedule(); p_Int->sendPhysicalEOI(); returnTRUE; }//發(fā)中斷結(jié)束消息 p_Int->sendPhysicalEOI(); returnFALSE; }//能調(diào)用同步VMM服務(wù)的中斷處理VOIDGEvent::handler(VMHANDLEhVM,

CLIENT_STRUCT*pRegs,PVOIDrefData) { //中斷處理,能調(diào)用同步VMM服務(wù) }11.6VxD實例11.6.1PCI設(shè)備配置的獲取獲取配置資源用到的兩個函數(shù)。(1)CONFIGRETCONFIGMG_Register_Device_Driver(DEVNODEnode,CMCONFIGHANDLERhandler,DWORDrefData,DWORDflags)功能:注冊一個設(shè)備節(jié)點配置處理程序。參數(shù):node:設(shè)備節(jié)點句柄

handler:設(shè)備配置處理程序入口 refData:發(fā)送給配置處理程序的數(shù)據(jù)(handler)flags:必須是CM_REGISTER_DEVICE_DRIVER_STATIC、CM_REGISTER_DEVICE_DRIVER_DISABLABLE、CM_REGISTER_DEVICE_DRIVER_REMOVABLE之一或組合。注意:該函數(shù)僅能在PnP的設(shè)備驅(qū)動程序的初始化期間被調(diào)用(2)CONFIGMG_Get_Alloc_Log_Conf(PCMCONFIG

pccBuffer,DEVNODEnode,DWORDflags);功能:從-個nice表格中取得硬件資源數(shù)據(jù)參數(shù):pccBuffer:一個CMCONFIG結(jié)構(gòu)指針

node:設(shè)備節(jié)點

flags:必須是 CM_GET_ALLOC_LOG_CONF_ALLOC或 CM_GET_ALLOC_CONF_BOOT_ALLOC。返回:如果成功,返回CR_SUCCESS;否則返回值可能是

CR_INVALID_POINTER,CR_INVALID_DEVNODE

或CR_INVALID_FLAG。以上兩個函數(shù)調(diào)用方式是:CONFIGRETCONFIGMG_Register_Device_Driver函數(shù)在消息PnP_NEW_DEVNODE的處理函數(shù)中在響應(yīng)DLVXD_LOAD_DEVLOADER的裝載類型時被調(diào)用。這個函數(shù)在被調(diào)用時還要觸發(fā)一個設(shè)備配置處理程序,該程序是一個自定義函數(shù),其格式如下:CONFIGRETCM_HANDLEROnConfigure(CONFIGUNCcf,SUBCONFIGFUNCsef,DEVNODEdevnode,DWORDrefdata,ULONGflags)為了觸發(fā)該函數(shù),只要將其函數(shù)名作為CONFIGMG_Register_Device_Driver函數(shù)的第二個參數(shù)即可。CMCONFIG結(jié)構(gòu)定義如下:structCMCONFIG{WORDwNumMemWindows; //存儲器空間數(shù)量DWORDdMemBase[MAX_MEM_REGISTERS]; //存儲器基地址DWORDdMemLength[MAX_MEM_REGISTERS];//存儲空間長度WORDwMemAttrib[MAX_MEM_REGISTERS];//存儲空間屬性WORDwNumIoports; //I/O端口數(shù)量WORDwIoportBase[MAX_IO_PORTS]; //IO端口基地址WORDwIoportLength[MAX_IO_PORTS]; //IO端口長度WORDwNumIRQS; //IRQ數(shù)BYTEbIRQRegisters[MAX_IRQS]; //IRQ號BYTEbIRQAttrib[MAX_IRQS]; //IRQ屬性WORDwNumDMAS; //DMA通道數(shù)BYTEbDMALst[MAX_DMA_CHANNELS]; //DMA號BYTEwDMAAttrib[MAX_DMA_CHANNELS];//DMA屬性BYTEbReservedl[3]; //保留};

在函數(shù)OnConfigure中調(diào)用CONFIGMG_Get_Alloc_Log_Conf獲取PCI設(shè)備的配置。 下面的VxD程序在Windows9x發(fā)現(xiàn)相應(yīng)的PCI設(shè)備時被加載,VxD讀取PCI設(shè)備的配置并保存,供Ring3層應(yīng)用程序使用。假設(shè)該PCI設(shè)備所需的資源為:一個存儲器空間,兩個I/O空間,一個中斷號。 //PCI_CON.VXD的頭文件 //PCI_CON.h-includefileforVxDPCI_CON #include<vtoolscp.h> #defineDEVICE_CLASS Pci_conDevice #definePCI_CON_DeviceID UNDEFINED_DEVICE_ID #definePCI_CON_Init_Order UNDEFINED_INIT_ORDER #definePCI_CON_Major 1 #definePCI_CON_Minor 0 #defineDIOC_FAILURE 1//VxD'smessageIDinOnW32DeviceIoControlhandle#defineDIOC_PCICFGCTL_CODE(FILE_DEVICE_UNKNOWN,0x802,\

METHOD_IN_DIRECT,FILE_ANY_ACCESS)classPci_conDevice:publicVDevice{public:virtualBOOLOnDeviceInit(VMHANDLEhSysVM,PCHARpszCmdTail);virtualCONFIGRETOnPnpNewDevnode(DEVNODEdevNode,DWORDloadType);virtualDWORDOnW32DeviceIoControl(PIOCTLPARAMSpDIOCParams);};structpci_cfg{DWORDMemBase; //存儲空間基地址DWORDMemLength; //存儲空間長度WORDIOBase[2];

//IOBase[0]:S5933狀態(tài)寄存器專用的I/O空間 //IOBase[1]:映射的I/O空間WORDIOPortLength[2];

//IOPortlength[0]:S5933狀態(tài)寄存器空間長度 //IOPortlength[1]:映射的I/O空間長度BYTEIRQ; //中斷號}*pci;//PCI_CON.VXD的源代碼PCI_CON.CPP#defineDEVICE_MAIN#include"pci_con.h"Declare_Virtual_Device(PCI_CON)#undefDEVICE_MAIN BOOL card=FALSE; CMCONFIGconfig; CONFIGRETCM_HANDLEROnConfigure(CONFIGFUNC

cf,SUBCONFIGFUNCscf,DEVNODEdevnode,

DWORDrefdata,ULONGflags); BOOLPci_conDevice::OnDeviceInit(VMHANDLE

hSysVM,PCHARpszCmdTail) {returnOnSysDynamicDeviceInit(); }//響應(yīng)新結(jié)點消息函數(shù)CONFIGRETPci_conDevice::OnPnpNewDevnode(DEVNODEdevNode,DWORDloadType){dprintf("DATAACQ:PnP-newdevnode:");switch(loadType){ caseDLVXD_LOAD_ENUMERATOR: //加載枚舉設(shè)備 returnCR_DEFAULT; caseDLVXD_LOAD_DEVLOADER: //加載設(shè)備加載器 card=TRUE; //表示PCI卡存在//注冊一個設(shè)備節(jié)點 returnCONFIGMG_Register_Device_Driver(devNode, OnConfigure,0, CM_REGISTER_DEVICE_DRIVER_REMOVABLE| CM_REGISTER_DEVICE_DRIVER_DISABLEABLE); caseDLVXD_LOAD_DRIVER: //加載設(shè)備驅(qū)動程序 returnCR_DEFAULT; default: returnCR_DLVXD_NOT_FOUND;}}//設(shè)備配置處理程序CONFIGRETCM_HANDLEROnConfigure(CONFIGFUNCcf, SUBCONFIGFUNCscf,DEVNODEdevnode,

DWORDrefdata,ULONGflags){DWORDtemp; CONFIGRETcr; dprintf("DATAACQ:configuration-handler:");switch(cf){ caseCONFIG_START: //取得配置信息 cr=CONFIGMG_Get_Alloc_Log_Conf(&config, devnode,CM_GET_ALLOC_LOG_CONF_ALLOC); returncr; caseCONFIG_STOP: caseCONFIG_REMOVE: returnCR_SUCCESS; default: returnCR_DEFAULT;}}//VXD響應(yīng)Ring3層應(yīng)用程序調(diào)用消息處理函數(shù)DWORDPci_conDevice::OnW32DeviceIoControl(PIOCTLPARAMSp){switch(p->dioc_IOCtlCode){ caseDIOC_OPEN://應(yīng)用程序調(diào)用CreateFile時產(chǎn)生。

if(!card) returnDIOC_FAILURE;//表示PCI卡不存在。

returnDEVIOCTL_NOERROR; caseDIOC_CLOSEHANDLE:

//應(yīng)用程序調(diào)用CloseHandle時或退出時產(chǎn)生。

returnDEVIOCTL_NOERROR; caseDIOC_PCICFG;

//填具體配置參數(shù)到Ring3層使用的配置結(jié)構(gòu)中

pci=(pci_cfg*)p->dioc_InBuf pci->IRQ=config.bIRQRegisters[0]; pci->IOBase[0]=config.wIOPortBase[0]; pci->IOBase[1]=config.wIOPortBase[1]; pci->IOPortLength[0]=config.wIOPortLength[0]; pci->IOPortLength[0]=config.dMemLength[0]; pci->MemBase=config.dMemBase[0]; pci->MemLength=config.dMemLength[0]; return DEVIOCTL_NOERROR; default: returnERROR_INVALID_PARAMETER; }}下面是應(yīng)用程序,程序在屏幕上顯示PCI設(shè)備的配置信息。#include<stdio.h>#include<conio.h>#include<windows.h>#include<winioctl.h>#defineDIOC_PCICFGCTL_CODE(FILE_DEVICE_UNKNOWN,\

0x802,METHOD_IN_DIRECT,FILE_ANY_ACCESS)//PCI配置信息structPCI_CONFIG{DWORD MemBase; //內(nèi)存范圍起始地址

DWORD MemLength; //內(nèi)存范圍長度

WORD IOBase[2]; //輸入輸出范圍起始地址

WORD IOPortLength[2]; //輸入輸出范圍長度

BYTE IRQ; //中斷向量}; HANDLEhDevice=NULL;//設(shè)備(文件)句柄voidmain(){BOOLstatus; PCI_CONFIGpci; //從PCI_CON.VxD獲取PCI設(shè)備的配置。 hDevice=CreateFile("\\\\.\\PCI_CON.VxD",0,0,0,CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0); if(hDevice==INVALID_HANDLE_VALUE) {printf("無法打開PCI_CON.VxD!"); exit(1); } status=DeviceIoControl(hDevice,DIOC_PCICFG,&pci,

0,NULL,0,&nRet,NULL); if(!status){ printf("無法獲取PCI配置信息!"); exit(1); } CloseHandle(hDevice);printf(“PCI設(shè)備內(nèi)存基地址:%X長度:%X\n",pci.MemBase,

pci.MemLength);printf(“PCI設(shè)備I/O基地址1:%X長度:%X\n",pci.IOBase[0],

pci.IOPortLength[0]); printf(“PCI設(shè)備I/O基地址2:%X長度:%X\n",pci.IOBase[1],

pci.IOPortLength[1]); printf("PCIS設(shè)備中斷號:%d\n",pci.IRQ);}11.6.2輸入輸出 假設(shè)相對于PCI設(shè)備I/O空間基地址偏移為1的端口是輸入端口,偏移量為2的端口是輸出端口。 本例先從輸入端口輸入數(shù)據(jù),然后寫入輸出端口。 對I/O設(shè)備的實際訪問,如使用_outp寫端口和使用_inp讀端口,是在虛擬驅(qū)動程序IOPORT.VxD中進行的。本例中,盡管讀寫I/O端口端口的操作也可在ring3層應(yīng)用程序中進行,但在其他設(shè)備中相應(yīng)的I/O操作不一定能在ring3層應(yīng)用程序中進行,而必須放在VxD中進行。

Ring3層的應(yīng)用程序先打開PCI_CON.VXD取得PCI的配置,然后打開IOPORT.VXD進行相應(yīng)的輸入輸出。//C++頭文件IOPORT.h#include<vtoolscp.h>#defineDEVICE_CLASS IODevice#defineIOPORT_DeviceID UNDEFINED_DEVICE_ID#defineIOPORT_Init_Order UNDEFINED_INIT_ORDER#defineIOPORT_Major 1#defineIOPORT_Minor 0//自定義控制代碼#defineDIOC_FAILURE 1#defineDIOC_INPUTCTL_CODE(FILE_DEVICE_UNKNOWN,0x813,\

METHOD_IN_DIRECT,FILE_ANY_ACCESS)#defineDIOC_OUTPUTCTL_CODE(FILE_DEVICE_UNKNOWN,\

0x814,METHOD_IN_DIRECT,FILE_ANY_ACCESS)//I/O數(shù)據(jù)結(jié)構(gòu),用于ring3層應(yīng)用程序和IOPORT.VxD交換數(shù)據(jù)structIOData{WORDwPort;//I/O端口

BYTEbData; //輸入/輸出數(shù)據(jù) };classIODevice:publicVDevice{public: virtualDWORDOnW32DeviceIoControl(PIOCTLPARAMSpDIOCParams);};//C++源文件IOPORT.CPP#defineDEVICE_MAIN#include"ioport.h"Declare_Virtual_Device(IOPORT)#undefDEVICE_MAINDWORDIODevice::OnW32DeviceIoControl(PIOCTLPARAMSpDIOCParams){IOData*pd;switch(pDIOCParams->dioc_IOCtlCode){ caseDIOC_OPEN: returnDEVIOCTL_NOERROR; caseDIOC_CLOSEHANDLE: returnDEVIOCTL_NOERROR;caseDIOC_INPUT; //Ring3層應(yīng)用程序使用控制代碼DIOC_INPUT執(zhí)行DeviceIoControl函數(shù) pd=(IOData*)pDIOCParams->dioc_InBuf;

//使用庫函數(shù)_inp從端口pd->wPort輸入數(shù)據(jù)到d->bData中 pd->bData=_inp(pd->wPort); returnDEVIOCTL_NOERROR;caseDIOC_OUTPUT://Ring3層應(yīng)用程序使用控制代碼DIOC_OUTPUT執(zhí)行DeviceIoControl函數(shù)

pd=(IOData*)pDIOCParams->dioc_InBuf;

//使用庫函數(shù)_outp向端口pd->wPort輸出數(shù)據(jù)pd->bData _outp(pd->wPort,pd->bData); returnDEVIOCTL_NOERROR;default: returnERROR_INVALID_PARAMETER; } return0;}下面是應(yīng)用程序。#include<stdio.h>#include<conio.h>#include<windows.h>#include<winioctl.h>#define DIOC_FAILURE1#define DIOC_PCICFGCTL_CODE(FILE_DEVICE_UNKNOWN,0x802,\

METHOD_IN_DIRECT,FILE_ANY_ACCESS)#define DIOC_INPUTCTL_CODE(FILE_DEVICE_UNKNOWN,0x813,\

METHOD_IN_DIRECT,FILE_ANY_ACCESS)#define DIOC_OUTPUTCTL_CODE(FILE_DEVICE_UNKNOWN,0x814,\

METHOD_IN_DIRECT,FILE_ANY_ACCESS)//PCI設(shè)備配置信息structPCI_CONFIG{DWORD MemBase; DWORD MemLength; WORD IOBase[2]; WORD IOPortLength[2]; BYTE IRQ;}; //I/O數(shù)據(jù)結(jié)構(gòu),用于ring3層應(yīng)用程序和IOPORT.VxD交換數(shù)據(jù)structIOData{WORDwPort; BYTEbData;}HANDLEhDevice=NULL;voidmain(){BOOLstatus; PCI_CONFIGpci; //從PCI_CON.VxD獲取PCI設(shè)備的配置。 hDevice=CreateFile("\\\\.\\PCI_CON.VxD",0,0,0,

CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0); if(hDevice==INVALID_HANDLE_VALUE) { printf("無法打開PCI_CON.VxD!"); exit(1);} status=DeviceIoControl(hDevice,DIOC_PCICFG,&pci,

0,NULL,0,&nRet,NULL); if(!status){printf("無法獲取PCI配置信息!"); exit(1);}

CloseHandle(hDevice); //打開IOPORT.VxD,準備進行輸入/輸出hDevice=CreateFile("\\\\.\\IOPORT.VxD",0,0,0, CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0);if(hDevice==INVALID_HANDLE_VALUE) {printf("無法打開IOPORT.VxD!"); exit(1);} //讀取I/O端口

id.wPort=pci.IOBase[1]+0x1; DeviceIoControl(hDevice,DIOC_INPUT,&id,0,NULL,0,

&nRet,NULL);//寫I/O端口

id.wPort=pci.IOBase[1]+0x2; DeviceIoControl(hDevice,DIOC_OUTPUT,&id,0,NULL,0,

&nRet,NULL); CloseHandle(hDevice);//關(guān)閉IOPORT.VxD}11.6.3中斷處理PCI卡采用共享中斷的方式,而且中斷號是由系統(tǒng)動態(tài)分配的,因此中斷處理類MyINT只能是VSharedHardwareInt的派生類。在VxD的初始化階段先要取得所分配的中斷號,然后初始化中斷處理類MyINT,隨后設(shè)置AMCC5933的INTCSRC中斷控制/狀態(tài)寄存器的中斷為輸入郵箱4,這里假設(shè)中斷請求是通過輸入郵箱4發(fā)出的。通過IOCTL命令DIOC_INTERR將Win32應(yīng)用程序回調(diào)函數(shù)的入口地址轉(zhuǎn)送給PCI_CON.VxD,并允許硬件中斷,等待中斷發(fā)生。由于采用共享中斷的方式,因此當中斷發(fā)生時,中斷服務(wù)程序首先要判斷是否是本PCI卡引起的,若是則進行處理,否則通知系統(tǒng)將控制權(quán)交給下一個設(shè)備。由于VWIN32_QueueUserApc()函數(shù)不能在中斷服務(wù)時調(diào)用,所以在中斷服務(wù)中安排了一個全局異步事件。這樣,當相應(yīng)中斷發(fā)生時,PCI_CON.VxD將先判斷是否是本PCI卡引起的,若是則引發(fā)一個全局異步事件。在全局異步事件處理時調(diào)用VWIN32_QueueUserApc()函數(shù)對Win32應(yīng)用程序回調(diào)函數(shù)進行異步過程調(diào)用。最后,應(yīng)用程序回調(diào)函數(shù)被調(diào)用時才對中斷進行相應(yīng)的處理。//PCI_CON.hforPCI_CON.CPP#include<vtoolscp.h>#defineDEVICE_CLASS Pci_conDevice#definePCI_CON_DeviceID UNDEFINED_DEVICE_ID#definePCI_CON_Init_Order UNDEFINED_INIT_ORDER#definePCI_CON_Major 1#definePCI_CON_Minor 0#defineDIOC_FAILURE 1//IOCTL控制碼定義#defineDIOC_PCICFGCTL_CODE(FILE_DEVICE_UNKNOWN,

0x802,METHOD_IN_DIRECT,FILE_ANY_ACCESS)#define DIOC_INTERRCTL_CODE(FILE_DEVICE_UNKNOWN,0x803,

METHOD_IN_DIRECT,FILE_ANY_ACCESS)classPci_conDevice:publicVDevice{public:virtualBOOLOnDeviceInit(VMHANDLEhSysVM,PCHARpszCmdTail); virtualCONFIGRETOnPnpNewDevnode(DEVNODEdevNode,DWORDloadType); virtualDWORDOnW32DeviceIoControl(PIOCTLPARAMSpDIOCParams);};//中斷處理類classMyINT:publicVSharedHardwareInt{ public: MyINT(); virtualBOOLOnSharedHardwareInt(VMHANDLEhVM); }//全局異步事件類classGEvent:publicVGlobalEvent{public: GEvent(); virtualVOIDhandler(VMHANDLEhVM,CLIENT_STRUCT*

pRegs,PVOIDrefData); };//PCI_CON.CPP#defineDEVICE_MAIN#include"pci_con.h"Declare_Virtual_Device(PCI_CON)#undefDEVICE_MAIN#defineIMB4 0x1c //AMCC5933's輸入郵箱地址#defineINTCSR0x38//AMCC5933's中斷控制/狀態(tài)寄存器地址#defineMBEF0x34 //AMCC5933's郵箱空/滿狀態(tài)寄存器地址HANDLE Ring3; //應(yīng)用程序的句柄,由應(yīng)用程序提供MyINT *p_Int=NULL;//中斷程序的實例指針GEvent *pEvent=NULL;//全局事件實例指針WORD MsgID; //Ring3層消息ID值DWORD address,IOBase0;BOOL card=FALSE;CMCONFIGconfig; //PCI配置結(jié)構(gòu)實例BYTE IRQ=255;PVOIDCallBackApc=0;THREADHANDLETheThread=0;CONFIGRETCM_HANDLEROnConfigure(CONFIGFUNCcf,

SUBCONFIGFUNCscf,DEVNODEdevnode,DWORD

refdata,ULONGflags);MyINT::MyINT():VSharedHardwareInt(IRQ,0,0,0){}BOOLPci_conDevice::OnDeviceInit(VMHANDLEhSysVM,

PCHARpszCmdTail) {returnOnSysDynamicDeviceInit(); }CONFIGRETPci_conDevice::OnPnpNewDevnode(DEVNODE

devNode,DWORDloadType){switch(loadType) { caseDLVXD_LOAD_ENUMERATOR: returnCR_DEFAULT; caseDLVXD_LOAD_DEVLOADER: card=TRUE; returnCONFIGMG_Register_Device_Driver (devNode,OnConfigure,0,

CM_REGISTER_DEVICE_DRIVER_REMOVABLE|

CM_REGISTER_DEVICE_DRIVER_DISABLEABLE); caseDLVXD_LOAD_DRIVER: returnCR_DEFAULT; default: returnCR_DLVXD_NOT_FOUND; }returnCR_DEFAULT;}CONFIGRETCM_HANDLEROnConfigure(CONFIGFUNCcf, SUBCONFIGFUNCscf,DEVNODEdevnode,

DWORDrefdata,ULONGflags){DWORDtemp;CONFIGRETcr; switch(cf){ caseCONFIG_START: cr=CONFIGMG_Get_Alloc_Log_Conf(&config,

devnode,CM_GET_ALLOC_LOG_CONF_ALLOC); switch(cr){ caseCR_SUCCESS: caseCR_DEFAULT: IRQ=config.bIRQRegisters[0]; p_Int=newMyINT(); //掛接中斷處理程序

if(!p_Int->hook()||(p_Int==NULL)) returnDIOC_FA

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論