1
2
3
4
5 package oshi.hardware.platform.windows;
6
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12
13 import com.sun.jna.platform.win32.Advapi32Util;
14 import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiResult;
15 import com.sun.jna.platform.win32.VersionHelpers;
16 import com.sun.jna.platform.win32.Win32Exception;
17 import com.sun.jna.platform.win32.WinError;
18 import com.sun.jna.platform.win32.WinReg;
19
20 import oshi.annotation.concurrent.Immutable;
21 import oshi.driver.windows.wmi.Win32VideoController;
22 import oshi.driver.windows.wmi.Win32VideoController.VideoControllerProperty;
23 import oshi.hardware.GraphicsCard;
24 import oshi.hardware.common.AbstractGraphicsCard;
25 import oshi.util.Constants;
26 import oshi.util.ParseUtil;
27 import oshi.util.Util;
28 import oshi.util.platform.windows.WmiUtil;
29 import oshi.util.tuples.Triplet;
30
31
32
33
34 @Immutable
35 final class WindowsGraphicsCard extends AbstractGraphicsCard {
36
37 private static final Logger LOG = LoggerFactory.getLogger(WindowsGraphicsCard.class);
38
39 private static final boolean IS_VISTA_OR_GREATER = VersionHelpers.IsWindowsVistaOrGreater();
40 public static final String ADAPTER_STRING = "HardwareInformation.AdapterString";
41 public static final String DRIVER_DESC = "DriverDesc";
42 public static final String DRIVER_VERSION = "DriverVersion";
43 public static final String VENDOR = "ProviderName";
44 public static final String QW_MEMORY_SIZE = "HardwareInformation.qwMemorySize";
45 public static final String MEMORY_SIZE = "HardwareInformation.MemorySize";
46 public static final String DISPLAY_DEVICES_REGISTRY_PATH =
47 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\";
48
49
50
51
52
53
54
55
56
57
58 WindowsGraphicsCard(String name, String deviceId, String vendor, String versionInfo, long vram) {
59 super(name, deviceId, vendor, versionInfo, vram);
60 }
61
62
63
64
65
66
67 public static List<GraphicsCard> getGraphicsCards() {
68 List<GraphicsCard> cardList = new ArrayList<>();
69
70 int index = 1;
71 String[] keys = Advapi32Util.registryGetKeys(WinReg.HKEY_LOCAL_MACHINE, DISPLAY_DEVICES_REGISTRY_PATH);
72 for (String key : keys) {
73 if (!key.startsWith("0")) {
74 continue;
75 }
76
77 try {
78 String fullKey = DISPLAY_DEVICES_REGISTRY_PATH + key;
79 if (!Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, fullKey, ADAPTER_STRING)) {
80 continue;
81 }
82
83 String name = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, fullKey, DRIVER_DESC);
84 String deviceId = "VideoController" + index++;
85 String vendor = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, fullKey, VENDOR);
86 String versionInfo = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, fullKey, DRIVER_VERSION);
87 long vram = 0L;
88
89 if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, fullKey, QW_MEMORY_SIZE)) {
90 vram = Advapi32Util.registryGetLongValue(WinReg.HKEY_LOCAL_MACHINE, fullKey, QW_MEMORY_SIZE);
91 } else if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, fullKey, MEMORY_SIZE)) {
92 Object genericValue = Advapi32Util.registryGetValue(WinReg.HKEY_LOCAL_MACHINE, fullKey, MEMORY_SIZE);
93 if (genericValue instanceof Long) {
94 vram = (long) genericValue;
95 } else if (genericValue instanceof Integer) {
96 vram = Integer.toUnsignedLong((int) genericValue);
97 } else if (genericValue instanceof byte[]) {
98 byte[] bytes = (byte[]) genericValue;
99 vram = ParseUtil.byteArrayToLong(bytes, bytes.length, false);
100 }
101 }
102
103 cardList.add(new WindowsGraphicsCard(
104 Util.isBlank(name) ? Constants.UNKNOWN : name,
105 Util.isBlank(deviceId) ? Constants.UNKNOWN : deviceId,
106 Util.isBlank(vendor) ? Constants.UNKNOWN : vendor,
107 Util.isBlank(versionInfo) ? Constants.UNKNOWN : versionInfo,
108 vram));
109 } catch (Win32Exception e) {
110 if (e.getErrorCode() != WinError.ERROR_ACCESS_DENIED) {
111
112 throw e;
113 }
114 }
115 }
116
117 if (cardList.isEmpty()) {
118 return getGraphicsCardsFromWmi();
119 }
120 return cardList;
121 }
122
123
124 private static List<GraphicsCard> getGraphicsCardsFromWmi() {
125 List<GraphicsCard> cardList = new ArrayList<>();
126 if (IS_VISTA_OR_GREATER) {
127 WmiResult<VideoControllerProperty> cards = Win32VideoController.queryVideoController();
128 for (int index = 0; index < cards.getResultCount(); index++) {
129 String name = WmiUtil.getString(cards, VideoControllerProperty.NAME, index);
130 Triplet<String, String, String> idPair = ParseUtil.parseDeviceIdToVendorProductSerial(
131 WmiUtil.getString(cards, VideoControllerProperty.PNPDEVICEID, index));
132 String deviceId = idPair == null ? Constants.UNKNOWN : idPair.getB();
133 String vendor = WmiUtil.getString(cards, VideoControllerProperty.ADAPTERCOMPATIBILITY, index);
134 if (idPair != null) {
135 if (Util.isBlank(vendor)) {
136 deviceId = idPair.getA();
137 } else {
138 vendor = vendor + " (" + idPair.getA() + ")";
139 }
140 }
141 String versionInfo = WmiUtil.getString(cards, VideoControllerProperty.DRIVERVERSION, index);
142 if (!Util.isBlank(versionInfo)) {
143 versionInfo = "DriverVersion=" + versionInfo;
144 } else {
145 versionInfo = Constants.UNKNOWN;
146 }
147 long vram = WmiUtil.getUint32asLong(cards, VideoControllerProperty.ADAPTERRAM, index);
148 cardList.add(new WindowsGraphicsCard(Util.isBlank(name) ? Constants.UNKNOWN : name, deviceId,
149 Util.isBlank(vendor) ? Constants.UNKNOWN : vendor, versionInfo, vram));
150 }
151 }
152 return cardList;
153 }
154 }