diff --git a/lib/osinfo.js b/lib/osinfo.js index a299f31..0720e1d 100644 --- a/lib/osinfo.js +++ b/lib/osinfo.js @@ -13,11 +13,13 @@ // 3. Operating System // ---------------------------------------------------------------------------------- -const os = require('os'); +const nodeUtil = require('util'); const exec = require('child_process').exec; +const execSync = require('child_process').execSync; +const execPromise = nodeUtil.promisify(require('child_process').exec); +const os = require('os'); const util = require('./util'); const fs = require('fs'); -const { execSync } = require('child_process'); let _platform = process.platform; @@ -320,19 +322,20 @@ function osInfo(callback) { result.logofile = getLogoFile(); result.release = result.kernel; try { - util.wmic('os get /value').then((stdout) => { - let lines = stdout.toString().split('\r\n'); + const workload = []; + workload.push(util.wmic('os get /value')); + workload.push(execPromise('systeminfo')); + util.promiseAll( + workload + ).then(data => { + let lines = data.results[0].toString().split('\r\n'); result.distro = util.getValue(lines, 'Caption', '=').trim(); result.serial = util.getValue(lines, 'SerialNumber', '=').trim(); result.build = util.getValue(lines, 'BuildNumber', '=').trim(); result.servicepack = util.getValue(lines, 'ServicePackMajorVersion', '=').trim() + '.' + util.getValue(lines, 'ServicePackMinorVersion', '=').trim(); result.codepage = util.getCodepage(); - try { - const systeminfo = execSync('systeminfo').toString(); - result.hypervisor = (systeminfo.indexOf('hypervisor has been detected') !== -1) || (systeminfo.indexOf('Es wurde ein Hypervisor erkannt') !== -1) || (systeminfo.indexOf('Un hyperviseur a ') !== -1); - } catch (e) { - util.noop(); - } + const systeminfo = data.results[1].stdout.toString(); + result.hypervisor = (systeminfo.indexOf('hypervisor has been detected') !== -1) || (systeminfo.indexOf('Es wurde ein Hypervisor erkannt') !== -1) || (systeminfo.indexOf('Un hyperviseur a ') !== -1); isUefiWindows().then(uefi => { result.uefi = uefi; if (callback) { diff --git a/lib/system.js b/lib/system.js index c1f89ae..b293447 100644 --- a/lib/system.js +++ b/lib/system.js @@ -13,8 +13,10 @@ // 2. System (Hardware, BIOS, Base Board) // ---------------------------------------------------------------------------------- +const nodeUtil = require('util'); const exec = require('child_process').exec; const execSync = require('child_process').execSync; +const execPromise = nodeUtil.promisify(require('child_process').exec); const fs = require('fs'); const os = require('os'); const util = require('./util'); @@ -566,6 +568,8 @@ function baseboard(callback) { version: '', serial: '-', assetTag: '-', + memMax: null, + memSlots: null }; let cmd = ''; if (_linux || _freebsd || _openbsd || _netbsd) { @@ -575,8 +579,13 @@ function baseboard(callback) { } else { cmd = 'export LC_ALL=C; dmidecode -t 2 2>/dev/null; unset LC_ALL'; } - exec(cmd, function (error, stdout) { - let lines = stdout.toString().split('\n'); + const workload = []; + workload.push(execPromise(cmd)); + workload.push(execPromise('export LC_ALL=C; dmidecode -t memory 2>/dev/null')); + util.promiseAll( + workload + ).then(data => { + let lines = data.results[0].stdout.toString().split('\n'); result.manufacturer = util.getValue(lines, 'Manufacturer'); result.model = util.getValue(lines, 'Product Name'); result.version = util.getValue(lines, 'Version'); @@ -601,19 +610,53 @@ function baseboard(callback) { if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; } if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; } + // mem + lines = data.results[1].stdout.toString().split('\n'); + result.memMax = util.toInt(util.getValue(lines, 'Maximum Capacity')) * 1024 * 1024 * 1024 || null; + result.memSlots = util.toInt(util.getValue(lines, 'Number Of Devices')) || null; + + // raspberry + const linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n'); + const hardware = util.getValue(linesRpi, 'hardware'); + if (hardware.startsWith('BCM')) { + const rpi = util.decodePiCpuinfo(linesRpi); + result.manufacturer = rpi.manufacturer; + result.model = 'Raspberry Pi'; + result.serial = rpi.serial; + result.version = rpi.type + ' - ' + rpi.revision; + result.memMax = os.totalmem(); + result.memSlots = 0; + } + if (callback) { callback(result); } resolve(result); }); } if (_darwin) { - exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) { - if (!error) { - let lines = stdout.toString().replace(/[<>"]/g, '').split('\n'); - result.manufacturer = util.getValue(lines, 'manufacturer', '=', true); - result.model = util.getValue(lines, 'model', '=', true); - result.version = util.getValue(lines, 'version', '=', true); - result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true); - result.assetTag = util.getValue(lines, 'board-id', '=', true); + const workload = []; + workload.push(execPromise('ioreg -c IOPlatformExpertDevice -d 2')); + workload.push(execPromise('system_profiler SPMemoryDataType')); + util.promiseAll( + workload + ).then(data => { + let lines = data.results[0].stdout.toString().replace(/[<>"]/g, '').split('\n'); + result.manufacturer = util.getValue(lines, 'manufacturer', '=', true); + result.model = util.getValue(lines, 'model', '=', true); + result.version = util.getValue(lines, 'version', '=', true); + result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true); + result.assetTag = util.getValue(lines, 'board-id', '=', true); + + // mem + let devices = data.results[1].stdout.toString().split(' BANK '); + if (devices.length === 1) { + devices = data.results[1].stdout.toString().split(' DIMM'); + } + devices.shift(); + result.memSlots = devices.length; + + if (os.arch() === 'arm64') { + result.memSlots = 0; + result.memMax = os.totalmem(); } if (callback) { callback(result); } @@ -626,22 +669,30 @@ function baseboard(callback) { } if (_windows) { try { - util.wmic('baseboard get /value').then((stdout, error) => { - if (!error) { - let lines = stdout.toString().split('\r\n'); + const workload = []; + workload.push(util.wmic('baseboard get /value')); + workload.push(util.wmic('memphysical get MaxCapacity, MemoryDevices /value')); + util.promiseAll( + workload + ).then(data => { + let lines = data.results[0].toString().split('\r\n'); - result.manufacturer = util.getValue(lines, 'manufacturer', '='); - result.model = util.getValue(lines, 'model', '='); - if (!result.model) { - result.model = util.getValue(lines, 'product', '='); - } - result.version = util.getValue(lines, 'version', '='); - result.serial = util.getValue(lines, 'serialnumber', '='); - result.assetTag = util.getValue(lines, 'partnumber', '='); - if (!result.assetTag) { - result.assetTag = util.getValue(lines, 'sku', '='); - } + result.manufacturer = util.getValue(lines, 'manufacturer', '='); + result.model = util.getValue(lines, 'model', '='); + if (!result.model) { + result.model = util.getValue(lines, 'product', '='); } + result.version = util.getValue(lines, 'version', '='); + result.serial = util.getValue(lines, 'serialnumber', '='); + result.assetTag = util.getValue(lines, 'partnumber', '='); + if (!result.assetTag) { + result.assetTag = util.getValue(lines, 'sku', '='); + } + + // memphysical + lines = data.results[1].toString().split('\r\n'); + result.memMax = util.toInt(util.getValue(lines, 'MaxCapacity', '=')) || null; + result.memSlots = util.toInt(util.getValue(lines, 'MemoryDevices', '=')) || null; if (callback) { callback(result); } resolve(result); diff --git a/lib/util.js b/lib/util.js index a9a8913..11b403c 100644 --- a/lib/util.js +++ b/lib/util.js @@ -832,6 +832,45 @@ function decodePiCpuinfo(lines) { return result; } +function promiseAll(promises) { + const resolvingPromises = promises.map(function (promise) { + return new Promise(function (resolve) { + var payload = new Array(2); + promise.then(function (result) { + payload[0] = result; + }) + .catch(function (error) { + payload[1] = error; + }) + .then(function () { + // The wrapped Promise returns an array: 0 = result, 1 = error ... we resolve all + resolve(payload); + }); + }); + }); + var errors = []; + var results = []; + + // Execute all wrapped Promises + return Promise.all(resolvingPromises) + .then(function (items) { + items.forEach(function (payload) { + if (payload[1]) { + errors.push(payload[1]); + results.push(null); + } else { + errors.push(null); + results.push(payload[0]); + } + }); + + return { + errors: errors, + results: results + }; + }); +} + function noop() { } exports.toInt = toInt; @@ -861,6 +900,7 @@ exports.isRaspbian = isRaspbian; exports.sanitizeShellString = sanitizeShellString; exports.isPrototypePolluted = isPrototypePolluted; exports.decodePiCpuinfo = decodePiCpuinfo; +exports.promiseAll = promiseAll; exports.stringReplace = stringReplace; exports.stringToLower = stringToLower; exports.stringToString = stringToString;