From f7fdbfa94af4780a91595e1c4eed76989c4c605b Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Wed, 14 Dec 2022 10:35:57 +0800 Subject: [PATCH] fix: usb tablet not function for windows 10 guest --- pkg/hostman/guestfs/fsdriver/windows.go | 13 +++--- pkg/util/stringutils2/i18n.go | 17 +++++++ pkg/util/winutils/winutils.go | 60 ++++++++++++++++++++++--- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/pkg/hostman/guestfs/fsdriver/windows.go b/pkg/hostman/guestfs/fsdriver/windows.go index 4ad0b4a2f4..abf1e590e0 100644 --- a/pkg/hostman/guestfs/fsdriver/windows.go +++ b/pkg/hostman/guestfs/fsdriver/windows.go @@ -127,9 +127,9 @@ func (w *SWindowsRootFs) GetLoginAccount(rootFs IDiskPartition, sUser string, de users := tool.GetUsers() admin := "Administrator" selUsr := "" - isWin10 := w.IsWindows10() - // Win10 try not to use Administrator users - if _, ok := users[admin]; ok && windowsDefaultAdminUser && !isWin10 { + isWin10NonPro := w.IsWindows10NonPro() + // Win10 try not to use Administrator users // Win 10 professional can use Adminsitrator + if _, ok := users[admin]; ok && windowsDefaultAdminUser && !isWin10NonPro { selUsr = admin } else { // Looking for an unlocked user who is not an Administrator @@ -169,9 +169,9 @@ func (w *SWindowsRootFs) GetArch(hostCpuArch string) string { } } -func (w *SWindowsRootFs) IsWindows10() bool { +func (w *SWindowsRootFs) IsWindows10NonPro() bool { info := w.GetReleaseInfo(nil) - if info != nil && strings.HasPrefix(info.Distro, "Windows 10 ") { + if info != nil && strings.HasPrefix(info.Distro, "Windows 10 ") && !strings.HasPrefix(info.Distro, "Windows 10 Pro") { return true } return false @@ -346,7 +346,7 @@ func (w *SWindowsRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []* lines = append(lines, ` )`) lines = append(lines, `)`) lines = append(lines, w.MakeGuestDebugCmd("netcfg step 2")) - lines = append(lines, `netsh advfirewall firewall set rule group=\"remote desktop\" new enable=yes`) + // lines = append(lines, `netsh advfirewall firewall set rule group=\"remote desktop\" new enable=yes`) netScript := strings.Join(lines, "\r\n") return w.putGuestScriptContents("/windows/netcfg.bat", netScript) } @@ -375,6 +375,7 @@ func (w *SWindowsRootFs) CommitChanges(part IDiskPartition) error { tool := winutils.NewWinRegTool(confPath) tool.CheckPath() tool.EnableRdp() + tool.ResetUSBProfile() if w.IsOldWindows() { // windows prior to windows 2003 should not try to commit changes diff --git a/pkg/util/stringutils2/i18n.go b/pkg/util/stringutils2/i18n.go index 3f709450ab..e7bb8b984c 100644 --- a/pkg/util/stringutils2/i18n.go +++ b/pkg/util/stringutils2/i18n.go @@ -14,6 +14,14 @@ package stringutils2 +import ( + "bytes" + "io/ioutil" + + "golang.org/x/text/encoding/simplifiedchinese" + "golang.org/x/text/transform" +) + func IsUtf8(str string) bool { for _, runeVal := range str { if runeVal > 0x7f { @@ -48,3 +56,12 @@ func IsPrintableAsciiString(str string) bool { } return true } + +func UTF82GB18030(s []byte) ([]byte, error) { + reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GB18030.NewEncoder()) + d, e := ioutil.ReadAll(reader) + if e != nil { + return nil, e + } + return d, nil +} diff --git a/pkg/util/winutils/winutils.go b/pkg/util/winutils/winutils.go index ef202a2d0d..663db8ee76 100644 --- a/pkg/util/winutils/winutils.go +++ b/pkg/util/winutils/winutils.go @@ -21,7 +21,6 @@ import ( "io/ioutil" "path" "regexp" - "strconv" "strings" "time" @@ -370,6 +369,7 @@ func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode []int) boo case err := <-done: if err != nil { if exitStatus, ok := proc.GetExitStatus(err); ok { + log.Errorf("exit status: %d", exitStatus) if in, _ := utils.InArray(exitStatus, retcode); in { return true } @@ -384,8 +384,28 @@ func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode []int) boo } func (w *SWinRegTool) setRegistry(spath string, keySeg []string, value string) bool { - keyPath := strings.Join(keySeg, "\\") - return w.cmdRegistry(spath, []string{fmt.Sprintf("ed %s", keyPath), value}, []int{0}) + cmds := make([]string, 0) + for i := range keySeg { + if i < len(keySeg)-1 { + cmds = append(cmds, fmt.Sprintf("cd %s", keySeg[i])) + } else { + cmds = append(cmds, fmt.Sprintf("ed %s", keySeg[i])) + } + } + cmds = append(cmds, value) + return w.cmdRegistry(spath, cmds, []int{0}) +} + +func (w *SWinRegTool) delRegistry(spath string, keySeg []string) bool { + cmds := make([]string, 0) + for i := range keySeg { + if i < len(keySeg)-1 { + cmds = append(cmds, fmt.Sprintf("cd %s", keySeg[i])) + } else { + cmds = append(cmds, fmt.Sprintf("rdel %s", keySeg[i])) + } + } + return w.cmdRegistry(spath, cmds, []int{0}) } func (w *SWinRegTool) mkdir(spath string, keySeg []string) bool { @@ -511,6 +531,20 @@ func (w *SWinRegTool) SetRegistry(keyPath, value, regtype string) bool { } } +func (w *SWinRegTool) DelRegistry(keyPath string) bool { + p1, p2s := w.GetRegFile(keyPath) + if len(p1) == 0 && len(p2s) == 0 { + return false + } else { + if w.keyExists(p1, p2s) { + ret := w.delRegistry(p1, p2s) + log.Debugf("delete %s %s %v", p1, p2s, ret) + return ret + } + return false + } +} + func (w *SWinRegTool) KeyExists(keyPath string) bool { p1, p2s := w.GetRegFile(keyPath) if len(p1) == 0 && len(p2s) == 0 { @@ -531,8 +565,8 @@ func (w *SWinRegTool) MkdirP(keyPath string) bool { func (w *SWinRegTool) GetCcsKey() string { ver := w.GetRegistry(`HKLM\SYSTEM\Select\Current`) - iv, _ := strconv.ParseInt(ver, 16, 0) - return fmt.Sprintf("ControlSet%03d", iv) + log.Debugf("Current Control set %s", ver) + return fmt.Sprintf("ControlSet%s", ver[len(ver)-3:]) } func (w *SWinRegTool) GetCcsKeyPath() string { @@ -707,4 +741,20 @@ func (w *SWinRegTool) EnableRdp() { w.SetRegistry(key, "0", `REG_DWORD`) key = w.GetCcsKeyPath() + `\Services\MpsSvc\Start` w.SetRegistry(key, "3", `REG_DWORD`) + // turn off Windows Firewall completely + for _, prof := range []string{ + "StandardProfile", "PublicProfile", "DomainProfile", + } { + key = w.GetCcsKeyPath() + `\Services\SharedAccess\Parameters\FirewallPolicy\` + prof + `\EnableFirewall` + w.SetRegistry(key, "0", `REG_DWORD`) + } +} + +func (w *SWinRegTool) ResetUSBProfile() { + // https://www.kraxel.org/blog/2014/03/qemu-and-usb-tablet-cpu-consumtion/ + // reset USB registry + key := w.GetCcsKeyPath() + `\Control\usbflags` + w.DelRegistry(key) + key = w.GetCcsKeyPath() + `\Enum\USB` + w.DelRegistry(key) }