Skip to content

Commit

Permalink
windows: add AddDllDirectory and RemoveDllDirectory
Browse files Browse the repository at this point in the history
Per https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-adddlldirectory
and https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-removedlldirectory.

Change-Id: If44a3758720345d1bbd9af96ec2481fbe9398a08
Reviewed-on: https://go-review.googlesource.com/c/sys/+/537755
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
  • Loading branch information
rolandshoemaker authored and gopherbot committed Nov 13, 2023
1 parent e4099bf commit 11eadc0
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
2 changes: 2 additions & 0 deletions windows/syscall_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW
//sys SetDefaultDllDirectories(directoryFlags uint32) (err error)
//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory
//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory
//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW
//sys GetVersion() (ver uint32, err error)
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
Expand Down
53 changes: 53 additions & 0 deletions windows/syscall_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
Expand Down Expand Up @@ -1222,3 +1223,55 @@ func TestGetStartupInfo(t *testing.T) {
t.Fatalf("GetStartupInfo: got error %v, want nil", err)
}
}

func TestAddRemoveDllDirectory(t *testing.T) {
if _, err := exec.LookPath("gcc"); err != nil {
t.Skip("skipping test: gcc is missing")
}
dllSrc := `#include <stdint.h>
#include <windows.h>
uintptr_t beep(void) {
return 5;
}`
tmpdir := t.TempDir()
srcname := "beep.c"
err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(dllSrc), 0)
if err != nil {
t.Fatal(err)
}
name := "beep.dll"
cmd := exec.Command("gcc", "-shared", "-s", "-Werror", "-o", name, srcname)
cmd.Dir = tmpdir
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("failed to build dll: %v - %v", err, string(out))
}

if _, err := windows.LoadLibraryEx("beep.dll", 0, windows.LOAD_LIBRARY_SEARCH_USER_DIRS); err == nil {
t.Fatal("LoadLibraryEx unexpectedly found beep.dll")
}

dllCookie, err := windows.AddDllDirectory(windows.StringToUTF16Ptr(tmpdir))
if err != nil {
t.Fatalf("AddDllDirectory failed: %s", err)
}

handle, err := windows.LoadLibraryEx("beep.dll", 0, windows.LOAD_LIBRARY_SEARCH_USER_DIRS)
if err != nil {
t.Fatalf("LoadLibraryEx failed: %s", err)
}

if err := windows.FreeLibrary(handle); err != nil {
t.Fatalf("FreeLibrary failed: %s", err)
}

if err := windows.RemoveDllDirectory(dllCookie); err != nil {
t.Fatalf("RemoveDllDirectory failed: %s", err)
}

_, err = windows.LoadLibraryEx("beep.dll", 0, windows.LOAD_LIBRARY_SEARCH_USER_DIRS)
if err == nil {
t.Fatal("LoadLibraryEx unexpectedly found beep.dll")
}
}
19 changes: 19 additions & 0 deletions windows/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 11eadc0

Please sign in to comment.