?? csdn_文檔中心_虛擬設備驅動程序結構(vxd教程3).htm
字號:
<TD align=middle height=10></TD>
<TD height=10></TD></TR></TBODY></TABLE><!--文章說明信息結束//-->
<TABLE border=0 width=600>
<TBODY>
<TR>
<TD align=left><BR>
<H1><FONT face=Arial,Helvetica><FONT
color=#ffff99>虛擬設備驅動程序結構</FONT></FONT></H1>
<CENTER></CENTER>
<DIV align=center>由 Ryo 翻譯,發表于 <A
href="http://asm.yeah.net/">http://asm.yeah.net/</A>,英文版本來自 [<A
href="http://win32asm.cjb.net/">Iczelion's Win32 Assembly
Homepage</A>] </DIV><BR><FONT face=Arial,Helvetica><FONT
size=-1>現在大家對vmm和vxd有了一定的了解,接下來我們來看一看如何編寫vxd代碼。首先,你必須具備<B><FONT
color=#66ff99>Windows 95/98 Device Driver Development
Kit</FONT></B>。Window95 ddk只有MSDN 訂戶才能拿到,但Windows98
ddk卻可以免費從Microsoft公司取得。盡管Windows 98
ddk是面向WDM的,但你還是可以用它來開發VxD程序。你可以從 <A
href="http://www.microsoft.com/hwdev/ddk/install98ddk.htm?">http://www.microsoft.com/hwdev/ddk/install98ddk.htm?</A>下載Window98
ddk。</FONT></FONT> <BR><FONT face=Arial,Helvetica><FONT
size=-1>你可以下載整個軟件包(大約30M),也可以只下載你感興趣的部分。如果你沒有下載整個軟件包,那么別忘了下載<B><FONT
color=#ffff99>other.exe</FONT></B></FONT></FONT> <BR><FONT
face=Arial,Helvetica><FONT color=#ffffff><FONT size=-1>里面的Window95
ddk documentation。Windows98 ddk
包含了6.11d版的MASM。你需要把它升級為最新版。如果你不知道到哪里去下載最新的版本,可以去我的<A
href="http://win32asm.cjb.net/">主頁</A>上查一查。</FONT></FONT></FONT>
<BR><FONT face=Arial,Helvetica><FONT color=#ffffff><FONT
size=-1>Window9x DDK包含了一些Masm32包所不具有的重要庫文件。</FONT></FONT></FONT>
<BR><FONT face=Arial,Helvetica><FONT color=#ffffff><FONT
size=-1>你可以在<A
href="http://freeshell.org/~michael/files/firstvxd.zip">這里</A>下載這一章的例子。</FONT></FONT></FONT>
<H3><FONT face=Arial,Helvetica><FONT color=#66ffff><FONT
size=+0>LE文件格式</FONT></FONT></FONT></H3><FONT
face=Arial,Helvetica><FONT color=#ffffff><FONT
size=-1>VxD采用線性可執行文件格式(LE)。這種文件格式是為OS/2
2.0版設計的。它同時包含16位和32位代碼,這點也是VxD程序的需要?;叵隫xD在Windows3.x的時代,在那時,從Dos啟動Windows,Windows在把機器轉到保護模式之前需要在實模式下做一些初始化。實模式的16位代碼必須和32位代碼一起放在可執行文件中。所以LE文件格式理所當然的選擇。幸運的,Windows
NT驅動程序不必在實模式下初始化,所以它們不必使用LE文件格式。它們用的是PE文件格式。</FONT></FONT></FONT><FONT
face=Arial,Helvetica><FONT color=#ffffff><FONT
size=-1></FONT></FONT></FONT>
<P><FONT face=Arial,Helvetica><FONT size=-1><FONT
color=#ffffff>在LE文件中,代碼和數據被存放在幾類運行屬性不同的</FONT><B><FONT
color=#ffff99>段</FONT></B><FONT
color=#ffffff>中。以下是一些可用的</FONT><B><FONT
color=#ffff99>段類</FONT></B><FONT
color=#ffffff>。</FONT></FONT></FONT>
<UL>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>LCODE</FONT></B><FONT
color=#ffffff> 頁面鎖定的代碼和數據段
這種段被鎖定在內存里。換句話說,這段永遠不會被放到硬盤上去,所以你一定要謹慎的使用這種段類以免浪費寶貴的內存。那些每時每刻都必須放在內存中的代碼和數據應該放在這個段里。尤其是那些硬件中斷處理程序。</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>PCODE</FONT></B><FONT color=#ffffff> 可調頁代碼段
VMM可以對這種段實行調頁處理,在這種段里的代碼不必時刻放在內存里,當VMM需要物理內存的時候,它就會把這段放到硬盤上去。</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>PDATA</FONT></B><FONT color=#ffffff>
可調頁數據段</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>ICODE</FONT></B><FONT color=#ffffff> 僅用于的初始化段
這種段里的代碼僅僅用來進行VxD的初始化。當初始化完成后,VMM就把這段從內存中釋放。</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>DBOCODE</FONT></B><FONT color=#ffffff> 僅用于調試的代碼數據段
當你要調試VxD程序時,就要用到這種段里的代碼和數據,例如,它包含要調試的消息的處理代碼。</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>SCODE</FONT></B><FONT color=#ffffff> 靜態代碼和數據段
這種段時刻存在于內存中,即使VxD已經卸載,這種段對某些動態的VxD程序很有用,這些VxD程序需要在某一Windows進程里不停的加載/卸載而又要紀錄上次的環境和狀態。</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>RCODE</FONT></B><FONT color=#ffffff> 實模式初始化代碼數據段
這種段包含實模式初始化需要的16位代碼和數據。 </FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>16ICODE</FONT></B><FONT color=#ffffff> 16ICODE
USE16保護模式初始化數據段
這是一個16位的段,它包含VxD要從保護模式拷貝到V86模式的代碼。例如,如果你要把一些V86的代碼拷貝到一個虛擬機上時,你想拷貝的代碼就要放在這里。如果你把它放在其他的段里,編譯程序就會產生錯誤的代碼,例如,它會產生32位代碼而不是16位代碼。</FONT></FONT></FONT>
<LI><FONT face=Arial,Helvetica><FONT size=-1><B><FONT
color=#ffff99>MCODE</FONT></B><FONT color=#ffffff> 鎖定的消息字串
這種段包含了由VMM消息宏幫助編譯的消息字串,這有助于你構造你的驅程的國際版本。</FONT></FONT></FONT>
</LI></UL><FONT face=Arial,Helvetica><FONT size=-1><FONT
color=#ffffff>這并不意味著你的VxD程序必須包含以上</FONT><B><FONT
color=#ffff99>所有</FONT></B><FONT
color=#ffffff>的段,你可以選擇你的VxD程序需要的段。例如,如果你的VxD程序不進行實模式初始化,那么就不必包含</FONT><B><FONT
color=#ffff99>RCODE</FONT></B><FONT
color=#ffffff>段。</FONT></FONT></FONT> <BR><FONT
face=Arial,Helvetica><FONT size=-1><FONT
color=#ffffff>大多數時候,你要用到</FONT><B><FONT
color=#ffff99>LCODE</FONT></B><FONT color=#ffffff>, </FONT><B><FONT
color=#ffff99>PCODE</FONT></B><FONT color=#ffffff>和</FONT><B><FONT
color=#ffff99>PDATA</FONT></B><FONT
color=#ffffff>段。作為一個VxD程序編寫者,為你的代碼和數據選擇合適的段取決于你自己的判斷??偟膩碚f,你應該盡可能多的使用</FONT><B><FONT
color=#ffff99>PCODE</FONT></B><FONT color=#ffffff>和</FONT><B><FONT
color=#ffff99>PDATA</FONT></B><FONT
color=#ffffff>因為這樣VMM就可以在需要的時候把段調入調出內存。另外,硬件中斷程序及其所用到的服務必須放在
</FONT><B><FONT color=#ffff99>LCODE</FONT></B><FONT
color=#ffffff>段里。</FONT></FONT></FONT> <BR><FONT
face=Arial,Helvetica><FONT color=#ffffff><FONT
size=-1>你不能直接地使用這些段類,你要用這些段類來定義段,這些段的定義被存放在模塊定義文件(.def)中。下面是一個標準的模塊定義文件:</FONT></FONT></FONT>
<BLOCKQUOTE><TT><FONT color=#ffff99><FONT size=-1>VXD
FIRSTVXD</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1>SEGMENTS</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_LPTEXT CLASS 'LCODE'
PRELOAD NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_LTEXT CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_LDATA CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_TEXT CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_DATA CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
CONST CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_TLS CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_BSS CLASS
'LCODE' PRELOAD
NONDISCARDABLE</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_LMGTABLE CLASS 'MCODE' PRELOAD
NONDISCARDABLE IOPL</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1>
_LMSGDATA CLASS 'MCODE' PRELOAD
NONDISCARDABLE IOPL</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1> _IMSGTABLE
CLASS 'MCODE' PRELOAD DISCARDABLE
IOPL</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1> _IMSGDATA CLASS
'MCODE' PRELOAD DISCARDABLE
IOPL</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1> _ITEXT
CLASS 'ICODE' DISCARDABLE</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_IDATA CLASS
'ICODE' DISCARDABLE</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_PTEXT CLASS
'PCODE' NONDISCARDABLE</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_PMSGTABLE CLASS 'MCODE' NONDISCARDABLE
IOPL</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1> _PMSGDATA CLASS
'MCODE' NONDISCARDABLE IOPL</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_PDATA CLASS
'PDATA' NONDISCARDABLE SHARED</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_STEXT CLASS
'SCODE' RESIDENT</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_SDATA CLASS
'SCODE' RESIDENT</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE
CONFORMING</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1> _DBOCODE CLASS
'DBOCODE' PRELOAD NONDISCARDABLE
CONFORMING</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1> _DBODATA CLASS
'DBOCODE' PRELOAD NONDISCARDABLE
CONFORMING</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1> _16ICODE CLASS
'16ICODE' PRELOAD DISCARDABLE</FONT></FONT></TT>
<BR><TT><FONT color=#ffff99><FONT size=-1>
_RCODE CLASS
'RCODE'</FONT></FONT></TT> <BR><TT><FONT color=#ffff99><FONT
size=-1>EXPORTS</FONT></FONT></TT> <BR><TT><FONT
color=#ffff99><FONT size=-1> FIRSTVXD_DDB
@1</FONT></FONT></TT></BLOCKQUOTE><FONT face=Arial,Helvetica><FONT
size=-1><FONT color=#ffffff>第一個聲明定義了VxD的名稱,一個VxD的名稱</FONT><B><FONT
color=#ffff99>必須</FONT></B><FONT
color=#ffffff>是全部大寫的,我曾經試過用小寫,結果VxD除了把自己載入內存外什么也不干。</FONT></FONT></FONT>
<BR><FONT face=Arial,Helvetica><FONT size=-1><FONT
color=#ffffff>接下來是段的定義,段的定義包括三個部分:段的名稱,段類和要求的段的運行屬性。你可以看到很多段都基于相同的段類,例如,</FONT><B><FONT
color=#ffff99>_LPTEXT</FONT></B><FONT color=#ffffff>,
</FONT><B><FONT color=#ffff99>_LTEXT</FONT></B><FONT color=#ffffff>,
</FONT><B><FONT color=#ffff99>_LDATA</FONT></B><FONT
color=#ffffff>都是基于</FONT><B><FONT
color=#ffff99>LCODE</FONT></B><FONT
color=#ffffff>段類而且屬性也完全一樣。這樣定義段有利于使代碼更容易理解。如:</FONT><B><FONT
color=#ffff99>LCODE</FONT></B><FONT
color=#ffffff>可以包含代碼和數據,對于一個程序員來說,如果他能把數據放到</FONT><B><FONT
color=#ffff99>_LDATA</FONT></B><FONT
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -