Changeset 64906 in vbox
- Timestamp:
- Dec 16, 2016 1:01:20 PM (8 years ago)
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 2 edited
-
VBoxManageControlVM.cpp (modified) (2 diffs)
-
VBoxManageHelp.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp
r63567 r64906 81 81 } 82 82 83 #define KBDCHARDEF_MOD_NONE 0x00 84 #define KBDCHARDEF_MOD_SHIFT 0x01 85 86 typedef struct KBDCHARDEF 87 { 88 uint8_t u8Scancode; 89 uint8_t u8Modifiers; 90 } KBDCHARDEF; 91 92 static const KBDCHARDEF g_aASCIIChars[0x80] = 93 { 94 /* 0x00 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 95 /* 0x01 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 96 /* 0x02 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 97 /* 0x03 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 98 /* 0x04 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 99 /* 0x05 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 100 /* 0x06 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 101 /* 0x07 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 102 /* 0x08 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 103 /* 0x09 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 104 /* 0x0A ' ' */ {0x1c, KBDCHARDEF_MOD_NONE}, 105 /* 0x0B ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 106 /* 0x0C ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 107 /* 0x0D ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 108 /* 0x0E ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 109 /* 0x0F ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 110 /* 0x10 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 111 /* 0x11 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 112 /* 0x12 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 113 /* 0x13 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 114 /* 0x14 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 115 /* 0x15 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 116 /* 0x16 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 117 /* 0x17 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 118 /* 0x18 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 119 /* 0x19 ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 120 /* 0x1A ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 121 /* 0x1B ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 122 /* 0x1C ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 123 /* 0x1D ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 124 /* 0x1E ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 125 /* 0x1F ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 126 /* 0x20 ' ' */ {0x39, KBDCHARDEF_MOD_NONE}, 127 /* 0x21 '!' */ {0x02, KBDCHARDEF_MOD_NONE}, 128 /* 0x22 '"' */ {0x28, KBDCHARDEF_MOD_SHIFT}, 129 /* 0x23 '#' */ {0x04, KBDCHARDEF_MOD_SHIFT}, 130 /* 0x24 '$' */ {0x05, KBDCHARDEF_MOD_SHIFT}, 131 /* 0x25 '%' */ {0x06, KBDCHARDEF_MOD_SHIFT}, 132 /* 0x26 '&' */ {0x08, KBDCHARDEF_MOD_SHIFT}, 133 /* 0x27 ''' */ {0x28, KBDCHARDEF_MOD_NONE}, 134 /* 0x28 '(' */ {0x0a, KBDCHARDEF_MOD_SHIFT}, 135 /* 0x29 ')' */ {0x0b, KBDCHARDEF_MOD_SHIFT}, 136 /* 0x2A '*' */ {0x09, KBDCHARDEF_MOD_SHIFT}, 137 /* 0x2B '+' */ {0x0d, KBDCHARDEF_MOD_SHIFT}, 138 /* 0x2C ',' */ {0x33, KBDCHARDEF_MOD_NONE}, 139 /* 0x2D '-' */ {0x0c, KBDCHARDEF_MOD_NONE}, 140 /* 0x2E '.' */ {0x34, KBDCHARDEF_MOD_NONE}, 141 /* 0x2F '/' */ {0x35, KBDCHARDEF_MOD_NONE}, 142 /* 0x30 '0' */ {0x0b, KBDCHARDEF_MOD_NONE}, 143 /* 0x31 '1' */ {0x02, KBDCHARDEF_MOD_NONE}, 144 /* 0x32 '2' */ {0x03, KBDCHARDEF_MOD_NONE}, 145 /* 0x33 '3' */ {0x04, KBDCHARDEF_MOD_NONE}, 146 /* 0x34 '4' */ {0x05, KBDCHARDEF_MOD_NONE}, 147 /* 0x35 '5' */ {0x06, KBDCHARDEF_MOD_NONE}, 148 /* 0x36 '6' */ {0x07, KBDCHARDEF_MOD_NONE}, 149 /* 0x37 '7' */ {0x08, KBDCHARDEF_MOD_NONE}, 150 /* 0x38 '8' */ {0x09, KBDCHARDEF_MOD_NONE}, 151 /* 0x39 '9' */ {0x0a, KBDCHARDEF_MOD_NONE}, 152 /* 0x3A ':' */ {0x27, KBDCHARDEF_MOD_SHIFT}, 153 /* 0x3B ';' */ {0x27, KBDCHARDEF_MOD_NONE}, 154 /* 0x3C '<' */ {0x33, KBDCHARDEF_MOD_SHIFT}, 155 /* 0x3D '=' */ {0x0d, KBDCHARDEF_MOD_NONE}, 156 /* 0x3E '>' */ {0x34, KBDCHARDEF_MOD_SHIFT}, 157 /* 0x3F '?' */ {0x35, KBDCHARDEF_MOD_SHIFT}, 158 /* 0x40 '@' */ {0x03, KBDCHARDEF_MOD_SHIFT}, 159 /* 0x41 'A' */ {0x1e, KBDCHARDEF_MOD_SHIFT}, 160 /* 0x42 'B' */ {0x30, KBDCHARDEF_MOD_SHIFT}, 161 /* 0x43 'C' */ {0x2e, KBDCHARDEF_MOD_SHIFT}, 162 /* 0x44 'D' */ {0x20, KBDCHARDEF_MOD_SHIFT}, 163 /* 0x45 'E' */ {0x12, KBDCHARDEF_MOD_SHIFT}, 164 /* 0x46 'F' */ {0x21, KBDCHARDEF_MOD_SHIFT}, 165 /* 0x47 'G' */ {0x22, KBDCHARDEF_MOD_SHIFT}, 166 /* 0x48 'H' */ {0x23, KBDCHARDEF_MOD_SHIFT}, 167 /* 0x49 'I' */ {0x17, KBDCHARDEF_MOD_SHIFT}, 168 /* 0x4A 'J' */ {0x24, KBDCHARDEF_MOD_SHIFT}, 169 /* 0x4B 'K' */ {0x25, KBDCHARDEF_MOD_SHIFT}, 170 /* 0x4C 'L' */ {0x26, KBDCHARDEF_MOD_SHIFT}, 171 /* 0x4D 'M' */ {0x32, KBDCHARDEF_MOD_SHIFT}, 172 /* 0x4E 'N' */ {0x31, KBDCHARDEF_MOD_SHIFT}, 173 /* 0x4F 'O' */ {0x18, KBDCHARDEF_MOD_SHIFT}, 174 /* 0x50 'P' */ {0x19, KBDCHARDEF_MOD_SHIFT}, 175 /* 0x51 'Q' */ {0x10, KBDCHARDEF_MOD_SHIFT}, 176 /* 0x52 'R' */ {0x13, KBDCHARDEF_MOD_SHIFT}, 177 /* 0x53 'S' */ {0x1f, KBDCHARDEF_MOD_SHIFT}, 178 /* 0x54 'T' */ {0x14, KBDCHARDEF_MOD_SHIFT}, 179 /* 0x55 'U' */ {0x16, KBDCHARDEF_MOD_SHIFT}, 180 /* 0x56 'V' */ {0x2f, KBDCHARDEF_MOD_SHIFT}, 181 /* 0x57 'W' */ {0x11, KBDCHARDEF_MOD_SHIFT}, 182 /* 0x58 'X' */ {0x2d, KBDCHARDEF_MOD_SHIFT}, 183 /* 0x59 'Y' */ {0x15, KBDCHARDEF_MOD_SHIFT}, 184 /* 0x5A 'Z' */ {0x2c, KBDCHARDEF_MOD_SHIFT}, 185 /* 0x5B '[' */ {0x1a, KBDCHARDEF_MOD_NONE}, 186 /* 0x5C '\' */ {0x2b, KBDCHARDEF_MOD_NONE}, 187 /* 0x5D ']' */ {0x1b, KBDCHARDEF_MOD_NONE}, 188 /* 0x5E '^' */ {0x07, KBDCHARDEF_MOD_SHIFT}, 189 /* 0x5F '_' */ {0x0c, KBDCHARDEF_MOD_SHIFT}, 190 /* 0x60 '`' */ {0x28, KBDCHARDEF_MOD_NONE}, 191 /* 0x61 'a' */ {0x1e, KBDCHARDEF_MOD_NONE}, 192 /* 0x62 'b' */ {0x30, KBDCHARDEF_MOD_NONE}, 193 /* 0x63 'c' */ {0x2e, KBDCHARDEF_MOD_NONE}, 194 /* 0x64 'd' */ {0x20, KBDCHARDEF_MOD_NONE}, 195 /* 0x65 'e' */ {0x12, KBDCHARDEF_MOD_NONE}, 196 /* 0x66 'f' */ {0x21, KBDCHARDEF_MOD_NONE}, 197 /* 0x67 'g' */ {0x22, KBDCHARDEF_MOD_NONE}, 198 /* 0x68 'h' */ {0x23, KBDCHARDEF_MOD_NONE}, 199 /* 0x69 'i' */ {0x17, KBDCHARDEF_MOD_NONE}, 200 /* 0x6A 'j' */ {0x24, KBDCHARDEF_MOD_NONE}, 201 /* 0x6B 'k' */ {0x25, KBDCHARDEF_MOD_NONE}, 202 /* 0x6C 'l' */ {0x26, KBDCHARDEF_MOD_NONE}, 203 /* 0x6D 'm' */ {0x32, KBDCHARDEF_MOD_NONE}, 204 /* 0x6E 'n' */ {0x31, KBDCHARDEF_MOD_NONE}, 205 /* 0x6F 'o' */ {0x18, KBDCHARDEF_MOD_NONE}, 206 /* 0x70 'p' */ {0x19, KBDCHARDEF_MOD_NONE}, 207 /* 0x71 'q' */ {0x10, KBDCHARDEF_MOD_NONE}, 208 /* 0x72 'r' */ {0x13, KBDCHARDEF_MOD_NONE}, 209 /* 0x73 's' */ {0x1f, KBDCHARDEF_MOD_NONE}, 210 /* 0x74 't' */ {0x14, KBDCHARDEF_MOD_NONE}, 211 /* 0x75 'u' */ {0x16, KBDCHARDEF_MOD_NONE}, 212 /* 0x76 'v' */ {0x2f, KBDCHARDEF_MOD_NONE}, 213 /* 0x77 'w' */ {0x11, KBDCHARDEF_MOD_NONE}, 214 /* 0x78 'x' */ {0x2d, KBDCHARDEF_MOD_NONE}, 215 /* 0x79 'y' */ {0x15, KBDCHARDEF_MOD_NONE}, 216 /* 0x7A 'z' */ {0x2c, KBDCHARDEF_MOD_NONE}, 217 /* 0x7B '{' */ {0x1a, KBDCHARDEF_MOD_SHIFT}, 218 /* 0x7C '|' */ {0x2b, KBDCHARDEF_MOD_SHIFT}, 219 /* 0x7D '}' */ {0x1b, KBDCHARDEF_MOD_SHIFT}, 220 /* 0x7E '~' */ {0x29, KBDCHARDEF_MOD_SHIFT}, 221 /* 0x7F ' ' */ {0x00, KBDCHARDEF_MOD_NONE}, 222 }; 223 224 static HRESULT keyboardPutScancodes(IKeyboard *pKeyboard, const std::list<LONG> &llScancodes) 225 { 226 /* Send scancodes to the VM. */ 227 com::SafeArray<LONG> saScancodes(llScancodes); 228 229 #if 1 230 HRESULT rc = S_OK; 231 int i; 232 for (i = 0; i < saScancodes.size(); ++i) 233 { 234 rc = pKeyboard->PutScancode(saScancodes[i]); 235 if (FAILED(rc)) 236 { 237 RTMsgError("Failed to send a scancode"); 238 break; 239 } 240 241 RTThreadSleep(10); /* "Typing" too fast causes lost characters. */ 242 } 243 #else 244 /** @todo PutScancodes does not deliver more than 20 scancodes. */ 245 ULONG codesStored = 0; 246 HRESULT rc = pKeyboard->PutScancodes(ComSafeArrayAsInParam(saScancodes), 247 &codesStored); 248 if (SUCCEEDED(rc) && codesStored < saScancodes.size()) 249 { 250 RTMsgError("Only %d scancodes were stored", codesStored); 251 rc = E_FAIL; 252 } 253 #endif 254 255 return rc; 256 } 257 258 static void keyboardCharsToScancodes(const char *pch, size_t cchMax, std::list<LONG> &llScancodes, bool *pfShift) 259 { 260 size_t cchProcessed = 0; 261 const char *p = pch; 262 while (cchProcessed < cchMax) 263 { 264 ++cchProcessed; 265 const uint8_t c = (uint8_t)*p++; 266 if (c < RT_ELEMENTS(g_aASCIIChars)) 267 { 268 const KBDCHARDEF *d = &g_aASCIIChars[c]; 269 if (d->u8Scancode) 270 { 271 const bool fNeedShift = RT_BOOL(d->u8Modifiers & KBDCHARDEF_MOD_SHIFT); 272 if (*pfShift != fNeedShift) 273 { 274 *pfShift = fNeedShift; 275 /* Press or release the SHIFT key. */ 276 llScancodes.push_back(0x2a | (fNeedShift? 0x00: 0x80)); 277 } 278 279 llScancodes.push_back(d->u8Scancode); 280 llScancodes.push_back(d->u8Scancode | 0x80); 281 } 282 } 283 } 284 } 285 286 static HRESULT keyboardPutString(IKeyboard *pKeyboard, int argc, char **argv) 287 { 288 std::list<LONG> llScancodes; 289 bool fShift = false; 290 291 /* Convert command line string(s) to the en-us keyboard scancodes. */ 292 int i; 293 for (i = 1 + 1; i < argc; ++i) 294 { 295 if (llScancodes.size() > 0) 296 { 297 /* Insert a SPACE before the next string. */ 298 llScancodes.push_back(0x39); 299 llScancodes.push_back(0x39 | 0x80); 300 } 301 302 keyboardCharsToScancodes(argv[i], strlen(argv[i]), llScancodes, &fShift); 303 } 304 305 /* Release SHIFT if pressed. */ 306 if (fShift) 307 llScancodes.push_back(0x2a | 0x80); 308 309 return keyboardPutScancodes(pKeyboard, llScancodes); 310 } 311 312 static HRESULT keyboardPutFile(IKeyboard *pKeyboard, const char *pszFilename) 313 { 314 std::list<LONG> llScancodes; 315 bool fShift = false; 316 317 RTFILE File = NIL_RTFILE; 318 int vrc = RTFileOpen(&File, pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 319 if (RT_SUCCESS(vrc)) 320 { 321 uint64_t cbFile = 0; 322 vrc = RTFileGetSize(File, &cbFile); 323 if (RT_SUCCESS(vrc)) 324 { 325 const uint64_t cbFileMax = _64K; 326 if (cbFile <= cbFileMax) 327 { 328 const size_t cbBuffer = _4K; 329 char *pchBuf = (char *)RTMemAlloc(cbBuffer); 330 if (pchBuf) 331 { 332 size_t cbRemaining = (size_t)cbFile; 333 while (cbRemaining > 0) 334 { 335 const size_t cbToRead = cbRemaining > cbBuffer ? cbBuffer : cbRemaining; 336 337 size_t cbRead = 0; 338 vrc = RTFileRead(File, pchBuf, cbToRead, &cbRead); 339 if (RT_FAILURE(vrc) || cbRead == 0) 340 break; 341 342 keyboardCharsToScancodes(pchBuf, cbRead, llScancodes, &fShift); 343 cbRemaining -= cbRead; 344 } 345 346 RTMemFree(pchBuf); 347 } 348 else 349 RTMsgError("Out of memory allocating %d bytes", cbBuffer); 350 } 351 else 352 RTMsgError("File size %RI64 is greater than %RI64: '%s'", cbFile, cbFileMax, pszFilename); 353 } 354 else 355 RTMsgError("Cannot get size of file '%s': %Rrc", pszFilename, vrc); 356 357 RTFileClose(File); 358 } 359 else 360 RTMsgError("Cannot open file '%s': %Rrc", pszFilename, vrc); 361 362 /* Release SHIFT if pressed. */ 363 if (fShift) 364 llScancodes.push_back(0x2a | 0x80); 365 366 return keyboardPutScancodes(pKeyboard, llScancodes); 367 } 368 83 369 84 370 RTEXITCODE handleControlVM(HandlerArg *a) … … 339 625 break; 340 626 341 /* Send scancodes to the VM. */ 342 com::SafeArray<LONG> saScancodes(llScancodes); 343 ULONG codesStored = 0; 344 CHECK_ERROR_BREAK(pKeyboard, PutScancodes(ComSafeArrayAsInParam(saScancodes), 345 &codesStored)); 346 if (codesStored < saScancodes.size()) 347 { 348 RTMsgError("Only %d scancodes were stored", codesStored); 349 rc = E_FAIL; 350 break; 351 } 627 rc = keyboardPutScancodes(pKeyboard, llScancodes); 628 } 629 else if (!strcmp(a->argv[1], "keyboardputstring")) 630 { 631 ComPtr<IKeyboard> pKeyboard; 632 CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(pKeyboard.asOutParam())); 633 if (!pKeyboard) 634 { 635 RTMsgError("Guest not running"); 636 rc = E_FAIL; 637 break; 638 } 639 640 if (a->argc <= 1 + 1) 641 { 642 errorArgument("Missing argument to '%s'. Expected ASCII string(s).", a->argv[1]); 643 rc = E_FAIL; 644 break; 645 } 646 647 rc = keyboardPutString(pKeyboard, a->argc, a->argv); 648 } 649 else if (!strcmp(a->argv[1], "keyboardputfile")) 650 { 651 ComPtr<IKeyboard> pKeyboard; 652 CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(pKeyboard.asOutParam())); 653 if (!pKeyboard) 654 { 655 RTMsgError("Guest not running"); 656 rc = E_FAIL; 657 break; 658 } 659 660 if (a->argc <= 1 + 1) 661 { 662 errorArgument("Missing argument to '%s'. Expected file name.", a->argv[1]); 663 rc = E_FAIL; 664 break; 665 } 666 667 rc = keyboardPutFile(pKeyboard, a->argv[2]); 352 668 } 353 669 else if (!strncmp(a->argv[1], "setlinkstate", 12)) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
r64434 r64906 961 961 " acpipowerbutton|acpisleepbutton|\n" 962 962 " keyboardputscancode <hex> [<hex> ...]|\n" 963 " keyboardputstring <string1> [<string2> ...]|\n" 964 " keyboardputfile <filename>|\n" 963 965 " setlinkstate<1-N> on|off |\n" 964 966 #if defined(VBOX_WITH_NETFLT)
Note:
See TracChangeset
for help on using the changeset viewer.

