Commit 8dbc5d05 authored by Hilko Bengen's avatar Hilko Bengen Committed by Alex Brainman

windows: add GetProcAddressByOrdinal

The current GetProcAddress implementation only resolves functions in
DLLs by name. Add GetProcAddressByOrdinal that allows resolving
functions by ordinal number, using the same GetProcAddress call from
kernel32.dll in the background.

This is particularly useful for some functions (e.g. IsOS from
shlwapi.dll in some older versions of Windows) that cannot be found by
name.

Fixes golang/go#16507

Change-Id: Ib5fba7568c365a0aa2491c1261876b3a3929ec3d
Reviewed-on: https://go-review.googlesource.com/70690Reviewed-by: 's avatarAlex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 68600074
......@@ -7,6 +7,7 @@
package windows_test
import (
"syscall"
"testing"
"golang.org/x/sys/windows"
......@@ -31,3 +32,22 @@ func TestEnv(t *testing.T) {
// make sure TESTENV gets set to "", not deleted
testSetGetenv(t, "TESTENV", "")
}
func TestGetProcAddressByOrdinal(t *testing.T) {
// Attempt calling shlwapi.dll:IsOS, resolving it by ordinal, as
// suggested in
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb773795.aspx
h, err := windows.LoadLibrary("shlwapi.dll")
if err != nil {
t.Fatalf("Failed to load shlwapi.dll: %s", err)
}
procIsOS, err := windows.GetProcAddressByOrdinal(h, 437)
if err != nil {
t.Fatalf("Could not find shlwapi.dll:IsOS by ordinal: %s", err)
}
const OS_NT = 1
r, _, _ := syscall.Syscall(procIsOS, 1, OS_NT, 0, 0)
if r == 0 {
t.Error("shlwapi.dll:IsOS(OS_NT) returned 0, expected non-zero value")
}
}
......@@ -202,6 +202,21 @@ func NewCallbackCDecl(fn interface{}) uintptr {
// syscall interface implementation for other packages
// GetProcAddressByOrdinal retrieves the address of the exported
// function from module by ordinal.
func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) {
r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0)
proc = uintptr(r0)
if proc == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func Exit(code int) { ExitProcess(uint32(code)) }
func makeInheritSa() *SecurityAttributes {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment