.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