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(); |