From 6aff5f38e54f06f432ddfd9b4af5bf0de052bc08 Mon Sep 17 00:00:00 2001 From: ly303550688 Date: Wed, 6 May 2020 13:54:32 +0000 Subject: [PATCH] windows: add (*DLL).FindProcByOrdinal Change-Id: I0b0ef2c62994fad4d89bf15c8c6c95fa660190c3 GitHub-Last-Rev: 379ab4a0f5a6ce8ee4b9eb234312a56e5cd07b72 GitHub-Pull-Request: golang/sys#69 Reviewed-on: https://go-review.googlesource.com/c/sys/+/227439 Run-TryBot: Alex Brainman TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman --- windows/dll_windows.go | 29 +++++++++++++++++++++++++++++ windows/syscall_test.go | 21 +++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/windows/dll_windows.go b/windows/dll_windows.go index d7771134..82076fb7 100644 --- a/windows/dll_windows.go +++ b/windows/dll_windows.go @@ -104,6 +104,35 @@ func (d *DLL) MustFindProc(name string) *Proc { return p } +// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc +// if found. It returns an error if search fails. +func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) { + a, e := GetProcAddressByOrdinal(d.Handle, ordinal) + name := "#" + itoa(int(ordinal)) + if e != nil { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), + } + } + p := &Proc{ + Dll: d, + Name: name, + addr: a, + } + return p, nil +} + +// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails. +func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc { + p, e := d.FindProcByOrdinal(ordinal) + if e != nil { + panic(e) + } + return p +} + // Release unloads DLL d from memory. func (d *DLL) Release() (err error) { return FreeLibrary(d.Handle) diff --git a/windows/syscall_test.go b/windows/syscall_test.go index 7e28834d..af3ff32d 100644 --- a/windows/syscall_test.go +++ b/windows/syscall_test.go @@ -79,3 +79,24 @@ func TestGetWindowsDirectory(t *testing.T) { t.Fatalf("System Windows directory does not end in windows: %s", d2) } } +func TestFindProcByOrdinal(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 + dll, err := windows.LoadDLL("shlwapi.dll") + if err != nil { + t.Fatalf("Failed to load shlwapi.dll: %s", err) + } + procIsOS, err := dll.FindProcByOrdinal(437) + if err != nil { + t.Fatalf("Could not find shlwapi.dll:IsOS by ordinal: %s", err) + } + if procIsOS.Name != "#437" { + t.Fatalf("Proc's name is incorrect: %s,expected #437", procIsOS.Name) + } + const OS_NT = 1 + r, _, _ := syscall.Syscall(procIsOS.Addr(), 1, OS_NT, 0, 0) + if r == 0 { + t.Error("shlwapi.dll:IsOS(OS_NT) returned 0, expected non-zero value") + } +}