move identifiers to server side to allow future updates (#5641)
* move identifiers to server side to allow future updates Signed-off-by: si458 <simonsmith5521@gmail.com> * add rpi support Signed-off-by: si458 <simonsmith5521@gmail.com> --------- Signed-off-by: si458 <simonsmith5521@gmail.com>
Simon Smith committed
Dec 22, 2023 at 23:18 UTC
bfae0d6c6e29b09f81a17778fa5adaed8c70d28c
2 files changed
+792
-16
agents/meshcore.js
+17
-16
@@ -622,7 +622,7 @@ if ((require('fs').existsSync(process.cwd() + 'batterystate.txt')) && (require('
622
else {
623
try {
624
// Setup normal battery monitoring
625
- if (require('identifiers').isBatteryPowered && require('identifiers').isBatteryPowered()) {
625
+ if (require('computer-identifiers').isBatteryPowered && require('computer-identifiers').isBatteryPowered()) {
626
require('MeshAgent')._battLevelChanged = function _battLevelChanged(val) {
627
_battLevelChanged.self._currentBatteryLevel = val;
628
_battLevelChanged.self.SendCommand({ action: 'battery', state: _battLevelChanged.self._currentPowerState, level: val });
@@ -657,14 +657,14 @@ try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; meshCoreO
657
// Get Volumes and BitLocker if Windows
658
try {
659
if (process.platform == 'win32'){
660
- if (require('identifiers').volumes_promise != null){
661
- var p = require('identifiers').volumes_promise();
660
+ if (require('computer-identifiers').volumes_promise != null){
661
+ var p = require('computer-identifiers').volumes_promise();
662
p.then(function (res){
663
meshCoreObj.volumes = res;
664
meshCoreObjChanged();
665
});
666
- }else if (require('identifiers').volumes != null){
667
- meshCoreObj.volumes = require('identifiers').volumes();
666
+ }else if (require('computer-identifiers').volumes != null){
667
+ meshCoreObj.volumes = require('computer-identifiers').volumes();
668
meshCoreObjChanged();
669
}
670
}
@@ -1813,7 +1813,7 @@ function onFileWatcher(a, b) {
1813
*/
1814
1815
// Replace all key name spaces with _ in an object recursively.
1816
-// This is a workaround since require('identifiers').get() returns key names with spaces in them on Linux.
1816
+// This is a workaround since require('computer-identifiers').get() returns key names with spaces in them on Linux.
1817
function replaceSpacesWithUnderscoresRec(o) {
1818
if (typeof o != 'object') return;
1819
for (var i in o) { if (i.indexOf(' ') >= 0) { o[i.split(' ').join('_')] = o[i]; delete o[i]; } replaceSpacesWithUnderscoresRec(o[i]); }
@@ -1821,8 +1821,7 @@ function replaceSpacesWithUnderscoresRec(o) {
1821
1822
function getSystemInformation(func) {
1823
try {
1824
- var results = { hardware: require('identifiers').get() }; // Hardware info
1825
-
1824
+ var results = { hardware: require('computer-identifiers').get() }; // Hardware info
1825
if (results.hardware && results.hardware.windows) {
1826
// Remove extra entries and things that change quickly
1827
var x = results.hardware.windows.osinfo;
@@ -1873,9 +1872,11 @@ function getSystemInformation(func) {
1872
}
1873
if(results.hardware && results.hardware.linux) {
1874
if (!results.hardware.identifiers['bios_serial']) {
1876
- if (require('fs').statSync('/sys/class/dmi/id/product_serial').isFile()){
1877
- results.hardware.identifiers['bios_serial'] = require('fs').readFileSync('/sys/class/dmi/id/product_serial').toString().trim();
1878
- }
1875
+ try {
1876
+ if (require('fs').statSync('/sys/class/dmi/id/product_serial').isFile()){
1877
+ results.hardware.identifiers['bios_serial'] = require('fs').readFileSync('/sys/class/dmi/id/product_serial').toString().trim();
1878
+ }
1879
+ } catch (ex) { }
1880
}
1881
if (!results.hardware.identifiers['bios_mode']) {
1882
try {
@@ -1928,9 +1929,9 @@ function getSystemInformation(func) {
1929
{
1930
results.pendingReboot = require('win-info').pendingReboot(); // Pending reboot
1931
1931
- if (require('identifiers').volumes_promise != null)
1932
+ if (require('computer-identifiers').volumes_promise != null)
1933
{
1933
- var p = require('identifiers').volumes_promise();
1934
+ var p = require('computer-identifiers').volumes_promise();
1935
p.then(function (res)
1936
{
1937
results.hardware.windows.volumes = res;
@@ -1938,9 +1939,9 @@ function getSystemInformation(func) {
1939
func(results);
1940
});
1941
}
1941
- else if (require('identifiers').volumes != null)
1942
+ else if (require('computer-identifiers').volumes != null)
1943
{
1943
- results.hardware.windows.volumes = require('identifiers').volumes();
1944
+ results.hardware.windows.volumes = require('computer-identifiers').volumes();
1945
results.hash = hasher.syncHash(JSON.stringify(results)).toString('hex');
1946
func(results);
1947
}
@@ -4250,7 +4251,7 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
4251
}
4252
break;
4253
case 'vm':
4253
- response = 'Virtual Machine = ' + require('identifiers').isVM();
4254
+ response = 'Virtual Machine = ' + require('computer-identifiers').isVM();
4255
break;
4256
case 'startupoptions':
4257
response = JSON.stringify(require('MeshAgent').getStartupOptions());
agents/modules_meshcore/computer-identifiers.js
new
+775
@@ -0,0 +1,775 @@
1
+/*
2
+Copyright 2019-2021 Intel Corporation
3
+
4
+Licensed under the Apache License, Version 2.0 (the "License");
5
+you may not use this file except in compliance with the License.
6
+You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+Unless required by applicable law or agreed to in writing, software
11
+distributed under the License is distributed on an "AS IS" BASIS,
12
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+See the License for the specific language governing permissions and
14
+limitations under the License.
15
+*/
16
+
17
+function trimIdentifiers(val)
18
+{
19
+ for(var v in val)
20
+ {
21
+ if (!val[v] || val[v] == 'None' || val[v] == '') { delete val[v]; }
22
+ }
23
+}
24
+function trimResults(val)
25
+{
26
+ var i, x;
27
+ for (i = 0; i < val.length; ++i)
28
+ {
29
+ for (x in val[i])
30
+ {
31
+ if (x.startsWith('_'))
32
+ {
33
+ delete val[i][x];
34
+ }
35
+ else
36
+ {
37
+ if (val[i][x] == null || val[i][x] == 0)
38
+ {
39
+ delete val[i][x];
40
+ }
41
+ }
42
+ }
43
+ }
44
+}
45
+function brief(headers, obj)
46
+{
47
+ var i, x;
48
+ for (x = 0; x < obj.length; ++x)
49
+ {
50
+ for (i in obj[x])
51
+ {
52
+ if (!headers.includes(i))
53
+ {
54
+ delete obj[x][i];
55
+ }
56
+ }
57
+ }
58
+ return (obj);
59
+}
60
+
61
+function dataHandler(c)
62
+{
63
+ this.str += c.toString();
64
+}
65
+
66
+function linux_identifiers()
67
+{
68
+ var identifiers = {};
69
+ var ret = {};
70
+ var values = {};
71
+
72
+ if (!require('fs').existsSync('/sys/class/dmi/id')) {
73
+ if(require('fs').existsSync('/sys/firmware/devicetree/base/model')){
74
+ if(require('fs').readFileSync('/sys/firmware/devicetree/base/model').toString().trim().startsWith('Raspberry')){
75
+ identifiers['board_vendor'] = 'Raspberry Pi';
76
+ identifiers['board_name'] = require('fs').readFileSync('/sys/firmware/devicetree/base/model').toString().trim();
77
+ identifiers['board_serial'] = require('fs').readFileSync('/sys/firmware/devicetree/base/serial-number').toString().trim();
78
+ }else{
79
+ throw('Unknown board');
80
+ }
81
+ }else {
82
+ throw ('this platform does not have DMI statistics');
83
+ }
84
+ } else {
85
+ var entries = require('fs').readdirSync('/sys/class/dmi/id');
86
+ for(var i in entries)
87
+ {
88
+ if (require('fs').statSync('/sys/class/dmi/id/' + entries[i]).isFile())
89
+ {
90
+ try
91
+ {
92
+ ret[entries[i]] = require('fs').readFileSync('/sys/class/dmi/id/' + entries[i]).toString().trim();
93
+ }
94
+ catch(z)
95
+ {
96
+ }
97
+ if (ret[entries[i]] == 'None') { delete ret[entries[i]];}
98
+ }
99
+ }
100
+ entries = null;
101
+
102
+ identifiers['bios_date'] = ret['bios_date'];
103
+ identifiers['bios_vendor'] = ret['bios_vendor'];
104
+ identifiers['bios_version'] = ret['bios_version'];
105
+ identifiers['bios_serial'] = ret['product_serial'];
106
+ identifiers['board_name'] = ret['board_name'];
107
+ identifiers['board_serial'] = ret['board_serial'];
108
+ identifiers['board_vendor'] = ret['board_vendor'];
109
+ identifiers['board_version'] = ret['board_version'];
110
+ identifiers['product_uuid'] = ret['product_uuid'];
111
+ identifiers['product_name'] = ret['product_name'];
112
+ }
113
+
114
+ try {
115
+ identifiers['bios_mode'] = (require('fs').statSync('/sys/firmware/efi').isDirectory() ? 'UEFI': 'Legacy');
116
+ } catch (ex) { identifiers['bios_mode'] = 'Legacy'; }
117
+
118
+ var child = require('child_process').execFile('/bin/sh', ['sh']);
119
+ child.stdout.str = ''; child.stdout.on('data', dataHandler);
120
+ child.stdin.write('cat /proc/cpuinfo | grep "model name" | ' + "tr '\\n' ':' | awk -F: '{ print $2 }'\nexit\n");
121
+ child.waitExit();
122
+ identifiers['cpu_name'] = child.stdout.str.trim();
123
+ child = null;
124
+
125
+
126
+ // Fetch GPU info
127
+ child = require('child_process').execFile('/bin/sh', ['sh']);
128
+ child.stdout.str = ''; child.stdout.on('data', dataHandler);
129
+ child.stdin.write("lspci | grep ' VGA ' | tr '\\n' '`' | awk '{ a=split($0,lines" + ',"`"); printf "["; for(i=1;i<a;++i) { split(lines[i],gpu,"r: "); printf "%s\\"%s\\"", (i==1?"":","),gpu[2]; } printf "]"; }\'\nexit\n');
130
+ child.waitExit();
131
+ try { identifiers['gpu_name'] = JSON.parse(child.stdout.str.trim()); } catch (xx) { }
132
+ child = null;
133
+
134
+ // Fetch Storage Info
135
+ child = require('child_process').execFile('/bin/sh', ['sh']);
136
+ child.stdout.str = ''; child.stdout.on('data', dataHandler);
137
+ child.stdin.write("lshw -class disk | tr '\\n' '`' | awk '" + '{ len=split($0,lines,"*"); printf "["; for(i=2;i<=len;++i) { model=""; caption=""; size=""; clen=split(lines[i],item,"`"); for(j=2;j<clen;++j) { split(item[j],tokens,":"); split(tokens[1],key," "); if(key[1]=="description") { caption=substr(tokens[2],2); } if(key[1]=="product") { model=substr(tokens[2],2); } if(key[1]=="size") { size=substr(tokens[2],2); } } if(model=="") { model=caption; } if(caption!="" || model!="") { printf "%s{\\"Caption\\":\\"%s\\",\\"Model\\":\\"%s\\",\\"Size\\":\\"%s\\"}",(i==2?"":","),caption,model,size; } } printf "]"; }\'\nexit\n');
138
+ child.waitExit();
139
+ try { identifiers['storage_devices'] = JSON.parse(child.stdout.str.trim()); } catch (xx) { }
140
+
141
+ values.identifiers = identifiers;
142
+ values.linux = ret;
143
+ trimIdentifiers(values.identifiers);
144
+ child = null;
145
+
146
+ var dmidecode = require('lib-finder').findBinary('dmidecode');
147
+ if (dmidecode != null)
148
+ {
149
+ child = require('child_process').execFile('/bin/sh', ['sh']);
150
+ child.stdout.str = ''; child.stdout.on('data', dataHandler);
151
+ child.stderr.str = ''; child.stderr.on('data', dataHandler);
152
+ child.stdin.write(dmidecode + " -t memory | tr '\\n' '`' | ");
153
+ child.stdin.write(" awk '{ ");
154
+ child.stdin.write(' printf("[");');
155
+ child.stdin.write(' comma="";');
156
+ child.stdin.write(' c=split($0, lines, "``");');
157
+ child.stdin.write(' for(i=1;i<=c;++i)');
158
+ child.stdin.write(' {');
159
+ child.stdin.write(' d=split(lines[i], val, "`");');
160
+ child.stdin.write(' split(val[1], tokens, ",");');
161
+ child.stdin.write(' split(tokens[2], dmitype, " ");');
162
+ child.stdin.write(' dmi = dmitype[3]+0; ');
163
+ child.stdin.write(' if(dmi == 5 || dmi == 6 || dmi == 16 || dmi == 17)');
164
+ child.stdin.write(' {');
165
+ child.stdin.write(' ccx="";');
166
+ child.stdin.write(' printf("%s{\\"%s\\": {", comma, val[2]);');
167
+ child.stdin.write(' for(j=3;j<d;++j)');
168
+ child.stdin.write(' {');
169
+ child.stdin.write(' sub(/^[ \\t]*/,"",val[j]);');
170
+ child.stdin.write(' if(split(val[j],tmp,":")>1)');
171
+ child.stdin.write(' {');
172
+ child.stdin.write(' sub(/^[ \\t]*/,"",tmp[2]);');
173
+ child.stdin.write(' gsub(/ /,"",tmp[1]);');
174
+ child.stdin.write(' printf("%s\\"%s\\": \\"%s\\"", ccx, tmp[1], tmp[2]);');
175
+ child.stdin.write(' ccx=",";');
176
+ child.stdin.write(' }');
177
+ child.stdin.write(' }');
178
+ child.stdin.write(' printf("}}");');
179
+ child.stdin.write(' comma=",";');
180
+ child.stdin.write(' }');
181
+ child.stdin.write(' }');
182
+ child.stdin.write(' printf("]");');
183
+ child.stdin.write("}'\nexit\n");
184
+ child.waitExit();
185
+
186
+ try
187
+ {
188
+ var j = JSON.parse(child.stdout.str);
189
+ var i, key, key2;
190
+ for (i = 0; i < j.length; ++i)
191
+ {
192
+ for (key in j[i])
193
+ {
194
+ delete j[i][key]['ArrayHandle'];
195
+ delete j[i][key]['ErrorInformationHandle'];
196
+ for (key2 in j[i][key])
197
+ {
198
+ if (j[i][key][key2] == 'Unknown' || j[i][key][key2] == 'Not Specified' || j[i][key][key2] == '')
199
+ {
200
+ delete j[i][key][key2];
201
+ }
202
+ }
203
+ }
204
+ }
205
+
206
+ if(j.length > 0){
207
+ var mem = {};
208
+ for (i = 0; i < j.length; ++i)
209
+ {
210
+ for (key in j[i])
211
+ {
212
+ if (mem[key] == null) { mem[key] = []; }
213
+ mem[key].push(j[i][key]);
214
+ }
215
+ }
216
+ values.linux.memory = mem;
217
+ }
218
+ }
219
+ catch (e)
220
+ { }
221
+ child = null;
222
+ }
223
+
224
+ var usbdevices = require('lib-finder').findBinary('usb-devices');
225
+ if (usbdevices != null)
226
+ {
227
+ var child = require('child_process').execFile('/bin/sh', ['sh']);
228
+ child.stdout.str = ''; child.stdout.on('data', dataHandler);
229
+ child.stderr.str = ''; child.stderr.on('data', dataHandler);
230
+ child.stdin.write(usbdevices + " | tr '\\n' '`' | ");
231
+ child.stdin.write(" awk '");
232
+ child.stdin.write('{');
233
+ child.stdin.write(' comma="";');
234
+ child.stdin.write(' printf("[");');
235
+ child.stdin.write(' len=split($0, group, "``");');
236
+ child.stdin.write(' for(i=1;i<=len;++i)');
237
+ child.stdin.write(' {');
238
+ child.stdin.write(' comma2="";');
239
+ child.stdin.write(' xlen=split(group[i], line, "`");');
240
+ child.stdin.write(' scount=0;');
241
+ child.stdin.write(' for(x=1;x<xlen;++x)');
242
+ child.stdin.write(' {');
243
+ child.stdin.write(' if(line[x] ~ "^S:")');
244
+ child.stdin.write(' {');
245
+ child.stdin.write(' ++scount;');
246
+ child.stdin.write(' }');
247
+ child.stdin.write(' }');
248
+ child.stdin.write(' if(scount>0)');
249
+ child.stdin.write(' {');
250
+ child.stdin.write(' printf("%s{", comma); comma=",";');
251
+ child.stdin.write(' for(x=1;x<xlen;++x)');
252
+ child.stdin.write(' {');
253
+ child.stdin.write(' if(line[x] ~ "^T:")');
254
+ child.stdin.write(' {');
255
+ child.stdin.write(' comma3="";');
256
+ child.stdin.write(' printf("%s\\"hardware\\": {", comma2); comma2=",";');
257
+ child.stdin.write(' sub(/^T:[ \\t]*/, "", line[x]);');
258
+ child.stdin.write(' gsub(/= */, "=", line[x]);');
259
+ child.stdin.write(' blen=split(line[x], tokens, " ");');
260
+ child.stdin.write(' for(y=1;y<blen;++y)');
261
+ child.stdin.write(' {');
262
+ child.stdin.write(' match(tokens[y],/=/);');
263
+ child.stdin.write(' h=substr(tokens[y],1,RSTART-1);');
264
+ child.stdin.write(' v=substr(tokens[y],RSTART+1);');
265
+ child.stdin.write(' sub(/#/, "", h);');
266
+ child.stdin.write(' printf("%s\\"%s\\": \\"%s\\"", comma3, h, v); comma3=",";');
267
+ child.stdin.write(' }');
268
+ child.stdin.write(' printf("}");');
269
+ child.stdin.write(' }');
270
+ child.stdin.write(' if(line[x] ~ "^S:")');
271
+ child.stdin.write(' {');
272
+ child.stdin.write(' sub(/^S:[ \\t]*/, "", line[x]);');
273
+ child.stdin.write(' match(line[x], /=/);');
274
+ child.stdin.write(' h=substr(line[x],1,RSTART-1);');
275
+ child.stdin.write(' v=substr(line[x],RSTART+1);');
276
+ child.stdin.write(' printf("%s\\"%s\\": \\"%s\\"", comma2, h,v); comma2=",";');
277
+ child.stdin.write(' }');
278
+ child.stdin.write(' }');
279
+ child.stdin.write(' printf("}");');
280
+ child.stdin.write(' }');
281
+ child.stdin.write(' }');
282
+ child.stdin.write(' printf("]");');
283
+ child.stdin.write("}'\nexit\n");
284
+ child.waitExit();
285
+
286
+ try
287
+ {
288
+ values.linux.usb = JSON.parse(child.stdout.str);
289
+ }
290
+ catch(x)
291
+ { }
292
+ child = null;
293
+ }
294
+
295
+ var pcidevices = require('lib-finder').findBinary('lspci');
296
+ if (pcidevices != null)
297
+ {
298
+ var child = require('child_process').execFile('/bin/sh', ['sh']);
299
+ child.stdout.str = ''; child.stdout.on('data', dataHandler);
300
+ child.stderr.str = ''; child.stderr.on('data', dataHandler);
301
+ child.stdin.write(pcidevices + " -m | tr '\\n' '`' | ");
302
+ child.stdin.write(" awk '");
303
+ child.stdin.write('{');
304
+ child.stdin.write(' printf("[");');
305
+ child.stdin.write(' comma="";');
306
+ child.stdin.write(' alen=split($0, lines, "`");');
307
+ child.stdin.write(' for(a=1;a<alen;++a)');
308
+ child.stdin.write(' {');
309
+ child.stdin.write(' match(lines[a], / /);');
310
+ child.stdin.write(' blen=split(lines[a], meta, "\\"");');
311
+ child.stdin.write(' bus=substr(lines[a], 1, RSTART);');
312
+ child.stdin.write(' gsub(/ /, "", bus);');
313
+ child.stdin.write(' printf("%s{\\"bus\\": \\"%s\\"", comma, bus); comma=",";');
314
+ child.stdin.write(' printf(", \\"device\\": \\"%s\\"", meta[2]);');
315
+ child.stdin.write(' printf(", \\"manufacturer\\": \\"%s\\"", meta[4]);');
316
+ child.stdin.write(' printf(", \\"description\\": \\"%s\\"", meta[6]);');
317
+ child.stdin.write(' if(meta[8] != "")');
318
+ child.stdin.write(' {');
319
+ child.stdin.write(' printf(", \\"subsystem\\": {");');
320
+ child.stdin.write(' printf("\\"manufacturer\\": \\"%s\\"", meta[8]);');
321
+ child.stdin.write(' printf(", \\"description\\": \\"%s\\"", meta[10]);');
322
+ child.stdin.write(' printf("}");');
323
+ child.stdin.write(' }');
324
+ child.stdin.write(' printf("}");');
325
+ child.stdin.write(' }');
326
+ child.stdin.write(' printf("]");');
327
+ child.stdin.write("}'\nexit\n");
328
+ child.waitExit();
329
+
330
+ try
331
+ {
332
+ values.linux.pci = JSON.parse(child.stdout.str);
333
+ }
334
+ catch (x)
335
+ { }
336
+ child = null;
337
+ }
338
+
339
+ return (values);
340
+}
341
+
342
+function windows_wmic_results(str)
343
+{
344
+ var lines = str.trim().split('\r\n');
345
+ var keys = lines[0].split(',');
346
+ var i, key, keyval;
347
+ var tokens;
348
+ var result = [];
349
+
350
+ console.log('Lines: ' + lines.length, 'Keys: ' + keys.length);
351
+
352
+ for (i = 1; i < lines.length; ++i)
353
+ {
354
+ var obj = {};
355
+ console.log('i: ' + i);
356
+ tokens = lines[i].split(',');
357
+ for (key = 0; key < keys.length; ++key)
358
+ {
359
+ var tmp = Buffer.from(tokens[key], 'binary').toString();
360
+ console.log(tokens[key], tmp);
361
+ tokens[key] = tmp == null ? '' : tmp;
362
+ if (tokens[key].trim())
363
+ {
364
+ obj[keys[key].trim()] = tokens[key].trim();
365
+ }
366
+ }
367
+ delete obj.Node;
368
+ result.push(obj);
369
+ }
370
+ return (result);
371
+}
372
+
373
+function windows_volumes()
374
+{
375
+ var promise = require('promise');
376
+ var p1 = new promise(function (res, rej) { this._res = res; this._rej = rej; });
377
+ var p2 = new promise(function (res, rej) { this._res = res; this._rej = rej; });
378
+
379
+ p1._p2 = p2;
380
+ p2._p1 = p1;
381
+
382
+ var child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['powershell', '-noprofile', '-nologo', '-command', '-']);
383
+ p1.child = child;
384
+ child.promise = p1;
385
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
386
+ child.stdin.write('Get-Volume | Select-Object -Property DriveLetter,FileSystemLabel,FileSystemType,Size,DriveType | ConvertTo-Csv -NoTypeInformation\nexit\n');
387
+ child.on('exit', function (c)
388
+ {
389
+ var a, i, tokens, key;
390
+ var ret = {};
391
+
392
+ a = this.stdout.str.trim().split('\r\n');
393
+ for (i = 1; i < a.length; ++i)
394
+ {
395
+ tokens = a[i].split(',');
396
+ if (tokens[0] != '' && tokens[1] != undefined)
397
+ {
398
+ ret[tokens[0].split('"')[1]] =
399
+ {
400
+ name: tokens[1].split('"')[1],
401
+ type: tokens[2].split('"')[1],
402
+ size: tokens[3].split('"')[1],
403
+ removable: tokens[4].split('"')[1] == 'Removable'
404
+ };
405
+ }
406
+ }
407
+ this.promise._res({ r: ret, t: tokens });
408
+ });
409
+
410
+ p1.then(function (j)
411
+ {
412
+ var ret = j.r;
413
+ var tokens = j.t;
414
+
415
+ var child = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['powershell', '-noprofile', '-nologo', '-command', '-']);
416
+ p2.child = child;
417
+ child.promise = p2;
418
+ child.tokens = tokens;
419
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
420
+ child.stdin.write('Get-BitLockerVolume | Select-Object -Property MountPoint,VolumeStatus,ProtectionStatus | ConvertTo-Csv -NoTypeInformation\nexit\n');
421
+ child.on('exit', function ()
422
+ {
423
+ var i;
424
+ var a = this.stdout.str.trim().split('\r\n');
425
+ for (i = 1; i < a.length; ++i)
426
+ {
427
+ tokens = a[i].split(',');
428
+ key = tokens[0].split(':').shift().split('"').pop();
429
+ if (ret[key] != null)
430
+ {
431
+ ret[key].volumeStatus = tokens[1].split('"')[1];
432
+ ret[key].protectionStatus = tokens[2].split('"')[1];
433
+ }
434
+ }
435
+ this.promise._res(ret);
436
+ });
437
+ });
438
+ return (p2);
439
+}
440
+
441
+function windows_identifiers()
442
+{
443
+ var ret = { windows: {} };
444
+ var items, item, i;
445
+
446
+ ret['identifiers'] = {};
447
+
448
+ var values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_Bios", ['ReleaseDate', 'Manufacturer', 'SMBIOSBIOSVersion', 'SerialNumber']);
449
+ if(values[0]){
450
+ ret['identifiers']['bios_date'] = values[0]['ReleaseDate'];
451
+ ret['identifiers']['bios_vendor'] = values[0]['Manufacturer'];
452
+ ret['identifiers']['bios_version'] = values[0]['SMBIOSBIOSVersion'];
453
+ ret['identifiers']['bios_serial'] = values[0]['SerialNumber'];
454
+ }
455
+ ret['identifiers']['bios_mode'] = 'Legacy';
456
+
457
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_BaseBoard", ['Product', 'SerialNumber', 'Manufacturer', 'Version']);
458
+ if(values[0]){
459
+ ret['identifiers']['board_name'] = values[0]['Product'];
460
+ ret['identifiers']['board_serial'] = values[0]['SerialNumber'];
461
+ ret['identifiers']['board_vendor'] = values[0]['Manufacturer'];
462
+ ret['identifiers']['board_version'] = values[0]['Version'];
463
+ }
464
+
465
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_ComputerSystemProduct", ['UUID', 'Name']);
466
+ if(values[0]){
467
+ ret['identifiers']['product_uuid'] = values[0]['UUID'];
468
+ ret['identifiers']['product_name'] = values[0]['Name'];
469
+ trimIdentifiers(ret.identifiers);
470
+ }
471
+
472
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_PhysicalMemory");
473
+ if(values[0]){
474
+ trimResults(values);
475
+ ret.windows.memory = values;
476
+ }
477
+
478
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_OperatingSystem");
479
+ if(values[0]){
480
+ trimResults(values);
481
+ ret.windows.osinfo = values[0];
482
+ }
483
+
484
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_DiskPartition");
485
+ if(values[0]){
486
+ trimResults(values);
487
+ ret.windows.partitions = values;
488
+ for (var i in values) {
489
+ if (values[i].Description=='GPT: System') {
490
+ ret['identifiers']['bios_mode'] = 'UEFI';
491
+ }
492
+ }
493
+ }
494
+
495
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_Processor", ['Caption', 'DeviceID', 'Manufacturer', 'MaxClockSpeed', 'Name', 'SocketDesignation']);
496
+ if(values[0]){
497
+ ret.windows.cpu = values;
498
+ }
499
+
500
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_VideoController", ['Name', 'CurrentHorizontalResolution', 'CurrentVerticalResolution']);
501
+ if(values[0]){
502
+ ret.windows.gpu = values;
503
+ }
504
+
505
+ values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_DiskDrive", ['Caption', 'DeviceID', 'Model', 'Partitions', 'Size', 'Status']);
506
+ if(values[0]){
507
+ ret.windows.drives = values;
508
+ }
509
+
510
+ // Insert GPU names
511
+ ret.identifiers.gpu_name = [];
512
+ for (var gpuinfo in ret.windows.gpu)
513
+ {
514
+ if (ret.windows.gpu[gpuinfo].Name) { ret.identifiers.gpu_name.push(ret.windows.gpu[gpuinfo].Name); }
515
+ }
516
+
517
+ // Insert Storage Devices
518
+ ret.identifiers.storage_devices = [];
519
+ for (var dv in ret.windows.drives)
520
+ {
521
+ ret.identifiers.storage_devices.push({ Caption: ret.windows.drives[dv].Caption, Model: ret.windows.drives[dv].Model, Size: ret.windows.drives[dv].Size });
522
+ }
523
+
524
+ try { ret.identifiers.cpu_name = ret.windows.cpu[0].Name; } catch (x) { }
525
+ return (ret);
526
+}
527
+function macos_identifiers()
528
+{
529
+ var ret = { identifiers: {} };
530
+ var child;
531
+
532
+ child = require('child_process').execFile('/bin/sh', ['sh']);
533
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
534
+ child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep board-id | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
535
+ child.waitExit();
536
+ ret.identifiers.board_name = child.stdout.str.trim();
537
+
538
+ child = require('child_process').execFile('/bin/sh', ['sh']);
539
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
540
+ child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformSerialNumber | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
541
+ child.waitExit();
542
+ ret.identifiers.board_serial = child.stdout.str.trim();
543
+
544
+ child = require('child_process').execFile('/bin/sh', ['sh']);
545
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
546
+ child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep manufacturer | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
547
+ child.waitExit();
548
+ ret.identifiers.board_vendor = child.stdout.str.trim();
549
+
550
+ child = require('child_process').execFile('/bin/sh', ['sh']);
551
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
552
+ child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep version | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
553
+ child.waitExit();
554
+ ret.identifiers.board_version = child.stdout.str.trim();
555
+
556
+ child = require('child_process').execFile('/bin/sh', ['sh']);
557
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
558
+ child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformUUID | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
559
+ child.waitExit();
560
+ ret.identifiers.product_uuid = child.stdout.str.trim();
561
+
562
+ child = require('child_process').execFile('/bin/sh', ['sh']);
563
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
564
+ child.stdin.write('sysctl -n machdep.cpu.brand_string\nexit\n');
565
+ child.waitExit();
566
+ ret.identifiers.cpu_name = child.stdout.str.trim();
567
+
568
+
569
+ trimIdentifiers(ret.identifiers);
570
+
571
+
572
+ child = null;
573
+ return (ret);
574
+}
575
+
576
+function win_chassisType()
577
+{
578
+ var child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'SystemEnclosure', 'get', 'ChassisTypes']);
579
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
580
+ child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
581
+ child.waitExit();
582
+
583
+ try
584
+ {
585
+ var tok = child.stdout.str.split('{')[1].split('}')[0];
586
+ var val = tok.split(',')[0];
587
+ return (parseInt(val));
588
+ }
589
+ catch (e)
590
+ {
591
+ return (2); // unknown
592
+ }
593
+}
594
+
595
+function win_systemType()
596
+{
597
+ var CSV = '/FORMAT:"' + require('util-language').wmicXslPath + 'csv"';
598
+ var child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'ComputerSystem', 'get', 'PCSystemType', CSV]);
599
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
600
+ child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
601
+ child.waitExit();
602
+
603
+ return (parseInt(child.stdout.str.trim().split(',').pop()));
604
+}
605
+
606
+function win_formFactor(chassistype)
607
+{
608
+ var ret = 'DESKTOP';
609
+ switch (chassistype)
610
+ {
611
+ case 11: // Handheld
612
+ case 30: // Tablet
613
+ case 31: // Convertible
614
+ case 32: // Detachable
615
+ ret = 'TABLET';
616
+ break;
617
+ case 9: // Laptop
618
+ case 10: // Notebook
619
+ case 14: // Sub Notebook
620
+ ret = 'LAPTOP';
621
+ break;
622
+ default:
623
+ ret = win_systemType() == 2 ? 'MOBILE' : 'DESKTOP';
624
+ break;
625
+ }
626
+
627
+ return (ret);
628
+}
629
+
630
+switch(process.platform)
631
+{
632
+ case 'linux':
633
+ module.exports = { _ObjectID: 'identifiers', get: linux_identifiers };
634
+ break;
635
+ case 'win32':
636
+ module.exports = { _ObjectID: 'identifiers', get: windows_identifiers, chassisType: win_chassisType, formFactor: win_formFactor, systemType: win_systemType };
637
+ break;
638
+ case 'darwin':
639
+ module.exports = { _ObjectID: 'identifiers', get: macos_identifiers };
640
+ break;
641
+ default:
642
+ module.exports = { get: function () { throw ('Unsupported Platform'); } };
643
+ break;
644
+}
645
+module.exports.isDocker = function isDocker()
646
+{
647
+ if (process.platform != 'linux') { return (false); }
648
+
649
+ var child = require('child_process').execFile('/bin/sh', ['sh']);
650
+ child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
651
+ child.stdin.write("cat /proc/self/cgroup | tr '\n' '`' | awk -F'`' '{ split($1, res, " + '"/"); if(res[2]=="docker"){print "1";} }\'\nexit\n');
652
+ child.waitExit();
653
+ return (child.stdout.str != '');
654
+};
655
+module.exports.isBatteryPowered = function isBatteryOperated()
656
+{
657
+ var ret = false;
658
+ switch(process.platform)
659
+ {
660
+ default:
661
+ break;
662
+ case 'linux':
663
+ var devices = require('fs').readdirSync('/sys/class/power_supply');
664
+ for (var i in devices)
665
+ {
666
+ if (require('fs').readFileSync('/sys/class/power_supply/' + devices[i] + '/type').toString().trim() == 'Battery')
667
+ {
668
+ ret = true;
669
+ break;
670
+ }
671
+ }
672
+ break;
673
+ case 'win32':
674
+ var GM = require('_GenericMarshal');
675
+ var stats = GM.CreateVariable(12);
676
+ var kernel32 = GM.CreateNativeProxy('Kernel32.dll');
677
+ kernel32.CreateMethod('GetSystemPowerStatus');
678
+ if (kernel32.GetSystemPowerStatus(stats).Val != 0)
679
+ {
680
+ if(stats.toBuffer()[1] != 128 && stats.toBuffer()[1] != 255)
681
+ {
682
+ ret = true;
683
+ }
684
+ else
685
+ {
686
+ // No Battery detected, so lets check if there is supposed to be one
687
+ var formFactor = win_formFactor(win_chassisType());
688
+ return (formFactor == 'LAPTOP' || formFactor == 'TABLET' || formFactor == 'MOBILE');
689
+ }
690
+ }
691
+ break;
692
+ case 'darwin':
693
+ var child = require('child_process').execFile('/bin/sh', ['sh']);
694
+ child.stdout.str = ''; child.stdout.on('data', function(c){ this.str += c.toString(); });
695
+ child.stderr.str = ''; child.stderr.on('data', function(c){ this.str += c.toString(); });
696
+ child.stdin.write("pmset -g batt | tr '\\n' '`' | awk -F'`' '{ if(NF>2) { print \"true\"; }}'\nexit\n");
697
+ child.waitExit();
698
+ if(child.stdout.str.trim() != '') { ret = true; }
699
+ break;
700
+ }
701
+ return (ret);
702
+};
703
+module.exports.isVM = function isVM()
704
+{
705
+ var ret = false;
706
+ var id = this.get();
707
+ if (id.linux && id.linux.sys_vendor)
708
+ {
709
+ switch (id.linux.sys_vendor)
710
+ {
711
+ case 'VMware, Inc.':
712
+ case 'QEMU':
713
+ case 'Xen':
714
+ ret = true;
715
+ break;
716
+ default:
717
+ break;
718
+ }
719
+ }
720
+ if (id.identifiers.bios_vendor)
721
+ {
722
+ switch(id.identifiers.bios_vendor)
723
+ {
724
+ case 'VMware, Inc.':
725
+ case 'Xen':
726
+ case 'SeaBIOS':
727
+ ret = true;
728
+ break;
729
+ default:
730
+ break;
731
+ }
732
+ }
733
+ if (id.identifiers.board_vendor && id.identifiers.board_vendor == 'VMware, Inc.') { ret = true; }
734
+ if (id.identifiers.board_name)
735
+ {
736
+ switch (id.identifiers.board_name)
737
+ {
738
+ case 'VirtualBox':
739
+ case 'Virtual Machine':
740
+ ret = true;
741
+ break;
742
+ default:
743
+ break;
744
+ }
745
+ }
746
+
747
+ if (process.platform == 'win32' && !ret)
748
+ {
749
+ for(var i in id.identifiers.gpu_name)
750
+ {
751
+ if(id.identifiers.gpu_name[i].startsWith('VMware '))
752
+ {
753
+ ret = true;
754
+ break;
755
+ }
756
+ }
757
+ }
758
+
759
+
760
+ if (!ret) { ret = this.isDocker(); }
761
+ return (ret);
762
+};
763
+
764
+if (process.platform == 'win32')
765
+{
766
+ module.exports.volumes_promise = windows_volumes;
767
+}
768
+
769
+// bios_date = BIOS->ReleaseDate
770
+// bios_vendor = BIOS->Manufacturer
771
+// bios_version = BIOS->SMBIOSBIOSVersion
772
+// board_name = BASEBOARD->Product = ioreg/board-id
773
+// board_serial = BASEBOARD->SerialNumber = ioreg/serial-number | ioreg/IOPlatformSerialNumber
774
+// board_vendor = BASEBOARD->Manufacturer = ioreg/manufacturer
775
+// board_version = BASEBOARD->Version
\ No newline at end of file