-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
query_setupapi_windows.go
108 lines (97 loc) · 2.51 KB
/
query_setupapi_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//+build windows
package edid
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
var (
setupapi = windows.NewLazySystemDLL("setupapi.dll")
procSetupDiGetClassDevsW = setupapi.NewProc("SetupDiGetClassDevsW")
procSetupDiDestroyDeviceInfoList = setupapi.NewProc("SetupDiDestroyDeviceInfoList")
procSetupDiEnumDeviceInfo = setupapi.NewProc("SetupDiEnumDeviceInfo")
procSetupDiOpenDevRegKey = setupapi.NewProc("SetupDiOpenDevRegKey")
// GUID_DEVINTERFACE_MONITOR
guidDevInterfaceMonitor = &windows.GUID{0xE6F07B5F, 0xEE97, 0x4A90, [8]byte{0xB0, 0x76, 0x33, 0xF5, 0x7B, 0xF4, 0xEA, 0xA7}}
)
// SP_DEVINFO_DATA
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/ns-setupapi-sp_devinfo_data
type devInfoData struct {
cbSize uint32
classGUID windows.GUID
devInst uint32
reserved uint
}
func queryEDIDSetupAPI() ([]*EDID, error) {
const (
DIGCF_PRESENT uintptr = 0x00000002
DIGCF_DEVICEINTERFACE uintptr = 0x00000010
KEY_READ uintptr = 0x00020019
DICS_FLAG_GLOBAL uintptr = 0x00000001
DIREG_DEV uintptr = 0x00000001
)
// get device information set
// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-information-sets
dis, _, err := syscall.Syscall6(
procSetupDiGetClassDevsW.Addr(),
4,
uintptr(unsafe.Pointer(guidDevInterfaceMonitor)),
0,
0,
DIGCF_DEVICEINTERFACE|DIGCF_PRESENT,
0, 0,
)
if syscall.Handle(dis) == syscall.InvalidHandle {
if err == 0 {
err = syscall.EINVAL
}
return nil, err
}
defer syscall.Syscall(
procSetupDiDestroyDeviceInfoList.Addr(),
1,
uintptr(dis),
0, 0,
)
var ret []*EDID
for i := 0; ; i++ {
var did devInfoData
did.cbSize = uint32(unsafe.Sizeof(did))
_, _, errNo := syscall.Syscall(
procSetupDiEnumDeviceInfo.Addr(),
3,
uintptr(dis),
uintptr(i),
uintptr(unsafe.Pointer(&did)),
)
if errNo != 0 {
break
}
r1, _, _ := syscall.Syscall6(
procSetupDiOpenDevRegKey.Addr(),
6,
dis,
uintptr(unsafe.Pointer(&did)),
DICS_FLAG_GLOBAL, // scope: global configuration information
0, // profile: current hardware profile
DIREG_DEV, // key type: hardware key
KEY_READ, // sam desired
)
if syscall.Handle(r1) == syscall.InvalidHandle {
continue
}
key := registry.Key(r1)
edid, _, err := key.GetBinaryValue(`EDID`)
if err == nil {
ret = append(
ret,
&EDID{
data: edid,
Querier: `setupapi`,
},
)
}
}
return ret, nil
}