diff --git a/lib/graphics.js b/lib/graphics.js index cb9e322..b1ee766 100644 --- a/lib/graphics.js +++ b/lib/graphics.js @@ -488,8 +488,6 @@ function graphics(callback) { return controller; } - - function parseLinesLinuxEdid(edid) { // parsen EDID // --> model @@ -775,6 +773,7 @@ function graphics(callback) { try { const workload = []; workload.push(util.wmic('path win32_VideoController get /value')); + workload.push(util.powerShell('gp "HKLM:\\SYSTEM\\ControlSet001\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\*" -ErrorAction SilentlyContinue | where MatchingDeviceId $null -NE | select MatchingDeviceId,HardwareInformation.qwMemorySize | fl')); workload.push(util.wmic('path win32_desktopmonitor get /value')); workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorBasicDisplayParams | fl')); workload.push(util.powerShell('Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Screen]::AllScreens')); @@ -786,10 +785,10 @@ function graphics(callback) { Promise.all( workload ).then(data => { - // controller + // controller + vram let csections = data[0].split(/\n\s*\n/); - result.controllers = parseLinesWindowsControllers(csections); - // needs to be rewritten ... using no spread operators + let vsections = data[1].split(/\n\s*\n/); + result.controllers = parseLinesWindowsControllers(csections, vsections); result.controllers = result.controllers.map((controller) => { // match by subDeviceId if (controller.vendor.toLowerCase() === 'nvidia') { return mergeControllerNvidia(controller, nvidiaData.find(device => { @@ -812,26 +811,27 @@ function graphics(callback) { return controller; } }); + // displays - let dsections = data[1].split(/\n\s*\n/); + let dsections = data[2].split(/\n\s*\n/); // result.displays = parseLinesWindowsDisplays(dsections); dsections.shift(); dsections.pop(); // monitor (powershell) - let msections = data[2].split('Active '); + let msections = data[3].split('Active '); msections.shift(); // forms.screens (powershell) - let ssections = data[3].split('BitsPerPixel '); + let ssections = data[4].split('BitsPerPixel '); ssections.shift(); // connection params (powershell) - video type - let tsections = data[4].split(/\n\s*\n/); + let tsections = data[5].split(/\n\s*\n/); tsections.shift(); // monitor ID (powershell) - model / vendor - const res = data[5].split(/\r\n/); + const res = data[6].split(/\r\n/); let isections = []; res.forEach(element => { const parts = element.split('|'); @@ -887,26 +887,85 @@ function graphics(callback) { }); }); - function parseLinesWindowsControllers(sections) { + function parseLinesWindowsControllers(sections, vections) { + const memorySizes = {}; + for (const i in vections) { + if ({}.hasOwnProperty.call(vections, i)) { + if (vections[i].trim() !== '') { + const lines = vections[i].trim().split(os.EOL); + const matchingDeviceId = util.getValue(lines, 'MatchingDeviceId').match(/PCI\\(VEN_[0-9A-F]{4})&(DEV_[0-9A-F]{4})(?:&(SUBSYS_[0-9A-F]{8}))?(?:&(REV_[0-9A-F]{2}))?/i); + if (matchingDeviceId) { + const quadWordmemorySize = parseInt(util.getValue(lines, 'HardwareInformation.qwMemorySize')); + if (!isNaN(quadWordmemorySize)) { + let deviceId = matchingDeviceId[1].toUpperCase() + '&' + matchingDeviceId[2].toUpperCase(); + if (matchingDeviceId[3]) { + deviceId += '&' + matchingDeviceId[3].toUpperCase(); + } + if (matchingDeviceId[4]) { + deviceId += '&' + matchingDeviceId[4].toUpperCase(); + } + memorySizes[deviceId] = quadWordmemorySize; + } + } + } + } + } + let controllers = []; for (let i in sections) { if ({}.hasOwnProperty.call(sections, i)) { if (sections[i].trim() !== '') { - let lines = sections[i].trim().split('\r\n'); - let pnpDeviceId = util.getValue(lines, 'PNPDeviceID', '=').match(/SUBSYS_[a-fA-F\d]{8}/); + let pnpDeviceId = util.getValue(lines, 'PNPDeviceID', '=').match(/PCI\\(VEN_[0-9A-F]{4})&(DEV_[0-9A-F]{4})(?:&(SUBSYS_[0-9A-F]{8}))?(?:&(REV_[0-9A-F]{2}))?/i); let subDeviceId = null; + let memorySize = null; if (pnpDeviceId) { - subDeviceId = pnpDeviceId[0]; + subDeviceId = pnpDeviceId[3]; if (subDeviceId) { subDeviceId = subDeviceId.split('_')[1]; } + + // Match PCI device identifier (there's an order of increasing generality): + // https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-pci-devices + + // PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4)&REV_r(2) + if (memorySize == null && pnpDeviceId[3] && pnpDeviceId[4]) { + const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase() + '&' + pnpDeviceId[3].toUpperCase() + '&' + pnpDeviceId[4].toUpperCase(); + if ({}.hasOwnProperty.call(memorySizes, deviceId)) { + memorySize = memorySizes[deviceId] + } + } + + // PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4) + if (memorySize == null && pnpDeviceId[3]) { + const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase() + '&' + pnpDeviceId[3].toUpperCase(); + if ({}.hasOwnProperty.call(memorySizes, deviceId)) { + memorySize = memorySizes[deviceId] + } + } + + // PCI\VEN_v(4)&DEV_d(4)&REV_r(2) + if (memorySize == null && pnpDeviceId[4]) { + const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase() + '&' + pnpDeviceId[4].toUpperCase(); + if ({}.hasOwnProperty.call(memorySizes, deviceId)) { + memorySize = memorySizes[deviceId] + } + } + + // PCI\VEN_v(4)&DEV_d(4) + if (memorySize == null) { + const deviceId = pnpDeviceId[1].toUpperCase() + '&' + pnpDeviceId[2].toUpperCase(); + if ({}.hasOwnProperty.call(memorySizes, deviceId)) { + memorySize = memorySizes[deviceId] + } + } } + controllers.push({ vendor: util.getValue(lines, 'AdapterCompatibility', '='), model: util.getValue(lines, 'name', '='), bus: util.getValue(lines, 'PNPDeviceID', '=').startsWith('PCI') ? 'PCI' : '', - vram: util.toInt(util.getValue(lines, 'AdapterRAM', '=')) / 1024 / 1024, + vram: (memorySize == null ? util.toInt(util.getValue(lines, 'AdapterRAM', '=')) : memorySize) / 1024 / 1024, vramDynamic: (util.getValue(lines, 'VideoMemoryType', '=') === '2'), subDeviceId });