A virtual device provides V86-mode and protected-mode API procedures to allow applications and other software running in a virtual machine access to the features of the virtual device. To make these optional procedures available, the virtual device must declare them as parameters in the Declare_Virtual_Device macro. If not declared, the VMM assumes that the virtual device has no API procedures.
An application or other software running in a virtual machine retrieves an entry-point address for an API procedure for a given virtual machine by calling the Get Device Entry Point Address function (Interrupt 2Fh Function 1684h) and setting the BX register to the identifier for the virtual device. The VMM returns an address to the application to indirectly enter the API procedure.
When an application calls the entry-point address, the VMM saves the application's registers and calls the virtual device's corresponding API procedure, placing the handle of the current virtual machine in the EBX register and the address of a Client_Reg_Struc structure in the EBP register. The API procedure must examine the client registers (using the Client_Reg_Struc) to determine which API call was made.
By convention, most API procedures use the AH register to specify the major function number and the AL register to specify the minor function number, with other client registers being used for additional parameters. The API procedure returns values by modifying the client registers. An API procedure may modify the EAX, EBX, ECX, EDX, ESI, and EDI registers.
The following example shows the sample API procedure VSAMPLED_API_Get_Version:
BeginProc VSAMPLED_API_Get_Version
movzx eax, [ebp.Client_AX] ; get function number
or eax, eax
jnz Undefined
Get_Version:
mov [ebp.Client_AX], 030Ah ; return version in client's AX
and [ebp.Client_Flags], NOT CF_Mask ; clear carry flag
ret
Undefined:
or [ebp.Client_Flags], CF_Mask ; set carry flag
ret
EndProc VSAMPLED_API_Get_Version
Share with your friends: |