mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	1. Capped smbios to 64k 2. Removed commented out code from win-console.js 3. Updated win-terminal to check for null before pushing
		
			
				
	
	
		
			349 lines
		
	
	
		
			No EOL
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			349 lines
		
	
	
		
			No EOL
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
Copyright 2018 Intel Corporation
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
 | 
						|
try { Object.defineProperty(String.prototype, "replaceAll", { value: function replaceAll(oldVal, newVal) { return (this.split(oldVal).join(newVal)); } }); } catch (e) { }
 | 
						|
 | 
						|
var RSMB = 1381190978;
 | 
						|
var memoryLocation = { 0x1: 'Other', 0x2: 'Unknown', 0x3: 'System Board', 0x4: 'ISA', 0x5: 'EISA', 0x6: 'PCI', 0x7: 'MCA', 0x8: 'PCMCIA', 0x9: 'Proprietary', 0xA: 'NuBus', 0xA0: 'PC-98/C20', 0xA1: 'PC-98/C24', 0xA2: 'PC-98/E', 0xA3: 'PC-98/LB' };
 | 
						|
var wakeReason = ['Reserved', 'Other', 'Unknown', 'APM Timer', 'Modem Ring', 'LAN', 'Power Switch', 'PCI', 'AC Power'];
 | 
						|
 | 
						|
// Fill the left with zeros until the string is of a given length
 | 
						|
function zeroLeftPad(str, len)
 | 
						|
{
 | 
						|
    if ((len == null) && (typeof (len) != 'number')) { return null; }
 | 
						|
    if (str == null) str = ''; // If null, this is to generate zero leftpad string
 | 
						|
    var zlp = '';
 | 
						|
    for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
 | 
						|
    return zlp + str;
 | 
						|
}
 | 
						|
 | 
						|
function SMBiosTables()
 | 
						|
{
 | 
						|
    this._ObjectID = 'SMBiosTable';
 | 
						|
    if (process.platform == 'win32') {
 | 
						|
        this._marshal = require('_GenericMarshal');
 | 
						|
        this._native = this._marshal.CreateNativeProxy("Kernel32.dll");
 | 
						|
 | 
						|
        this._native.CreateMethod('EnumSystemFirmwareTables');
 | 
						|
        this._native.CreateMethod('GetSystemFirmwareTable');
 | 
						|
    }
 | 
						|
    if (process.platform == 'linux') {
 | 
						|
        this._canonicalizeData = function _canonicalizeData(data) {
 | 
						|
            var lines = data.toString().split('Header and Data:\x0A');
 | 
						|
            var MemoryStream = require('MemoryStream');
 | 
						|
            var ms = new MemoryStream();
 | 
						|
 | 
						|
            for (var i = 1; i < lines.length; ++i) {
 | 
						|
                var tokens = lines[i].split('Strings:\x0A');
 | 
						|
                var header = tokens[0].split('\x0A\x0A')[0].replaceAll('\x0A', '').trim().replaceAll(' ', '').replaceAll('\x09', '');
 | 
						|
                ms.write(Buffer.from(header, 'hex'));
 | 
						|
                if (tokens.length > 1) {
 | 
						|
                    var strings = tokens[1].split('\x0A\x0A')[0].split('\x0A');
 | 
						|
                    var stringsFinal = [];
 | 
						|
                    for (var strx in strings) {
 | 
						|
                        var tmp = strings[strx].trim().replaceAll(' ', '').replaceAll('\x09', '');
 | 
						|
                        if (!(tmp[0] == '"')) { stringsFinal.push(tmp); }
 | 
						|
                    }
 | 
						|
                    ms.write(Buffer.from(stringsFinal.join(''), 'hex'));
 | 
						|
                    ms.write(Buffer.from('00', 'hex'));
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    ms.write(Buffer.from('0000', 'hex'));
 | 
						|
                }
 | 
						|
            }
 | 
						|
            var retVal = ms.buffer;
 | 
						|
            retVal.ms = ms;
 | 
						|
            return (retVal);
 | 
						|
        };
 | 
						|
    }
 | 
						|
    this._parse = function _parse(SMData) {
 | 
						|
        var ret = {};
 | 
						|
        var pbyte;
 | 
						|
        var i = 0
 | 
						|
        var SMData;
 | 
						|
        var structcount = 0;
 | 
						|
 | 
						|
        while (SMData && i < SMData.length)
 | 
						|
        {
 | 
						|
            var SMtype = SMData[i];
 | 
						|
            var SMlength = SMData[i + 1];
 | 
						|
 | 
						|
            if (!ret[SMtype]) { ret[SMtype] = []; }
 | 
						|
            ret[SMtype].push(SMData.slice(i + 4, i + SMlength));
 | 
						|
            if (process.platform == 'win32') { ret[SMtype].peek()._ext = pbyte; }
 | 
						|
            i += SMlength;
 | 
						|
 | 
						|
            ret[SMtype].peek()._strings = [];
 | 
						|
 | 
						|
            while (SMData[i] != 0 && i <= SMData.length)
 | 
						|
            {
 | 
						|
                var strstart = i;
 | 
						|
 | 
						|
                // Start of String, find end of string
 | 
						|
                while (SMData[i++] != 0 && i <= SMData.length);
 | 
						|
                try
 | 
						|
                {
 | 
						|
                    ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
 | 
						|
                }
 | 
						|
                catch (ee)
 | 
						|
                {
 | 
						|
                    console.log('oops');
 | 
						|
                }
 | 
						|
            }
 | 
						|
            i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
 | 
						|
            ++structcount;
 | 
						|
            //console.log('End of Table[' + SMtype + ']: ' + i);
 | 
						|
        }
 | 
						|
        //console.log('Struct Count = ' + structcount);
 | 
						|
        return (ret);
 | 
						|
    };
 | 
						|
    this.get = function get(callback) {
 | 
						|
        if (process.platform == 'win32') {
 | 
						|
            var size = this._native.GetSystemFirmwareTable(RSMB, 0, 0, 0).Val;
 | 
						|
            //console.log('Table Size: ' + size);
 | 
						|
 | 
						|
            var PtrSize = this._marshal.CreatePointer()._size;
 | 
						|
            var buffer = this._marshal.CreateVariable(size);
 | 
						|
            var written = this._native.GetSystemFirmwareTable(RSMB, 0, buffer, size).Val;
 | 
						|
            //console.log('Written Size: ' + written);
 | 
						|
 | 
						|
            var rawBuffer = buffer.toBuffer();
 | 
						|
            var length = buffer.Deref(4, 4).toBuffer().readUInt32LE(0);
 | 
						|
 | 
						|
            pbyte = buffer.Deref(8, length);
 | 
						|
            SMData = pbyte.toBuffer();
 | 
						|
 | 
						|
            if (callback) { callback.apply(this, [this._parse(SMData)]); return; } else { return (this._parse(SMData)); }
 | 
						|
        }
 | 
						|
        if (process.platform == 'linux') {
 | 
						|
            var MemoryStream = require('MemoryStream');
 | 
						|
            this.child = require('child_process').execFile('/usr/sbin/dmidecode', ['dmidecode', '-u']);
 | 
						|
            this.child.SMBiosTable = this;
 | 
						|
            this.child.ms = new MemoryStream();
 | 
						|
            this.child.ms.callback = callback;
 | 
						|
            this.child.ms.child = this.child;
 | 
						|
            this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
 | 
						|
            this.child.on('exit', function () { this.ms.end(); });
 | 
						|
            this.child.ms.on('end', function () {
 | 
						|
                //console.log('read ' + this.buffer.length + ' bytes');
 | 
						|
                if (this.buffer.length < 300) {
 | 
						|
                    //console.log('Not enough permission to read SMBiosTable');
 | 
						|
                    if (this.callback) { this.callback.apply(this.child.SMBiosTable, []); }
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    var SMData = this.child.SMBiosTable._canonicalizeData(this.buffer);
 | 
						|
                    var j = this.child.SMBiosTable._parse(SMData);
 | 
						|
                    if (this.callback) { this.callback.apply(this.child.SMBiosTable, [j]); }
 | 
						|
                }
 | 
						|
            });
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        if (callback) { callback.apply(this, [null]); return; } else { return (null); }
 | 
						|
    };
 | 
						|
    this.parse = function parse(data) {
 | 
						|
        var r = {};
 | 
						|
        try
 | 
						|
        {
 | 
						|
            r.processorInfo = this.processorInfo(data);
 | 
						|
        }
 | 
						|
        catch(e)
 | 
						|
        {
 | 
						|
        }
 | 
						|
        try
 | 
						|
        {
 | 
						|
            r.memoryInfo = this.memoryInfo(data);
 | 
						|
        }
 | 
						|
        catch(e)
 | 
						|
        {
 | 
						|
        }
 | 
						|
        try
 | 
						|
        {
 | 
						|
            r.systemInfo = this.systemInfo(data);
 | 
						|
        }
 | 
						|
        catch(e)
 | 
						|
        {
 | 
						|
        }
 | 
						|
        try
 | 
						|
        {
 | 
						|
            r.systemSlots = this.systemInfo(data);
 | 
						|
        }
 | 
						|
        catch(e)
 | 
						|
        {
 | 
						|
        }
 | 
						|
        try
 | 
						|
        {
 | 
						|
            r.amtInfo = this.amtInfo(data);
 | 
						|
        }
 | 
						|
        catch(e)
 | 
						|
        {
 | 
						|
        }
 | 
						|
        try
 | 
						|
        {
 | 
						|
            if (JSON.stringify(r).length > 65535) { r = {}; }
 | 
						|
        }
 | 
						|
        catch(ee)
 | 
						|
        {}
 | 
						|
        return r;
 | 
						|
    }
 | 
						|
    this.processorInfo = function processorInfo(data) {
 | 
						|
        if (!data) { throw ('no data'); }
 | 
						|
        var ret = [];
 | 
						|
        var ptype = ['ERROR', 'Other', 'Unknown', 'CPU', 'ALU', 'DSP', 'GPU'];
 | 
						|
        var statusString = ['Unknown', 'Enabled', 'Disabled by user', 'Disabled by BIOS', 'Idle', 'Reserved', 'Reserved', 'Other'];
 | 
						|
        var cpuid = 0;
 | 
						|
        while (data[4] && data[4].length > 0) {
 | 
						|
            var p = data[4].pop();
 | 
						|
            var populated = p[20] & 0x40;
 | 
						|
            var status = p[20] & 0x07
 | 
						|
            if (populated) {
 | 
						|
                var j = { _ObjectID: 'SMBiosTables.processorInfo' };
 | 
						|
                j.Processor = ptype[p[1]];
 | 
						|
                j.MaxSpeed = p.readUInt16LE(16) + ' Mhz';
 | 
						|
                if (p[31]) { j.Cores = p[31]; }
 | 
						|
                if (p[33]) { j.Threads = p[33]; }
 | 
						|
                j.Populated = 1;
 | 
						|
                j.Status = statusString[status];
 | 
						|
                j.Socket = p._strings[p[0] - 1];
 | 
						|
                j.Manufacturer = p._strings[p[3] - 1];
 | 
						|
                j.Version = p._strings[p[12] - 1];
 | 
						|
                ret.push(j);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return (ret);
 | 
						|
    };
 | 
						|
    this.memoryInfo = function memoryInfo(data) {
 | 
						|
        if (!data) { throw ('no data'); }
 | 
						|
        var retVal = { _ObjectID: 'SMBiosTables.memoryInfo' };
 | 
						|
        if (data[16]) {
 | 
						|
            var m = data[16].peek();
 | 
						|
            retVal.location = memoryLocation[m[0]];
 | 
						|
            if ((retVal.maxCapacityKb = m.readUInt32LE(3)) == 0x80000000) {
 | 
						|
                retVal.maxCapacityKb = 'A really big number';
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return (retVal);
 | 
						|
    };
 | 
						|
    this.systemInfo = function systemInfo(data)
 | 
						|
    {
 | 
						|
        if (!data) { throw ('no data'); }
 | 
						|
        var retVal = { _ObjectID: 'SMBiosTables.systemInfo' };
 | 
						|
        if (data[1])
 | 
						|
        {
 | 
						|
            var si = data[1].peek();
 | 
						|
            var uuid = si.slice(4, 20);
 | 
						|
 | 
						|
            retVal.uuid = [zeroLeftPad(uuid.readUInt32LE(0).toString(16), 8),
 | 
						|
            zeroLeftPad(uuid.readUInt16LE(4).toString(16), 4),
 | 
						|
            zeroLeftPad(uuid.readUInt16LE(6).toString(16), 4),
 | 
						|
            zeroLeftPad(uuid.readUInt16BE(8).toString(16), 4),
 | 
						|
            zeroLeftPad(uuid.slice(10).toString('hex').toLowerCase(), 12)].join('-');
 | 
						|
 | 
						|
            retVal.wakeReason = wakeReason[si[20]];
 | 
						|
        }
 | 
						|
        return (retVal);
 | 
						|
    };
 | 
						|
    this.systemSlots = function systemSlots(data) {
 | 
						|
        if (!data) { throw ('no data'); }
 | 
						|
        var retVal = [];
 | 
						|
        if (data[9]) {
 | 
						|
            while (data[9].length > 0) {
 | 
						|
                var ss = data[9].pop();
 | 
						|
                retVal.push({ name: ss._strings[ss[0] - 1] });
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return (retVal);
 | 
						|
    };
 | 
						|
    this.amtInfo = function amtInfo(data) {
 | 
						|
        if (!data) { throw ('no data'); }
 | 
						|
        var retVal = { AMT: false };
 | 
						|
        if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') {
 | 
						|
            var amt = data[130].peek();
 | 
						|
            retVal.AMT = amt[4] ? true : false;
 | 
						|
            if (retVal.AMT) {
 | 
						|
                retVal.enabled = amt[5] ? true : false;
 | 
						|
                retVal.storageRedirection = amt[6] ? true : false;
 | 
						|
                retVal.serialOverLan = amt[7] ? true : false;
 | 
						|
                retVal.kvm = amt[14] ? true : false;
 | 
						|
                if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') {
 | 
						|
                    var settings = data[131].peek();
 | 
						|
                    if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; }
 | 
						|
                    if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; }
 | 
						|
                    retVal.MEBX = settings.readUInt16LE(4).toString() + '.' + settings.readUInt16LE(6).toString() + '.' + settings.readUInt16LE(8).toString() + '.' + settings.readUInt16LE(10).toString();
 | 
						|
 | 
						|
                    var mecap = settings.slice(20, 32);
 | 
						|
                    retVal.ManagementEngine = mecap.readUInt16LE(6).toString() + '.' + mecap.readUInt16LE(4).toString() + '.' + mecap.readUInt16LE(10).toString() + '.' + mecap.readUInt16LE(8).toString();
 | 
						|
 | 
						|
                    //var lan = settings.slice(36, 48);
 | 
						|
                    //console.log(lan.toString('hex'));
 | 
						|
                    //retVal.LAN = (lan.readUInt16LE(10) & 0x03).toString() + '/' + ((lan.readUInt16LE(10) & 0xF8) >> 3).toString();
 | 
						|
 | 
						|
                    //console.log(lan.readUInt16LE(3));
 | 
						|
                    //retVal.WLAN = (lan.readUInt16LE(3) & 0x07).toString() + '/' + ((lan.readUInt16LE(3) & 0xF8) >> 3).toString() + '/' + (lan.readUInt16LE(3) >> 8).toString();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return (retVal);
 | 
						|
    };
 | 
						|
    this.smTableTypes = {
 | 
						|
        0: 'BIOS information',
 | 
						|
        1: 'System information',
 | 
						|
        2: 'Baseboard (or Module) information',
 | 
						|
        4: 'Processor information',
 | 
						|
        5: 'memory controller information',
 | 
						|
        6: 'Memory module information',
 | 
						|
        7: 'Cache information',
 | 
						|
        8: 'Port connector information',
 | 
						|
        9: 'System slots',
 | 
						|
        10: 'On board devices information',
 | 
						|
        11: 'OEM strings',
 | 
						|
        12: 'System configuration options',
 | 
						|
        13: 'BIOS language information',
 | 
						|
        14: 'Group associations',
 | 
						|
        15: 'System event log',
 | 
						|
        16: 'Physical memory array',
 | 
						|
        17: 'Memory device',
 | 
						|
        18: '32bit memory error information',
 | 
						|
        19: 'Memory array mapped address',
 | 
						|
        20: 'Memory device mapped address',
 | 
						|
        21: 'Built-in pointing device',
 | 
						|
        22: 'Portable battery',
 | 
						|
        23: 'System reset',
 | 
						|
        24: 'Hardware security',
 | 
						|
        25: 'System power controls',
 | 
						|
        26: 'Voltage probe',
 | 
						|
        27: 'Cooling device',
 | 
						|
        28: 'Temperature probe',
 | 
						|
        29: 'Electrical current probe',
 | 
						|
        30: 'Out-of-band remote access',
 | 
						|
        31: 'Boot integrity services (BIS) entry point',
 | 
						|
        32: 'System boot information',
 | 
						|
        33: '64bit memory error information',
 | 
						|
        34: 'Management device',
 | 
						|
        35: 'Management device component',
 | 
						|
        36: 'Management device threshold data',
 | 
						|
        37: 'Memory channel',
 | 
						|
        38: 'IPMI device information',
 | 
						|
        39: 'System power supply',
 | 
						|
        40: 'Additional information',
 | 
						|
        41: 'Onboard devices extended information',
 | 
						|
        42: 'Management controller host interface',
 | 
						|
        126: 'Inactive',
 | 
						|
        127: 'End-of-table'
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
module.exports = new SMBiosTables(); |