亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

VxD的初始化和結(jié)束

 更新時(shí)間:2006年10月11日 00:00:00   作者:  

VxD程序分為兩種:靜態(tài)的和動(dòng)態(tài)的。每種的加載方法都不同,接受到的初始化和結(jié)束的控制消息也不同。 
靜態(tài)VxD: 
下列情況下,VMM加載一個(gè)靜態(tài)VxD: 
一個(gè)實(shí)模式常駐程序通過調(diào)用中斷2FH,1605H,來調(diào)用此VxD。 
此VxD在注冊(cè)表中的如下位置有定義: 
HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\VxD\\key\\StaticVxD=VxD帶路徑文件名 
此VxD在system.ini中的[386enh]行下有定義:[386enh] section: 

device=VxD帶路徑文件名 
在開發(fā)的時(shí)候,我建議你從system.ini載入VxD程序,因?yàn)檫@樣如果你的VxD程序有錯(cuò)而導(dǎo)致Windows不能啟動(dòng)的話,你可以在Dos下修改system.ini,而如果你使用的注冊(cè)表載入的辦法,就無法修改了。 
當(dāng)VMM加載你的靜態(tài)VxD程序時(shí),你的VxD程序會(huì)按以下順序接收到三個(gè)系統(tǒng)控制消息: 
Sys_Critical_Init VMM在轉(zhuǎn)入到保護(hù)模式后,開放中斷前發(fā)出這個(gè)控制消息。大多數(shù)VxD程序到不要用到這個(gè)消息,除非: 
你的VxD程序要接管一些其他VxD程序或者保護(hù)模式程序要用到的中斷。既然你處理這個(gè)消息的時(shí)候這個(gè)中斷還沒有打開,你就可以確定在你接管這個(gè)中斷的時(shí)候此中斷不會(huì)被調(diào)用。 
你的VxD程序?yàn)槠渌腣xD程序提供了一些VxD服務(wù)。例如,一些在你的VxD程序后加載的VxD程序在處理Device_Init控制消息時(shí)需要調(diào)用一些你的VxD服務(wù),既然Sys_Critical_Init 控制消息在Device_Init消息之前被發(fā)送,所以你應(yīng)該在Sys_Critical_Init 消息發(fā)送時(shí)初始化你的程序。 
如果你要對(duì)這消息進(jìn)行處理,你應(yīng)該盡可能快的做完初始化工作,以免太長的執(zhí)行時(shí)間導(dǎo)致的硬中斷丟失。(記?。褐袛噙€沒打開) 
Device_Init VMM在開放中斷后發(fā)送此信息。大多數(shù)VxD程序都在得到這個(gè)消息時(shí)初始化。因?yàn)橹袛喽奸_放了,所以耗時(shí)的操作也可以在這里執(zhí)行而不必怕會(huì)導(dǎo)致硬中斷的丟失。你可以在這時(shí)進(jìn)行初始化(如果你需要的話)。 
Init_Complete 在所有的VxD程序處理完Device_Init 消息之后,VMM釋放初始化段(ICODE和RCODE段類)之前,VMM發(fā)出這個(gè)控制消息。只有少數(shù)幾個(gè)VxD要處理這個(gè)消息。 
你的VxD程序在成功地初始化后,必須將返回標(biāo)志清零,反之,必須在返回之前把返回標(biāo)志設(shè)為出錯(cuò)信息。如果你的VxD不需要初始化,你就不必對(duì)這些消息進(jìn)行處理。 
當(dāng)要結(jié)束靜態(tài)VxD的時(shí)候,VMM發(fā)送如下的控制消息: 
System_Exit2 當(dāng)你的VxD程序收到這個(gè)消息,Windows95正在關(guān)閉系統(tǒng),除了系統(tǒng)虛擬機(jī)所有其他虛擬機(jī)都已經(jīng)退出了。盡管如此,CPU仍然處于保護(hù)模式下,在系統(tǒng)虛擬機(jī)上執(zhí)行實(shí)模式編碼也是安全的。在這時(shí)Kernel32.dll也已經(jīng)被卸載了。 
Sys_Critical_Exit2 當(dāng)所有的VxD完成對(duì)System_Exit2的響應(yīng)處理并且中斷都被關(guān)閉后,你的VxD收到到這個(gè)消息。 
許多VxD程序并不要響應(yīng)這兩個(gè)消息,除非你要為系統(tǒng)做轉(zhuǎn)換到實(shí)模式的準(zhǔn)備。要知道,當(dāng)Window95關(guān)閉時(shí),它進(jìn)入到實(shí)模式。所以如果你的VxD程序?qū)?shí)模式影像做了一些會(huì)導(dǎo)致它不穩(wěn)定的操作,它就需要在這時(shí)進(jìn)行恢復(fù)。 
你也許會(huì)感到奇怪:為什么這兩個(gè)消息后面都跟著個(gè)“2\" ”。這是因?yàn)椋涸赩MM加載VxD程序的時(shí)候,它是按照初始化順序值小的VxD先加載的順序加載的,這樣VxD程序就可以使用那些在它們之前加載的VxD程序提供的服務(wù)。例如,VxD2要用到VxD1中的服務(wù),它就必須把它的初始化順序值定義的比VxD小。加載的順序是: 
..... VxD1 ===> VxD2 ===> VxD3 ..... 
那么卸載的時(shí)候,理所當(dāng)然的是初始化順序值大的VxD程序先被卸載,這樣他們?nèi)匀豢梢允褂帽人鼈兒蠹虞d的那些VxD程序提供的服務(wù)。如上面的例子,次序是: 
.... VxD3 ===> VxD2 ===> VxD1..... 
在上邊的例子中,如果VxD2在初始化時(shí)調(diào)用了VxD1中的某些服務(wù),那么卸載時(shí)它可能也要再次用到一些VxD1中的服務(wù)。System_Exit2和Sys_Critical_Exit2是反初始化順序發(fā)送的。這表示,當(dāng)VxD2接受到這些消息時(shí),VxD1還沒有被卸載,它仍可以調(diào)用VxD1的服務(wù),而System_Exit和Sys_Critical_Exit消息不是按照反初始化順序發(fā)送的。這意味著,你不能肯定你是否仍能調(diào)用在你之前加載的VxD提供的VxD服務(wù)。新一代的VxD程序不應(yīng)該使用這些消息。 
還有兩種退出消息: 
Device_Reboot_Notify2 告訴VxD程序VMM正在準(zhǔn)備重新啟動(dòng)系統(tǒng)。這時(shí)候中斷還是開放的。 
Crit_Reboot_Notify2 告訴VxD程序VMM正在準(zhǔn)備重新啟動(dòng)系統(tǒng)。這時(shí)候中斷已經(jīng)被關(guān)閉了。 
到這里,你可以猜到還有Device_Reboot_Notify和Crit_Reboot_Notify 消息,但它們并不是像“2”版本的消息一樣按反初始化順序發(fā)送的。 
動(dòng)態(tài)VxD: 
動(dòng)態(tài)VxD在Windows9x里可以動(dòng)態(tài)的被加載和卸載。這個(gè)特點(diǎn)在Window3.x下是沒有的。動(dòng)態(tài)VxD程序的主要作用是用來支持某些動(dòng)態(tài)的硬件設(shè)備的重裝,比如:即插即用設(shè)備。盡管如此,你可以從你的Win32程序中加載/卸載它,也可以把它看作是你的程序的一個(gè)到ring-0的擴(kuò)展。 
上一節(jié)我們提到的例子是一個(gè)靜態(tài)的VxD,你可以把它轉(zhuǎn)換成一個(gè)動(dòng)態(tài)的VxD,只要在.def文件中VxD標(biāo)記的后面加上關(guān)鍵字DYNAMIC。 
VxD FIRSTVxD DYNAMIC 
這就是你把一個(gè)靜態(tài)VxD轉(zhuǎn)換成一個(gè)動(dòng)態(tài)的VxD所要做的一切。 
一個(gè)動(dòng)態(tài)的VxD可以按以下的方法被加載: 
把它放到你的Windows目錄下的\\SYSTEM\\IOSUBSYS目錄中。在這個(gè)目錄里的VxD會(huì)被輸入輸出監(jiān)視器(ios)加載。這些VxD必須支持層設(shè)備驅(qū)動(dòng)。所以用這種方法加載你的動(dòng)態(tài)VxD并不是一個(gè)好辦法。 
用VxD加載服務(wù)。 VxDLDR是一個(gè)可以加載動(dòng)態(tài)VxD的靜態(tài)VxD。你可以在其他VxD里面或者在16位代碼里面調(diào)用它的服務(wù)。 
用Win32應(yīng)用程序里的 CreateFile API。你在調(diào)用CreateFile時(shí),你的動(dòng)態(tài)VxD要以下面的格式填寫: 

\\\\.\\VxD完整路徑名 

例如,如果你要加載一個(gè)在當(dāng)前目錄下名為FirstVxD的動(dòng)態(tài)VxD,你需要做如下的工作: 

.data 
VxDName db \"\\\\.\\FirstVxD.VxD\",0 
...... 
.data? 
hDevice dd ? 
..... 
.code 
..... 
invoke CreateFile, addr VxDName,0,0,0,0, FILE_FLAG_DELETE_ON_CLOSE,0 
mov hDevice,eax 
...... 
invoke CloseHandle,hDevice 
...... 


FILE_FLAG_DELETE_ON_CLOSE 這個(gè)標(biāo)志用來說明該VxD在CreateFile返回的句柄關(guān)閉時(shí)被卸載。 
如果你用CreateFile來加載一個(gè)動(dòng)態(tài)VxD,那么這個(gè)動(dòng)態(tài)VxD必須處理w32_DeviceIoControl 消息。當(dāng)你的動(dòng)態(tài)VxD第一次被CreateFile函數(shù)加載的時(shí)候,VWIN32 向你的VxD發(fā)出這個(gè)消息。你的VxD響應(yīng)這個(gè)消息,返回時(shí)eax中的值必須為零。當(dāng)應(yīng)用程序調(diào)用DeviceIoControl API來與一個(gè)動(dòng)態(tài)VxD通訊時(shí),w32_DeviceIoControl消息也被發(fā)送。我們會(huì)在下一章講到DeviceIoControl接口。 
一個(gè)動(dòng)態(tài)VxD在初始化時(shí)收到一個(gè)消息: 
Sys_Dynamic_Device_Init 
在結(jié)束時(shí)也收到一個(gè)控制消息: 
Sys_Dynamic_Device_Exit 
動(dòng)態(tài)VxD不會(huì)收到Sys_Critical_Init, Device_Init和Init_Complete控制消息,因?yàn)檫@些消息是在系統(tǒng)虛擬機(jī)初始化時(shí)發(fā)送的。除了這三個(gè)消息,動(dòng)態(tài)VxD能收到所有的控制消息,只要它還在內(nèi)存里。它可以做靜態(tài)VxD可以做的所有事情。簡單的說,動(dòng)態(tài)VxD除了加載機(jī)制和接收到的初始化/結(jié)束消息跟靜態(tài)VxD不同以外,它能做靜態(tài)VxD所能做的一切。 
其它系統(tǒng)控制消息 
當(dāng)VxD在內(nèi)存里的時(shí)候,除了接收和初始化及結(jié)束相關(guān)的消息外,它還要收到許多別的控制消息。有些消息是關(guān)于虛擬機(jī)管理器的,有的是關(guān)于各種事件的。例如,關(guān)于虛擬機(jī)的消息如下: 
Create_VM 
VM_Critical_Init 
VM_Suspend 
VM_Resume 
Close_VM_Notify 
Destroy_VM 
選擇地響應(yīng)你所感興趣的消息是你自己的責(zé)任。 
在VxD內(nèi)創(chuàng)建函數(shù) 
你要在一個(gè)段里面定義你的函數(shù)。你應(yīng)該首先定義一個(gè)段,然后把你的函數(shù)放進(jìn)去。例如,如果你要把你的函數(shù)放到一個(gè)可調(diào)頁段中。你應(yīng)該先定義一個(gè)可調(diào)頁段,像這樣: 
VxD_PAGEABLE_CODE_SEG 
(你的函數(shù)寫在這里) 

VxD_PAGEABLE_CODE_ENDS 

你可以在一個(gè)段里面插入多個(gè)的函數(shù)。作為一個(gè)VxD編寫者,你必須決定每一個(gè)函數(shù)應(yīng)該放到哪個(gè)段里面去。如果你的函數(shù)必須時(shí)刻存在于內(nèi)存中,如某些硬件中斷處理程序,就把它們放到鎖定頁面段里面,否則,你應(yīng)該把它們放到可調(diào)頁段。 
你要用BeginProc和EndProc 宏來定義你的函數(shù): 
BeginProc 函數(shù)名 
EndProc 函數(shù)名 

使用BeginProc 宏還可以加上一些參數(shù),想了解這些細(xì)節(jié),你可以看看Win95 DDK的文檔。大多數(shù)時(shí)候,你只用填寫函數(shù)的名字就夠了。 
因?yàn)锽eginProc-EndProc 宏比proc-endp 指令的功能要強(qiáng),所以你應(yīng)該用BeginProc-EndProc宏來代替proc-endp指令 
VxD編程約定 
寄存器的使用 
你的VxD程序可以使用所有的寄存器,F(xiàn)S和GS。但是在改動(dòng)段寄存器的時(shí)候一定要小心。尤其是,一定不要改動(dòng)CS和SS的內(nèi)容,除非你對(duì)將發(fā)生的事情有絕對(duì)的把握。你可以使用DS和ES,但一定要記住在返回時(shí)恢復(fù)它們初值。有兩個(gè)特征位尤其重要:方向和中斷特征位。不要長時(shí)間的屏蔽中斷。還有如果你要改動(dòng)方向特征位,不要忘了在返回之前恢復(fù)它的初值。 
參數(shù)傳遞約定 
VxD服務(wù)函數(shù)有兩種調(diào)用約定:寄存器法和堆棧法。調(diào)用寄存器法服務(wù)函數(shù)時(shí),你通過各種寄存器來傳遞服務(wù)函數(shù)的參數(shù)。并且,在調(diào)用完成后檢查寄存器的值來看操作是否成功。不要總是以為在調(diào)用服務(wù)函數(shù)后主要寄存器的值還和以前一樣。當(dāng)調(diào)用堆棧法服務(wù)函數(shù)時(shí),你把要傳遞的參數(shù)壓棧,在eax得到返回值。堆棧調(diào)用法的服務(wù)函數(shù)保存ebx,esi,edi和ebp的值。許多寄存器調(diào)用法服務(wù)函數(shù)都源于Windows3.x的時(shí)代。在大多數(shù)時(shí)候,你可以通過名字來區(qū)分這兩種服務(wù)函數(shù),如果一個(gè)函數(shù)的名字一下劃線開頭,如_HeapAllocate,它就是一個(gè)堆棧法的服務(wù)函數(shù)(除了少數(shù)從VWIN32.VxD導(dǎo)出的函數(shù))。如果函數(shù)名不是一下劃線開頭,它就是一個(gè)寄存器法的服務(wù)函數(shù)。 
調(diào)用VxD服務(wù)函數(shù) 
你可以通過VMMCall和VxDCall 宏來調(diào)用VMM和VxD服務(wù)。這兩個(gè)宏的語法是一樣的。當(dāng)你要調(diào)用VMM導(dǎo)出的VxD服務(wù)函數(shù)時(shí),用VMMCall。當(dāng)你要用其它VxD程序?qū)С龅腣xD服務(wù)函數(shù)時(shí),用VxDCall。 
VMMCall service ; 調(diào)用寄存器法服務(wù)函數(shù)e 
VMMCall _service, ; 調(diào)用堆棧法服務(wù)函數(shù) 
正如我在前面所講的,VMMCall和VxDCall分解出一個(gè)跟著一個(gè)雙字的20h中斷,這樣用起來很方便。當(dāng)你調(diào)用堆棧法服務(wù)時(shí),你必須用角括號(hào)把你的參數(shù)列括起來。 
VMMCall _HeapAllocate, <, HeapLockedIfDP> 
_HeapAllocate是一個(gè)堆棧法服務(wù)函數(shù)。它有兩個(gè)參數(shù),我們必須用角括號(hào)把它們括起來。由于第一個(gè)參數(shù)是一個(gè)這個(gè)宏不能正確解釋的表達(dá)式,所以我們又要用一個(gè)角括號(hào)把它括起來。 
Flat地址 
在老的編譯工具里,當(dāng)你使用offset 操作符時(shí),編譯器和聯(lián)接器會(huì)生成錯(cuò)誤地址,所以VxD編寫者用offset flat:來代替offset。imm.inc包括了一個(gè)使這更簡單的宏:OFFSET32 來代替offset flat:。所以如果你要用地址操作時(shí),用OFFSET32 來代替offset操作符。 
注意: 當(dāng)我寫這篇教程的時(shí)候,我試了一下用offset 操作符。它可以生成正確的地址。所以我想MASM6.14修正了這個(gè)bug。但是為了安全起見,你還是應(yīng)該用OFFSET32宏來代替offset。

相關(guān)文章

最新評(píng)論