Created
February 11, 2019 23:34
-
-
Save konsumer/e65020916e5c6f8a5d73d12cac24c01b to your computer and use it in GitHub Desktop.
An OSX parser for `ioreg` that will get you vendor/device ID and name of devices on PCI bus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { spawn } = require('child_process') | |
const Xml = require('xml-stream') | |
const fetch = require('node-fetch') | |
const cheerio = require('cheerio') | |
// apple returns IDs in funny order | |
const unmangleID = string => { | |
if (string) { | |
const s = string.split('').slice(0, 4) | |
return `${s[2]}${s[3]}${s[0]}${s[1]}` | |
} | |
} | |
const getDevices = () => new Promise((resolve, reject) => { | |
const plist = spawn('ioreg', ['-c', 'IOPCIDevice', '-a']) | |
const xml = new Xml(plist.stdout) | |
xml.on('error', reject) | |
const out = [] | |
xml.on('end', () => { resolve(out) }) | |
xml.preserve('dict', true) | |
xml.on('endElement: dict', item => { | |
if (item.$children) { | |
item.$children.forEach(c => { | |
if (c.$text === 'IOPCIDevice') { | |
const info = item.$children.filter(cc => cc && cc.$text && cc.$text.trim() !== '') | |
let vendor | |
let device | |
let subsystem | |
let subsystemVendor | |
info.forEach((iv, ii) => { | |
if (iv.$text === 'vendor-id') { | |
vendor = unmangleID(Buffer.from(info[ii + 1].$text, 'base64').toString('hex')) | |
} | |
if (iv.$text === 'device-id') { | |
device = unmangleID(Buffer.from(info[ii + 1].$text, 'base64').toString('hex')) | |
} | |
if (iv.$text === 'subsystem-vendor-id') { | |
subsystemVendor = unmangleID(Buffer.from(info[ii + 1].$text, 'base64').toString('hex')) | |
} | |
if (iv.$text === 'subsystem-id') { | |
subsystem = unmangleID(Buffer.from(info[ii + 1].$text, 'base64').toString('hex')) | |
} | |
}) | |
if (subsystem) { | |
out.push(`${vendor}:${device} - ${subsystemVendor} ${subsystem}`) | |
} else { | |
out.push(`${vendor}:${device}`) | |
} | |
} | |
}) | |
} | |
}) | |
}) | |
// use pci-ids.ucw.cz to lookup vendor/device IDs | |
const lookup = async () => { | |
const devices = await getDevices() | |
console.log(await Promise.all(devices.map(d => { | |
const [ vendor, device ] = d.split(' - ')[0].split(':') | |
return fetch(`https://pci-ids.ucw.cz/read/PC/${vendor}/${device}`) | |
.then(r => r.status === 200 && r.text()) | |
.then(b => b && cheerio.load(b)('.name').text().replace('Name: ', '')) | |
.then(name => { | |
if (name) { | |
return `${d} | ${name}` | |
} else { | |
return d | |
} | |
}) | |
}))) | |
} | |
lookup() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment