systeminformation 5.9.9 → 5.9.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/system.js CHANGED
@@ -1,839 +1,841 @@
1
- 'use strict';
2
- // @ts-check
3
- // ==================================================================================
4
- // system.js
5
- // ----------------------------------------------------------------------------------
6
- // Description: System Information - library
7
- // for Node.js
8
- // Copyright: (c) 2014 - 2021
9
- // Author: Sebastian Hildebrandt
10
- // ----------------------------------------------------------------------------------
11
- // License: MIT
12
- // ==================================================================================
13
- // 2. System (Hardware, BIOS, Base Board)
14
- // ----------------------------------------------------------------------------------
15
-
16
- const fs = require('fs');
17
- const os = require('os');
18
- const util = require('./util');
19
- const exec = require('child_process').exec;
20
- const execSync = require('child_process').execSync;
21
- const execPromise = util.promisify(require('child_process').exec);
22
-
23
- let _platform = process.platform;
24
-
25
- const _linux = (_platform === 'linux');
26
- const _darwin = (_platform === 'darwin');
27
- const _windows = (_platform === 'win32');
28
- const _freebsd = (_platform === 'freebsd');
29
- const _openbsd = (_platform === 'openbsd');
30
- const _netbsd = (_platform === 'netbsd');
31
- const _sunos = (_platform === 'sunos');
32
-
33
- function system(callback) {
34
-
35
- return new Promise((resolve) => {
36
- process.nextTick(() => {
37
-
38
- let result = {
39
- manufacturer: '',
40
- model: 'Computer',
41
- version: '',
42
- serial: '-',
43
- uuid: '-',
44
- sku: '-',
45
- virtual: false
46
- };
47
-
48
- if (_linux || _freebsd || _openbsd || _netbsd) {
49
- exec('export LC_ALL=C; dmidecode -t system 2>/dev/null; unset LC_ALL', function (error, stdout) {
50
- // if (!error) {
51
- let lines = stdout.toString().split('\n');
52
- result.manufacturer = util.getValue(lines, 'manufacturer');
53
- result.model = util.getValue(lines, 'product name');
54
- result.version = util.getValue(lines, 'version');
55
- result.serial = util.getValue(lines, 'serial number');
56
- result.uuid = util.getValue(lines, 'uuid').toLowerCase();
57
- result.sku = util.getValue(lines, 'sku number');
58
- // }
59
- // Non-Root values
60
- const cmd = `echo -n "product_name: "; cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null; echo;
61
- echo -n "product_serial: "; cat /sys/devices/virtual/dmi/id/product_serial 2>/dev/null; echo;
62
- echo -n "product_uuid: "; cat /sys/devices/virtual/dmi/id/product_uuid 2>/dev/null; echo;
63
- echo -n "product_version: "; cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null; echo;
64
- echo -n "sys_vendor: "; cat /sys/devices/virtual/dmi/id/sys_vendor 2>/dev/null; echo;`;
65
- try {
66
- lines = execSync(cmd).toString().split('\n');
67
- result.manufacturer = result.manufacturer === '' ? util.getValue(lines, 'sys_vendor') : result.manufacturer;
68
- result.model = result.model === '' ? util.getValue(lines, 'product_name') : result.model;
69
- result.version = result.version === '' ? util.getValue(lines, 'product_version') : result.version;
70
- result.serial = result.serial === '' ? util.getValue(lines, 'product_serial') : result.serial;
71
- result.uuid = result.uuid === '' ? util.getValue(lines, 'product_uuid').toLowerCase() : result.uuid;
72
- } catch (e) {
73
- util.noop();
74
- }
75
- if (!result.serial || result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
76
- if (!result.manufacturer || result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = ''; }
77
- if (!result.model || result.model.toLowerCase().indexOf('o.e.m.') !== -1) { result.model = 'Computer'; }
78
- if (!result.version || result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = ''; }
79
- if (!result.sku || result.sku.toLowerCase().indexOf('o.e.m.') !== -1) { result.sku = '-'; }
80
-
81
- // detect virtual (1)
82
- if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware') || result.model.toLowerCase().startsWith('droplet')) {
83
- result.virtual = true;
84
- switch (result.model.toLowerCase()) {
85
- case 'virtualbox':
86
- result.virtualHost = 'VirtualBox';
87
- break;
88
- case 'vmware':
89
- result.virtualHost = 'VMware';
90
- break;
91
- case 'kvm':
92
- result.virtualHost = 'KVM';
93
- break;
94
- case 'bochs':
95
- result.virtualHost = 'bochs';
96
- break;
97
- }
98
- }
99
- if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
100
- result.virtual = true;
101
- switch (result.manufacturer.toLowerCase()) {
102
- case 'vmware':
103
- result.virtualHost = 'VMware';
104
- break;
105
- case 'xen':
106
- result.virtualHost = 'Xen';
107
- break;
108
- }
109
- }
110
- if (!result.virtual) {
111
- try {
112
- const disksById = execSync('ls -1 /dev/disk/by-id/ 2>/dev/null').toString();
113
- if (disksById.indexOf('_QEMU_') >= 0) {
114
- result.virtual = true;
115
- result.virtualHost = 'QEMU';
116
- }
117
- if (disksById.indexOf('_VBOX_') >= 0) {
118
- result.virtual = true;
119
- result.virtualHost = 'VirtualBox';
120
- }
121
- } catch (e) {
122
- util.noop();
123
- }
124
- }
125
- if (!result.virtual && (os.release().toLowerCase().indexOf('microsoft') >= 0 || os.release().toLowerCase().endsWith('wsl2'))) {
126
- const kernelVersion = parseFloat(os.release().toLowerCase());
127
- result.virtual = true;
128
- result.manufacturer = 'Microsoft';
129
- result.model = 'WSL';
130
- result.version = kernelVersion < 4.19 ? '1' : '2';
131
- }
132
- if ((_freebsd || _openbsd || _netbsd) && !result.virtualHost) {
133
- try {
134
- const procInfo = execSync('dmidecode -t 4');
135
- const procLines = procInfo.toString().split('\n');
136
- const procManufacturer = util.getValue(procLines, 'manufacturer', ':', true);
137
- switch (procManufacturer.toLowerCase()) {
138
- case 'virtualbox':
139
- result.virtualHost = 'VirtualBox';
140
- break;
141
- case 'vmware':
142
- result.virtualHost = 'VMware';
143
- break;
144
- case 'kvm':
145
- result.virtualHost = 'KVM';
146
- break;
147
- case 'bochs':
148
- result.virtualHost = 'bochs';
149
- break;
150
- }
151
- } catch (e) {
152
- util.noop();
153
- }
154
- }
155
- // detect docker
156
- if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) {
157
- result.model = 'Docker Container';
158
- }
159
- try {
160
- const stdout = execSync('dmesg 2>/dev/null | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen" | grep -viE "Nested Virtualization|/virtual/"');
161
- // detect virtual machines
162
- let lines = stdout.toString().split('\n');
163
- if (lines.length > 0) {
164
- if (result.model === 'Computer') { result.model = 'Virtual machine'; }
165
- result.virtual = true;
166
- if (stdout.toString().toLowerCase().indexOf('vmware') >= 0 && !result.virtualHost) {
167
- result.virtualHost = 'VMware';
168
- }
169
- if (stdout.toString().toLowerCase().indexOf('qemu') >= 0 && !result.virtualHost) {
170
- result.virtualHost = 'QEMU';
171
- }
172
- if (stdout.toString().toLowerCase().indexOf('xen') >= 0 && !result.virtualHost) {
173
- result.virtualHost = 'Xen';
174
- }
175
- if (stdout.toString().toLowerCase().indexOf('kvm') >= 0 && !result.virtualHost) {
176
- result.virtualHost = 'KVM';
177
- }
178
- }
179
- } catch (e) {
180
- util.noop();
181
- }
182
-
183
- if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') {
184
- // Check Raspberry Pi
185
- fs.readFile('/proc/cpuinfo', function (error, stdout) {
186
- if (!error) {
187
- let lines = stdout.toString().split('\n');
188
- result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
189
- result.version = util.getValue(lines, 'revision', ':', true).toLowerCase();
190
- result.serial = util.getValue(lines, 'serial', ':', true);
191
- const model = util.getValue(lines, 'model:', ':', true);
192
- // reference values: https://elinux.org/RPi_HardwareHistory
193
- // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
194
- if ((result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2710' || result.model === 'BCM2711' || result.model === 'BCM2836' || result.model === 'BCM2837') && model.toLowerCase().indexOf('raspberry') >= 0) {
195
- const rPIRevision = util.decodePiCpuinfo(lines);
196
- result.model = rPIRevision.model;
197
- result.version = rPIRevision.revisionCode;
198
- result.manufacturer = 'Raspberry Pi Foundation';
199
- result.raspberry = {
200
- manufacturer: rPIRevision.manufacturer,
201
- processor: rPIRevision.processor,
202
- type: rPIRevision.type,
203
- revision: rPIRevision.revision
204
- };
205
- }
206
-
207
- // if (result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2835' || result.model === 'BCM2837') {
208
-
209
-
210
- // // Pi 4
211
- // if (['d03114'].indexOf(result.version) >= 0) {
212
- // result.model = result.model + ' - Pi 4 Model B';
213
- // result.version = result.version + ' - Rev. 1.4';
214
- // }
215
- // if (['b03112', 'c03112'].indexOf(result.version) >= 0) {
216
- // result.model = result.model + ' - Pi 4 Model B';
217
- // result.version = result.version + ' - Rev. 1.2';
218
- // }
219
- // if (['a03111', 'b03111', 'c03111'].indexOf(result.version) >= 0) {
220
- // result.model = result.model + ' - Pi 4 Model B';
221
- // result.version = result.version + ' - Rev. 1.1';
222
- // }
223
- // // Pi 3
224
- // if (['a02082', 'a22082', 'a32082', 'a52082'].indexOf(result.version) >= 0) {
225
- // result.model = result.model + ' - Pi 3 Model B';
226
- // result.version = result.version + ' - Rev. 1.2';
227
- // }
228
- // if (['a22083'].indexOf(result.version) >= 0) {
229
- // result.model = result.model + ' - Pi 3 Model B';
230
- // result.version = result.version + ' - Rev. 1.3';
231
- // }
232
- // if (['a020d3'].indexOf(result.version) >= 0) {
233
- // result.model = result.model + ' - Pi 3 Model B+';
234
- // result.version = result.version + ' - Rev. 1.3';
235
- // }
236
- // if (['9020e0'].indexOf(result.version) >= 0) {
237
- // result.model = result.model + ' - Pi 3 Model A+';
238
- // result.version = result.version + ' - Rev. 1.3';
239
- // }
240
- // // Pi 2 Model B
241
- // if (['a01040'].indexOf(result.version) >= 0) {
242
- // result.model = result.model + ' - Pi 2 Model B';
243
- // result.version = result.version + ' - Rev. 1.0';
244
- // }
245
- // if (['a01041', 'a21041'].indexOf(result.version) >= 0) {
246
- // result.model = result.model + ' - Pi 2 Model B';
247
- // result.version = result.version + ' - Rev. 1.1';
248
- // }
249
- // if (['a22042', 'a02042'].indexOf(result.version) >= 0) {
250
- // result.model = result.model + ' - Pi 2 Model B';
251
- // result.version = result.version + ' - Rev. 1.2';
252
- // }
253
-
254
- // // Compute Model
255
- // if (['a02100'].indexOf(result.version) >= 0) {
256
- // result.model = result.model + ' - Pi CM3+';
257
- // result.version = result.version + ' - Rev 1.0';
258
- // }
259
- // if (['a020a0', 'a220a0'].indexOf(result.version) >= 0) {
260
- // result.model = result.model + ' - Pi CM3';
261
- // result.version = result.version + ' - Rev 1.0';
262
- // }
263
- // if (['900061'].indexOf(result.version) >= 0) {
264
- // result.model = result.model + ' - Pi CM';
265
- // result.version = result.version + ' - Rev 1.1';
266
- // }
267
-
268
- // // Pi Zero
269
- // if (['900092', '920092'].indexOf(result.version) >= 0) {
270
- // result.model = result.model + ' - Pi Zero';
271
- // result.version = result.version + ' - Rev 1.2';
272
- // }
273
- // if (['900093', '920093'].indexOf(result.version) >= 0) {
274
- // result.model = result.model + ' - Pi Zero';
275
- // result.version = result.version + ' - Rev 1.3';
276
- // }
277
- // if (['9000c1'].indexOf(result.version) >= 0) {
278
- // result.model = result.model + ' - Pi Zero W';
279
- // result.version = result.version + ' - Rev 1.1';
280
- // }
281
-
282
- // // A, B, A+ B+
283
- // if (['0002', '0003'].indexOf(result.version) >= 0) {
284
- // result.model = result.model + ' - Pi Model B';
285
- // result.version = result.version + ' - Rev 1.0';
286
- // }
287
- // if (['0004', '0005', '0006', '000d', '000e', '000f'].indexOf(result.version) >= 0) {
288
- // result.model = result.model + ' - Pi Model B';
289
- // result.version = result.version + ' - Rev 2.0';
290
- // }
291
- // if (['0007', '0008', '0009'].indexOf(result.version) >= 0) {
292
- // result.model = result.model + ' - Pi Model A';
293
- // result.version = result.version + ' - Rev 2.0';
294
- // }
295
- // if (['0010'].indexOf(result.version) >= 0) {
296
- // result.model = result.model + ' - Pi Model B+';
297
- // result.version = result.version + ' - Rev 1.0';
298
- // }
299
- // if (['0012'].indexOf(result.version) >= 0) {
300
- // result.model = result.model + ' - Pi Model A+';
301
- // result.version = result.version + ' - Rev 1.0';
302
- // }
303
- // if (['0013', '900032'].indexOf(result.version) >= 0) {
304
- // result.model = result.model + ' - Pi Model B+';
305
- // result.version = result.version + ' - Rev 1.2';
306
- // }
307
- // if (['0015', '900021'].indexOf(result.version) >= 0) {
308
- // result.model = result.model + ' - Pi Model A+';
309
- // result.version = result.version + ' - Rev 1.1';
310
- // }
311
- // if (result.model.indexOf('Pi') !== -1 && result.version) { // Pi, Pi Zero
312
- // result.manufacturer = 'Raspberry Pi Foundation';
313
- // }
314
- // }
315
- }
316
- if (callback) { callback(result); }
317
- resolve(result);
318
- });
319
- } else {
320
- if (callback) { callback(result); }
321
- resolve(result);
322
- }
323
- });
324
- }
325
- if (_darwin) {
326
- exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
327
- if (!error) {
328
- let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
329
- result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
330
- result.model = util.getValue(lines, 'model', '=', true);
331
- result.version = util.getValue(lines, 'version', '=', true);
332
- result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
333
- result.uuid = util.getValue(lines, 'ioplatformuuid', '=', true).toLowerCase();
334
- result.sku = util.getValue(lines, 'board-id', '=', true);
335
- }
336
- if (callback) { callback(result); }
337
- resolve(result);
338
- });
339
- }
340
- if (_sunos) {
341
- if (callback) { callback(result); }
342
- resolve(result);
343
- }
344
- if (_windows) {
345
- try {
346
- util.powerShell('Get-WmiObject Win32_ComputerSystemProduct | fl *').then((stdout, error) => {
347
- if (!error) {
348
- // let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0)[0].trim().split(/\s\s+/);
349
- let lines = stdout.split('\r\n');
350
- result.manufacturer = util.getValue(lines, 'vendor', ':');
351
- result.model = util.getValue(lines, 'name', ':');
352
- result.version = util.getValue(lines, 'version', ':');
353
- result.serial = util.getValue(lines, 'identifyingnumber', ':');
354
- result.uuid = util.getValue(lines, 'uuid', ':').toLowerCase();
355
- // detect virtual (1)
356
- if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware')) {
357
- result.virtual = true;
358
- switch (result.model.toLowerCase()) {
359
- case 'virtualbox':
360
- result.virtualHost = 'VirtualBox';
361
- break;
362
- case 'vmware':
363
- result.virtualHost = 'VMware';
364
- break;
365
- case 'kvm':
366
- result.virtualHost = 'KVM';
367
- break;
368
- case 'bochs':
369
- result.virtualHost = 'bochs';
370
- break;
371
- }
372
- }
373
- if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
374
- result.virtual = true;
375
- switch (result.manufacturer.toLowerCase()) {
376
- case 'vmware':
377
- result.virtualHost = 'VMware';
378
- break;
379
- case 'xen':
380
- result.virtualHost = 'Xen';
381
- break;
382
- }
383
- }
384
- util.powerShell('Get-WmiObject MS_Systeminformation -Namespace "root/wmi" | fl *').then((stdout, error) => {
385
- if (!error) {
386
- let lines = stdout.split('\r\n');
387
- result.sku = util.getValue(lines, 'systemsku', ':');
388
- }
389
- if (!result.virtual) {
390
- util.powerShell('Get-WmiObject Win32_bios | select Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => {
391
- if (!error) {
392
- let lines = stdout.toString();
393
- if (lines.indexOf('VRTUAL') >= 0 || lines.indexOf('A M I ') >= 0 || lines.indexOf('VirtualBox') >= 0 || lines.indexOf('VMWare') >= 0 || lines.indexOf('Xen') >= 0) {
394
- result.virtual = true;
395
- if (lines.indexOf('VirtualBox') >= 0 && !result.virtualHost) {
396
- result.virtualHost = 'VirtualBox';
397
- }
398
- if (lines.indexOf('VMware') >= 0 && !result.virtualHost) {
399
- result.virtualHost = 'VMware';
400
- }
401
- if (lines.indexOf('Xen') >= 0 && !result.virtualHost) {
402
- result.virtualHost = 'Xen';
403
- }
404
- if (lines.indexOf('VRTUAL') >= 0 && !result.virtualHost) {
405
- result.virtualHost = 'Hyper-V';
406
- }
407
- if (lines.indexOf('A M I') >= 0 && !result.virtualHost) {
408
- result.virtualHost = 'Virtual PC';
409
- }
410
- }
411
- if (callback) { callback(result); }
412
- resolve(result);
413
- } else {
414
- if (callback) { callback(result); }
415
- resolve(result);
416
- }
417
- });
418
- } else {
419
- if (callback) { callback(result); }
420
- resolve(result);
421
- }
422
- });
423
- } else {
424
- if (callback) { callback(result); }
425
- resolve(result);
426
- }
427
- });
428
- } catch (e) {
429
- if (callback) { callback(result); }
430
- resolve(result);
431
- }
432
- }
433
- });
434
- });
435
- }
436
-
437
- exports.system = system;
438
-
439
- function bios(callback) {
440
-
441
- return new Promise((resolve) => {
442
- process.nextTick(() => {
443
-
444
- let result = {
445
- vendor: '',
446
- version: '',
447
- releaseDate: '',
448
- revision: '',
449
- };
450
- let cmd = '';
451
- if (_linux || _freebsd || _openbsd || _netbsd) {
452
- if (process.arch === 'arm') {
453
- cmd = 'cat /proc/cpuinfo | grep Serial';
454
- } else {
455
- cmd = 'export LC_ALL=C; dmidecode -t bios 2>/dev/null; unset LC_ALL';
456
- }
457
- exec(cmd, function (error, stdout) {
458
- let lines = stdout.toString().split('\n');
459
- result.vendor = util.getValue(lines, 'Vendor');
460
- result.version = util.getValue(lines, 'Version');
461
- let datetime = util.getValue(lines, 'Release Date');
462
- result.releaseDate = util.parseDateTime(datetime).date;
463
- result.revision = util.getValue(lines, 'BIOS Revision');
464
- let language = util.getValue(lines, 'Currently Installed Language').split('|')[0];
465
- if (language) {
466
- result.language = language;
467
- }
468
- if (lines.length && stdout.toString().indexOf('Characteristics:') >= 0) {
469
- const features = [];
470
- lines.forEach(line => {
471
- if (line.indexOf(' is supported') >= 0) {
472
- const feature = line.split(' is supported')[0].trim();
473
- features.push(feature);
474
- }
475
- });
476
- result.features = features;
477
- }
478
- // Non-Root values
479
- const cmd = `echo -n "bios_date: "; cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null; echo;
480
- echo -n "bios_vendor: "; cat /sys/devices/virtual/dmi/id/bios_vendor 2>/dev/null; echo;
481
- echo -n "bios_version: "; cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null; echo;`;
482
- try {
483
- lines = execSync(cmd).toString().split('\n');
484
- result.vendor = !result.vendor ? util.getValue(lines, 'bios_vendor') : result.vendor;
485
- result.version = !result.version ? util.getValue(lines, 'bios_version') : result.version;
486
- datetime = util.getValue(lines, 'bios_date');
487
- result.releaseDate = !result.releaseDate ? util.parseDateTime(datetime).date : result.releaseDate;
488
- } catch (e) {
489
- util.noop();
490
- }
491
- if (callback) { callback(result); }
492
- resolve(result);
493
- });
494
- }
495
- if (_darwin) {
496
- result.vendor = 'Apple Inc.';
497
- exec(
498
- 'system_profiler SPHardwareDataType -json', function (error, stdout) {
499
- try {
500
- const hardwareData = JSON.parse(stdout.toString());
501
- if (hardwareData && hardwareData.SPHardwareDataType && hardwareData.SPHardwareDataType.length) {
502
- let bootRomVersion = hardwareData.SPHardwareDataType[0].boot_rom_version;
503
- bootRomVersion = bootRomVersion ? bootRomVersion.split('(')[0].trim() : null;
504
- result.version = bootRomVersion;
505
- }
506
- } catch (e) {
507
- util.noop();
508
- }
509
- if (callback) { callback(result); }
510
- resolve(result);
511
- });
512
- }
513
- if (_sunos) {
514
- result.vendor = 'Sun Microsystems';
515
- if (callback) { callback(result); }
516
- resolve(result);
517
- }
518
- if (_windows) {
519
- try {
520
- util.powerShell('Get-WmiObject Win32_bios | fl *').then((stdout, error) => {
521
- if (!error) {
522
- let lines = stdout.toString().split('\r\n');
523
- const description = util.getValue(lines, 'description', ':');
524
- if (description.indexOf(' Version ') !== -1) {
525
- // ... Phoenix ROM BIOS PLUS Version 1.10 A04
526
- result.vendor = description.split(' Version ')[0].trim();
527
- result.version = description.split(' Version ')[1].trim();
528
- } else if (description.indexOf(' Ver: ') !== -1) {
529
- // ... BIOS Date: 06/27/16 17:50:16 Ver: 1.4.5
530
- result.vendor = util.getValue(lines, 'manufacturer', ':');
531
- result.version = description.split(' Ver: ')[1].trim();
532
- } else {
533
- result.vendor = util.getValue(lines, 'manufacturer', ':');
534
- result.version = util.getValue(lines, 'version', ':');
535
- }
536
- result.releaseDate = util.getValue(lines, 'releasedate', ':');
537
- if (result.releaseDate.length >= 10) {
538
- result.releaseDate = result.releaseDate.substr(0, 4) + '-' + result.releaseDate.substr(4, 2) + '-' + result.releaseDate.substr(6, 2);
539
- }
540
- result.revision = util.getValue(lines, 'buildnumber', ':');
541
- }
542
-
543
- if (callback) { callback(result); }
544
- resolve(result);
545
- });
546
- } catch (e) {
547
- if (callback) { callback(result); }
548
- resolve(result);
549
- }
550
- }
551
- });
552
- });
553
- }
554
-
555
- exports.bios = bios;
556
-
557
- function baseboard(callback) {
558
-
559
- return new Promise((resolve) => {
560
- process.nextTick(() => {
561
-
562
- let result = {
563
- manufacturer: '',
564
- model: '',
565
- version: '',
566
- serial: '-',
567
- assetTag: '-',
568
- memMax: null,
569
- memSlots: null
570
- };
571
- let cmd = '';
572
- if (_linux || _freebsd || _openbsd || _netbsd) {
573
- if (process.arch === 'arm') {
574
- cmd = 'cat /proc/cpuinfo | grep Serial';
575
- // 'BCM2709', 'BCM2835', 'BCM2708' -->
576
- } else {
577
- cmd = 'export LC_ALL=C; dmidecode -t 2 2>/dev/null; unset LC_ALL';
578
- }
579
- const workload = [];
580
- workload.push(execPromise(cmd));
581
- workload.push(execPromise('export LC_ALL=C; dmidecode -t memory 2>/dev/null'));
582
- util.promiseAll(
583
- workload
584
- ).then(data => {
585
- let lines = data.results[0] ? data.results[0].toString().split('\n') : [''];
586
- result.manufacturer = util.getValue(lines, 'Manufacturer');
587
- result.model = util.getValue(lines, 'Product Name');
588
- result.version = util.getValue(lines, 'Version');
589
- result.serial = util.getValue(lines, 'Serial Number');
590
- result.assetTag = util.getValue(lines, 'Asset Tag');
591
- // Non-Root values
592
- const cmd = `echo -n "board_asset_tag: "; cat /sys/devices/virtual/dmi/id/board_asset_tag 2>/dev/null; echo;
593
- echo -n "board_name: "; cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null; echo;
594
- echo -n "board_serial: "; cat /sys/devices/virtual/dmi/id/board_serial 2>/dev/null; echo;
595
- echo -n "board_vendor: "; cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null; echo;
596
- echo -n "board_version: "; cat /sys/devices/virtual/dmi/id/board_version 2>/dev/null; echo;`;
597
- try {
598
- lines = execSync(cmd).toString().split('\n');
599
- result.manufacturer = !result.manufacturer ? util.getValue(lines, 'board_vendor') : result.manufacturer;
600
- result.model = !result.model ? util.getValue(lines, 'board_name') : result.model;
601
- result.version = !result.version ? util.getValue(lines, 'board_version') : result.version;
602
- result.serial = !result.serial ? util.getValue(lines, 'board_serial') : result.serial;
603
- result.assetTag = !result.assetTag ? util.getValue(lines, 'board_asset_tag') : result.assetTag;
604
- } catch (e) {
605
- util.noop();
606
- }
607
- if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
608
- if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
609
-
610
- // mem
611
- lines = data.results[1] ? data.results[1].toString().split('\n') : [''];
612
- result.memMax = util.toInt(util.getValue(lines, 'Maximum Capacity')) * 1024 * 1024 * 1024 || null;
613
- result.memSlots = util.toInt(util.getValue(lines, 'Number Of Devices')) || null;
614
-
615
- // raspberry
616
- let linesRpi = '';
617
- try {
618
- linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
619
- } catch (e) {
620
- util.noop();
621
- }
622
- const hardware = util.getValue(linesRpi, 'hardware');
623
- if (hardware.startsWith('BCM')) {
624
- const rpi = util.decodePiCpuinfo(linesRpi);
625
- result.manufacturer = rpi.manufacturer;
626
- result.model = 'Raspberry Pi';
627
- result.serial = rpi.serial;
628
- result.version = rpi.type + ' - ' + rpi.revision;
629
- result.memMax = os.totalmem();
630
- result.memSlots = 0;
631
- }
632
-
633
- if (callback) { callback(result); }
634
- resolve(result);
635
- });
636
- }
637
- if (_darwin) {
638
- const workload = [];
639
- workload.push(execPromise('ioreg -c IOPlatformExpertDevice -d 2'));
640
- workload.push(execPromise('system_profiler SPMemoryDataType'));
641
- util.promiseAll(
642
- workload
643
- ).then(data => {
644
- let lines = data.results[0] ? data.results[0].toString().replace(/[<>"]/g, '').split('\n') : [''];
645
- result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
646
- result.model = util.getValue(lines, 'model', '=', true);
647
- result.version = util.getValue(lines, 'version', '=', true);
648
- result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
649
- result.assetTag = util.getValue(lines, 'board-id', '=', true);
650
-
651
- // mem
652
- let devices = data.results[1] ? data.results[1].toString().split(' BANK ') : [''];
653
- if (devices.length === 1) {
654
- devices = data.results[1] ? data.results[1].toString().split(' DIMM') : [''];
655
- }
656
- devices.shift();
657
- result.memSlots = devices.length;
658
-
659
- if (os.arch() === 'arm64') {
660
- result.memSlots = 0;
661
- result.memMax = os.totalmem();
662
- }
663
-
664
- if (callback) { callback(result); }
665
- resolve(result);
666
- });
667
- }
668
- if (_sunos) {
669
- if (callback) { callback(result); }
670
- resolve(result);
671
- }
672
- if (_windows) {
673
- try {
674
- const workload = [];
675
- workload.push(util.powerShell('Get-WmiObject Win32_baseboard | fl *'));
676
- workload.push(util.powerShell('Get-WmiObject Win32_physicalmemoryarray | select MaxCapacity, MemoryDevices | fl'));
677
- util.promiseAll(
678
- workload
679
- ).then(data => {
680
- let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
681
-
682
- result.manufacturer = util.getValue(lines, 'manufacturer', ':');
683
- result.model = util.getValue(lines, 'model', ':');
684
- if (!result.model) {
685
- result.model = util.getValue(lines, 'product', ':');
686
- }
687
- result.version = util.getValue(lines, 'version', ':');
688
- result.serial = util.getValue(lines, 'serialnumber', ':');
689
- result.assetTag = util.getValue(lines, 'partnumber', ':');
690
- if (!result.assetTag) {
691
- result.assetTag = util.getValue(lines, 'sku', ':');
692
- }
693
-
694
- // memphysical
695
- lines = data.results[1] ? data.results[1].toString().split('\r\n') : [''];
696
- result.memMax = util.toInt(util.getValue(lines, 'MaxCapacity', ':')) || null;
697
- result.memSlots = util.toInt(util.getValue(lines, 'MemoryDevices', ':')) || null;
698
-
699
- if (callback) { callback(result); }
700
- resolve(result);
701
- });
702
- } catch (e) {
703
- if (callback) { callback(result); }
704
- resolve(result);
705
- }
706
- }
707
- });
708
- });
709
- }
710
-
711
- exports.baseboard = baseboard;
712
-
713
- function chassis(callback) {
714
- const chassisTypes = ['Other',
715
- 'Unknown',
716
- 'Desktop',
717
- 'Low Profile Desktop',
718
- 'Pizza Box',
719
- 'Mini Tower',
720
- 'Tower',
721
- 'Portable',
722
- 'Laptop',
723
- 'Notebook',
724
- 'Hand Held',
725
- 'Docking Station',
726
- 'All in One',
727
- 'Sub Notebook',
728
- 'Space-Saving',
729
- 'Lunch Box',
730
- 'Main System Chassis',
731
- 'Expansion Chassis',
732
- 'SubChassis',
733
- 'Bus Expansion Chassis',
734
- 'Peripheral Chassis',
735
- 'Storage Chassis',
736
- 'Rack Mount Chassis',
737
- 'Sealed-Case PC',
738
- 'Multi-System Chassis',
739
- 'Compact PCI',
740
- 'Advanced TCA',
741
- 'Blade',
742
- 'Blade Enclosure',
743
- 'Tablet',
744
- 'Convertible',
745
- 'Detachable',
746
- 'IoT Gateway ',
747
- 'Embedded PC',
748
- 'Mini PC',
749
- 'Stick PC',
750
- ];
751
-
752
- return new Promise((resolve) => {
753
- process.nextTick(() => {
754
-
755
- let result = {
756
- manufacturer: '',
757
- model: '',
758
- type: '',
759
- version: '',
760
- serial: '-',
761
- assetTag: '-',
762
- sku: '',
763
- };
764
- if (_linux || _freebsd || _openbsd || _netbsd) {
765
- const cmd = `echo -n "chassis_asset_tag: "; cat /sys/devices/virtual/dmi/id/chassis_asset_tag 2>/dev/null; echo;
766
- echo -n "chassis_serial: "; cat /sys/devices/virtual/dmi/id/chassis_serial 2>/dev/null; echo;
767
- echo -n "chassis_type: "; cat /sys/devices/virtual/dmi/id/chassis_type 2>/dev/null; echo;
768
- echo -n "chassis_vendor: "; cat /sys/devices/virtual/dmi/id/chassis_vendor 2>/dev/null; echo;
769
- echo -n "chassis_version: "; cat /sys/devices/virtual/dmi/id/chassis_version 2>/dev/null; echo;`;
770
- exec(cmd, function (error, stdout) {
771
- let lines = stdout.toString().split('\n');
772
- result.manufacturer = util.getValue(lines, 'chassis_vendor');
773
- const ctype = parseInt(util.getValue(lines, 'chassis_type').replace(/\D/g, ''));
774
- result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
775
- result.version = util.getValue(lines, 'chassis_version');
776
- result.serial = util.getValue(lines, 'chassis_serial');
777
- result.assetTag = util.getValue(lines, 'chassis_asset_tag');
778
- if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
779
- if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
780
- if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
781
- if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
782
-
783
- if (callback) { callback(result); }
784
- resolve(result);
785
- });
786
- }
787
- if (_darwin) {
788
- exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
789
- if (!error) {
790
- let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
791
- result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
792
- result.model = util.getValue(lines, 'model', '=', true);
793
- result.version = util.getValue(lines, 'version', '=', true);
794
- result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
795
- result.assetTag = util.getValue(lines, 'board-id', '=', true);
796
- }
797
-
798
- if (callback) { callback(result); }
799
- resolve(result);
800
- });
801
- }
802
- if (_sunos) {
803
- if (callback) { callback(result); }
804
- resolve(result);
805
- }
806
- if (_windows) {
807
- try {
808
- util.powerShell('Get-WmiObject Win32_SystemEnclosure | fl *').then((stdout, error) => {
809
- if (!error) {
810
- let lines = stdout.toString().split('\r\n');
811
-
812
- result.manufacturer = util.getValue(lines, 'manufacturer', ':');
813
- result.model = util.getValue(lines, 'model', ':');
814
- const ctype = parseInt(util.getValue(lines, 'ChassisTypes', ':').replace(/\D/g, ''));
815
- result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
816
- result.version = util.getValue(lines, 'version', ':');
817
- result.serial = util.getValue(lines, 'serialnumber', ':');
818
- result.assetTag = util.getValue(lines, 'partnumber', ':');
819
- result.sku = util.getValue(lines, 'sku', ':');
820
- if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
821
- if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
822
- if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
823
- if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
824
- }
825
-
826
- if (callback) { callback(result); }
827
- resolve(result);
828
- });
829
- } catch (e) {
830
- if (callback) { callback(result); }
831
- resolve(result);
832
- }
833
- }
834
- });
835
- });
836
- }
837
-
838
- exports.chassis = chassis;
839
-
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // system.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2021
9
+ // Author: Sebastian Hildebrandt
10
+ // ----------------------------------------------------------------------------------
11
+ // License: MIT
12
+ // ==================================================================================
13
+ // 2. System (Hardware, BIOS, Base Board)
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const fs = require('fs');
17
+ const os = require('os');
18
+ const util = require('./util');
19
+ const exec = require('child_process').exec;
20
+ const execSync = require('child_process').execSync;
21
+ const execPromise = util.promisify(require('child_process').exec);
22
+
23
+ let _platform = process.platform;
24
+
25
+ const _linux = (_platform === 'linux');
26
+ const _darwin = (_platform === 'darwin');
27
+ const _windows = (_platform === 'win32');
28
+ const _freebsd = (_platform === 'freebsd');
29
+ const _openbsd = (_platform === 'openbsd');
30
+ const _netbsd = (_platform === 'netbsd');
31
+ const _sunos = (_platform === 'sunos');
32
+
33
+ function system(callback) {
34
+
35
+ return new Promise((resolve) => {
36
+ process.nextTick(() => {
37
+
38
+ let result = {
39
+ manufacturer: '',
40
+ model: 'Computer',
41
+ version: '',
42
+ serial: '-',
43
+ uuid: '-',
44
+ sku: '-',
45
+ virtual: false
46
+ };
47
+
48
+ if (_linux || _freebsd || _openbsd || _netbsd) {
49
+ exec('export LC_ALL=C; dmidecode -t system 2>/dev/null; unset LC_ALL', function (error, stdout) {
50
+ // if (!error) {
51
+ let lines = stdout.toString().split('\n');
52
+ result.manufacturer = util.getValue(lines, 'manufacturer');
53
+ result.model = util.getValue(lines, 'product name');
54
+ result.version = util.getValue(lines, 'version');
55
+ result.serial = util.getValue(lines, 'serial number');
56
+ result.uuid = util.getValue(lines, 'uuid').toLowerCase();
57
+ result.sku = util.getValue(lines, 'sku number');
58
+ // }
59
+ // Non-Root values
60
+ const cmd = `echo -n "product_name: "; cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null; echo;
61
+ echo -n "product_serial: "; cat /sys/devices/virtual/dmi/id/product_serial 2>/dev/null; echo;
62
+ echo -n "product_uuid: "; cat /sys/devices/virtual/dmi/id/product_uuid 2>/dev/null; echo;
63
+ echo -n "product_version: "; cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null; echo;
64
+ echo -n "sys_vendor: "; cat /sys/devices/virtual/dmi/id/sys_vendor 2>/dev/null; echo;`;
65
+ try {
66
+ lines = execSync(cmd).toString().split('\n');
67
+ result.manufacturer = result.manufacturer === '' ? util.getValue(lines, 'sys_vendor') : result.manufacturer;
68
+ result.model = result.model === '' ? util.getValue(lines, 'product_name') : result.model;
69
+ result.version = result.version === '' ? util.getValue(lines, 'product_version') : result.version;
70
+ result.serial = result.serial === '' ? util.getValue(lines, 'product_serial') : result.serial;
71
+ result.uuid = result.uuid === '' ? util.getValue(lines, 'product_uuid').toLowerCase() : result.uuid;
72
+ } catch (e) {
73
+ util.noop();
74
+ }
75
+ if (!result.serial || result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
76
+ if (!result.manufacturer || result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = ''; }
77
+ if (!result.model || result.model.toLowerCase().indexOf('o.e.m.') !== -1) { result.model = 'Computer'; }
78
+ if (!result.version || result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = ''; }
79
+ if (!result.sku || result.sku.toLowerCase().indexOf('o.e.m.') !== -1) { result.sku = '-'; }
80
+
81
+ // detect virtual (1)
82
+ if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware') || result.model.toLowerCase().startsWith('droplet')) {
83
+ result.virtual = true;
84
+ switch (result.model.toLowerCase()) {
85
+ case 'virtualbox':
86
+ result.virtualHost = 'VirtualBox';
87
+ break;
88
+ case 'vmware':
89
+ result.virtualHost = 'VMware';
90
+ break;
91
+ case 'kvm':
92
+ result.virtualHost = 'KVM';
93
+ break;
94
+ case 'bochs':
95
+ result.virtualHost = 'bochs';
96
+ break;
97
+ }
98
+ }
99
+ if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
100
+ result.virtual = true;
101
+ switch (result.manufacturer.toLowerCase()) {
102
+ case 'vmware':
103
+ result.virtualHost = 'VMware';
104
+ break;
105
+ case 'xen':
106
+ result.virtualHost = 'Xen';
107
+ break;
108
+ }
109
+ }
110
+ if (!result.virtual) {
111
+ try {
112
+ const disksById = execSync('ls -1 /dev/disk/by-id/ 2>/dev/null').toString();
113
+ if (disksById.indexOf('_QEMU_') >= 0) {
114
+ result.virtual = true;
115
+ result.virtualHost = 'QEMU';
116
+ }
117
+ if (disksById.indexOf('_VBOX_') >= 0) {
118
+ result.virtual = true;
119
+ result.virtualHost = 'VirtualBox';
120
+ }
121
+ } catch (e) {
122
+ util.noop();
123
+ }
124
+ }
125
+ if (!result.virtual && (os.release().toLowerCase().indexOf('microsoft') >= 0 || os.release().toLowerCase().endsWith('wsl2'))) {
126
+ const kernelVersion = parseFloat(os.release().toLowerCase());
127
+ result.virtual = true;
128
+ result.manufacturer = 'Microsoft';
129
+ result.model = 'WSL';
130
+ result.version = kernelVersion < 4.19 ? '1' : '2';
131
+ }
132
+ if ((_freebsd || _openbsd || _netbsd) && !result.virtualHost) {
133
+ try {
134
+ const procInfo = execSync('dmidecode -t 4');
135
+ const procLines = procInfo.toString().split('\n');
136
+ const procManufacturer = util.getValue(procLines, 'manufacturer', ':', true);
137
+ switch (procManufacturer.toLowerCase()) {
138
+ case 'virtualbox':
139
+ result.virtualHost = 'VirtualBox';
140
+ break;
141
+ case 'vmware':
142
+ result.virtualHost = 'VMware';
143
+ break;
144
+ case 'kvm':
145
+ result.virtualHost = 'KVM';
146
+ break;
147
+ case 'bochs':
148
+ result.virtualHost = 'bochs';
149
+ break;
150
+ }
151
+ } catch (e) {
152
+ util.noop();
153
+ }
154
+ }
155
+ // detect docker
156
+ if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) {
157
+ result.model = 'Docker Container';
158
+ }
159
+ try {
160
+ const stdout = execSync('dmesg 2>/dev/null | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen" | grep -viE "Nested Virtualization|/virtual/"');
161
+ // detect virtual machines
162
+ let lines = stdout.toString().split('\n');
163
+ if (lines.length > 0) {
164
+ if (result.model === 'Computer') { result.model = 'Virtual machine'; }
165
+ result.virtual = true;
166
+ if (stdout.toString().toLowerCase().indexOf('vmware') >= 0 && !result.virtualHost) {
167
+ result.virtualHost = 'VMware';
168
+ }
169
+ if (stdout.toString().toLowerCase().indexOf('qemu') >= 0 && !result.virtualHost) {
170
+ result.virtualHost = 'QEMU';
171
+ }
172
+ if (stdout.toString().toLowerCase().indexOf('xen') >= 0 && !result.virtualHost) {
173
+ result.virtualHost = 'Xen';
174
+ }
175
+ if (stdout.toString().toLowerCase().indexOf('kvm') >= 0 && !result.virtualHost) {
176
+ result.virtualHost = 'KVM';
177
+ }
178
+ }
179
+ } catch (e) {
180
+ util.noop();
181
+ }
182
+
183
+ if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') {
184
+ // Check Raspberry Pi
185
+ fs.readFile('/proc/cpuinfo', function (error, stdout) {
186
+ if (!error) {
187
+ let lines = stdout.toString().split('\n');
188
+ result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
189
+ result.version = util.getValue(lines, 'revision', ':', true).toLowerCase();
190
+ result.serial = util.getValue(lines, 'serial', ':', true);
191
+ const model = util.getValue(lines, 'model:', ':', true);
192
+ // reference values: https://elinux.org/RPi_HardwareHistory
193
+ // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
194
+ if ((result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2710' || result.model === 'BCM2711' || result.model === 'BCM2836' || result.model === 'BCM2837') && model.toLowerCase().indexOf('raspberry') >= 0) {
195
+ const rPIRevision = util.decodePiCpuinfo(lines);
196
+ result.model = rPIRevision.model;
197
+ result.version = rPIRevision.revisionCode;
198
+ result.manufacturer = 'Raspberry Pi Foundation';
199
+ result.raspberry = {
200
+ manufacturer: rPIRevision.manufacturer,
201
+ processor: rPIRevision.processor,
202
+ type: rPIRevision.type,
203
+ revision: rPIRevision.revision
204
+ };
205
+ }
206
+
207
+ // if (result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2835' || result.model === 'BCM2837') {
208
+
209
+
210
+ // // Pi 4
211
+ // if (['d03114'].indexOf(result.version) >= 0) {
212
+ // result.model = result.model + ' - Pi 4 Model B';
213
+ // result.version = result.version + ' - Rev. 1.4';
214
+ // }
215
+ // if (['b03112', 'c03112'].indexOf(result.version) >= 0) {
216
+ // result.model = result.model + ' - Pi 4 Model B';
217
+ // result.version = result.version + ' - Rev. 1.2';
218
+ // }
219
+ // if (['a03111', 'b03111', 'c03111'].indexOf(result.version) >= 0) {
220
+ // result.model = result.model + ' - Pi 4 Model B';
221
+ // result.version = result.version + ' - Rev. 1.1';
222
+ // }
223
+ // // Pi 3
224
+ // if (['a02082', 'a22082', 'a32082', 'a52082'].indexOf(result.version) >= 0) {
225
+ // result.model = result.model + ' - Pi 3 Model B';
226
+ // result.version = result.version + ' - Rev. 1.2';
227
+ // }
228
+ // if (['a22083'].indexOf(result.version) >= 0) {
229
+ // result.model = result.model + ' - Pi 3 Model B';
230
+ // result.version = result.version + ' - Rev. 1.3';
231
+ // }
232
+ // if (['a020d3'].indexOf(result.version) >= 0) {
233
+ // result.model = result.model + ' - Pi 3 Model B+';
234
+ // result.version = result.version + ' - Rev. 1.3';
235
+ // }
236
+ // if (['9020e0'].indexOf(result.version) >= 0) {
237
+ // result.model = result.model + ' - Pi 3 Model A+';
238
+ // result.version = result.version + ' - Rev. 1.3';
239
+ // }
240
+ // // Pi 2 Model B
241
+ // if (['a01040'].indexOf(result.version) >= 0) {
242
+ // result.model = result.model + ' - Pi 2 Model B';
243
+ // result.version = result.version + ' - Rev. 1.0';
244
+ // }
245
+ // if (['a01041', 'a21041'].indexOf(result.version) >= 0) {
246
+ // result.model = result.model + ' - Pi 2 Model B';
247
+ // result.version = result.version + ' - Rev. 1.1';
248
+ // }
249
+ // if (['a22042', 'a02042'].indexOf(result.version) >= 0) {
250
+ // result.model = result.model + ' - Pi 2 Model B';
251
+ // result.version = result.version + ' - Rev. 1.2';
252
+ // }
253
+
254
+ // // Compute Model
255
+ // if (['a02100'].indexOf(result.version) >= 0) {
256
+ // result.model = result.model + ' - Pi CM3+';
257
+ // result.version = result.version + ' - Rev 1.0';
258
+ // }
259
+ // if (['a020a0', 'a220a0'].indexOf(result.version) >= 0) {
260
+ // result.model = result.model + ' - Pi CM3';
261
+ // result.version = result.version + ' - Rev 1.0';
262
+ // }
263
+ // if (['900061'].indexOf(result.version) >= 0) {
264
+ // result.model = result.model + ' - Pi CM';
265
+ // result.version = result.version + ' - Rev 1.1';
266
+ // }
267
+
268
+ // // Pi Zero
269
+ // if (['900092', '920092'].indexOf(result.version) >= 0) {
270
+ // result.model = result.model + ' - Pi Zero';
271
+ // result.version = result.version + ' - Rev 1.2';
272
+ // }
273
+ // if (['900093', '920093'].indexOf(result.version) >= 0) {
274
+ // result.model = result.model + ' - Pi Zero';
275
+ // result.version = result.version + ' - Rev 1.3';
276
+ // }
277
+ // if (['9000c1'].indexOf(result.version) >= 0) {
278
+ // result.model = result.model + ' - Pi Zero W';
279
+ // result.version = result.version + ' - Rev 1.1';
280
+ // }
281
+
282
+ // // A, B, A+ B+
283
+ // if (['0002', '0003'].indexOf(result.version) >= 0) {
284
+ // result.model = result.model + ' - Pi Model B';
285
+ // result.version = result.version + ' - Rev 1.0';
286
+ // }
287
+ // if (['0004', '0005', '0006', '000d', '000e', '000f'].indexOf(result.version) >= 0) {
288
+ // result.model = result.model + ' - Pi Model B';
289
+ // result.version = result.version + ' - Rev 2.0';
290
+ // }
291
+ // if (['0007', '0008', '0009'].indexOf(result.version) >= 0) {
292
+ // result.model = result.model + ' - Pi Model A';
293
+ // result.version = result.version + ' - Rev 2.0';
294
+ // }
295
+ // if (['0010'].indexOf(result.version) >= 0) {
296
+ // result.model = result.model + ' - Pi Model B+';
297
+ // result.version = result.version + ' - Rev 1.0';
298
+ // }
299
+ // if (['0012'].indexOf(result.version) >= 0) {
300
+ // result.model = result.model + ' - Pi Model A+';
301
+ // result.version = result.version + ' - Rev 1.0';
302
+ // }
303
+ // if (['0013', '900032'].indexOf(result.version) >= 0) {
304
+ // result.model = result.model + ' - Pi Model B+';
305
+ // result.version = result.version + ' - Rev 1.2';
306
+ // }
307
+ // if (['0015', '900021'].indexOf(result.version) >= 0) {
308
+ // result.model = result.model + ' - Pi Model A+';
309
+ // result.version = result.version + ' - Rev 1.1';
310
+ // }
311
+ // if (result.model.indexOf('Pi') !== -1 && result.version) { // Pi, Pi Zero
312
+ // result.manufacturer = 'Raspberry Pi Foundation';
313
+ // }
314
+ // }
315
+ }
316
+ if (callback) { callback(result); }
317
+ resolve(result);
318
+ });
319
+ } else {
320
+ if (callback) { callback(result); }
321
+ resolve(result);
322
+ }
323
+ });
324
+ }
325
+ if (_darwin) {
326
+ exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
327
+ if (!error) {
328
+ let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
329
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
330
+ result.model = util.getValue(lines, 'model', '=', true);
331
+ result.version = util.getValue(lines, 'version', '=', true);
332
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
333
+ result.uuid = util.getValue(lines, 'ioplatformuuid', '=', true).toLowerCase();
334
+ result.sku = util.getValue(lines, 'board-id', '=', true);
335
+ }
336
+ if (callback) { callback(result); }
337
+ resolve(result);
338
+ });
339
+ }
340
+ if (_sunos) {
341
+ if (callback) { callback(result); }
342
+ resolve(result);
343
+ }
344
+ if (_windows) {
345
+ try {
346
+ util.powerShell('Get-WmiObject Win32_ComputerSystemProduct | fl *').then((stdout, error) => {
347
+ if (!error) {
348
+ // let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0)[0].trim().split(/\s\s+/);
349
+ let lines = stdout.split('\r\n');
350
+ result.manufacturer = util.getValue(lines, 'vendor', ':');
351
+ result.model = util.getValue(lines, 'name', ':');
352
+ result.version = util.getValue(lines, 'version', ':');
353
+ result.serial = util.getValue(lines, 'identifyingnumber', ':');
354
+ result.uuid = util.getValue(lines, 'uuid', ':').toLowerCase();
355
+ // detect virtual (1)
356
+ if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware')) {
357
+ result.virtual = true;
358
+ switch (result.model.toLowerCase()) {
359
+ case 'virtualbox':
360
+ result.virtualHost = 'VirtualBox';
361
+ break;
362
+ case 'vmware':
363
+ result.virtualHost = 'VMware';
364
+ break;
365
+ case 'kvm':
366
+ result.virtualHost = 'KVM';
367
+ break;
368
+ case 'bochs':
369
+ result.virtualHost = 'bochs';
370
+ break;
371
+ }
372
+ }
373
+ if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
374
+ result.virtual = true;
375
+ switch (result.manufacturer.toLowerCase()) {
376
+ case 'vmware':
377
+ result.virtualHost = 'VMware';
378
+ break;
379
+ case 'xen':
380
+ result.virtualHost = 'Xen';
381
+ break;
382
+ }
383
+ }
384
+ util.powerShell('Get-WmiObject MS_Systeminformation -Namespace "root/wmi" | fl *').then((stdout, error) => {
385
+ if (!error) {
386
+ let lines = stdout.split('\r\n');
387
+ result.sku = util.getValue(lines, 'systemsku', ':');
388
+ }
389
+ if (!result.virtual) {
390
+ util.powerShell('Get-WmiObject Win32_bios | select Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => {
391
+ if (!error) {
392
+ let lines = stdout.toString();
393
+ if (lines.indexOf('VRTUAL') >= 0 || lines.indexOf('A M I ') >= 0 || lines.indexOf('VirtualBox') >= 0 || lines.indexOf('VMWare') >= 0 || lines.indexOf('Xen') >= 0) {
394
+ result.virtual = true;
395
+ if (lines.indexOf('VirtualBox') >= 0 && !result.virtualHost) {
396
+ result.virtualHost = 'VirtualBox';
397
+ }
398
+ if (lines.indexOf('VMware') >= 0 && !result.virtualHost) {
399
+ result.virtualHost = 'VMware';
400
+ }
401
+ if (lines.indexOf('Xen') >= 0 && !result.virtualHost) {
402
+ result.virtualHost = 'Xen';
403
+ }
404
+ if (lines.indexOf('VRTUAL') >= 0 && !result.virtualHost) {
405
+ result.virtualHost = 'Hyper-V';
406
+ }
407
+ if (lines.indexOf('A M I') >= 0 && !result.virtualHost) {
408
+ result.virtualHost = 'Virtual PC';
409
+ }
410
+ }
411
+ if (callback) { callback(result); }
412
+ resolve(result);
413
+ } else {
414
+ if (callback) { callback(result); }
415
+ resolve(result);
416
+ }
417
+ });
418
+ } else {
419
+ if (callback) { callback(result); }
420
+ resolve(result);
421
+ }
422
+ });
423
+ } else {
424
+ if (callback) { callback(result); }
425
+ resolve(result);
426
+ }
427
+ });
428
+ } catch (e) {
429
+ if (callback) { callback(result); }
430
+ resolve(result);
431
+ }
432
+ }
433
+ });
434
+ });
435
+ }
436
+
437
+ exports.system = system;
438
+
439
+ function bios(callback) {
440
+
441
+ return new Promise((resolve) => {
442
+ process.nextTick(() => {
443
+
444
+ let result = {
445
+ vendor: '',
446
+ version: '',
447
+ releaseDate: '',
448
+ revision: '',
449
+ };
450
+ let cmd = '';
451
+ if (_linux || _freebsd || _openbsd || _netbsd) {
452
+ if (process.arch === 'arm') {
453
+ cmd = 'cat /proc/cpuinfo | grep Serial';
454
+ } else {
455
+ cmd = 'export LC_ALL=C; dmidecode -t bios 2>/dev/null; unset LC_ALL';
456
+ }
457
+ exec(cmd, function (error, stdout) {
458
+ let lines = stdout.toString().split('\n');
459
+ result.vendor = util.getValue(lines, 'Vendor');
460
+ result.version = util.getValue(lines, 'Version');
461
+ let datetime = util.getValue(lines, 'Release Date');
462
+ result.releaseDate = util.parseDateTime(datetime).date;
463
+ result.revision = util.getValue(lines, 'BIOS Revision');
464
+ result.serial = util.getValue(lines, 'SerialNumber');
465
+ let language = util.getValue(lines, 'Currently Installed Language').split('|')[0];
466
+ if (language) {
467
+ result.language = language;
468
+ }
469
+ if (lines.length && stdout.toString().indexOf('Characteristics:') >= 0) {
470
+ const features = [];
471
+ lines.forEach(line => {
472
+ if (line.indexOf(' is supported') >= 0) {
473
+ const feature = line.split(' is supported')[0].trim();
474
+ features.push(feature);
475
+ }
476
+ });
477
+ result.features = features;
478
+ }
479
+ // Non-Root values
480
+ const cmd = `echo -n "bios_date: "; cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null; echo;
481
+ echo -n "bios_vendor: "; cat /sys/devices/virtual/dmi/id/bios_vendor 2>/dev/null; echo;
482
+ echo -n "bios_version: "; cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null; echo;`;
483
+ try {
484
+ lines = execSync(cmd).toString().split('\n');
485
+ result.vendor = !result.vendor ? util.getValue(lines, 'bios_vendor') : result.vendor;
486
+ result.version = !result.version ? util.getValue(lines, 'bios_version') : result.version;
487
+ datetime = util.getValue(lines, 'bios_date');
488
+ result.releaseDate = !result.releaseDate ? util.parseDateTime(datetime).date : result.releaseDate;
489
+ } catch (e) {
490
+ util.noop();
491
+ }
492
+ if (callback) { callback(result); }
493
+ resolve(result);
494
+ });
495
+ }
496
+ if (_darwin) {
497
+ result.vendor = 'Apple Inc.';
498
+ exec(
499
+ 'system_profiler SPHardwareDataType -json', function (error, stdout) {
500
+ try {
501
+ const hardwareData = JSON.parse(stdout.toString());
502
+ if (hardwareData && hardwareData.SPHardwareDataType && hardwareData.SPHardwareDataType.length) {
503
+ let bootRomVersion = hardwareData.SPHardwareDataType[0].boot_rom_version;
504
+ bootRomVersion = bootRomVersion ? bootRomVersion.split('(')[0].trim() : null;
505
+ result.version = bootRomVersion;
506
+ }
507
+ } catch (e) {
508
+ util.noop();
509
+ }
510
+ if (callback) { callback(result); }
511
+ resolve(result);
512
+ });
513
+ }
514
+ if (_sunos) {
515
+ result.vendor = 'Sun Microsystems';
516
+ if (callback) { callback(result); }
517
+ resolve(result);
518
+ }
519
+ if (_windows) {
520
+ try {
521
+ util.powerShell('Get-WmiObject Win32_bios | fl *').then((stdout, error) => {
522
+ if (!error) {
523
+ let lines = stdout.toString().split('\r\n');
524
+ const description = util.getValue(lines, 'description', ':');
525
+ if (description.indexOf(' Version ') !== -1) {
526
+ // ... Phoenix ROM BIOS PLUS Version 1.10 A04
527
+ result.vendor = description.split(' Version ')[0].trim();
528
+ result.version = description.split(' Version ')[1].trim();
529
+ } else if (description.indexOf(' Ver: ') !== -1) {
530
+ // ... BIOS Date: 06/27/16 17:50:16 Ver: 1.4.5
531
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
532
+ result.version = description.split(' Ver: ')[1].trim();
533
+ } else {
534
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
535
+ result.version = util.getValue(lines, 'version', ':');
536
+ }
537
+ result.releaseDate = util.getValue(lines, 'releasedate', ':');
538
+ if (result.releaseDate.length >= 10) {
539
+ result.releaseDate = result.releaseDate.substr(0, 4) + '-' + result.releaseDate.substr(4, 2) + '-' + result.releaseDate.substr(6, 2);
540
+ }
541
+ result.revision = util.getValue(lines, 'buildnumber', ':');
542
+ result.serial = util.getValue(lines, 'serialnumber', ':');
543
+ }
544
+
545
+ if (callback) { callback(result); }
546
+ resolve(result);
547
+ });
548
+ } catch (e) {
549
+ if (callback) { callback(result); }
550
+ resolve(result);
551
+ }
552
+ }
553
+ });
554
+ });
555
+ }
556
+
557
+ exports.bios = bios;
558
+
559
+ function baseboard(callback) {
560
+
561
+ return new Promise((resolve) => {
562
+ process.nextTick(() => {
563
+
564
+ let result = {
565
+ manufacturer: '',
566
+ model: '',
567
+ version: '',
568
+ serial: '-',
569
+ assetTag: '-',
570
+ memMax: null,
571
+ memSlots: null
572
+ };
573
+ let cmd = '';
574
+ if (_linux || _freebsd || _openbsd || _netbsd) {
575
+ if (process.arch === 'arm') {
576
+ cmd = 'cat /proc/cpuinfo | grep Serial';
577
+ // 'BCM2709', 'BCM2835', 'BCM2708' -->
578
+ } else {
579
+ cmd = 'export LC_ALL=C; dmidecode -t 2 2>/dev/null; unset LC_ALL';
580
+ }
581
+ const workload = [];
582
+ workload.push(execPromise(cmd));
583
+ workload.push(execPromise('export LC_ALL=C; dmidecode -t memory 2>/dev/null'));
584
+ util.promiseAll(
585
+ workload
586
+ ).then(data => {
587
+ let lines = data.results[0] ? data.results[0].toString().split('\n') : [''];
588
+ result.manufacturer = util.getValue(lines, 'Manufacturer');
589
+ result.model = util.getValue(lines, 'Product Name');
590
+ result.version = util.getValue(lines, 'Version');
591
+ result.serial = util.getValue(lines, 'Serial Number');
592
+ result.assetTag = util.getValue(lines, 'Asset Tag');
593
+ // Non-Root values
594
+ const cmd = `echo -n "board_asset_tag: "; cat /sys/devices/virtual/dmi/id/board_asset_tag 2>/dev/null; echo;
595
+ echo -n "board_name: "; cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null; echo;
596
+ echo -n "board_serial: "; cat /sys/devices/virtual/dmi/id/board_serial 2>/dev/null; echo;
597
+ echo -n "board_vendor: "; cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null; echo;
598
+ echo -n "board_version: "; cat /sys/devices/virtual/dmi/id/board_version 2>/dev/null; echo;`;
599
+ try {
600
+ lines = execSync(cmd).toString().split('\n');
601
+ result.manufacturer = !result.manufacturer ? util.getValue(lines, 'board_vendor') : result.manufacturer;
602
+ result.model = !result.model ? util.getValue(lines, 'board_name') : result.model;
603
+ result.version = !result.version ? util.getValue(lines, 'board_version') : result.version;
604
+ result.serial = !result.serial ? util.getValue(lines, 'board_serial') : result.serial;
605
+ result.assetTag = !result.assetTag ? util.getValue(lines, 'board_asset_tag') : result.assetTag;
606
+ } catch (e) {
607
+ util.noop();
608
+ }
609
+ if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
610
+ if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
611
+
612
+ // mem
613
+ lines = data.results[1] ? data.results[1].toString().split('\n') : [''];
614
+ result.memMax = util.toInt(util.getValue(lines, 'Maximum Capacity')) * 1024 * 1024 * 1024 || null;
615
+ result.memSlots = util.toInt(util.getValue(lines, 'Number Of Devices')) || null;
616
+
617
+ // raspberry
618
+ let linesRpi = '';
619
+ try {
620
+ linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
621
+ } catch (e) {
622
+ util.noop();
623
+ }
624
+ const hardware = util.getValue(linesRpi, 'hardware');
625
+ if (hardware.startsWith('BCM')) {
626
+ const rpi = util.decodePiCpuinfo(linesRpi);
627
+ result.manufacturer = rpi.manufacturer;
628
+ result.model = 'Raspberry Pi';
629
+ result.serial = rpi.serial;
630
+ result.version = rpi.type + ' - ' + rpi.revision;
631
+ result.memMax = os.totalmem();
632
+ result.memSlots = 0;
633
+ }
634
+
635
+ if (callback) { callback(result); }
636
+ resolve(result);
637
+ });
638
+ }
639
+ if (_darwin) {
640
+ const workload = [];
641
+ workload.push(execPromise('ioreg -c IOPlatformExpertDevice -d 2'));
642
+ workload.push(execPromise('system_profiler SPMemoryDataType'));
643
+ util.promiseAll(
644
+ workload
645
+ ).then(data => {
646
+ let lines = data.results[0] ? data.results[0].toString().replace(/[<>"]/g, '').split('\n') : [''];
647
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
648
+ result.model = util.getValue(lines, 'model', '=', true);
649
+ result.version = util.getValue(lines, 'version', '=', true);
650
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
651
+ result.assetTag = util.getValue(lines, 'board-id', '=', true);
652
+
653
+ // mem
654
+ let devices = data.results[1] ? data.results[1].toString().split(' BANK ') : [''];
655
+ if (devices.length === 1) {
656
+ devices = data.results[1] ? data.results[1].toString().split(' DIMM') : [''];
657
+ }
658
+ devices.shift();
659
+ result.memSlots = devices.length;
660
+
661
+ if (os.arch() === 'arm64') {
662
+ result.memSlots = 0;
663
+ result.memMax = os.totalmem();
664
+ }
665
+
666
+ if (callback) { callback(result); }
667
+ resolve(result);
668
+ });
669
+ }
670
+ if (_sunos) {
671
+ if (callback) { callback(result); }
672
+ resolve(result);
673
+ }
674
+ if (_windows) {
675
+ try {
676
+ const workload = [];
677
+ workload.push(util.powerShell('Get-WmiObject Win32_baseboard | fl *'));
678
+ workload.push(util.powerShell('Get-WmiObject Win32_physicalmemoryarray | select MaxCapacity, MemoryDevices | fl'));
679
+ util.promiseAll(
680
+ workload
681
+ ).then(data => {
682
+ let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
683
+
684
+ result.manufacturer = util.getValue(lines, 'manufacturer', ':');
685
+ result.model = util.getValue(lines, 'model', ':');
686
+ if (!result.model) {
687
+ result.model = util.getValue(lines, 'product', ':');
688
+ }
689
+ result.version = util.getValue(lines, 'version', ':');
690
+ result.serial = util.getValue(lines, 'serialnumber', ':');
691
+ result.assetTag = util.getValue(lines, 'partnumber', ':');
692
+ if (!result.assetTag) {
693
+ result.assetTag = util.getValue(lines, 'sku', ':');
694
+ }
695
+
696
+ // memphysical
697
+ lines = data.results[1] ? data.results[1].toString().split('\r\n') : [''];
698
+ result.memMax = util.toInt(util.getValue(lines, 'MaxCapacity', ':')) || null;
699
+ result.memSlots = util.toInt(util.getValue(lines, 'MemoryDevices', ':')) || null;
700
+
701
+ if (callback) { callback(result); }
702
+ resolve(result);
703
+ });
704
+ } catch (e) {
705
+ if (callback) { callback(result); }
706
+ resolve(result);
707
+ }
708
+ }
709
+ });
710
+ });
711
+ }
712
+
713
+ exports.baseboard = baseboard;
714
+
715
+ function chassis(callback) {
716
+ const chassisTypes = ['Other',
717
+ 'Unknown',
718
+ 'Desktop',
719
+ 'Low Profile Desktop',
720
+ 'Pizza Box',
721
+ 'Mini Tower',
722
+ 'Tower',
723
+ 'Portable',
724
+ 'Laptop',
725
+ 'Notebook',
726
+ 'Hand Held',
727
+ 'Docking Station',
728
+ 'All in One',
729
+ 'Sub Notebook',
730
+ 'Space-Saving',
731
+ 'Lunch Box',
732
+ 'Main System Chassis',
733
+ 'Expansion Chassis',
734
+ 'SubChassis',
735
+ 'Bus Expansion Chassis',
736
+ 'Peripheral Chassis',
737
+ 'Storage Chassis',
738
+ 'Rack Mount Chassis',
739
+ 'Sealed-Case PC',
740
+ 'Multi-System Chassis',
741
+ 'Compact PCI',
742
+ 'Advanced TCA',
743
+ 'Blade',
744
+ 'Blade Enclosure',
745
+ 'Tablet',
746
+ 'Convertible',
747
+ 'Detachable',
748
+ 'IoT Gateway ',
749
+ 'Embedded PC',
750
+ 'Mini PC',
751
+ 'Stick PC',
752
+ ];
753
+
754
+ return new Promise((resolve) => {
755
+ process.nextTick(() => {
756
+
757
+ let result = {
758
+ manufacturer: '',
759
+ model: '',
760
+ type: '',
761
+ version: '',
762
+ serial: '-',
763
+ assetTag: '-',
764
+ sku: '',
765
+ };
766
+ if (_linux || _freebsd || _openbsd || _netbsd) {
767
+ const cmd = `echo -n "chassis_asset_tag: "; cat /sys/devices/virtual/dmi/id/chassis_asset_tag 2>/dev/null; echo;
768
+ echo -n "chassis_serial: "; cat /sys/devices/virtual/dmi/id/chassis_serial 2>/dev/null; echo;
769
+ echo -n "chassis_type: "; cat /sys/devices/virtual/dmi/id/chassis_type 2>/dev/null; echo;
770
+ echo -n "chassis_vendor: "; cat /sys/devices/virtual/dmi/id/chassis_vendor 2>/dev/null; echo;
771
+ echo -n "chassis_version: "; cat /sys/devices/virtual/dmi/id/chassis_version 2>/dev/null; echo;`;
772
+ exec(cmd, function (error, stdout) {
773
+ let lines = stdout.toString().split('\n');
774
+ result.manufacturer = util.getValue(lines, 'chassis_vendor');
775
+ const ctype = parseInt(util.getValue(lines, 'chassis_type').replace(/\D/g, ''));
776
+ result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
777
+ result.version = util.getValue(lines, 'chassis_version');
778
+ result.serial = util.getValue(lines, 'chassis_serial');
779
+ result.assetTag = util.getValue(lines, 'chassis_asset_tag');
780
+ if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
781
+ if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
782
+ if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
783
+ if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
784
+
785
+ if (callback) { callback(result); }
786
+ resolve(result);
787
+ });
788
+ }
789
+ if (_darwin) {
790
+ exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
791
+ if (!error) {
792
+ let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
793
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
794
+ result.model = util.getValue(lines, 'model', '=', true);
795
+ result.version = util.getValue(lines, 'version', '=', true);
796
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
797
+ result.assetTag = util.getValue(lines, 'board-id', '=', true);
798
+ }
799
+
800
+ if (callback) { callback(result); }
801
+ resolve(result);
802
+ });
803
+ }
804
+ if (_sunos) {
805
+ if (callback) { callback(result); }
806
+ resolve(result);
807
+ }
808
+ if (_windows) {
809
+ try {
810
+ util.powerShell('Get-WmiObject Win32_SystemEnclosure | fl *').then((stdout, error) => {
811
+ if (!error) {
812
+ let lines = stdout.toString().split('\r\n');
813
+
814
+ result.manufacturer = util.getValue(lines, 'manufacturer', ':');
815
+ result.model = util.getValue(lines, 'model', ':');
816
+ const ctype = parseInt(util.getValue(lines, 'ChassisTypes', ':').replace(/\D/g, ''));
817
+ result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
818
+ result.version = util.getValue(lines, 'version', ':');
819
+ result.serial = util.getValue(lines, 'serialnumber', ':');
820
+ result.assetTag = util.getValue(lines, 'partnumber', ':');
821
+ result.sku = util.getValue(lines, 'sku', ':');
822
+ if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
823
+ if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
824
+ if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
825
+ if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
826
+ }
827
+
828
+ if (callback) { callback(result); }
829
+ resolve(result);
830
+ });
831
+ } catch (e) {
832
+ if (callback) { callback(result); }
833
+ resolve(result);
834
+ }
835
+ }
836
+ });
837
+ });
838
+ }
839
+
840
+ exports.chassis = chassis;
841
+