Esempio di VxD: MessageBox

Nei precedenti tutorial, avete imparato i meccanismi della programmazione dei VxD. Ora e' giunto il momento di mettere in pratica le vostre conoscenze. In questo tutorial, creeremo un semplice VxD statico che mostra una message box quanto una VM viene creata o distrutta.
Scaricate l'esempio qui.

Trapping degli eventi di creazione e di chiusura di una VM

Quando una VM viene creata, la VMM invia un messaggio Create_VM del controllo a tutti i VxD. Anche quando una VM viene regolarmente chiusa, essa invia un VM_Terminate e un VM_Terminate2 a tutti i VxD. Il nostro lavoro e' semplice: elaborare i messaggi Create_VM e VM_Terminate2 nella nostra procedura del device control. Quando il VxD ricece i due messaggi del controllo, esso mostra una message box sullo schermo.
Quando il VxD riceve un messaggio Create_VM o VM_Terminate2, ebx contiene l'handle della VM. Un handle della VM puo' essere considerato come l'unico ID della VM. Ogni VM ha il suo unico ID (VM handle). Potete usare il VM handle nello stesso modo in cui usate un ID di un processo, passandolo come parametro al servizio che lo necessita.
Esaminandolo strettamente, un handle di VM e' l'attuale linear address a 32-bit del VM control block (VMCB).
La VM Control Block e' una struttura che contiene varie importanti caratteristiche riguardanti la VM. Essa e' definita come:

Mostrare una MessageBox

Un VxD puo' usare i servizio della Virtual Shell Device per comunicare con gli utenti. Un servizio di di questo tipo che utilizzeremo in questo esempio e' SHELL_Message.
SHELL_Message e' un servizio register-based. Cio' significa che i parametri vanno passati tramite registri. Al ritorno, se la call e' stata effettuata con successo, il flag di carry e' resettato . Negli altri casi esso risulta settato.

L'esempio

.386p
include vmm.inc
include shell.inc

DECLARE_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 MESSAGE

VxD_PAGEABLE_DATA_SEG
    MsgTitle db "VxD MessageBox",0
    VMCreated db "Una VM e' stata creata",0
    VMDestroyed db "Una VM e' stata distrutta",0
VxD_PAGEABLE_DATA_ENDS

VxD_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 OnVMCreate

BeginProc OnVMClose
    mov ecx,OFFSET32 VMDestroyed
    jmp CommonCode
EndProc OnVMClose
VxD_PAGEABLE_CODE_ENDS

end

Analisi:

Begin_control_dispatch MESSAGE
    Control_Dispatch Create_VM, OnVMCreate
    Control_Dispatch VM_Terminate2, OnVMClose
End_control_dispatch MESSAGE
Il VxD elabora i due messaggi del control, Create_VM e VM_Terminate2. Quando il messaggio Create_VM del controllo viene ricevuto, chiama la procedura OnVMCreate. E quando riceve il messaggio VM_Terminate2, chiama la procedura OnVMClose.
VxD_PAGEABLE_DATA_SEG
    MsgTitle db "VxD MessageBox",0
    VMCreated db "Una VM e' stata creata",0
    VMDestroyed db "Una VM e' stata distrutta",0
VxD_PAGEABLE_DATA_ENDS
Mettiamo i dati nel pageable data segment.
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 OnVMCreate
La procedura OnVMCreate viene creata usando le macro BeginProc e EndProc. Essa mette i parametri per il servizio SHELL_Message nei registri. Siccome desideriamo mostrare la message box nella VM di sistema, non possiamo usare il valore in ebx (che e' l'handle della VM che stiamo creando). Invece di cio', usiamo un servizio VMM, Get_Sys_VM_Handle, per ottenere l'handle della VM di sistema. Questo servizio ritorna l'handle della VM in ebx. Mettiamo gli indirizzi del messaggio e del titolo rispettivamente in ecx e edi. Non ci interessa sapere la risposta dell'utente, quindi azzeriamo esi e edx. Quando tutti i parametri sono nei registri appropriati, chiamiamo SHELL_Message per mostrare la message box.
BeginProc OnVMClose
    mov ecx,OFFSET32 VMDestroyed
    jmp CommonCode
EndProc OnVMClose
La procedura OnVMClose e' molto semplice. Dato che usa lo stesso codice di OnVMCreate, essa inizializza ecx con l'indirizzo del diverso messaggio e quindi salta nel codice interno di OnVMCreate.

Module Definition File *

VXD MESSAGE

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

Operazione di Assemblamento

 ml -coff -c -Cx  -DMASM6 -DBLD_COFF -DIS_32 message.asm

 link -vxd -def:message.def message.obj

Installazione del VxD

  1. Mettere message.vxd nella cartella \system
  2. aggiungere la seguente riga all'interno della sezione [386enh] del system.ini
      device=message.vxd
  3. riavviare il computer

Controllare il VxD

Create una finestra DOS. Vedrete una message box che mostra il messaggio "Una VM e' stata creata". Quando chiudete la finestra DOS, una message box apparira' con il messaggio: "Una VM e' stata distrutta"

Traduzione italiana a cura di: fabio@privacy.nu

Torna alla main page! Torna alla pagina principale