148 lines
2.9 KiB
HolyC
148 lines
2.9 KiB
HolyC
// https://wiki.osdev.org/VMware_tools
|
|
|
|
#define VMWARE_MAGIC 0x564D5868
|
|
#define VMWARE_PORT 0x5658
|
|
#define VMWARE_PORTHB 0x5659
|
|
|
|
#define CMD_GETVERSION 10
|
|
|
|
#define CMD_ABSPOINTER_DATA 39
|
|
#define CMD_ABSPOINTER_STATUS 40
|
|
#define CMD_ABSPOINTER_COMMAND 41
|
|
|
|
#define ABSPOINTER_ENABLE 0x45414552
|
|
#define ABSPOINTER_RELATIVE 0xF5
|
|
#define ABSPOINTER_ABSOLUTE 0x53424152
|
|
|
|
class @vmware_cmd
|
|
{
|
|
union {
|
|
U32 ax;
|
|
U32 magic;
|
|
};
|
|
union {
|
|
U32 bx;
|
|
I32 size;
|
|
};
|
|
union {
|
|
U32 cx;
|
|
U16 command;
|
|
};
|
|
union {
|
|
U32 dx;
|
|
U16 port;
|
|
};
|
|
U32 si;
|
|
U32 di;
|
|
};
|
|
|
|
U0 @vmware_send(@vmware_cmd* cmd)
|
|
{
|
|
U32 reg RAX reg_ax = cmd->ax;
|
|
U32 reg RBX reg_bx = cmd->bx;
|
|
U32 reg RCX reg_cx = cmd->cx;
|
|
U32 reg RDX reg_dx = cmd->dx;
|
|
U32 reg RSI reg_si = cmd->si;
|
|
U32 reg RDI reg_di = cmd->di;
|
|
reg_ax = VMWARE_MAGIC;
|
|
reg_dx = VMWARE_PORT;
|
|
asm {
|
|
IN AX, DX
|
|
}
|
|
cmd->ax = reg_ax;
|
|
cmd->bx = reg_bx;
|
|
cmd->cx = reg_cx;
|
|
cmd->dx = reg_dx;
|
|
cmd->si = reg_si;
|
|
cmd->di = reg_di;
|
|
}
|
|
|
|
Bool @vmware_backdoor_is_present()
|
|
{
|
|
@vmware_cmd cmd;
|
|
cmd.bx = ~VMWARE_MAGIC;
|
|
cmd.command = CMD_GETVERSION;
|
|
@vmware_send(&cmd);
|
|
if (cmd.bx != VMWARE_MAGIC || cmd.ax == 0xFFFFFFFF) {
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
U0 @vmware_ms_absolute()
|
|
{
|
|
@vmware_cmd cmd;
|
|
|
|
cmd.bx = ABSPOINTER_ENABLE;
|
|
cmd.command = CMD_ABSPOINTER_COMMAND;
|
|
@vmware_send(&cmd);
|
|
|
|
cmd.bx = 0;
|
|
cmd.command = CMD_ABSPOINTER_STATUS;
|
|
@vmware_send(&cmd);
|
|
|
|
cmd.bx = 1;
|
|
cmd.command = CMD_ABSPOINTER_DATA;
|
|
@vmware_send(&cmd);
|
|
|
|
cmd.bx = ABSPOINTER_ABSOLUTE;
|
|
cmd.command = CMD_ABSPOINTER_COMMAND;
|
|
@vmware_send(&cmd);
|
|
}
|
|
|
|
U0 @vmware_handle_mouse()
|
|
{
|
|
@vmware_cmd cmd;
|
|
cmd.bx = 0;
|
|
cmd.command = CMD_ABSPOINTER_STATUS;
|
|
@vmware_send(&cmd);
|
|
|
|
if (cmd.ax == 0xFFFF0000) {
|
|
@vmware_ms_absolute;
|
|
return;
|
|
}
|
|
|
|
if ((cmd.ax & 0xFFFF) < 4)
|
|
return;
|
|
|
|
cmd.bx = 4;
|
|
cmd.command = CMD_ABSPOINTER_DATA;
|
|
@vmware_send(&cmd);
|
|
|
|
I32 buttons = (cmd.ax & 0xFFFF);
|
|
I64 z = cmd.dx;
|
|
if (z > 1) {
|
|
z = -1;
|
|
}
|
|
|
|
MsSet(@lerp(cmd.bx, 0xffff, Display.width), @lerp(cmd.cx, 0xffff, Display.height), ms.pos.z + z);
|
|
Mouse.x = @lerp(cmd.bx, 0xffff, Display.width);
|
|
Mouse.y = @lerp(cmd.cx, 0xffff, Display.height);
|
|
// MsSet((cmd.bx * Display.width) / 0xffff, (cmd.cx * Display.height) / 0xffff, ms.pos.z + z);
|
|
ms.lb = buttons & 0x20;
|
|
ms.rb = buttons & 0x10;
|
|
}
|
|
|
|
U0 @vmware_ms_nop() { }
|
|
|
|
U0 @vmware_ms_update()
|
|
{
|
|
while (1) {
|
|
@vmware_handle_mouse;
|
|
Sleep(1);
|
|
}
|
|
}
|
|
|
|
U0 @vmware_tools_init()
|
|
{
|
|
if (!@vmware_backdoor_is_present) {
|
|
return;
|
|
}
|
|
@patch_jmp_rel32(&WinMsUpdate, &@vmware_ms_nop);
|
|
@vmware_ms_absolute;
|
|
Spawn(&@vmware_ms_update, , "VMwareMsUpdateTask");
|
|
}
|
|
|
|
@vmware_tools_init;
|
|
|
|
"vmware-tools ";
|