-
Notifications
You must be signed in to change notification settings - Fork 187
/
Copy pathgpu_windows.go
133 lines (120 loc) · 4.18 KB
/
gpu_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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.
//
package gpu
import (
"strings"
"github.com/StackExchange/wmi"
"github.com/jaypipes/pcidb"
"github.com/jaypipes/ghw/pkg/pci"
"github.com/jaypipes/ghw/pkg/util"
)
const wqlVideoController = "SELECT Caption, CreationClassName, Description, DeviceID, DriverVersion, Name, PNPDeviceID, SystemCreationClassName, SystemName, VideoArchitecture, VideoMemoryType, VideoModeDescription, VideoProcessor FROM Win32_VideoController"
type win32VideoController struct {
Caption string
CreationClassName string
Description string
DeviceID string
DriverVersion string
Name string
PNPDeviceID string
SystemCreationClassName string
SystemName string
VideoArchitecture uint16
VideoMemoryType uint16
VideoModeDescription string
VideoProcessor string
}
const wqlPnPEntity = "SELECT Caption, CreationClassName, Description, DeviceID, Manufacturer, Name, PNPClass, PNPDeviceID FROM Win32_PnPEntity"
type win32PnPEntity struct {
Caption string
CreationClassName string
Description string
DeviceID string
Manufacturer string
Name string
PNPClass string
PNPDeviceID string
}
func (i *Info) load() error {
// Getting data from WMI
var win32VideoControllerDescriptions []win32VideoController
if err := wmi.Query(wqlVideoController, &win32VideoControllerDescriptions); err != nil {
return err
}
// Building dynamic WHERE clause with addresses to create a single query collecting all desired data
queryAddresses := []string{}
for _, description := range win32VideoControllerDescriptions {
var queryAddres = strings.Replace(description.PNPDeviceID, "\\", `\\`, -1)
queryAddresses = append(queryAddresses, "PNPDeviceID='"+queryAddres+"'")
}
whereClause := strings.Join(queryAddresses[:], " OR ")
// Getting data from WMI
var win32PnPDescriptions []win32PnPEntity
var wqlPnPDevice = wqlPnPEntity + " WHERE " + whereClause
if err := wmi.Query(wqlPnPDevice, &win32PnPDescriptions); err != nil {
return err
}
// Converting into standard structures
cards := make([]*GraphicsCard, 0)
for _, description := range win32VideoControllerDescriptions {
card := &GraphicsCard{
Address: description.DeviceID, // https://stackoverflow.com/questions/32073667/how-do-i-discover-the-pcie-bus-topology-and-slot-numbers-on-the-board
Index: 0,
DeviceInfo: GetDevice(description.PNPDeviceID, win32PnPDescriptions),
}
card.DeviceInfo.Driver = description.DriverVersion
cards = append(cards, card)
}
i.GraphicsCards = cards
return nil
}
func GetDevice(id string, entities []win32PnPEntity) *pci.Device {
// Backslashing PnP address ID as requested by JSON and VMI query: https://docs.microsoft.com/en-us/windows/win32/wmisdk/where-clause
var queryAddress = strings.Replace(id, "\\", `\\`, -1)
// Preparing default structure
var device = &pci.Device{
Address: queryAddress,
Vendor: &pcidb.Vendor{
ID: util.UNKNOWN,
Name: util.UNKNOWN,
Products: []*pcidb.Product{},
},
Subsystem: &pcidb.Product{
ID: util.UNKNOWN,
Name: util.UNKNOWN,
Subsystems: []*pcidb.Product{},
},
Product: &pcidb.Product{
ID: util.UNKNOWN,
Name: util.UNKNOWN,
Subsystems: []*pcidb.Product{},
},
Class: &pcidb.Class{
ID: util.UNKNOWN,
Name: util.UNKNOWN,
Subclasses: []*pcidb.Subclass{},
},
Subclass: &pcidb.Subclass{
ID: util.UNKNOWN,
Name: util.UNKNOWN,
ProgrammingInterfaces: []*pcidb.ProgrammingInterface{},
},
ProgrammingInterface: &pcidb.ProgrammingInterface{
ID: util.UNKNOWN,
Name: util.UNKNOWN,
},
}
// If an entity is found we get its data inside the standard structure
for _, description := range entities {
if id == description.PNPDeviceID {
device.Vendor.ID = description.Manufacturer
device.Vendor.Name = description.Manufacturer
device.Product.ID = description.Name
device.Product.Name = description.Description
break
}
}
return device
}