windows/registry: lock OS thread while enumerating keys

CL 361154 updated the standard syscall package to document that
successive calls to syscall.RegEnumKeyEx must occur on the same OS
thread (after that requirement was empirically discovered in
golang/go#49320).

This use in x/sys needs to be updated to comply with the
newly-discovered requirement.

Fixes golang/go#49466.

Change-Id: Idc45d91f175e1db25c215213fcaa45982c2f5e6e
Reviewed-on: https://go-review.googlesource.com/c/sys/+/362576
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/windows/registry/key.go b/windows/registry/key.go
index c256483..906325e 100644
--- a/windows/registry/key.go
+++ b/windows/registry/key.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
 // +build windows
 
 // Package registry provides access to the Windows registry.
@@ -24,6 +25,7 @@
 
 import (
 	"io"
+	"runtime"
 	"syscall"
 	"time"
 )
@@ -113,6 +115,13 @@
 // The parameter n controls the number of returned names,
 // analogous to the way os.File.Readdirnames works.
 func (k Key) ReadSubKeyNames(n int) ([]string, error) {
+	// RegEnumKeyEx must be called repeatedly and to completion.
+	// During this time, this goroutine cannot migrate away from
+	// its current thread. See https://golang.org/issue/49320 and
+	// https://golang.org/issue/49466.
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
 	names := make([]string, 0)
 	// Registry key size limit is 255 bytes and described there:
 	// https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx