@depup/systeminformation 5.31.4-depup.0
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/LICENSE +20 -0
- package/README.md +25 -0
- package/changes.json +5 -0
- package/lib/audio.js +276 -0
- package/lib/battery.js +330 -0
- package/lib/bluetooth.js +311 -0
- package/lib/bluetoothVendors.js +1138 -0
- package/lib/cli.js +100 -0
- package/lib/cpu.js +2237 -0
- package/lib/docker.js +803 -0
- package/lib/dockerSocket.js +322 -0
- package/lib/filesystem.js +1745 -0
- package/lib/graphics.js +1235 -0
- package/lib/index.d.ts +1053 -0
- package/lib/index.js +518 -0
- package/lib/internet.js +259 -0
- package/lib/memory.js +613 -0
- package/lib/network.js +2022 -0
- package/lib/osinfo.js +1303 -0
- package/lib/printer.js +209 -0
- package/lib/processes.js +1425 -0
- package/lib/system.js +856 -0
- package/lib/usb.js +313 -0
- package/lib/users.js +412 -0
- package/lib/util.js +2760 -0
- package/lib/virtualbox.js +110 -0
- package/lib/wifi.js +843 -0
- package/package.json +115 -0
package/lib/memory.js
ADDED
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// @ts-check
|
|
3
|
+
// ==================================================================================
|
|
4
|
+
// memory.js
|
|
5
|
+
// ----------------------------------------------------------------------------------
|
|
6
|
+
// Description: System Information - library
|
|
7
|
+
// for Node.js
|
|
8
|
+
// Copyright: (c) 2014 - 2026
|
|
9
|
+
// Author: Sebastian Hildebrandt
|
|
10
|
+
// ----------------------------------------------------------------------------------
|
|
11
|
+
// License: MIT
|
|
12
|
+
// ==================================================================================
|
|
13
|
+
// 5. Memory
|
|
14
|
+
// ----------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
const os = require('os');
|
|
17
|
+
const exec = require('child_process').exec;
|
|
18
|
+
const execSync = require('child_process').execSync;
|
|
19
|
+
const util = require('./util');
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
|
|
22
|
+
let _platform = process.platform;
|
|
23
|
+
|
|
24
|
+
const _linux = _platform === 'linux' || _platform === 'android';
|
|
25
|
+
const _darwin = _platform === 'darwin';
|
|
26
|
+
const _windows = _platform === 'win32';
|
|
27
|
+
const _freebsd = _platform === 'freebsd';
|
|
28
|
+
const _openbsd = _platform === 'openbsd';
|
|
29
|
+
const _netbsd = _platform === 'netbsd';
|
|
30
|
+
const _sunos = _platform === 'sunos';
|
|
31
|
+
|
|
32
|
+
const RAM_manufacturers = {
|
|
33
|
+
'00CE': 'Samsung Electronics Inc',
|
|
34
|
+
'014F': 'Transcend Information Inc.',
|
|
35
|
+
'017A': 'Apacer Technology Inc.',
|
|
36
|
+
'0198': 'HyperX',
|
|
37
|
+
'029E': 'Corsair',
|
|
38
|
+
'02FE': 'Elpida',
|
|
39
|
+
'04CB': 'A-DATA',
|
|
40
|
+
'04CD': 'G.Skill International Enterprise',
|
|
41
|
+
'059B': 'Crucial',
|
|
42
|
+
1315: 'Crucial',
|
|
43
|
+
'2C00': 'Micron Technology Inc.',
|
|
44
|
+
5105: 'Qimonda AG i. In.',
|
|
45
|
+
'802C': 'Micron Technology Inc.',
|
|
46
|
+
'80AD': 'Hynix Semiconductor Inc.',
|
|
47
|
+
'80CE': 'Samsung Electronics Inc.',
|
|
48
|
+
8551: 'Qimonda AG i. In.',
|
|
49
|
+
'859B': 'Crucial',
|
|
50
|
+
AD00: 'Hynix Semiconductor Inc.',
|
|
51
|
+
CE00: 'Samsung Electronics Inc.',
|
|
52
|
+
SAMSUNG: 'Samsung Electronics Inc.',
|
|
53
|
+
HYNIX: 'Hynix Semiconductor Inc.',
|
|
54
|
+
'G-SKILL': 'G-Skill International Enterprise',
|
|
55
|
+
'G.SKILL': 'G-Skill International Enterprise',
|
|
56
|
+
TRANSCEND: 'Transcend Information',
|
|
57
|
+
APACER: 'Apacer Technology Inc',
|
|
58
|
+
MICRON: 'Micron Technology Inc.',
|
|
59
|
+
QIMONDA: 'Qimonda AG i. In.'
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// _______________________________________________________________________________________
|
|
63
|
+
// | R A M | H D |
|
|
64
|
+
// |______________________|_________________________| | |
|
|
65
|
+
// | active buffers/cache | | |
|
|
66
|
+
// |________________________________________________|___________|_________|______________|
|
|
67
|
+
// | used free | used free |
|
|
68
|
+
// |____________________________________________________________|________________________|
|
|
69
|
+
// | total | swap |
|
|
70
|
+
// |____________________________________________________________|________________________|
|
|
71
|
+
|
|
72
|
+
// free (older versions)
|
|
73
|
+
// ----------------------------------
|
|
74
|
+
// # free
|
|
75
|
+
// total used free shared buffers cached
|
|
76
|
+
// Mem: 16038 (1) 15653 (2) 384 (3) 0 (4) 236 (5) 14788 (6)
|
|
77
|
+
// -/+ buffers/cache: 628 (7) 15409 (8)
|
|
78
|
+
// Swap: 16371 83 16288
|
|
79
|
+
//
|
|
80
|
+
// |------------------------------------------------------------|
|
|
81
|
+
// | R A M |
|
|
82
|
+
// |______________________|_____________________________________|
|
|
83
|
+
// | active (2-(5+6) = 7) | available (3+5+6 = 8) |
|
|
84
|
+
// |______________________|_________________________|___________|
|
|
85
|
+
// | active | buffers/cache (5+6) | |
|
|
86
|
+
// |________________________________________________|___________|
|
|
87
|
+
// | used (2) | free (3) |
|
|
88
|
+
// |____________________________________________________________|
|
|
89
|
+
// | total (1) |
|
|
90
|
+
// |____________________________________________________________|
|
|
91
|
+
|
|
92
|
+
//
|
|
93
|
+
// free (since free von procps-ng 3.3.10)
|
|
94
|
+
// ----------------------------------
|
|
95
|
+
// # free
|
|
96
|
+
// total used free shared buffers/cache available
|
|
97
|
+
// Mem: 16038 (1) 628 (2) 386 (3) 0 (4) 15024 (5) 14788 (6)
|
|
98
|
+
// Swap: 16371 83 16288
|
|
99
|
+
//
|
|
100
|
+
// |------------------------------------------------------------|
|
|
101
|
+
// | R A M |
|
|
102
|
+
// |______________________|_____________________________________|
|
|
103
|
+
// | | available (6) estimated |
|
|
104
|
+
// |______________________|_________________________|___________|
|
|
105
|
+
// | active (2) | buffers/cache (5) | free (3) |
|
|
106
|
+
// |________________________________________________|___________|
|
|
107
|
+
// | total (1) |
|
|
108
|
+
// |____________________________________________________________|
|
|
109
|
+
//
|
|
110
|
+
// Reference: http://www.software-architect.net/blog/article/date/2015/06/12/-826c6e5052.html
|
|
111
|
+
|
|
112
|
+
// /procs/meminfo - sample (all in kB)
|
|
113
|
+
//
|
|
114
|
+
// MemTotal: 32806380 kB
|
|
115
|
+
// MemFree: 17977744 kB
|
|
116
|
+
// MemAvailable: 19768972 kB
|
|
117
|
+
// Buffers: 517028 kB
|
|
118
|
+
// Cached: 2161876 kB
|
|
119
|
+
// SwapCached: 456 kB
|
|
120
|
+
// Active: 12081176 kB
|
|
121
|
+
// Inactive: 2164616 kB
|
|
122
|
+
// Active(anon): 10832884 kB
|
|
123
|
+
// Inactive(anon): 1477272 kB
|
|
124
|
+
// Active(file): 1248292 kB
|
|
125
|
+
// Inactive(file): 687344 kB
|
|
126
|
+
// Unevictable: 0 kB
|
|
127
|
+
// Mlocked: 0 kB
|
|
128
|
+
// SwapTotal: 16768892 kB
|
|
129
|
+
// SwapFree: 16768304 kB
|
|
130
|
+
// Dirty: 268 kB
|
|
131
|
+
// Writeback: 0 kB
|
|
132
|
+
// AnonPages: 11568832 kB
|
|
133
|
+
// Mapped: 719992 kB
|
|
134
|
+
// Shmem: 743272 kB
|
|
135
|
+
// Slab: 335716 kB
|
|
136
|
+
// SReclaimable: 256364 kB
|
|
137
|
+
// SUnreclaim: 79352 kB
|
|
138
|
+
|
|
139
|
+
function mem(callback) {
|
|
140
|
+
return new Promise((resolve) => {
|
|
141
|
+
process.nextTick(() => {
|
|
142
|
+
let result = {
|
|
143
|
+
total: os.totalmem(),
|
|
144
|
+
free: os.freemem(),
|
|
145
|
+
used: os.totalmem() - os.freemem(),
|
|
146
|
+
|
|
147
|
+
active: os.totalmem() - os.freemem(), // temporarily (fallback)
|
|
148
|
+
available: os.freemem(), // temporarily (fallback)
|
|
149
|
+
buffers: 0,
|
|
150
|
+
cached: 0,
|
|
151
|
+
slab: 0,
|
|
152
|
+
buffcache: 0,
|
|
153
|
+
reclaimable: 0,
|
|
154
|
+
|
|
155
|
+
swaptotal: 0,
|
|
156
|
+
swapused: 0,
|
|
157
|
+
swapfree: 0,
|
|
158
|
+
writeback: null,
|
|
159
|
+
dirty: null
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
if (_linux) {
|
|
163
|
+
try {
|
|
164
|
+
fs.readFile('/proc/meminfo', (error, stdout) => {
|
|
165
|
+
if (!error) {
|
|
166
|
+
const lines = stdout.toString().split('\n');
|
|
167
|
+
result.total = parseInt(util.getValue(lines, 'memtotal'), 10);
|
|
168
|
+
result.total = result.total ? result.total * 1024 : os.totalmem();
|
|
169
|
+
result.free = parseInt(util.getValue(lines, 'memfree'), 10);
|
|
170
|
+
result.free = result.free ? result.free * 1024 : os.freemem();
|
|
171
|
+
result.used = result.total - result.free;
|
|
172
|
+
|
|
173
|
+
result.buffers = parseInt(util.getValue(lines, 'buffers'), 10);
|
|
174
|
+
result.buffers = result.buffers ? result.buffers * 1024 : 0;
|
|
175
|
+
result.cached = parseInt(util.getValue(lines, 'cached'), 10);
|
|
176
|
+
result.cached = result.cached ? result.cached * 1024 : 0;
|
|
177
|
+
result.slab = parseInt(util.getValue(lines, 'slab'), 10);
|
|
178
|
+
result.slab = result.slab ? result.slab * 1024 : 0;
|
|
179
|
+
result.buffcache = result.buffers + result.cached + result.slab;
|
|
180
|
+
|
|
181
|
+
let available = parseInt(util.getValue(lines, 'memavailable'), 10);
|
|
182
|
+
result.available = available ? available * 1024 : result.free + result.buffcache;
|
|
183
|
+
result.active = result.total - result.available;
|
|
184
|
+
|
|
185
|
+
result.swaptotal = parseInt(util.getValue(lines, 'swaptotal'), 10);
|
|
186
|
+
result.swaptotal = result.swaptotal ? result.swaptotal * 1024 : 0;
|
|
187
|
+
result.swapfree = parseInt(util.getValue(lines, 'swapfree'), 10);
|
|
188
|
+
result.swapfree = result.swapfree ? result.swapfree * 1024 : 0;
|
|
189
|
+
result.swapused = result.swaptotal - result.swapfree;
|
|
190
|
+
result.writeback = parseInt(util.getValue(lines, 'writeback'), 10);
|
|
191
|
+
result.writeback = result.writeback ? result.writeback * 1024 : 0;
|
|
192
|
+
result.dirty = parseInt(util.getValue(lines, 'dirty'), 10);
|
|
193
|
+
result.dirty = result.dirty ? result.dirty * 1024 : 0;
|
|
194
|
+
result.reclaimable = parseInt(util.getValue(lines, 'sreclaimable'), 10);
|
|
195
|
+
result.reclaimable = result.reclaimable ? result.reclaimable * 1024 : 0;
|
|
196
|
+
}
|
|
197
|
+
if (callback) {
|
|
198
|
+
callback(result);
|
|
199
|
+
}
|
|
200
|
+
resolve(result);
|
|
201
|
+
});
|
|
202
|
+
} catch {
|
|
203
|
+
if (callback) {
|
|
204
|
+
callback(result);
|
|
205
|
+
}
|
|
206
|
+
resolve(result);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (_freebsd || _openbsd || _netbsd) {
|
|
210
|
+
try {
|
|
211
|
+
exec(
|
|
212
|
+
'/sbin/sysctl hw.realmem hw.physmem vm.stats.vm.v_page_count vm.stats.vm.v_wire_count vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count vm.stats.vm.v_cache_count vm.stats.vm.v_free_count vm.stats.vm.v_page_size',
|
|
213
|
+
(error, stdout) => {
|
|
214
|
+
if (!error) {
|
|
215
|
+
const lines = stdout.toString().split('\n');
|
|
216
|
+
const pagesize = parseInt(util.getValue(lines, 'vm.stats.vm.v_page_size'), 10);
|
|
217
|
+
const inactive = parseInt(util.getValue(lines, 'vm.stats.vm.v_inactive_count'), 10) * pagesize;
|
|
218
|
+
const cache = parseInt(util.getValue(lines, 'vm.stats.vm.v_cache_count'), 10) * pagesize;
|
|
219
|
+
|
|
220
|
+
result.total = parseInt(util.getValue(lines, 'hw.realmem'), 10);
|
|
221
|
+
if (isNaN(result.total)) {
|
|
222
|
+
result.total = parseInt(util.getValue(lines, 'hw.physmem'), 10);
|
|
223
|
+
}
|
|
224
|
+
result.free = parseInt(util.getValue(lines, 'vm.stats.vm.v_free_count'), 10) * pagesize;
|
|
225
|
+
result.buffcache = inactive + cache;
|
|
226
|
+
result.available = result.buffcache + result.free;
|
|
227
|
+
result.active = result.total - result.free - result.buffcache;
|
|
228
|
+
|
|
229
|
+
result.swaptotal = 0;
|
|
230
|
+
result.swapfree = 0;
|
|
231
|
+
result.swapused = 0;
|
|
232
|
+
}
|
|
233
|
+
if (callback) {
|
|
234
|
+
callback(result);
|
|
235
|
+
}
|
|
236
|
+
resolve(result);
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
} catch {
|
|
240
|
+
if (callback) {
|
|
241
|
+
callback(result);
|
|
242
|
+
}
|
|
243
|
+
resolve(result);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (_sunos) {
|
|
247
|
+
if (callback) {
|
|
248
|
+
callback(result);
|
|
249
|
+
}
|
|
250
|
+
resolve(result);
|
|
251
|
+
}
|
|
252
|
+
if (_darwin) {
|
|
253
|
+
let pageSize = 4096;
|
|
254
|
+
try {
|
|
255
|
+
let sysPpageSize = util.toInt(execSync('sysctl -n vm.pagesize').toString());
|
|
256
|
+
pageSize = sysPpageSize || pageSize;
|
|
257
|
+
} catch {
|
|
258
|
+
util.noop();
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
exec('vm_stat 2>/dev/null | egrep "Pages active|Pages inactive"', (error, stdout) => {
|
|
262
|
+
if (!error) {
|
|
263
|
+
let lines = stdout.toString().split('\n');
|
|
264
|
+
result.active = (parseInt(util.getValue(lines, 'Pages active'), 10) || 0) * pageSize;
|
|
265
|
+
result.reclaimable = (parseInt(util.getValue(lines, 'Pages inactive'), 10) || 0) * pageSize;
|
|
266
|
+
result.buffcache = result.used - result.active;
|
|
267
|
+
result.available = result.free + result.buffcache;
|
|
268
|
+
}
|
|
269
|
+
exec('sysctl -n vm.swapusage 2>/dev/null', (error, stdout) => {
|
|
270
|
+
if (!error) {
|
|
271
|
+
let lines = stdout.toString().split('\n');
|
|
272
|
+
if (lines.length > 0) {
|
|
273
|
+
let firstline = lines[0].replace(/,/g, '.').replace(/M/g, '');
|
|
274
|
+
let lineArray = firstline.trim().split(' ');
|
|
275
|
+
lineArray.forEach((line) => {
|
|
276
|
+
if (line.toLowerCase().indexOf('total') !== -1) {
|
|
277
|
+
result.swaptotal = parseFloat(line.split('=')[1].trim()) * 1024 * 1024;
|
|
278
|
+
}
|
|
279
|
+
if (line.toLowerCase().indexOf('used') !== -1) {
|
|
280
|
+
result.swapused = parseFloat(line.split('=')[1].trim()) * 1024 * 1024;
|
|
281
|
+
}
|
|
282
|
+
if (line.toLowerCase().indexOf('free') !== -1) {
|
|
283
|
+
result.swapfree = parseFloat(line.split('=')[1].trim()) * 1024 * 1024;
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (callback) {
|
|
289
|
+
callback(result);
|
|
290
|
+
}
|
|
291
|
+
resolve(result);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
} catch {
|
|
295
|
+
if (callback) {
|
|
296
|
+
callback(result);
|
|
297
|
+
}
|
|
298
|
+
resolve(result);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (_windows) {
|
|
302
|
+
let swaptotal = 0;
|
|
303
|
+
let swapused = 0;
|
|
304
|
+
try {
|
|
305
|
+
util.powerShell('Get-CimInstance Win32_PageFileUsage | Select AllocatedBaseSize, CurrentUsage').then((stdout, error) => {
|
|
306
|
+
if (!error) {
|
|
307
|
+
let lines = stdout
|
|
308
|
+
.split('\r\n')
|
|
309
|
+
.filter((line) => line.trim() !== '')
|
|
310
|
+
.filter((line, idx) => idx > 0);
|
|
311
|
+
lines.forEach((line) => {
|
|
312
|
+
if (line !== '') {
|
|
313
|
+
line = line.trim().split(/\s\s+/);
|
|
314
|
+
swaptotal = swaptotal + (parseInt(line[0], 10) || 0);
|
|
315
|
+
swapused = swapused + (parseInt(line[1], 10) || 0);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
result.swaptotal = swaptotal * 1024 * 1024;
|
|
320
|
+
result.swapused = swapused * 1024 * 1024;
|
|
321
|
+
result.swapfree = result.swaptotal - result.swapused;
|
|
322
|
+
|
|
323
|
+
if (callback) {
|
|
324
|
+
callback(result);
|
|
325
|
+
}
|
|
326
|
+
resolve(result);
|
|
327
|
+
});
|
|
328
|
+
} catch {
|
|
329
|
+
if (callback) {
|
|
330
|
+
callback(result);
|
|
331
|
+
}
|
|
332
|
+
resolve(result);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
exports.mem = mem;
|
|
340
|
+
|
|
341
|
+
function memLayout(callback) {
|
|
342
|
+
function getManufacturer(manId) {
|
|
343
|
+
const manIdSearch = manId.replace('0x', '').toUpperCase();
|
|
344
|
+
if (manIdSearch.length >= 4 && {}.hasOwnProperty.call(RAM_manufacturers, manIdSearch)) {
|
|
345
|
+
return RAM_manufacturers[manIdSearch];
|
|
346
|
+
}
|
|
347
|
+
return manId;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return new Promise((resolve) => {
|
|
351
|
+
process.nextTick(() => {
|
|
352
|
+
let result = [];
|
|
353
|
+
|
|
354
|
+
if (_linux || _freebsd || _openbsd || _netbsd) {
|
|
355
|
+
exec(
|
|
356
|
+
'export LC_ALL=C; dmidecode -t memory 2>/dev/null | grep -iE "Size:|Type|Speed|Manufacturer|Form Factor|Locator|Memory Device|Serial Number|Voltage|Part Number"; unset LC_ALL',
|
|
357
|
+
(error, stdout) => {
|
|
358
|
+
if (!error) {
|
|
359
|
+
const devices = stdout.toString().split('Memory Device');
|
|
360
|
+
devices.shift();
|
|
361
|
+
devices.forEach((device) => {
|
|
362
|
+
const lines = device.split('\n');
|
|
363
|
+
const sizeString = util.getValue(lines, 'Size');
|
|
364
|
+
const size = sizeString.indexOf('GB') >= 0 ? parseInt(sizeString, 10) * 1024 * 1024 * 1024 : parseInt(sizeString, 10) * 1024 * 1024;
|
|
365
|
+
let bank = util.getValue(lines, 'Bank Locator');
|
|
366
|
+
if (bank.toLowerCase().indexOf('bad') >= 0) {
|
|
367
|
+
bank = '';
|
|
368
|
+
}
|
|
369
|
+
if (parseInt(util.getValue(lines, 'Size'), 10) > 0) {
|
|
370
|
+
const totalWidth = util.toInt(util.getValue(lines, 'Total Width'));
|
|
371
|
+
const dataWidth = util.toInt(util.getValue(lines, 'Data Width'));
|
|
372
|
+
result.push({
|
|
373
|
+
size,
|
|
374
|
+
bank,
|
|
375
|
+
type: util.getValue(lines, 'Type:'),
|
|
376
|
+
ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
|
|
377
|
+
clockSpeed: util.getValue(lines, 'Configured Clock Speed:')
|
|
378
|
+
? parseInt(util.getValue(lines, 'Configured Clock Speed:'), 10)
|
|
379
|
+
: util.getValue(lines, 'Speed:')
|
|
380
|
+
? parseInt(util.getValue(lines, 'Speed:'), 10)
|
|
381
|
+
: null,
|
|
382
|
+
formFactor: util.getValue(lines, 'Form Factor:'),
|
|
383
|
+
manufacturer: getManufacturer(util.getValue(lines, 'Manufacturer:')),
|
|
384
|
+
partNum: util.getValue(lines, 'Part Number:'),
|
|
385
|
+
serialNum: util.getValue(lines, 'Serial Number:'),
|
|
386
|
+
voltageConfigured: parseFloat(util.getValue(lines, 'Configured Voltage:')) || null,
|
|
387
|
+
voltageMin: parseFloat(util.getValue(lines, 'Minimum Voltage:')) || null,
|
|
388
|
+
voltageMax: parseFloat(util.getValue(lines, 'Maximum Voltage:')) || null
|
|
389
|
+
});
|
|
390
|
+
} else {
|
|
391
|
+
result.push({
|
|
392
|
+
size: 0,
|
|
393
|
+
bank,
|
|
394
|
+
type: 'Empty',
|
|
395
|
+
ecc: null,
|
|
396
|
+
clockSpeed: 0,
|
|
397
|
+
formFactor: util.getValue(lines, 'Form Factor:'),
|
|
398
|
+
partNum: '',
|
|
399
|
+
serialNum: '',
|
|
400
|
+
voltageConfigured: null,
|
|
401
|
+
voltageMin: null,
|
|
402
|
+
voltageMax: null
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (!result.length) {
|
|
408
|
+
result.push({
|
|
409
|
+
size: os.totalmem(),
|
|
410
|
+
bank: '',
|
|
411
|
+
type: '',
|
|
412
|
+
ecc: null,
|
|
413
|
+
clockSpeed: 0,
|
|
414
|
+
formFactor: '',
|
|
415
|
+
partNum: '',
|
|
416
|
+
serialNum: '',
|
|
417
|
+
voltageConfigured: null,
|
|
418
|
+
voltageMin: null,
|
|
419
|
+
voltageMax: null
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Try Raspberry PI
|
|
423
|
+
try {
|
|
424
|
+
let stdout = execSync('cat /proc/cpuinfo 2>/dev/null', util.execOptsLinux);
|
|
425
|
+
let lines = stdout.toString().split('\n');
|
|
426
|
+
let version = util.getValue(lines, 'revision', ':', true).toLowerCase();
|
|
427
|
+
|
|
428
|
+
if (util.isRaspberry(lines)) {
|
|
429
|
+
const clockSpeed = {
|
|
430
|
+
0: 400,
|
|
431
|
+
1: 450,
|
|
432
|
+
2: 450,
|
|
433
|
+
3: 3200,
|
|
434
|
+
4: 4267
|
|
435
|
+
};
|
|
436
|
+
result[0].type = 'LPDDR2';
|
|
437
|
+
result[0].type = version && version[2] && version[2] === '3' ? 'LPDDR4' : result[0].type;
|
|
438
|
+
result[0].type = version && version[2] && version[2] === '4' ? 'LPDDR4X' : result[0].type;
|
|
439
|
+
result[0].ecc = false;
|
|
440
|
+
result[0].clockSpeed = (version && version[2] && clockSpeed[version[2]]) || 400;
|
|
441
|
+
result[0].clockSpeed = version && version[4] && version[4] === 'd' ? 500 : result[0].clockSpeed;
|
|
442
|
+
result[0].formFactor = 'SoC';
|
|
443
|
+
|
|
444
|
+
stdout = execSync('vcgencmd get_config sdram_freq 2>/dev/null', util.execOptsLinux);
|
|
445
|
+
lines = stdout.toString().split('\n');
|
|
446
|
+
let freq = parseInt(util.getValue(lines, 'sdram_freq', '=', true), 10) || 0;
|
|
447
|
+
if (freq) {
|
|
448
|
+
result[0].clockSpeed = freq;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
stdout = execSync('vcgencmd measure_volts sdram_p 2>/dev/null', util.execOptsLinux);
|
|
452
|
+
lines = stdout.toString().split('\n');
|
|
453
|
+
let voltage = parseFloat(util.getValue(lines, 'volt', '=', true)) || 0;
|
|
454
|
+
if (voltage) {
|
|
455
|
+
result[0].voltageConfigured = voltage;
|
|
456
|
+
result[0].voltageMin = voltage;
|
|
457
|
+
result[0].voltageMax = voltage;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
} catch {
|
|
461
|
+
util.noop();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (callback) {
|
|
465
|
+
callback(result);
|
|
466
|
+
}
|
|
467
|
+
resolve(result);
|
|
468
|
+
}
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (_darwin) {
|
|
473
|
+
exec('system_profiler SPMemoryDataType', (error, stdout) => {
|
|
474
|
+
if (!error) {
|
|
475
|
+
const allLines = stdout.toString().split('\n');
|
|
476
|
+
const eccStatus = util.getValue(allLines, 'ecc', ':', true).toLowerCase();
|
|
477
|
+
let devices = stdout.toString().split(' BANK ');
|
|
478
|
+
let hasBank = true;
|
|
479
|
+
if (devices.length === 1) {
|
|
480
|
+
devices = stdout.toString().split(' DIMM');
|
|
481
|
+
hasBank = false;
|
|
482
|
+
}
|
|
483
|
+
devices.shift();
|
|
484
|
+
devices.forEach((device) => {
|
|
485
|
+
const lines = device.split('\n');
|
|
486
|
+
const bank = (hasBank ? 'BANK ' : 'DIMM') + lines[0].trim().split('/')[0];
|
|
487
|
+
const size = parseInt(util.getValue(lines, ' Size'));
|
|
488
|
+
if (size) {
|
|
489
|
+
result.push({
|
|
490
|
+
size: size * 1024 * 1024 * 1024,
|
|
491
|
+
bank: bank,
|
|
492
|
+
type: util.getValue(lines, ' Type:'),
|
|
493
|
+
ecc: eccStatus ? eccStatus === 'enabled' : null,
|
|
494
|
+
clockSpeed: parseInt(util.getValue(lines, ' Speed:'), 10),
|
|
495
|
+
formFactor: '',
|
|
496
|
+
manufacturer: getManufacturer(util.getValue(lines, ' Manufacturer:')),
|
|
497
|
+
partNum: util.getValue(lines, ' Part Number:'),
|
|
498
|
+
serialNum: util.getValue(lines, ' Serial Number:'),
|
|
499
|
+
voltageConfigured: null,
|
|
500
|
+
voltageMin: null,
|
|
501
|
+
voltageMax: null
|
|
502
|
+
});
|
|
503
|
+
} else {
|
|
504
|
+
result.push({
|
|
505
|
+
size: 0,
|
|
506
|
+
bank: bank,
|
|
507
|
+
type: 'Empty',
|
|
508
|
+
ecc: null,
|
|
509
|
+
clockSpeed: 0,
|
|
510
|
+
formFactor: '',
|
|
511
|
+
manufacturer: '',
|
|
512
|
+
partNum: '',
|
|
513
|
+
serialNum: '',
|
|
514
|
+
voltageConfigured: null,
|
|
515
|
+
voltageMin: null,
|
|
516
|
+
voltageMax: null
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
if (!result.length) {
|
|
522
|
+
const lines = stdout.toString().split('\n');
|
|
523
|
+
const size = parseInt(util.getValue(lines, ' Memory:'));
|
|
524
|
+
const type = util.getValue(lines, ' Type:');
|
|
525
|
+
const manufacturerId = util.getValue(lines, ' Manufacturer:');
|
|
526
|
+
if (size && type) {
|
|
527
|
+
result.push({
|
|
528
|
+
size: size * 1024 * 1024 * 1024,
|
|
529
|
+
bank: '0',
|
|
530
|
+
type,
|
|
531
|
+
ecc: false,
|
|
532
|
+
clockSpeed: null,
|
|
533
|
+
formFactor: 'SOC',
|
|
534
|
+
manufacturer: getManufacturer(manufacturerId),
|
|
535
|
+
partNum: '',
|
|
536
|
+
serialNum: '',
|
|
537
|
+
voltageConfigured: null,
|
|
538
|
+
voltageMin: null,
|
|
539
|
+
voltageMax: null
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
if (callback) {
|
|
544
|
+
callback(result);
|
|
545
|
+
}
|
|
546
|
+
resolve(result);
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
if (_sunos) {
|
|
550
|
+
if (callback) {
|
|
551
|
+
callback(result);
|
|
552
|
+
}
|
|
553
|
+
resolve(result);
|
|
554
|
+
}
|
|
555
|
+
if (_windows) {
|
|
556
|
+
// https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.4.0a.pdf
|
|
557
|
+
const memoryTypes =
|
|
558
|
+
'Unknown|Other|DRAM|Synchronous DRAM|Cache DRAM|EDO|EDRAM|VRAM|SRAM|RAM|ROM|FLASH|EEPROM|FEPROM|EPROM|CDRAM|3DRAM|SDRAM|SGRAM|RDRAM|DDR|DDR2|DDR2 FB-DIMM|Reserved|DDR3|FBD2|DDR4|LPDDR|LPDDR2|LPDDR3|LPDDR4|Logical non-volatile device|HBM|HBM2|DDR5|LPDDR5'.split(
|
|
559
|
+
'|'
|
|
560
|
+
);
|
|
561
|
+
const FormFactors = 'Unknown|Other|SIP|DIP|ZIP|SOJ|Proprietary|SIMM|DIMM|TSOP|PGA|RIMM|SODIMM|SRIMM|SMD|SSMP|QFP|TQFP|SOIC|LCC|PLCC|BGA|FPBGA|LGA'.split('|');
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
util
|
|
565
|
+
.powerShell(
|
|
566
|
+
'Get-CimInstance Win32_PhysicalMemory | select DataWidth,TotalWidth,Capacity,BankLabel,MemoryType,SMBIOSMemoryType,ConfiguredClockSpeed,Speed,FormFactor,Manufacturer,PartNumber,SerialNumber,ConfiguredVoltage,MinVoltage,MaxVoltage,Tag | fl'
|
|
567
|
+
)
|
|
568
|
+
.then((stdout, error) => {
|
|
569
|
+
if (!error) {
|
|
570
|
+
const devices = stdout.toString().split(/\n\s*\n/);
|
|
571
|
+
devices.shift();
|
|
572
|
+
devices.forEach((device) => {
|
|
573
|
+
const lines = device.split('\r\n');
|
|
574
|
+
const dataWidth = util.toInt(util.getValue(lines, 'DataWidth', ':'));
|
|
575
|
+
const totalWidth = util.toInt(util.getValue(lines, 'TotalWidth', ':'));
|
|
576
|
+
const size = parseInt(util.getValue(lines, 'Capacity', ':'), 10) || 0;
|
|
577
|
+
const tag = util.getValue(lines, 'Tag', ':');
|
|
578
|
+
const tagInt = util.splitByNumber(tag);
|
|
579
|
+
if (size) {
|
|
580
|
+
result.push({
|
|
581
|
+
size,
|
|
582
|
+
bank: util.getValue(lines, 'BankLabel', ':') + (tagInt[1] ? '/' + tagInt[1] : ''), // BankLabel
|
|
583
|
+
type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', ':'), 10) || parseInt(util.getValue(lines, 'SMBIOSMemoryType', ':'), 10)],
|
|
584
|
+
ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
|
|
585
|
+
clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', ':'), 10) || parseInt(util.getValue(lines, 'Speed', ':'), 10) || 0,
|
|
586
|
+
formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', ':'), 10) || 0],
|
|
587
|
+
manufacturer: getManufacturer(util.getValue(lines, 'Manufacturer', ':')),
|
|
588
|
+
partNum: util.getValue(lines, 'PartNumber', ':'),
|
|
589
|
+
serialNum: util.getValue(lines, 'SerialNumber', ':'),
|
|
590
|
+
voltageConfigured: (parseInt(util.getValue(lines, 'ConfiguredVoltage', ':'), 10) || 0) / 1000.0,
|
|
591
|
+
voltageMin: (parseInt(util.getValue(lines, 'MinVoltage', ':'), 10) || 0) / 1000.0,
|
|
592
|
+
voltageMax: (parseInt(util.getValue(lines, 'MaxVoltage', ':'), 10) || 0) / 1000.0
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
if (callback) {
|
|
598
|
+
callback(result);
|
|
599
|
+
}
|
|
600
|
+
resolve(result);
|
|
601
|
+
});
|
|
602
|
+
} catch {
|
|
603
|
+
if (callback) {
|
|
604
|
+
callback(result);
|
|
605
|
+
}
|
|
606
|
+
resolve(result);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
exports.memLayout = memLayout;
|