.386p
include vmm.inc
include shell.incDECLARE_VIRTUAL_DEVICE MESSAGE,1,0, MESSAGE_Control, UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER
Begin_control_dispatch MESSAGE
Control_Dispatch Create_VM, OnVMCreate
Control_Dispatch VM_Terminate2, OnVMClose
End_control_dispatch MESSAGEVxD_PAGEABLE_DATA_SEG
MsgTitle db "VxD MessageBox",0
VMCreated db "A VM is created",0
VMDestroyed db "A VM is destroyed",0
VxD_PAGEABLE_DATA_ENDSVxD_PAGEABLE_CODE_SEG
BeginProc OnVMCreate
mov ecx, OFFSET32 VMCreated
CommonCode:
VMMCall Get_sys_vm_handle
mov eax,MB_OK+MB_ICONEXCLAMATION
mov edi, OFFSET32 MsgTitle
xor esi,esi
xor edx,edx
VxDCall SHELL_Message
ret
EndProc OnVMCreateBeginProc OnVMClose
mov ecx,OFFSET32 VMDestroyed
jmp CommonCode
EndProc OnVMClose
VxD_PAGEABLE_CODE_ENDSend
Begin_control_dispatch MESSAGEThe VxD processes two control messages, Create_VM and VM_Terminate2. When Create_VM control message is received, it calls OnVMCreate procedure. And when it receives VM_Terminate2 message, it calls OnVMClose procedure.
Control_Dispatch Create_VM, OnVMCreate
Control_Dispatch VM_Terminate2, OnVMClose
End_control_dispatch MESSAGE
VxD_PAGEABLE_DATA_SEGWe put the data in the pageable data segment.
MsgTitle db "VxD MessageBox",0
VMCreated db "A VM is created",0
VMDestroyed db "A VM is destroyed",0
VxD_PAGEABLE_DATA_ENDS
BeginProc OnVMCreateOnVMCreate procedure is created using BeginProc and EndProc macros. It puts the parameters for SHELL_Message service into the registers. Since we want to display the message box in the system VM, we cannot use the value in ebx (which is the handle of the VM that is being created). Instead, we use a VMM service, Get_Sys_VM_Handle, to obtain the VM handle of the system VM. This service returns the VM handle in ebx. We put the addresses of the message and the caption into ecx and edi, respectively. We don't want to know the response of the user, so we zero out esi and edx. When all parameters are in the appropriate registers, we call SHELL_Message to display the message box.
mov ecx, OFFSET32 VMCreated
CommonCode:
VMMCall Get_sys_vm_handle
mov eax,MB_OK+MB_ICONEXCLAMATION
mov edi, OFFSET32 MsgTitle
xor esi,esi
xor edx,edx
VxDCall SHELL_Message
ret
EndProc OnVMCreate
BeginProc OnVMCloseOnVMClose procedure is simplicity in itself. Since it uses identical code as OnVMCreate, it initializes ecx with the address of the different message and then jumps to the code inside OnVMCreate.
mov ecx,OFFSET32 VMDestroyed
jmp CommonCode
EndProc OnVMClose
SEGMENTS
   
_LPTEXT    CLASS 'LCODE'    PRELOAD NONDISCARDABLE
   
_LTEXT      CLASS 'LCODE'    PRELOAD
NONDISCARDABLE
   
_LDATA      CLASS 'LCODE'    PRELOAD
NONDISCARDABLE
   
_TEXT        CLASS 'LCODE'   
PRELOAD NONDISCARDABLE
   
_DATA        CLASS 'LCODE'   
PRELOAD NONDISCARDABLE
   
CONST       CLASS 'LCODE'   
PRELOAD NONDISCARDABLE
   
_TLS          CLASS 'LCODE'   
PRELOAD NONDISCARDABLE
   
_BSS          CLASS 'LCODE'   
PRELOAD NONDISCARDABLE
   
_LMGTABLE    CLASS 'MCODE'    PRELOAD NONDISCARDABLE
IOPL
   
_LMSGDATA    CLASS 'MCODE'    PRELOAD NONDISCARDABLE
IOPL
   
_IMSGTABLE   CLASS 'MCODE'    PRELOAD DISCARDABLE
IOPL
   
_IMSGDATA     CLASS 'MCODE'    PRELOAD
DISCARDABLE IOPL
   
_ITEXT            
CLASS 'ICODE'     DISCARDABLE
   
_IDATA            
CLASS 'ICODE'    DISCARDABLE
   
_PTEXT           
CLASS 'PCODE'    NONDISCARDABLE
   
_PMSGTABLE    CLASS 'MCODE'    NONDISCARDABLE
IOPL
   
_PMSGDATA    CLASS 'MCODE'    NONDISCARDABLE
IOPL
   
_PDATA           
CLASS 'PDATA'    NONDISCARDABLE SHARED
   
_STEXT           
CLASS 'SCODE'    RESIDENT
   
_SDATA           
CLASS 'SCODE'    RESIDENT
   
_DBOSTART    CLASS 'DBOCODE'    PRELOAD NONDISCARDABLE
CONFORMING
   
_DBOCODE       CLASS 'DBOCODE'   
PRELOAD NONDISCARDABLE CONFORMING
   
_DBODATA        CLASS 'DBOCODE'   
PRELOAD NONDISCARDABLE CONFORMING
   
_16ICODE          CLASS '16ICODE'   
PRELOAD DISCARDABLE
   
_RCODE            
CLASS 'RCODE'
EXPORTS
MESSAGE_DDB @1
link -vxd -def:message.def message.obj