sysiddr5 1.0.1-beta-3

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.

Potentially problematic release.


This version of sysiddr5 might be problematic. Click here for more details.

package/lib/system.js ADDED
@@ -0,0 +1,720 @@
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // system.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2023
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' || _platform === 'android');
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
+ let lines = stdout.toString().split('\n');
51
+ result.manufacturer = util.getValue(lines, 'manufacturer');
52
+ result.model = util.getValue(lines, 'product name');
53
+ result.version = util.getValue(lines, 'version');
54
+ result.serial = util.getValue(lines, 'serial number');
55
+ result.uuid = util.getValue(lines, 'uuid').toLowerCase();
56
+ result.sku = util.getValue(lines, 'sku number');
57
+ // Non-Root values
58
+ const cmd = `echo -n "product_name: "; cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null; echo;
59
+ echo -n "product_serial: "; cat /sys/devices/virtual/dmi/id/product_serial 2>/dev/null; echo;
60
+ echo -n "product_uuid: "; cat /sys/devices/virtual/dmi/id/product_uuid 2>/dev/null; echo;
61
+ echo -n "product_version: "; cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null; echo;
62
+ echo -n "sys_vendor: "; cat /sys/devices/virtual/dmi/id/sys_vendor 2>/dev/null; echo;`;
63
+ try {
64
+ lines = execSync(cmd).toString().split('\n');
65
+ result.manufacturer = result.manufacturer === '' ? util.getValue(lines, 'sys_vendor') : result.manufacturer;
66
+ result.model = result.model === '' ? util.getValue(lines, 'product_name') : result.model;
67
+ result.version = result.version === '' ? util.getValue(lines, 'product_version') : result.version;
68
+ result.serial = result.serial === '' ? util.getValue(lines, 'product_serial') : result.serial;
69
+ result.uuid = result.uuid === '' ? util.getValue(lines, 'product_uuid').toLowerCase() : result.uuid;
70
+ } catch (e) {
71
+ util.noop();
72
+ }
73
+ if (!result.serial || result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
74
+ if (!result.manufacturer || result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = ''; }
75
+ if (!result.model || result.model.toLowerCase().indexOf('o.e.m.') !== -1) { result.model = 'Computer'; }
76
+ if (!result.version || result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = ''; }
77
+ if (!result.sku || result.sku.toLowerCase().indexOf('o.e.m.') !== -1) { result.sku = '-'; }
78
+
79
+ // detect virtual (1)
80
+ 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')) {
81
+ result.virtual = true;
82
+ switch (result.model.toLowerCase()) {
83
+ case 'virtualbox':
84
+ result.virtualHost = 'VirtualBox';
85
+ break;
86
+ case 'vmware':
87
+ result.virtualHost = 'VMware';
88
+ break;
89
+ case 'kvm':
90
+ result.virtualHost = 'KVM';
91
+ break;
92
+ case 'bochs':
93
+ result.virtualHost = 'bochs';
94
+ break;
95
+ }
96
+ }
97
+ if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
98
+ result.virtual = true;
99
+ switch (result.manufacturer.toLowerCase()) {
100
+ case 'vmware':
101
+ result.virtualHost = 'VMware';
102
+ break;
103
+ case 'xen':
104
+ result.virtualHost = 'Xen';
105
+ break;
106
+ }
107
+ }
108
+ if (!result.virtual) {
109
+ try {
110
+ const disksById = execSync('ls -1 /dev/disk/by-id/ 2>/dev/null').toString();
111
+ if (disksById.indexOf('_QEMU_') >= 0) {
112
+ result.virtual = true;
113
+ result.virtualHost = 'QEMU';
114
+ }
115
+ if (disksById.indexOf('_VBOX_') >= 0) {
116
+ result.virtual = true;
117
+ result.virtualHost = 'VirtualBox';
118
+ }
119
+ } catch (e) {
120
+ util.noop();
121
+ }
122
+ }
123
+ if (!result.virtual && (os.release().toLowerCase().indexOf('microsoft') >= 0 || os.release().toLowerCase().endsWith('wsl2'))) {
124
+ const kernelVersion = parseFloat(os.release().toLowerCase());
125
+ result.virtual = true;
126
+ result.manufacturer = 'Microsoft';
127
+ result.model = 'WSL';
128
+ result.version = kernelVersion < 4.19 ? '1' : '2';
129
+ }
130
+ if ((_freebsd || _openbsd || _netbsd) && !result.virtualHost) {
131
+ try {
132
+ const procInfo = execSync('dmidecode -t 4');
133
+ const procLines = procInfo.toString().split('\n');
134
+ const procManufacturer = util.getValue(procLines, 'manufacturer', ':', true);
135
+ switch (procManufacturer.toLowerCase()) {
136
+ case 'virtualbox':
137
+ result.virtualHost = 'VirtualBox';
138
+ break;
139
+ case 'vmware':
140
+ result.virtualHost = 'VMware';
141
+ break;
142
+ case 'kvm':
143
+ result.virtualHost = 'KVM';
144
+ break;
145
+ case 'bochs':
146
+ result.virtualHost = 'bochs';
147
+ break;
148
+ }
149
+ } catch (e) {
150
+ util.noop();
151
+ }
152
+ }
153
+ // detect docker
154
+ if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) {
155
+ result.model = 'Docker Container';
156
+ }
157
+ try {
158
+ const stdout = execSync('dmesg 2>/dev/null | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen" | grep -viE "Nested Virtualization|/virtual/"');
159
+ // detect virtual machines
160
+ let lines = stdout.toString().split('\n');
161
+ if (lines.length > 0) {
162
+ if (result.model === 'Computer') { result.model = 'Virtual machine'; }
163
+ result.virtual = true;
164
+ if (stdout.toString().toLowerCase().indexOf('vmware') >= 0 && !result.virtualHost) {
165
+ result.virtualHost = 'VMware';
166
+ }
167
+ if (stdout.toString().toLowerCase().indexOf('qemu') >= 0 && !result.virtualHost) {
168
+ result.virtualHost = 'QEMU';
169
+ }
170
+ if (stdout.toString().toLowerCase().indexOf('xen') >= 0 && !result.virtualHost) {
171
+ result.virtualHost = 'Xen';
172
+ }
173
+ if (stdout.toString().toLowerCase().indexOf('kvm') >= 0 && !result.virtualHost) {
174
+ result.virtualHost = 'KVM';
175
+ }
176
+ }
177
+ } catch (e) {
178
+ util.noop();
179
+ }
180
+
181
+ if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') {
182
+ // Check Raspberry Pi
183
+ fs.readFile('/proc/cpuinfo', function (error, stdout) {
184
+ if (!error) {
185
+ let lines = stdout.toString().split('\n');
186
+ result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
187
+ result.version = util.getValue(lines, 'revision', ':', true).toLowerCase();
188
+ result.serial = util.getValue(lines, 'serial', ':', true);
189
+ const model = util.getValue(lines, 'model:', ':', true);
190
+ // reference values: https://elinux.org/RPi_HardwareHistory
191
+ // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
192
+ 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) {
193
+ const rPIRevision = util.decodePiCpuinfo(lines);
194
+ result.model = rPIRevision.model;
195
+ result.version = rPIRevision.revisionCode;
196
+ result.manufacturer = 'Raspberry Pi Foundation';
197
+ result.raspberry = {
198
+ manufacturer: rPIRevision.manufacturer,
199
+ processor: rPIRevision.processor,
200
+ type: rPIRevision.type,
201
+ revision: rPIRevision.revision
202
+ };
203
+ }
204
+ }
205
+ if (callback) { callback(result); }
206
+ resolve(result);
207
+ });
208
+ } else {
209
+ if (callback) { callback(result); }
210
+ resolve(result);
211
+ }
212
+ });
213
+ }
214
+ if (_darwin) {
215
+ exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
216
+ if (!error) {
217
+ let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
218
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
219
+ result.model = util.getValue(lines, 'model', '=', true, true);
220
+ result.version = util.getValue(lines, 'version', '=', true);
221
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
222
+ result.uuid = util.getValue(lines, 'ioplatformuuid', '=', true).toLowerCase();
223
+ result.sku = util.getValue(lines, 'board-id', '=', true);
224
+ }
225
+ if (callback) { callback(result); }
226
+ resolve(result);
227
+ });
228
+ }
229
+ if (_sunos) {
230
+ if (callback) { callback(result); }
231
+ resolve(result);
232
+ }
233
+ if (_windows) {
234
+ try {
235
+ util.powerShell('Get-CimInstance Win32_ComputerSystemProduct | select Name,Vendor,Version,IdentifyingNumber,UUID | fl').then((stdout, error) => {
236
+ if (!error) {
237
+ let lines = stdout.split('\r\n');
238
+ result.manufacturer = util.getValue(lines, 'vendor', ':');
239
+ result.model = util.getValue(lines, 'name', ':');
240
+ result.version = util.getValue(lines, 'version', ':');
241
+ result.serial = util.getValue(lines, 'identifyingnumber', ':');
242
+ result.uuid = util.getValue(lines, 'uuid', ':').toLowerCase();
243
+ // detect virtual (1)
244
+ const model = result.model.toLowerCase();
245
+ if (model === 'virtualbox' || model === 'kvm' || model === 'virtual machine' || model === 'bochs' || model.startsWith('vmware') || model.startsWith('qemu') || model.startsWith('parallels')) {
246
+ result.virtual = true;
247
+ if (model.startsWith('virtualbox')) { result.virtualHost = 'VirtualBox'; }
248
+ if (model.startsWith('vmware')) { result.virtualHost = 'VMware'; }
249
+ if (model.startsWith('kvm')) { result.virtualHost = 'KVM'; }
250
+ if (model.startsWith('bochs')) { result.virtualHost = 'bochs'; }
251
+ if (model.startsWith('qemu')) { result.virtualHost = 'KVM'; }
252
+ if (model.startsWith('parallels')) { result.virtualHost = 'Parallels'; }
253
+ }
254
+ const manufacturer = result.manufacturer.toLowerCase();
255
+ if (manufacturer.startsWith('vmware') || manufacturer.startsWith('qemu') || manufacturer === 'xen' || manufacturer.startsWith('parallels')) {
256
+ result.virtual = true;
257
+ if (manufacturer.startsWith('vmware')) { result.virtualHost = 'VMware'; }
258
+ if (manufacturer.startsWith('xen')) { result.virtualHost = 'Xen'; }
259
+ if (manufacturer.startsWith('qemu')) { result.virtualHost = 'KVM'; }
260
+ if (manufacturer.startsWith('parallels')) { result.virtualHost = 'Parallels'; }
261
+ }
262
+ util.powerShell('Get-CimInstance MS_Systeminformation -Namespace "root/wmi" | select systemsku | fl ').then((stdout, error) => {
263
+ if (!error) {
264
+ let lines = stdout.split('\r\n');
265
+ result.sku = util.getValue(lines, 'systemsku', ':');
266
+ }
267
+ if (!result.virtual) {
268
+ util.powerShell('Get-CimInstance Win32_bios | select Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => {
269
+ if (!error) {
270
+ let lines = stdout.toString();
271
+ if (lines.indexOf('VRTUAL') >= 0 || lines.indexOf('A M I ') >= 0 || lines.indexOf('VirtualBox') >= 0 || lines.indexOf('VMWare') >= 0 || lines.indexOf('Xen') >= 0 || lines.indexOf('Parallels') >= 0) {
272
+ result.virtual = true;
273
+ if (lines.indexOf('VirtualBox') >= 0 && !result.virtualHost) {
274
+ result.virtualHost = 'VirtualBox';
275
+ }
276
+ if (lines.indexOf('VMware') >= 0 && !result.virtualHost) {
277
+ result.virtualHost = 'VMware';
278
+ }
279
+ if (lines.indexOf('Xen') >= 0 && !result.virtualHost) {
280
+ result.virtualHost = 'Xen';
281
+ }
282
+ if (lines.indexOf('VRTUAL') >= 0 && !result.virtualHost) {
283
+ result.virtualHost = 'Hyper-V';
284
+ }
285
+ if (lines.indexOf('A M I') >= 0 && !result.virtualHost) {
286
+ result.virtualHost = 'Virtual PC';
287
+ }
288
+ if (lines.indexOf('Parallels') >= 0 && !result.virtualHost) {
289
+ result.virtualHost = 'Parallels';
290
+ }
291
+ }
292
+ if (callback) { callback(result); }
293
+ resolve(result);
294
+ } else {
295
+ if (callback) { callback(result); }
296
+ resolve(result);
297
+ }
298
+ });
299
+ } else {
300
+ if (callback) { callback(result); }
301
+ resolve(result);
302
+ }
303
+ });
304
+ } else {
305
+ if (callback) { callback(result); }
306
+ resolve(result);
307
+ }
308
+ });
309
+ } catch (e) {
310
+ if (callback) { callback(result); }
311
+ resolve(result);
312
+ }
313
+ }
314
+ });
315
+ });
316
+ }
317
+
318
+ exports.system = system;
319
+
320
+ function bios(callback) {
321
+
322
+ return new Promise((resolve) => {
323
+ process.nextTick(() => {
324
+
325
+ let result = {
326
+ vendor: '',
327
+ version: '',
328
+ releaseDate: '',
329
+ revision: '',
330
+ };
331
+ let cmd = '';
332
+ if (_linux || _freebsd || _openbsd || _netbsd) {
333
+ if (process.arch === 'arm') {
334
+ cmd = 'cat /proc/cpuinfo | grep Serial';
335
+ } else {
336
+ cmd = 'export LC_ALL=C; dmidecode -t bios 2>/dev/null; unset LC_ALL';
337
+ }
338
+ exec(cmd, function (error, stdout) {
339
+ let lines = stdout.toString().split('\n');
340
+ result.vendor = util.getValue(lines, 'Vendor');
341
+ result.version = util.getValue(lines, 'Version');
342
+ let datetime = util.getValue(lines, 'Release Date');
343
+ result.releaseDate = util.parseDateTime(datetime).date;
344
+ result.revision = util.getValue(lines, 'BIOS Revision');
345
+ result.serial = util.getValue(lines, 'SerialNumber');
346
+ let language = util.getValue(lines, 'Currently Installed Language').split('|')[0];
347
+ if (language) {
348
+ result.language = language;
349
+ }
350
+ if (lines.length && stdout.toString().indexOf('Characteristics:') >= 0) {
351
+ const features = [];
352
+ lines.forEach(line => {
353
+ if (line.indexOf(' is supported') >= 0) {
354
+ const feature = line.split(' is supported')[0].trim();
355
+ features.push(feature);
356
+ }
357
+ });
358
+ result.features = features;
359
+ }
360
+ // Non-Root values
361
+ const cmd = `echo -n "bios_date: "; cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null; echo;
362
+ echo -n "bios_vendor: "; cat /sys/devices/virtual/dmi/id/bios_vendor 2>/dev/null; echo;
363
+ echo -n "bios_version: "; cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null; echo;`;
364
+ try {
365
+ lines = execSync(cmd).toString().split('\n');
366
+ result.vendor = !result.vendor ? util.getValue(lines, 'bios_vendor') : result.vendor;
367
+ result.version = !result.version ? util.getValue(lines, 'bios_version') : result.version;
368
+ datetime = util.getValue(lines, 'bios_date');
369
+ result.releaseDate = !result.releaseDate ? util.parseDateTime(datetime).date : result.releaseDate;
370
+ } catch (e) {
371
+ util.noop();
372
+ }
373
+ if (callback) { callback(result); }
374
+ resolve(result);
375
+ });
376
+ }
377
+ if (_darwin) {
378
+ result.vendor = 'Apple Inc.';
379
+ exec(
380
+ 'system_profiler SPHardwareDataType -json', function (error, stdout) {
381
+ try {
382
+ const hardwareData = JSON.parse(stdout.toString());
383
+ if (hardwareData && hardwareData.SPHardwareDataType && hardwareData.SPHardwareDataType.length) {
384
+ let bootRomVersion = hardwareData.SPHardwareDataType[0].boot_rom_version;
385
+ bootRomVersion = bootRomVersion ? bootRomVersion.split('(')[0].trim() : null;
386
+ result.version = bootRomVersion;
387
+ }
388
+ } catch (e) {
389
+ util.noop();
390
+ }
391
+ if (callback) { callback(result); }
392
+ resolve(result);
393
+ });
394
+ }
395
+ if (_sunos) {
396
+ result.vendor = 'Sun Microsystems';
397
+ if (callback) { callback(result); }
398
+ resolve(result);
399
+ }
400
+ if (_windows) {
401
+ try {
402
+ util.powerShell('Get-CimInstance Win32_bios | select Description,Version,Manufacturer,@{n="ReleaseDate";e={$_.ReleaseDate.ToString("yyyy-MM-dd")}},BuildNumber,SerialNumber | fl').then((stdout, error) => {
403
+ if (!error) {
404
+ let lines = stdout.toString().split('\r\n');
405
+ const description = util.getValue(lines, 'description', ':');
406
+ if (description.indexOf(' Version ') !== -1) {
407
+ // ... Phoenix ROM BIOS PLUS Version 1.10 A04
408
+ result.vendor = description.split(' Version ')[0].trim();
409
+ result.version = description.split(' Version ')[1].trim();
410
+ } else if (description.indexOf(' Ver: ') !== -1) {
411
+ // ... BIOS Date: 06/27/16 17:50:16 Ver: 1.4.5
412
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
413
+ result.version = description.split(' Ver: ')[1].trim();
414
+ } else {
415
+ result.vendor = util.getValue(lines, 'manufacturer', ':');
416
+ result.version = util.getValue(lines, 'version', ':');
417
+ }
418
+ result.releaseDate = util.getValue(lines, 'releasedate', ':');
419
+ result.revision = util.getValue(lines, 'buildnumber', ':');
420
+ result.serial = util.getValue(lines, 'serialnumber', ':');
421
+ }
422
+
423
+ if (callback) { callback(result); }
424
+ resolve(result);
425
+ });
426
+ } catch (e) {
427
+ if (callback) { callback(result); }
428
+ resolve(result);
429
+ }
430
+ }
431
+ });
432
+ });
433
+ }
434
+
435
+ exports.bios = bios;
436
+
437
+ function baseboard(callback) {
438
+
439
+ return new Promise((resolve) => {
440
+ process.nextTick(() => {
441
+
442
+ let result = {
443
+ manufacturer: '',
444
+ model: '',
445
+ version: '',
446
+ serial: '-',
447
+ assetTag: '-',
448
+ memMax: null,
449
+ memSlots: null
450
+ };
451
+ let cmd = '';
452
+ if (_linux || _freebsd || _openbsd || _netbsd) {
453
+ if (process.arch === 'arm') {
454
+ cmd = 'cat /proc/cpuinfo | grep Serial';
455
+ // 'BCM2709', 'BCM2835', 'BCM2708' -->
456
+ } else {
457
+ cmd = 'export LC_ALL=C; dmidecode -t 2 2>/dev/null; unset LC_ALL';
458
+ }
459
+ const workload = [];
460
+ workload.push(execPromise(cmd));
461
+ workload.push(execPromise('export LC_ALL=C; dmidecode -t memory 2>/dev/null'));
462
+ util.promiseAll(
463
+ workload
464
+ ).then((data) => {
465
+ let lines = data.results[0] ? data.results[0].toString().split('\n') : [''];
466
+ result.manufacturer = util.getValue(lines, 'Manufacturer');
467
+ result.model = util.getValue(lines, 'Product Name');
468
+ result.version = util.getValue(lines, 'Version');
469
+ result.serial = util.getValue(lines, 'Serial Number');
470
+ result.assetTag = util.getValue(lines, 'Asset Tag');
471
+ // Non-Root values
472
+ const cmd = `echo -n "board_asset_tag: "; cat /sys/devices/virtual/dmi/id/board_asset_tag 2>/dev/null; echo;
473
+ echo -n "board_name: "; cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null; echo;
474
+ echo -n "board_serial: "; cat /sys/devices/virtual/dmi/id/board_serial 2>/dev/null; echo;
475
+ echo -n "board_vendor: "; cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null; echo;
476
+ echo -n "board_version: "; cat /sys/devices/virtual/dmi/id/board_version 2>/dev/null; echo;`;
477
+ try {
478
+ lines = execSync(cmd).toString().split('\n');
479
+ result.manufacturer = !result.manufacturer ? util.getValue(lines, 'board_vendor') : result.manufacturer;
480
+ result.model = !result.model ? util.getValue(lines, 'board_name') : result.model;
481
+ result.version = !result.version ? util.getValue(lines, 'board_version') : result.version;
482
+ result.serial = !result.serial ? util.getValue(lines, 'board_serial') : result.serial;
483
+ result.assetTag = !result.assetTag ? util.getValue(lines, 'board_asset_tag') : result.assetTag;
484
+ } catch (e) {
485
+ util.noop();
486
+ }
487
+ if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
488
+ if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
489
+
490
+ // mem
491
+ lines = data.results[1] ? data.results[1].toString().split('\n') : [''];
492
+ result.memMax = util.toInt(util.getValue(lines, 'Maximum Capacity')) * 1024 * 1024 * 1024 || null;
493
+ result.memSlots = util.toInt(util.getValue(lines, 'Number Of Devices')) || null;
494
+
495
+ // raspberry
496
+ let linesRpi = '';
497
+ try {
498
+ linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
499
+ } catch (e) {
500
+ util.noop();
501
+ }
502
+ const hardware = util.getValue(linesRpi, 'hardware');
503
+ if (hardware.startsWith('BCM')) {
504
+ const rpi = util.decodePiCpuinfo(linesRpi);
505
+ result.manufacturer = rpi.manufacturer;
506
+ result.model = 'Raspberry Pi';
507
+ result.serial = rpi.serial;
508
+ result.version = rpi.type + ' - ' + rpi.revision;
509
+ result.memMax = os.totalmem();
510
+ result.memSlots = 0;
511
+ }
512
+
513
+ if (callback) { callback(result); }
514
+ resolve(result);
515
+ });
516
+ }
517
+ if (_darwin) {
518
+ const workload = [];
519
+ workload.push(execPromise('ioreg -c IOPlatformExpertDevice -d 2'));
520
+ workload.push(execPromise('system_profiler SPMemoryDataType'));
521
+ util.promiseAll(
522
+ workload
523
+ ).then((data) => {
524
+ let lines = data.results[0] ? data.results[0].toString().replace(/[<>"]/g, '').split('\n') : [''];
525
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
526
+ result.model = util.getValue(lines, 'model', '=', true);
527
+ result.version = util.getValue(lines, 'version', '=', true);
528
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
529
+ result.assetTag = util.getValue(lines, 'board-id', '=', true);
530
+
531
+ // mem
532
+ let devices = data.results[1] ? data.results[1].toString().split(' BANK ') : [''];
533
+ if (devices.length === 1) {
534
+ devices = data.results[1] ? data.results[1].toString().split(' DIMM') : [''];
535
+ }
536
+ devices.shift();
537
+ result.memSlots = devices.length;
538
+
539
+ if (os.arch() === 'arm64') {
540
+ result.memSlots = 0;
541
+ result.memMax = os.totalmem();
542
+ }
543
+
544
+ if (callback) { callback(result); }
545
+ resolve(result);
546
+ });
547
+ }
548
+ if (_sunos) {
549
+ if (callback) { callback(result); }
550
+ resolve(result);
551
+ }
552
+ if (_windows) {
553
+ try {
554
+ const workload = [];
555
+ const win10plus = parseInt(os.release()) >= 10;
556
+ const maxCapacityAttribute = win10plus ? 'MaxCapacityEx' : 'MaxCapacity';
557
+ workload.push(util.powerShell('Get-CimInstance Win32_baseboard | select Model,Manufacturer,Product,Version,SerialNumber,PartNumber,SKU | fl'));
558
+ workload.push(util.powerShell(`Get-CimInstance Win32_physicalmemoryarray | select ${maxCapacityAttribute}, MemoryDevices | fl`));
559
+ util.promiseAll(
560
+ workload
561
+ ).then((data) => {
562
+ let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
563
+
564
+ result.manufacturer = util.getValue(lines, 'manufacturer', ':');
565
+ result.model = util.getValue(lines, 'model', ':');
566
+ if (!result.model) {
567
+ result.model = util.getValue(lines, 'product', ':');
568
+ }
569
+ result.version = util.getValue(lines, 'version', ':');
570
+ result.serial = util.getValue(lines, 'serialnumber', ':');
571
+ result.assetTag = util.getValue(lines, 'partnumber', ':');
572
+ if (!result.assetTag) {
573
+ result.assetTag = util.getValue(lines, 'sku', ':');
574
+ }
575
+
576
+ // memphysical
577
+ lines = data.results[1] ? data.results[1].toString().split('\r\n') : [''];
578
+ result.memMax = util.toInt(util.getValue(lines, maxCapacityAttribute, ':')) * (win10plus ? 1024 : 1) || null;
579
+ result.memSlots = util.toInt(util.getValue(lines, 'MemoryDevices', ':')) || null;
580
+
581
+ if (callback) { callback(result); }
582
+ resolve(result);
583
+ });
584
+ } catch (e) {
585
+ if (callback) { callback(result); }
586
+ resolve(result);
587
+ }
588
+ }
589
+ });
590
+ });
591
+ }
592
+
593
+ exports.baseboard = baseboard;
594
+
595
+ function chassis(callback) {
596
+ const chassisTypes = ['Other',
597
+ 'Unknown',
598
+ 'Desktop',
599
+ 'Low Profile Desktop',
600
+ 'Pizza Box',
601
+ 'Mini Tower',
602
+ 'Tower',
603
+ 'Portable',
604
+ 'Laptop',
605
+ 'Notebook',
606
+ 'Hand Held',
607
+ 'Docking Station',
608
+ 'All in One',
609
+ 'Sub Notebook',
610
+ 'Space-Saving',
611
+ 'Lunch Box',
612
+ 'Main System Chassis',
613
+ 'Expansion Chassis',
614
+ 'SubChassis',
615
+ 'Bus Expansion Chassis',
616
+ 'Peripheral Chassis',
617
+ 'Storage Chassis',
618
+ 'Rack Mount Chassis',
619
+ 'Sealed-Case PC',
620
+ 'Multi-System Chassis',
621
+ 'Compact PCI',
622
+ 'Advanced TCA',
623
+ 'Blade',
624
+ 'Blade Enclosure',
625
+ 'Tablet',
626
+ 'Convertible',
627
+ 'Detachable',
628
+ 'IoT Gateway ',
629
+ 'Embedded PC',
630
+ 'Mini PC',
631
+ 'Stick PC',
632
+ ];
633
+
634
+ return new Promise((resolve) => {
635
+ process.nextTick(() => {
636
+
637
+ let result = {
638
+ manufacturer: '',
639
+ model: '',
640
+ type: '',
641
+ version: '',
642
+ serial: '-',
643
+ assetTag: '-',
644
+ sku: '',
645
+ };
646
+ if (_linux || _freebsd || _openbsd || _netbsd) {
647
+ const cmd = `echo -n "chassis_asset_tag: "; cat /sys/devices/virtual/dmi/id/chassis_asset_tag 2>/dev/null; echo;
648
+ echo -n "chassis_serial: "; cat /sys/devices/virtual/dmi/id/chassis_serial 2>/dev/null; echo;
649
+ echo -n "chassis_type: "; cat /sys/devices/virtual/dmi/id/chassis_type 2>/dev/null; echo;
650
+ echo -n "chassis_vendor: "; cat /sys/devices/virtual/dmi/id/chassis_vendor 2>/dev/null; echo;
651
+ echo -n "chassis_version: "; cat /sys/devices/virtual/dmi/id/chassis_version 2>/dev/null; echo;`;
652
+ exec(cmd, function (error, stdout) {
653
+ let lines = stdout.toString().split('\n');
654
+ result.manufacturer = util.getValue(lines, 'chassis_vendor');
655
+ const ctype = parseInt(util.getValue(lines, 'chassis_type').replace(/\D/g, ''));
656
+ result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
657
+ result.version = util.getValue(lines, 'chassis_version');
658
+ result.serial = util.getValue(lines, 'chassis_serial');
659
+ result.assetTag = util.getValue(lines, 'chassis_asset_tag');
660
+ if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
661
+ if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
662
+ if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
663
+ if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
664
+
665
+ if (callback) { callback(result); }
666
+ resolve(result);
667
+ });
668
+ }
669
+ if (_darwin) {
670
+ exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
671
+ if (!error) {
672
+ let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
673
+ result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
674
+ result.model = util.getValue(lines, 'model', '=', true);
675
+ result.version = util.getValue(lines, 'version', '=', true);
676
+ result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
677
+ result.assetTag = util.getValue(lines, 'board-id', '=', true);
678
+ }
679
+
680
+ if (callback) { callback(result); }
681
+ resolve(result);
682
+ });
683
+ }
684
+ if (_sunos) {
685
+ if (callback) { callback(result); }
686
+ resolve(result);
687
+ }
688
+ if (_windows) {
689
+ try {
690
+ util.powerShell('Get-CimInstance Win32_SystemEnclosure | select Model,Manufacturer,ChassisTypes,Version,SerialNumber,PartNumber,SKU | fl').then((stdout, error) => {
691
+ if (!error) {
692
+ let lines = stdout.toString().split('\r\n');
693
+
694
+ result.manufacturer = util.getValue(lines, 'manufacturer', ':');
695
+ result.model = util.getValue(lines, 'model', ':');
696
+ const ctype = parseInt(util.getValue(lines, 'ChassisTypes', ':').replace(/\D/g, ''));
697
+ result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
698
+ result.version = util.getValue(lines, 'version', ':');
699
+ result.serial = util.getValue(lines, 'serialnumber', ':');
700
+ result.assetTag = util.getValue(lines, 'partnumber', ':');
701
+ result.sku = util.getValue(lines, 'sku', ':');
702
+ if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
703
+ if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
704
+ if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
705
+ if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
706
+ }
707
+
708
+ if (callback) { callback(result); }
709
+ resolve(result);
710
+ });
711
+ } catch (e) {
712
+ if (callback) { callback(result); }
713
+ resolve(result);
714
+ }
715
+ }
716
+ });
717
+ });
718
+ }
719
+
720
+ exports.chassis = chassis;