v 1
July 5, 2020

HID Virtual Driver Kit

The to Emulate

Joystick, Keyboard and Mouse for Windows 7, 8, 8.1, 10 64 bit

Using the Mouse Rel Driver

Overview

The mouse driver rel(relative) allows you to:

  • Position the cursor relative to the current cursor position.
  • Press and/or release the left, middle and right buttons.

The Mouse Driver Rel Sender Utility

Use the SDK Mouse Driver Rel Sender to send relative movement values and mouse button states to the mouse driver. The mouse cursor will respond as if a real physical mouse had been moved and its buttons pressed. Be sure to press the ‘Connect to Mouse Driver’ before sending relative movement values and button states to the driver.

Relative Coordinates

The driver sends relative movement values.

  • [-10,-5] moves the cursor 10 pixels to the left and 5 pixels up.
  • [20, 16] moves the cursor 20 pixels to the right and 16 pixels down.
  • [0, 0] doesn’t move the cursor, so this is useful when pressing or releasing mouse buttons.

Sending Data to the Driver

First, iterate through all drivers until you find ‘Tetherscript Virtual Mouse Rel’ and connect to that driver. Then send a packed record as a ‘Feature Report’ to the driver. More info on feature reports below:

https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/

Mouse driver reports are based sdk/delphi/common/hut1_12v2.pdf

Delphi

Here’s the mouse driver report Delphi data format. In our Delphi source we call this a Feature, but really it is a standard HID Input Report. This is just the terminology left over from Delphi’s JCL and JVCL libraries.:

type
PTSetFeatureMouseRel = ^TSetFeatureMouseRel;
TSetFeatureMouseRel = packed record
  ReportID: Byte;
  CommandCode: Byte;
  buttons: byte;
  X: Byte;
  Y: Byte;
end;

C#

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SetFeatureMouseRel
{
  public Byte ReportID;
  public Byte CommandCode;
  public Byte Buttons;
  public sbyte X;
  public sbyte Y;
}

c

This corresponds to the following c struct (this is the actual receiving input report struct from the driver source):

typedef struct _HIDMINI_CONTROL_INFO {
  UCHAR ReportId;
  UCHAR ControlCode;
  BYTE buttons;
  CHAR X;
  CHAR Y;
} HIDMINI_CONTROL_INFO, * PHIDMINI_CONTROL_INFO;

  • ReportID: is always 1, whether sending data or resetting the driver. Just leave it as 1.
  • CommandCode: This is 1 if resetting the driver, 2 if sending data.
  • buttons: Left, middle and right mouse buttons are encoded in this byte. Left button down = 1. Right button down adds 2. Left button down adds 4. This is basically or’ing the rightmost three bits of the byte to indicate button state. Releasing a button is done by clearing the bit to zero and sending the report to the driver again. The hid spec supports only three buttons, but obviously most mice have more than that. Usually those mice will require some additional software/driver from the mouse manufacturer to recognize those buttons. We’re not sure how these are sent exactly.
    • 00000000 = no buttons pressed.
    • 00000001 = only left button pressed.
    • 00000010 = only right button pressed.
    • 00000100 = only middle button pressed.
    • 00000110 = only right and middle buttons pressed.
    • 00000101 = only left and middle buttons pressed.
    • 00000111 = all buttons pressed.
    • 00000010 and then wait x ms and then 00000000 = to right-click and then release the button. x is a delay, try at least 50ms. That is the time the button remains pressed.
  • X: The mouse relative X position from -127 to 127.
  • Y: The mouse relative Y position from -127 to 127.

Handling Stuck Mouse Buttons

As an example, normally a right-mouse-click is 00000010 and then wait x ms then 00000000. It is possible that you may have forgotten, or due to your app crashing, that a button remains pressed. There are three ways to unstuck a button.

  1. Send a Reset command to the mouse driver. This will release all mouse buttons.
  2. Physically press and release the button on a real physical mouse. That should clear it.
  3. Reboot.

Resetting the Driver

To reset the driver, send the report with a CommandCode = 1. The X and Z values are ignored, so Z and Y to any value you like. Internally, the driver will release the buttons and set X = 0 and Y = 0. Alternatively, , you can send a report with CommandCode = 1, buttons = 0, X and Y = 0. It’s up to you whether to use the reset function, but it isn’t critical for the mouse driver.

Your First Hello-Driver App – a Suggestion

  1. Iterate through the drivers and find and connect to the mouse driver.
  2. Send data with a command code of 2, buttons = 0, X = 10, Y = 10.
  3. Run your code. If it works, you’ll see the mouse cursor move a little to the lower-right.