📄 vxd-e5.html
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Iczelion">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (Win98; I) [Netscape]">
<title>VxD Example:MessageBox</title>
</head>
<body text="#FFFFFF" bgcolor="#000080" link="#FFFF00" vlink="#8080FF" alink="#FF00FF">
<center>
<h1>
<font face="Arial,Helvetica"><font color="#FFFF99">VxD Example: MessageBox</font></font></h1></center>
<font face="Arial,Helvetica"><font size=-1>In the previous tutorials, you
learn about mechanics of VxD programming. Now is the time to apply what
you have learned. In this tutorial, we will create a simple static VxD
which will display a message box whenever a VM is created/destroyed.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>Download the example <a href="files/vxdmessage.zip">here</a>.</font></font>
<h3>
<font face="Arial,Helvetica"><font color="#66FFFF"><font size=+0>Trapping
VM creation and termination events</font></font></font></h3>
<font face="Arial,Helvetica"><font size=-1>When a VM is created, the VMM
sends <b><font color="#FFFF99">Create_VM</font></b> control message to
all VxDs. Also when a VM is terminated normally, it sends <b><font color="#FFFF99">VM_Terminate</font></b>
and <b><font color="#FFFF99">VM_Terminate2</font></b> to all VxDs. Our
job is easy: Process <b><font color="#FFFF99">Create_VM</font></b> and
<b><font color="#FFFF99">VM_Terminate2</font></b>
messages in our device control procedure. When our VxD receives those two
control messages, it displays a message box on the screen.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>When our VxD receives <b><font color="#FFFF99">Create_VM</font></b>
or<b><font color="#FFFF99"> VM_Terminate2</font></b> message, ebx contains
the handle of the VM. A VM handle can be considered as the unique ID of
the VM. Each VM has its unique ID (VM handle). You can use VM handle in
the same manner as you use a process ID, by passing it as a parameter to
the services that need it.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>On closer examination, a
VM handle is actually the 32-bit linear address of the <b><font color="#FFFF99">VM
control block (VMCB)</font></b>.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>VM Control Block is a structure
that contains several important items about the VM. It's defined as:</font></font>
<ul><b><tt>cb_s <font color="#FFCC33">STRUC</font></tt></b>
<br><b><tt><font color="#FFFF99">CB_VM_Status </font>
DD ?</tt></b>
<br><b><tt><font color="#FFFF99">CB_High_Linear</font>
DD ?</tt></b>
<br><b><tt><font color="#FFFF99">CB_Client_Pointer</font> DD
?</tt></b>
<br><b><tt><font color="#FFFF99">CB_VMID </font>
DD ?</tt></b>
<br><b><tt><font color="#FFFF99">CB_Signature </font>
DD ?</tt></b>
<br><b><tt>cb_s <font color="#FFCC33">ENDS</font></tt></b>
<br>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#66FF99"><b>CB_VM_Status</b> </font>
contains the bit flags that you can examine to find out about the state
of the VM.</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#66FF99">CB_High_Linear </font></b>
is the starting linear address of the mirror of the VM in the shared system
region (above 3 GB). This concept requires an explanation. Under Windows
95, a VxD should not touch the V86 region directly instead the VMM maps
the whole V86 region of every VM to the shared system region. When a VxD
wants to modify/touch the memory in V86 region of the VM, it should do
so to the high-linear area of the VM. For example, if the video memory
is at 0B8000h and your VxD needs to touch that area, it should add the
value in CB_High_Linear to 0B8000h and touch that area instead. The changes
you made to the high-linear mirror will be reflected to the VM because
both areas share the same page directory entry. Using the high-linear mirror
is better in most situation because you can modify the VM even if it's
not the current VM.</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#66FF99">CB_Client_Pointer</font></b>
contains the address of the <b><font color="#FFFF99">client register structure</font></b>.
The client register structure contains the values of all registers of the
interrupted V86 or protected mode application in the VM. If your VxD wants
to know/modify the state of the V86 or PM application, it can modify the
members of the client register structure and the changes will propagate
to the application when the VMM resumes its execution.</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#66FF99">CB_VMID</font></b>
The numeric identifer of the VM. The VMM assigns this number when it creates
the VM. The system VM has the VMID of 1.</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#66FF99">CB_Signature</font></b>
contains the string "VMcb". This member is used in checking if the VM handle
is valid.</font></font></li>
</ul>
<h3>
<font face="Arial,Helvetica"><font color="#66FFFF"><font size=+0>Displaying
a MessageBox</font></font></font></h3>
<font face="Arial,Helvetica"><font size=-1>A VxD can use <b><font color="#FFFF99">Virtual
Shell Device</font></b> services to communicate to the users. One such
service we will use in this example is <b><font color="#FFFF99">SHELL_Message</font></b>.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>SHELL_Message is a register-based
service. You pass parameters to it via registers.</font></font>
<ul>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#FFCC33">ebx</font></b>
Handle of the VM that is responsible for the message</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#FFCC33">eax </font></b>
MessageBox flags. You can look them up in shell.inc. They start with MB_.</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#FFCC33">ecx</font></b>
32-bit linear address of the message to display</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#FFCC33">edi </font></b>
32-bit linear address of the message box caption</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#FFCC33">esi </font></b>
32-bit linear address of the callback function in case you need to know
the response of the user to the message box. If you don't want to know,
use NULL.</font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><b><font color="#FFCC33">edx</font></b>
Reference data that will be passed to your callback (if you specify one
in esi)</font></font></li>
</ul>
<font face="Arial,Helvetica"><font size=-1>On return, the carry flag is
clear if the call is successful. The carry flag is set otherwise.</font></font>
<h3>
<font face="Arial,Helvetica"><font color="#66FFFF"><font size=+0>The example</font></font></font></h3>
<blockquote><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>.386p</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>include
vmm.inc</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>include
shell.inc</font></font></font></b>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>DECLARE_VIRTUAL_DEVICE
MESSAGE,1,0, MESSAGE_Control, UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER</font></font></font></b>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>Begin_control_dispatch
MESSAGE</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FFFF99"><font size=-1>
Control_Dispatch Create_VM, OnVMCreate</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FFFF99"><font size=-1>
Control_Dispatch VM_Terminate2, OnVMClose</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>End_control_dispatch
MESSAGE</font></font></font></b>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>VxD_PAGEABLE_DATA_SEG</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
MsgTitle db "VxD MessageBox",0</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
VMCreated db "A VM is created",0</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
VMDestroyed db "A VM is destroyed",0</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>VxD_PAGEABLE_DATA_ENDS</font></font></font></b>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>VxD_PAGEABLE_CODE_SEG</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>BeginProc
OnVMCreate</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov ecx, OFFSET32 VMCreated</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>CommonCode:</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
VMMCall Get_sys_vm_handle</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov eax,MB_OK+MB_ICONEXCLAMATION</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov edi, OFFSET32 MsgTitle</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
xor esi,esi</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
xor edx,edx</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
VxDCall SHELL_Message</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
ret</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>EndProc
OnVMCreate</font></font></font></b>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>BeginProc
OnVMClose</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov ecx,OFFSET32 VMDestroyed</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
jmp CommonCode</font></font></font></b>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -