github.com/tailscale/wireguard-go@v0.0.20201119-0.20210522003738-46b531feb08a/tun/wintun/dll_fromrsrc_windows.go (about) 1 // +build load_wintun_from_rsrc 2 3 /* SPDX-License-Identifier: MIT 4 * 5 * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. 6 */ 7 8 package wintun 9 10 import ( 11 "fmt" 12 "sync" 13 "sync/atomic" 14 "unsafe" 15 16 "golang.org/x/sys/windows" 17 18 "github.com/tailscale/wireguard-go/tun/wintun/memmod" 19 ) 20 21 type lazyDLL struct { 22 Name string 23 mu sync.Mutex 24 module *memmod.Module 25 onLoad func(d *lazyDLL) 26 } 27 28 func (d *lazyDLL) Load() error { 29 if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.module))) != nil { 30 return nil 31 } 32 d.mu.Lock() 33 defer d.mu.Unlock() 34 if d.module != nil { 35 return nil 36 } 37 38 const ourModule windows.Handle = 0 39 resInfo, err := windows.FindResource(ourModule, d.Name, windows.RT_RCDATA) 40 if err != nil { 41 return fmt.Errorf("Unable to find \"%v\" RCDATA resource: %w", d.Name, err) 42 } 43 data, err := windows.LoadResourceData(ourModule, resInfo) 44 if err != nil { 45 return fmt.Errorf("Unable to load resource: %w", err) 46 } 47 module, err := memmod.LoadLibrary(data) 48 if err != nil { 49 return fmt.Errorf("Unable to load library: %w", err) 50 } 51 52 atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.module)), unsafe.Pointer(module)) 53 if d.onLoad != nil { 54 d.onLoad(d) 55 } 56 return nil 57 } 58 59 func (p *lazyProc) nameToAddr() (uintptr, error) { 60 return p.dll.module.ProcAddressByName(p.Name) 61 }