mirror of
https://github.com/golang/sys.git
synced 2026-02-08 03:36:03 +03:00
windows: add IsWow64Process2 for detecting x86 on arm
The original IsWow64Process returns false on arm, always, and so IsWow64Process2 was added to account for this scenario. This isn't available on older versions of Windows, so we mark it as such using the new '?' notation. Finally, we add a test to make sure this all works and does the expected thing on different versions of Windows. Change-Id: Ic0412578cfb3f4cf6c9dc92a0028abc579bf6c85 Reviewed-on: https://go-review.googlesource.com/c/sys/+/269077 Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Trust: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
@@ -174,6 +174,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
||||
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
|
||||
//sys ExitProcess(exitcode uint32)
|
||||
//sys IsWow64Process(handle Handle, isWow64 *bool) (err error) = IsWow64Process
|
||||
//sys IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) = IsWow64Process2?
|
||||
//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
|
||||
//sys ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
|
||||
//sys WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package windows_test
|
||||
|
||||
import (
|
||||
"debug/pe"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -458,3 +460,29 @@ func TestJobObjectInfo(t *testing.T) {
|
||||
t.Errorf("ProcessMemoryLimit is wrong: want %v have %v", wantMemLimit, have)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsWow64Process2(t *testing.T) {
|
||||
var processMachine, nativeMachine uint16
|
||||
err := windows.IsWow64Process2(windows.CurrentProcess(), &processMachine, &nativeMachine)
|
||||
if errors.Is(err, windows.ERROR_PROC_NOT_FOUND) {
|
||||
maj, min, build := windows.RtlGetNtVersionNumbers()
|
||||
if maj < 10 || (maj == 10 && min == 0 && build < 17763) {
|
||||
t.Skip("not available on older versions of Windows")
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("IsWow64Process2 failed: %v", err)
|
||||
}
|
||||
if processMachine == pe.IMAGE_FILE_MACHINE_UNKNOWN {
|
||||
processMachine = nativeMachine
|
||||
}
|
||||
switch {
|
||||
case processMachine == pe.IMAGE_FILE_MACHINE_AMD64 && runtime.GOARCH == "amd64":
|
||||
case processMachine == pe.IMAGE_FILE_MACHINE_I386 && runtime.GOARCH == "386":
|
||||
case processMachine == pe.IMAGE_FILE_MACHINE_ARMNT && runtime.GOARCH == "arm":
|
||||
case processMachine == pe.IMAGE_FILE_MACHINE_ARM64 && runtime.GOARCH == "arm64":
|
||||
default:
|
||||
t.Errorf("IsWow64Process2 is wrong: want %v have %v", runtime.GOARCH, processMachine)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,7 @@ var (
|
||||
procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
|
||||
procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW")
|
||||
procIsWow64Process = modkernel32.NewProc("IsWow64Process")
|
||||
procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2")
|
||||
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
|
||||
procLoadLibraryW = modkernel32.NewProc("LoadLibraryW")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
@@ -2055,6 +2056,18 @@ func IsWow64Process(handle Handle, isWow64 *bool) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) {
|
||||
err = procIsWow64Process2.Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall(procIsWow64Process2.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(libname)
|
||||
|
||||
Reference in New Issue
Block a user