How to send a string to a virtualbox-guest-machine?
This is my code:
public void testKeyboard() throws Exception {
IVirtualBox b = connect();
List<IMachine> machines = b.getMachines();
for (IMachine m : machines) {
MachineState d = b.getMachineStates(Arrays.asList(m)).iterator().next();
if (d == MachineState.Running) {
ISession s = manager.getSessionObject();
m.lockMachine(s, LockType.Shared);
IConsole console = s.getConsole();
IKeyboard k = console.getKeyboard();
k.putScancodes(Arrays.asList(25, 25 | 0x80)); // <- sends the character P
s.unlockMachine();
}
}
}
java.awt.event.KeyEvent also say its 0x50:
/** Constant for the "P" key. */
public static final int VK_P = 0x50;
In virtualbox its different. P=25 2=0x50 b=0x30
Why in the world is the code of P = 25 in virtualbox?
Scan codes are keyboard layout dependent mappings to key layouts. You can send codes based on the scan codes for a USB keyboard, which all modern systems are likely to understand. The codes are documented in Appendix C of the Microsoft document "Keyboard Scan Code Specification". You will see there that character
Pis in position 26 in the 1-indexed table of key location. This would explain a 0-indexed code of 25 producing the characterP.You will see that "key down" needs you to send 25 as the scan code (0x19) and then 0x99 for key up. This is what your (25 | 0x80) is doing. So your code at the moment sends a message meaning "Key P has been pressed (make in the table)" followed by "Key P has been released (break in the table)"
The direct link to the doc I'm referencing here is: https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
N.B. These codes are quite different to ASCII codes, which are where you are getting the 0x50 from.
Sending strings via the keyboard
If you want to send a whole string via the keyboard this way, what you will need is a mapping table from ASCII codes for each character to key make and key break codes. You can then take the string character by character and work out which scan code pairs to send for each character. Note - you'll need to deal with case by adding a "Shift down" before the pair and "Shift up" afterwards. This is do-able with a fairly long mapping table, I'd use a
WeakHashMap