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  }