systeminformation 5.9.4 → 5.9.8

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,841 +1,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 && util.linuxVersion().toLowerCase().indexOf('microsoft') >= 0) {
126
- let versionStr = util.linuxVersion().toLowerCase();
127
- versionStr = versionStr.split('-')[0].replace('#', '');
128
- const version = parseInt(versionStr, 10) || null;
129
- result.virtual = true;
130
- result.manufacturer = 'Microsoft';
131
- result.model = 'WSL';
132
- result.version = version;
133
- }
134
- if ((_freebsd || _openbsd || _netbsd) && !result.virtualHost) {
135
- try {
136
- const procInfo = execSync('dmidecode -t 4');
137
- const procLines = procInfo.toString().split('\n');
138
- const procManufacturer = util.getValue(procLines, 'manufacturer', ':', true);
139
- switch (procManufacturer.toLowerCase()) {
140
- case 'virtualbox':
141
- result.virtualHost = 'VirtualBox';
142
- break;
143
- case 'vmware':
144
- result.virtualHost = 'VMware';
145
- break;
146
- case 'kvm':
147
- result.virtualHost = 'KVM';
148
- break;
149
- case 'bochs':
150
- result.virtualHost = 'bochs';
151
- break;
152
- }
153
- } catch (e) {
154
- util.noop();
155
- }
156
- }
157
- // detect docker
158
- if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) {
159
- result.model = 'Docker Container';
160
- }
161
- try {
162
- const stdout = execSync('dmesg 2>/dev/null | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen" | grep -viE "Nested Virtualization|/virtual/"');
163
- // detect virtual machines
164
- let lines = stdout.toString().split('\n');
165
- if (lines.length > 0) {
166
- if (result.model === 'Computer') { result.model = 'Virtual machine'; }
167
- result.virtual = true;
168
- if (stdout.toString().toLowerCase().indexOf('vmware') >= 0 && !result.virtualHost) {
169
- result.virtualHost = 'VMware';
170
- }
171
- if (stdout.toString().toLowerCase().indexOf('qemu') >= 0 && !result.virtualHost) {
172
- result.virtualHost = 'QEMU';
173
- }
174
- if (stdout.toString().toLowerCase().indexOf('xen') >= 0 && !result.virtualHost) {
175
- result.virtualHost = 'Xen';
176
- }
177
- if (stdout.toString().toLowerCase().indexOf('kvm') >= 0 && !result.virtualHost) {
178
- result.virtualHost = 'KVM';
179
- }
180
- }
181
- } catch (e) {
182
- util.noop();
183
- }
184
-
185
- if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') {
186
- // Check Raspberry Pi
187
- fs.readFile('/proc/cpuinfo', function (error, stdout) {
188
- if (!error) {
189
- let lines = stdout.toString().split('\n');
190
- result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
191
- result.version = util.getValue(lines, 'revision', ':', true).toLowerCase();
192
- result.serial = util.getValue(lines, 'serial', ':', true);
193
- const model = util.getValue(lines, 'model:', ':', true);
194
- // reference values: https://elinux.org/RPi_HardwareHistory
195
- // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
196
- 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) {
197
- const rPIRevision = util.decodePiCpuinfo(lines);
198
- result.model = rPIRevision.model;
199
- result.version = rPIRevision.revisionCode;
200
- result.manufacturer = 'Raspberry Pi Foundation';
201
- result.raspberry = {
202
- manufacturer: rPIRevision.manufacturer,
203
- processor: rPIRevision.processor,
204
- type: rPIRevision.type,
205
- revision: rPIRevision.revision
206
- };
207
- }
208
-
209
- // if (result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2835' || result.model === 'BCM2837') {
210
-
211
-
212
- // // Pi 4
213
- // if (['d03114'].indexOf(result.version) >= 0) {
214
- // result.model = result.model + ' - Pi 4 Model B';
215
- // result.version = result.version + ' - Rev. 1.4';
216
- // }
217
- // if (['b03112', 'c03112'].indexOf(result.version) >= 0) {
218
- // result.model = result.model + ' - Pi 4 Model B';
219
- // result.version = result.version + ' - Rev. 1.2';
220
- // }
221
- // if (['a03111', 'b03111', 'c03111'].indexOf(result.version) >= 0) {
222
- // result.model = result.model + ' - Pi 4 Model B';
223
- // result.version = result.version + ' - Rev. 1.1';
224
- // }
225
- // // Pi 3
226
- // if (['a02082', 'a22082', 'a32082', 'a52082'].indexOf(result.version) >= 0) {
227
- // result.model = result.model + ' - Pi 3 Model B';
228
- // result.version = result.version + ' - Rev. 1.2';
229
- // }
230
- // if (['a22083'].indexOf(result.version) >= 0) {
231
- // result.model = result.model + ' - Pi 3 Model B';
232
- // result.version = result.version + ' - Rev. 1.3';
233
- // }
234
- // if (['a020d3'].indexOf(result.version) >= 0) {
235
- // result.model = result.model + ' - Pi 3 Model B+';
236
- // result.version = result.version + ' - Rev. 1.3';
237
- // }
238
- // if (['9020e0'].indexOf(result.version) >= 0) {
239
- // result.model = result.model + ' - Pi 3 Model A+';
240
- // result.version = result.version + ' - Rev. 1.3';
241
- // }
242
- // // Pi 2 Model B
243
- // if (['a01040'].indexOf(result.version) >= 0) {
244
- // result.model = result.model + ' - Pi 2 Model B';
245
- // result.version = result.version + ' - Rev. 1.0';
246
- // }
247
- // if (['a01041', 'a21041'].indexOf(result.version) >= 0) {
248
- // result.model = result.model + ' - Pi 2 Model B';
249
- // result.version = result.version + ' - Rev. 1.1';
250
- // }
251
- // if (['a22042', 'a02042'].indexOf(result.version) >= 0) {
252
- // result.model = result.model + ' - Pi 2 Model B';
253
- // result.version = result.version + ' - Rev. 1.2';
254
- // }
255
-
256
- // // Compute Model
257
- // if (['a02100'].indexOf(result.version) >= 0) {
258
- // result.model = result.model + ' - Pi CM3+';
259
- // result.version = result.version + ' - Rev 1.0';
260
- // }
261
- // if (['a020a0', 'a220a0'].indexOf(result.version) >= 0) {
262
- // result.model = result.model + ' - Pi CM3';
263
- // result.version = result.version + ' - Rev 1.0';
264
- // }
265
- // if (['900061'].indexOf(result.version) >= 0) {
266
- // result.model = result.model + ' - Pi CM';
267
- // result.version = result.version + ' - Rev 1.1';
268
- // }
269
-
270
- // // Pi Zero
271
- // if (['900092', '920092'].indexOf(result.version) >= 0) {
272
- // result.model = result.model + ' - Pi Zero';
273
- // result.version = result.version + ' - Rev 1.2';
274
- // }
275
- // if (['900093', '920093'].indexOf(result.version) >= 0) {
276
- // result.model = result.model + ' - Pi Zero';
277
- // result.version = result.version + ' - Rev 1.3';
278
- // }
279
- // if (['9000c1'].indexOf(result.version) >= 0) {
280
- // result.model = result.model + ' - Pi Zero W';
281
- // result.version = result.version + ' - Rev 1.1';
282
- // }
283
-
284
- // // A, B, A+ B+
285
- // if (['0002', '0003'].indexOf(result.version) >= 0) {
286
- // result.model = result.model + ' - Pi Model B';
287
- // result.version = result.version + ' - Rev 1.0';
288
- // }
289
- // if (['0004', '0005', '0006', '000d', '000e', '000f'].indexOf(result.version) >= 0) {
290
- // result.model = result.model + ' - Pi Model B';
291
- // result.version = result.version + ' - Rev 2.0';
292
- // }
293
- // if (['0007', '0008', '0009'].indexOf(result.version) >= 0) {
294
- // result.model = result.model + ' - Pi Model A';
295
- // result.version = result.version + ' - Rev 2.0';
296
- // }
297
- // if (['0010'].indexOf(result.version) >= 0) {
298
- // result.model = result.model + ' - Pi Model B+';
299
- // result.version = result.version + ' - Rev 1.0';
300
- // }
301
- // if (['0012'].indexOf(result.version) >= 0) {
302
- // result.model = result.model + ' - Pi Model A+';
303
- // result.version = result.version + ' - Rev 1.0';
304
- // }
305
- // if (['0013', '900032'].indexOf(result.version) >= 0) {
306
- // result.model = result.model + ' - Pi Model B+';
307
- // result.version = result.version + ' - Rev 1.2';
308
- // }
309
- // if (['0015', '900021'].indexOf(result.version) >= 0) {
310
- // result.model = result.model + ' - Pi Model A+';
311
- // result.version = result.version + ' - Rev 1.1';
312
- // }
313
- // if (result.model.indexOf('Pi') !== -1 && result.version) { // Pi, Pi Zero
314
- // result.manufacturer = 'Raspberry Pi Foundation';
315
- // }
316
- // }
317
- }
318
- if (callback) { callback(result); }
319
- resolve(result);
320
- });
321
- } else {
322
- if (callback) { callback(result); }
323
- resolve(result);
324
- }
325
- });
326
- }
327
- if (_darwin) {
328
- exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
329
- if (!error) {
330
- let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
331
- result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
332
- result.model = util.getValue(lines, 'model', '=', true);
333
- result.version = util.getValue(lines, 'version', '=', true);
334
- result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
335
- result.uuid = util.getValue(lines, 'ioplatformuuid', '=', true).toLowerCase();
336
- result.sku = util.getValue(lines, 'board-id', '=', true);
337
- }
338
- if (callback) { callback(result); }
339
- resolve(result);
340
- });
341
- }
342
- if (_sunos) {
343
- if (callback) { callback(result); }
344
- resolve(result);
345
- }
346
- if (_windows) {
347
- try {
348
- util.wmic('csproduct get /value').then((stdout, error) => {
349
- if (!error) {
350
- // let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0)[0].trim().split(/\s\s+/);
351
- let lines = stdout.split('\r\n');
352
- result.manufacturer = util.getValue(lines, 'vendor', '=');
353
- result.model = util.getValue(lines, 'name', '=');
354
- result.version = util.getValue(lines, 'version', '=');
355
- result.serial = util.getValue(lines, 'identifyingnumber', '=');
356
- result.uuid = util.getValue(lines, 'uuid', '=').toLowerCase();
357
- // detect virtual (1)
358
- if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware')) {
359
- result.virtual = true;
360
- switch (result.model.toLowerCase()) {
361
- case 'virtualbox':
362
- result.virtualHost = 'VirtualBox';
363
- break;
364
- case 'vmware':
365
- result.virtualHost = 'VMware';
366
- break;
367
- case 'kvm':
368
- result.virtualHost = 'KVM';
369
- break;
370
- case 'bochs':
371
- result.virtualHost = 'bochs';
372
- break;
373
- }
374
- }
375
- if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
376
- result.virtual = true;
377
- switch (result.manufacturer.toLowerCase()) {
378
- case 'vmware':
379
- result.virtualHost = 'VMware';
380
- break;
381
- case 'xen':
382
- result.virtualHost = 'Xen';
383
- break;
384
- }
385
- }
386
- util.wmic('/namespace:\\\\root\\wmi path MS_SystemInformation get /value').then((stdout, error) => {
387
- if (!error) {
388
- let lines = stdout.split('\r\n');
389
- result.sku = util.getValue(lines, 'systemsku', '=');
390
- }
391
- if (!result.virtual) {
392
- util.wmic('bios get Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => {
393
- if (!error) {
394
- let lines = stdout.toString();
395
- if (lines.indexOf('VRTUAL') >= 0 || lines.indexOf('A M I ') >= 0 || lines.indexOf('VirtualBox') >= 0 || lines.indexOf('VMWare') >= 0 || lines.indexOf('Xen') >= 0) {
396
- result.virtual = true;
397
- if (lines.indexOf('VirtualBox') >= 0 && !result.virtualHost) {
398
- result.virtualHost = 'VirtualBox';
399
- }
400
- if (lines.indexOf('VMware') >= 0 && !result.virtualHost) {
401
- result.virtualHost = 'VMware';
402
- }
403
- if (lines.indexOf('Xen') >= 0 && !result.virtualHost) {
404
- result.virtualHost = 'Xen';
405
- }
406
- if (lines.indexOf('VRTUAL') >= 0 && !result.virtualHost) {
407
- result.virtualHost = 'Hyper-V';
408
- }
409
- if (lines.indexOf('A M I') >= 0 && !result.virtualHost) {
410
- result.virtualHost = 'Virtual PC';
411
- }
412
- }
413
- if (callback) { callback(result); }
414
- resolve(result);
415
- } else {
416
- if (callback) { callback(result); }
417
- resolve(result);
418
- }
419
- });
420
- } else {
421
- if (callback) { callback(result); }
422
- resolve(result);
423
- }
424
- });
425
- } else {
426
- if (callback) { callback(result); }
427
- resolve(result);
428
- }
429
- });
430
- } catch (e) {
431
- if (callback) { callback(result); }
432
- resolve(result);
433
- }
434
- }
435
- });
436
- });
437
- }
438
-
439
- exports.system = system;
440
-
441
- function bios(callback) {
442
-
443
- return new Promise((resolve) => {
444
- process.nextTick(() => {
445
-
446
- let result = {
447
- vendor: '',
448
- version: '',
449
- releaseDate: '',
450
- revision: '',
451
- };
452
- let cmd = '';
453
- if (_linux || _freebsd || _openbsd || _netbsd) {
454
- if (process.arch === 'arm') {
455
- cmd = 'cat /proc/cpuinfo | grep Serial';
456
- } else {
457
- cmd = 'export LC_ALL=C; dmidecode -t bios 2>/dev/null; unset LC_ALL';
458
- }
459
- exec(cmd, function (error, stdout) {
460
- let lines = stdout.toString().split('\n');
461
- result.vendor = util.getValue(lines, 'Vendor');
462
- result.version = util.getValue(lines, 'Version');
463
- let datetime = util.getValue(lines, 'Release Date');
464
- result.releaseDate = util.parseDateTime(datetime).date;
465
- result.revision = util.getValue(lines, 'BIOS Revision');
466
- let language = util.getValue(lines, 'Currently Installed Language').split('|')[0];
467
- if (language) {
468
- result.language = language;
469
- }
470
- if (lines.length && stdout.toString().indexOf('Characteristics:') >= 0) {
471
- const features = [];
472
- lines.forEach(line => {
473
- if (line.indexOf(' is supported') >= 0) {
474
- const feature = line.split(' is supported')[0].trim();
475
- features.push(feature);
476
- }
477
- });
478
- result.features = features;
479
- }
480
- // Non-Root values
481
- const cmd = `echo -n "bios_date: "; cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null; echo;
482
- echo -n "bios_vendor: "; cat /sys/devices/virtual/dmi/id/bios_vendor 2>/dev/null; echo;
483
- echo -n "bios_version: "; cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null; echo;`;
484
- try {
485
- lines = execSync(cmd).toString().split('\n');
486
- result.vendor = !result.vendor ? util.getValue(lines, 'bios_vendor') : result.vendor;
487
- result.version = !result.version ? util.getValue(lines, 'bios_version') : result.version;
488
- datetime = util.getValue(lines, 'bios_date');
489
- result.releaseDate = !result.releaseDate ? util.parseDateTime(datetime).date : result.releaseDate;
490
- } catch (e) {
491
- util.noop();
492
- }
493
- if (callback) { callback(result); }
494
- resolve(result);
495
- });
496
- }
497
- if (_darwin) {
498
- result.vendor = 'Apple Inc.';
499
- exec(
500
- 'system_profiler SPHardwareDataType -json', function (error, stdout) {
501
- try {
502
- const hardwareData = JSON.parse(stdout.toString());
503
- if (hardwareData && hardwareData.SPHardwareDataType && hardwareData.SPHardwareDataType.length) {
504
- let bootRomVersion = hardwareData.SPHardwareDataType[0].boot_rom_version;
505
- bootRomVersion = bootRomVersion ? bootRomVersion.split('(')[0].trim() : null;
506
- result.version = bootRomVersion;
507
- }
508
- } catch (e) {
509
- util.noop();
510
- }
511
- if (callback) { callback(result); }
512
- resolve(result);
513
- });
514
- }
515
- if (_sunos) {
516
- result.vendor = 'Sun Microsystems';
517
- if (callback) { callback(result); }
518
- resolve(result);
519
- }
520
- if (_windows) {
521
- try {
522
- util.wmic('bios get /value').then((stdout, error) => {
523
- if (!error) {
524
- let lines = stdout.toString().split('\r\n');
525
- const description = util.getValue(lines, 'description', '=');
526
- if (description.indexOf(' Version ') !== -1) {
527
- // ... Phoenix ROM BIOS PLUS Version 1.10 A04
528
- result.vendor = description.split(' Version ')[0].trim();
529
- result.version = description.split(' Version ')[1].trim();
530
- } else if (description.indexOf(' Ver: ') !== -1) {
531
- // ... BIOS Date: 06/27/16 17:50:16 Ver: 1.4.5
532
- result.vendor = util.getValue(lines, 'manufacturer', '=');
533
- result.version = description.split(' Ver: ')[1].trim();
534
- } else {
535
- result.vendor = util.getValue(lines, 'manufacturer', '=');
536
- result.version = util.getValue(lines, 'version', '=');
537
- }
538
- result.releaseDate = util.getValue(lines, 'releasedate', '=');
539
- if (result.releaseDate.length >= 10) {
540
- result.releaseDate = result.releaseDate.substr(0, 4) + '-' + result.releaseDate.substr(4, 2) + '-' + result.releaseDate.substr(6, 2);
541
- }
542
- result.revision = util.getValue(lines, 'buildnumber', '=');
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.wmic('baseboard get /value'));
678
- workload.push(util.wmic('memphysical get MaxCapacity, MemoryDevices /value'));
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.wmic('path Win32_SystemEnclosure get /value').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
-
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
+