From 60b3766b89b9cc664d9bbdc9ab34b283e0374d21 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 11 Nov 2020 18:51:44 +0100 Subject: [PATCH] wintun: load from filesystem by default We let people loading this from resources opt in via: go build -tags load_wintun_from_rsrc Signed-off-by: Jason A. Donenfeld --- tun/wintun/dll_fromfile_windows.go | 50 ++++++++++++++++++++++++++ tun/wintun/dll_fromrsrc_windows.go | 58 ++++++++++++++++++++++++++++++ tun/wintun/dll_windows.go | 40 +-------------------- 3 files changed, 109 insertions(+), 39 deletions(-) create mode 100644 tun/wintun/dll_fromfile_windows.go create mode 100644 tun/wintun/dll_fromrsrc_windows.go diff --git a/tun/wintun/dll_fromfile_windows.go b/tun/wintun/dll_fromfile_windows.go new file mode 100644 index 0000000..525812b --- /dev/null +++ b/tun/wintun/dll_fromfile_windows.go @@ -0,0 +1,50 @@ +// +build !load_wintun_from_rsrc + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package wintun + +import ( + "fmt" + "sync" + "sync/atomic" + "unsafe" + + "golang.org/x/sys/windows" +) + +type lazyDLL struct { + Name string + mu sync.Mutex + module windows.Handle +} + +func (d *lazyDLL) Load() error { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.module))) != nil { + return nil + } + d.mu.Lock() + defer d.mu.Unlock() + if d.module != 0 { + return nil + } + + const ( + LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200 + LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ) + module, err := windows.LoadLibraryEx(d.Name, 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_SYSTEM32) + if err != nil { + return fmt.Errorf("Unable to load library: %w", err) + } + + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.module)), unsafe.Pointer(module)) + return nil +} + +func (p *lazyProc) nameToAddr() (uintptr, error) { + return windows.GetProcAddress(p.dll.module, p.Name) +} diff --git a/tun/wintun/dll_fromrsrc_windows.go b/tun/wintun/dll_fromrsrc_windows.go new file mode 100644 index 0000000..e6e393f --- /dev/null +++ b/tun/wintun/dll_fromrsrc_windows.go @@ -0,0 +1,58 @@ +// +build load_wintun_from_rsrc + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package wintun + +import ( + "fmt" + "sync" + "sync/atomic" + "unsafe" + + "golang.org/x/sys/windows" + + "golang.zx2c4.com/wireguard/tun/wintun/memmod" + "golang.zx2c4.com/wireguard/tun/wintun/resource" +) + +type lazyDLL struct { + Name string + mu sync.Mutex + module *memmod.Module +} + +func (d *lazyDLL) Load() error { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.module))) != nil { + return nil + } + d.mu.Lock() + defer d.mu.Unlock() + if d.module != nil { + return nil + } + + const ourModule windows.Handle = 0 + resInfo, err := resource.FindByName(ourModule, d.Name, resource.RT_RCDATA) + if err != nil { + return fmt.Errorf("Unable to find \"%v\" RCDATA resource: %w", d.Name, err) + } + data, err := resource.Load(ourModule, resInfo) + if err != nil { + return fmt.Errorf("Unable to load resource: %w", err) + } + module, err := memmod.LoadLibrary(data) + if err != nil { + return fmt.Errorf("Unable to load library: %w", err) + } + + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.module)), unsafe.Pointer(module)) + return nil +} + +func (p *lazyProc) nameToAddr() (uintptr, error) { + return p.dll.module.ProcAddressByName(p.Name) +} diff --git a/tun/wintun/dll_windows.go b/tun/wintun/dll_windows.go index 4a55e97..9f04f73 100644 --- a/tun/wintun/dll_windows.go +++ b/tun/wintun/dll_windows.go @@ -10,50 +10,12 @@ import ( "sync" "sync/atomic" "unsafe" - - "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/tun/wintun/memmod" - "golang.zx2c4.com/wireguard/tun/wintun/resource" ) -type lazyDLL struct { - Name string - mu sync.Mutex - module *memmod.Module -} - func newLazyDLL(name string) *lazyDLL { return &lazyDLL{Name: name} } -func (d *lazyDLL) Load() error { - if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.module))) != nil { - return nil - } - d.mu.Lock() - defer d.mu.Unlock() - if d.module != nil { - return nil - } - - const ourModule windows.Handle = 0 - resInfo, err := resource.FindByName(ourModule, d.Name, resource.RT_RCDATA) - if err != nil { - return fmt.Errorf("Unable to find \"%v\" RCDATA resource: %w", d.Name, err) - } - data, err := resource.Load(ourModule, resInfo) - if err != nil { - return fmt.Errorf("Unable to load resource: %w", err) - } - module, err := memmod.LoadLibrary(data) - if err != nil { - return fmt.Errorf("Unable to load library: %w", err) - } - - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.module)), unsafe.Pointer(module)) - return nil -} - func (d *lazyDLL) NewProc(name string) *lazyProc { return &lazyProc{dll: d, Name: name} } @@ -79,7 +41,7 @@ func (p *lazyProc) Find() error { if err != nil { return fmt.Errorf("Error loading %v DLL: %w", p.dll.Name, err) } - addr, err := p.dll.module.ProcAddressByName(p.Name) + addr, err := p.nameToAddr() if err != nil { return fmt.Errorf("Error getting %v address: %w", p.Name, err) }