From fdc6ac631acdbfc18fb82e29cf0a98c9d945f364 Mon Sep 17 00:00:00 2001 From: Andrew Pennebaker Date: Mon, 19 Mar 2018 16:25:09 -0500 Subject: [PATCH] fix vbox scancodes and support critical key combinations during boot-time operations --- .../common/step_type_boot_command.go | 98 ++++++++++++++++--- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index fc8ee5c7322..be9397e7650 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "regexp" "strings" "time" "unicode" @@ -120,7 +121,7 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} func scancodes(message string) []string { - // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + // Scancodes reference: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html // // Scancodes represent raw keyboard output and are fed to the VM by the // VBoxManage controlvm keyboardputscancode program. @@ -130,7 +131,7 @@ func scancodes(message string) []string { // derived from the first by the addition of 0x80. special := make(map[string][]string) special[""] = []string{"0e", "8e"} - special[""] = []string{"53", "d3"} + special[""] = []string{"e053", "e0d3"} special[""] = []string{"1c", "9c"} special[""] = []string{"01", "81"} special[""] = []string{"3b", "bb"} @@ -143,24 +144,28 @@ func scancodes(message string) []string { special[""] = []string{"42", "c2"} special[""] = []string{"43", "c3"} special[""] = []string{"44", "c4"} + special[""] = []string{"57", "d7"} + special[""] = []string{"58", "d8"} special[""] = []string{"1c", "9c"} special[""] = []string{"0f", "8f"} - special[""] = []string{"48", "c8"} - special[""] = []string{"50", "d0"} - special[""] = []string{"4b", "cb"} - special[""] = []string{"4d", "cd"} + special[""] = []string{"e048", "e0c8"} + special[""] = []string{"e050", "e0d0"} + special[""] = []string{"e04b", "e0cb"} + special[""] = []string{"e04d", "e0cd"} special[""] = []string{"39", "b9"} - special[""] = []string{"52", "d2"} - special[""] = []string{"47", "c7"} - special[""] = []string{"4f", "cf"} - special[""] = []string{"49", "c9"} - special[""] = []string{"51", "d1"} + special[""] = []string{"e052", "e0d2"} + special[""] = []string{"e047", "e0c7"} + special[""] = []string{"e04f", "e0cf"} + special[""] = []string{"e049", "e0c9"} + special[""] = []string{"e051", "e0d1"} special[""] = []string{"38", "b8"} special[""] = []string{"1d", "9d"} special[""] = []string{"2a", "aa"} special[""] = []string{"e038", "e0b8"} special[""] = []string{"e01d", "e09d"} special[""] = []string{"36", "b6"} + special[""] = []string{"e05b", "e0db"} + special[""] = []string{"e05c", "e0dc"} shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" @@ -186,10 +191,51 @@ func scancodes(message string) []string { } } + azOnRegex := regexp.MustCompile("^<(?P[a-zA-Z])On>") + azOffRegex := regexp.MustCompile("^<(?P[a-zA-Z])Off>") + result := make([]string, 0, len(message)*2) for len(message) > 0 { var scancode []string + if azOnRegex.MatchString(message) { + m := azOnRegex.FindStringSubmatch(message) + r, _ := utf8.DecodeRuneInString(m[1]) + message = message[len(""):] + scancodeInt := scancodeMap[r] + keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) + + if keyShift { + scancode = append(scancode, "2a") + } + + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + + log.Printf("Sending char '%c', code '%v', shift %v", r, scancodeInt, keyShift) + } + + if azOffRegex.MatchString(message) { + m := azOffRegex.FindStringSubmatch(message) + r, _ := utf8.DecodeRuneInString(m[1]) + message = message[len(""):] + scancodeInt := scancodeMap[r] + 0x80 + keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) + + if keyShift { + scancode = append(scancode, "aa") + } + + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + + log.Printf("Sending char '%c', code '%v', shift %v", r, scancodeInt, keyShift) + } + + if strings.HasPrefix(message, "") { + scancode = append(scancode, "58") + message = message[len(""):] + log.Printf("Special code '', replacing with: 58") + } + if strings.HasPrefix(message, "") { scancode = append(scancode, "38") message = message[len(""):] @@ -208,6 +254,18 @@ func scancodes(message string) []string { log.Printf("Special code '' found, replacing with: 2a") } + if strings.HasPrefix(message, "") { + scancode = append(scancode, "e05b") + message = message[len(""):] + log.Printf("Special code '' found, replacing with: e05b") + } + + if strings.HasPrefix(message, "") { + scancode = append(scancode, "d8") + message = message[len(""):] + log.Printf("Special code '' found, replacing with: d8") + } + if strings.HasPrefix(message, "") { scancode = append(scancode, "b8") message = message[len(""):] @@ -226,6 +284,12 @@ func scancodes(message string) []string { log.Printf("Special code '' found, replacing with: aa") } + if strings.HasPrefix(message, "") { + scancode = append(scancode, "e0db") + message = message[len(""):] + log.Printf("Special code '' found, replacing with: e0db") + } + if strings.HasPrefix(message, "") { scancode = append(scancode, "e038") message = message[len(""):] @@ -244,6 +308,12 @@ func scancodes(message string) []string { log.Printf("Special code '' found, replacing with: 36") } + if strings.HasPrefix(message, "") { + scancode = append(scancode, "e05c") + message = message[len(""):] + log.Printf("Special code '' found, replacing with: e05c") + } + if strings.HasPrefix(message, "") { scancode = append(scancode, "e0b8") message = message[len(""):] @@ -262,6 +332,12 @@ func scancodes(message string) []string { log.Printf("Special code '' found, replacing with: b6") } + if strings.HasPrefix(message, "") { + scancode = append(scancode, "e0dc") + message = message[len(""):] + log.Printf("Special code '' found, replacing with: e0dc") + } + if strings.HasPrefix(message, "") { log.Printf("Special code found, will sleep 1 second at this point.") scancode = append(scancode, "wait")