vendor/golang.org/x/sys/windows/dll_windows.go
author Mikael Berthe <mikael@lilotux.net>
Sat, 04 Feb 2023 12:58:35 +0100
changeset 265 05c40b36d3b2
permissions -rw-r--r--
Bump to version 3.0.0-dev, using madon v3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Copyright 2011 The Go Authors. All rights reserved.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
// Use of this source code is governed by a BSD-style
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// license that can be found in the LICENSE file.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
package windows
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
import (
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
	"sync"
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
	"sync/atomic"
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
	"syscall"
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
	"unsafe"
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
// We need to use LoadLibrary and GetProcAddress from the Go runtime, because
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
// the these symbols are loaded by the system linker and are required to
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
// dynamically load additional symbols. Note that in the Go runtime, these
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
// return syscall.Handle and syscall.Errno, but these are the same, in fact,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
// as windows.Handle and windows.Errno, and we intend to keep these the same.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
//go:linkname syscall_loadlibrary syscall.loadlibrary
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
func syscall_loadlibrary(filename *uint16) (handle Handle, err Errno)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
//go:linkname syscall_getprocaddress syscall.getprocaddress
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
func syscall_getprocaddress(handle Handle, procname *uint8) (proc uintptr, err Errno)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
// DLLError describes reasons for DLL load failures.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
type DLLError struct {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
	Err     error
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
	ObjName string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	Msg     string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
func (e *DLLError) Error() string { return e.Msg }
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
func (e *DLLError) Unwrap() error { return e.Err }
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
// A DLL implements access to a single DLL.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
type DLL struct {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
	Name   string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	Handle Handle
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
// LoadDLL loads DLL file into memory.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
// Warning: using LoadDLL without an absolute path name is subject to
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
// DLL preloading attacks. To safely load a system DLL, use LazyDLL
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
// with System set to true, or use LoadLibraryEx directly.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
func LoadDLL(name string) (dll *DLL, err error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
	namep, err := UTF16PtrFromString(name)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
	if err != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
		return nil, err
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
	h, e := syscall_loadlibrary(namep)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
	if e != 0 {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
		return nil, &DLLError{
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
			Err:     e,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
			ObjName: name,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
			Msg:     "Failed to load " + name + ": " + e.Error(),
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
		}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
	d := &DLL{
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
		Name:   name,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
		Handle: h,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
	return d, nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
// MustLoadDLL is like LoadDLL but panics if load operation failes.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
func MustLoadDLL(name string) *DLL {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
	d, e := LoadDLL(name)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
	if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
		panic(e)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
	return d
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
// FindProc searches DLL d for procedure named name and returns *Proc
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
// if found. It returns an error if search fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
func (d *DLL) FindProc(name string) (proc *Proc, err error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	namep, err := BytePtrFromString(name)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
	if err != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
		return nil, err
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	a, e := syscall_getprocaddress(d.Handle, namep)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
	if e != 0 {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
		return nil, &DLLError{
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
			Err:     e,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
			ObjName: name,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
		}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
	p := &Proc{
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
		Dll:  d,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
		Name: name,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
		addr: a,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
	return p, nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
// MustFindProc is like FindProc but panics if search fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
func (d *DLL) MustFindProc(name string) *Proc {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
	p, e := d.FindProc(name)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
		panic(e)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	return p
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
// if found. It returns an error if search fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
	a, e := GetProcAddressByOrdinal(d.Handle, ordinal)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	name := "#" + itoa(int(ordinal))
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
	if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
		return nil, &DLLError{
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
			Err:     e,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
			ObjName: name,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
		}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	p := &Proc{
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
		Dll:  d,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
		Name: name,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
		addr: a,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	return p, nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	p, e := d.FindProcByOrdinal(ordinal)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
	if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
		panic(e)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
	return p
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
// Release unloads DLL d from memory.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
func (d *DLL) Release() (err error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	return FreeLibrary(d.Handle)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
// A Proc implements access to a procedure inside a DLL.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
type Proc struct {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
	Dll  *DLL
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
	Name string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
	addr uintptr
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
// Addr returns the address of the procedure represented by p.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
// The return value can be passed to Syscall to run the procedure.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
func (p *Proc) Addr() uintptr {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
	return p.addr
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
//go:uintptrescapes
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
// are supplied.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
// The returned error is always non-nil, constructed from the result of GetLastError.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
// Callers must inspect the primary return value to decide whether an error occurred
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
// (according to the semantics of the specific function being called) before consulting
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
// the error. The error will be guaranteed to contain windows.Errno.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
	switch len(a) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
	case 0:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
		return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
	case 1:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
	case 2:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
	case 3:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
	case 4:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
	case 5:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
	case 6:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
	case 7:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
	case 8:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
	case 9:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
	case 10:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
	case 11:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
	case 12:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
	case 13:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
	case 14:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
	case 15:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
	default:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
// A LazyDLL implements access to a single DLL.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
// It will delay the load of the DLL until the first
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
// call to its Handle method or to one of its
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
// LazyProc's Addr method.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
type LazyDLL struct {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
	Name string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
	// System determines whether the DLL must be loaded from the
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
	// Windows System directory, bypassing the normal DLL search
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
	// path.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
	System bool
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
	mu  sync.Mutex
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
	dll *DLL // non nil once DLL is loaded
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
// Load loads DLL file d.Name into memory. It returns an error if fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
// Load will not try to load DLL, if it is already loaded into memory.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
func (d *LazyDLL) Load() error {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
	// Non-racy version of:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
	// if d.dll != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
		return nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
	d.mu.Lock()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
	defer d.mu.Unlock()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
	if d.dll != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
		return nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
	// kernel32.dll is special, since it's where LoadLibraryEx comes from.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
	// The kernel already special-cases its name, so it's always
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
	// loaded from system32.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
	var dll *DLL
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
	var err error
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
	if d.Name == "kernel32.dll" {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
		dll, err = LoadDLL(d.Name)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
	} else {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
		dll, err = loadLibraryEx(d.Name, d.System)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
	if err != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
		return err
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
	// Non-racy version of:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
	// d.dll = dll
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
	return nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
// mustLoad is like Load but panics if search fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
func (d *LazyDLL) mustLoad() {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
	e := d.Load()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
	if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
		panic(e)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
// Handle returns d's module handle.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
func (d *LazyDLL) Handle() uintptr {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
	d.mustLoad()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
	return uintptr(d.dll.Handle)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
func (d *LazyDLL) NewProc(name string) *LazyProc {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
	return &LazyProc{l: d, Name: name}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
// NewLazyDLL creates new LazyDLL associated with DLL file.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
func NewLazyDLL(name string) *LazyDLL {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
	return &LazyDLL{Name: name}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
// NewLazySystemDLL is like NewLazyDLL, but will only
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
// search Windows System directory for the DLL if name is
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
// a base name (like "advapi32.dll").
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
func NewLazySystemDLL(name string) *LazyDLL {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
	return &LazyDLL{Name: name, System: true}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
// A LazyProc implements access to a procedure inside a LazyDLL.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
// It delays the lookup until the Addr method is called.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
type LazyProc struct {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
	Name string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
	mu   sync.Mutex
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
	l    *LazyDLL
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
	proc *Proc
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
// Find searches DLL for procedure named p.Name. It returns
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
// an error if search fails. Find will not search procedure,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
// if it is already found and loaded into memory.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
func (p *LazyProc) Find() error {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
	// Non-racy version of:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
	// if p.proc == nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
		p.mu.Lock()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
		defer p.mu.Unlock()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
		if p.proc == nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
			e := p.l.Load()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
			if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
				return e
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
			}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
			proc, e := p.l.dll.FindProc(p.Name)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
			if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
				return e
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
			}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
			// Non-racy version of:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
			// p.proc = proc
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   315
			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   316
		}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   317
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   318
	return nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   320
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   321
// mustFind is like Find but panics if search fails.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   322
func (p *LazyProc) mustFind() {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   323
	e := p.Find()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   324
	if e != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   325
		panic(e)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   326
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
// Addr returns the address of the procedure represented by p.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
// The return value can be passed to Syscall to run the procedure.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
// It will panic if the procedure cannot be found.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
func (p *LazyProc) Addr() uintptr {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
	p.mustFind()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
	return p.proc.Addr()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
//go:uintptrescapes
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
// Call executes procedure p with arguments a. It will panic, if more than 15 arguments
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
// are supplied. It will also panic if the procedure cannot be found.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
// The returned error is always non-nil, constructed from the result of GetLastError.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
// Callers must inspect the primary return value to decide whether an error occurred
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
// (according to the semantics of the specific function being called) before consulting
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
// the error. The error will be guaranteed to contain windows.Errno.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
	p.mustFind()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
	return p.proc.Call(a...)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   351
var canDoSearchSystem32Once struct {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   352
	sync.Once
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   353
	v bool
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   354
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   355
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   356
func initCanDoSearchSystem32() {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   357
	// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says:
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   358
	// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   359
	// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
	// systems that have KB2533623 installed. To determine whether the
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
	// flags are available, use GetProcAddress to get the address of the
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
	// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
	// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_*
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
	// flags can be used with LoadLibraryEx."
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
	canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
func canDoSearchSystem32() bool {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
	canDoSearchSystem32Once.Do(initCanDoSearchSystem32)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
	return canDoSearchSystem32Once.v
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
func isBaseName(name string) bool {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
	for _, c := range name {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
		if c == ':' || c == '/' || c == '\\' {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
			return false
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
		}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
	return true
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
// loadLibraryEx wraps the Windows LoadLibraryEx function.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
// If name is not an absolute path, LoadLibraryEx searches for the DLL
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
// in a variety of automatic locations unless constrained by flags.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
func loadLibraryEx(name string, system bool) (*DLL, error) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
	loadDLL := name
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
	var flags uintptr
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
	if system {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
		if canDoSearchSystem32() {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
			flags = LOAD_LIBRARY_SEARCH_SYSTEM32
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
		} else if isBaseName(name) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
			// WindowsXP or unpatched Windows machine
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
			// trying to load "foo.dll" out of the system
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
			// folder, but LoadLibraryEx doesn't support
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
			// that yet on their system, so emulate it.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   400
			systemdir, err := GetSystemDirectory()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   401
			if err != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   402
				return nil, err
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   403
			}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   404
			loadDLL = systemdir + "\\" + name
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   405
		}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
	h, err := LoadLibraryEx(loadDLL, 0, flags)
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   408
	if err != nil {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   409
		return nil, err
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   410
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   411
	return &DLL{Name: name, Handle: h}, nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   412
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   413
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   414
type errString string
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   415
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   416
func (s errString) Error() string { return string(s) }