diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 008ffc11..3b6c5ae7 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -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) diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index 2f1513f3..cb03e1d5 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -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) + } +} diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index d400c351..cc5d74f5 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -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)