New MeshAgent, new border blinking feature.

This commit is contained in:
Ylian Saint-Hilaire 2018-08-29 18:47:22 -07:00
parent c531b64643
commit 1b3255e844
35 changed files with 7423 additions and 177 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1532,7 +1532,7 @@ if (serviceName == null) {
if (serviceInstall == 0) {
run(process.argv);
} else {
var serviceHost = require('serviceHost');
var serviceHost = require('service-host');
var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
// Called when the background service is started.

View File

@ -14,12 +14,59 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
function borderController()
{
this.container = null;
this.Start = function Start(user)
{
if (this.container == null) {
if (process.platform == 'win32') {
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
}
else {
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid });
}
this.container.addModule('monitor-info', getJSModule('monitor-info'));
this.container.addModule('monitor-border', getJSModule('monitor-border'));
this.container.addModule('promise', getJSModule('promise'));
this.container.ExecuteString("var border = require('monitor-border'); border.Start();");
}
}
this.Stop = function Stop()
{
if (this.container != null)
{
this._container = this.container;
this._container.parent = this;
this.container = null;
this._container.once('exit', function () { this.parent._container = null; });
this._container.exit();
}
}
}
function createMeshCore(agent) {
var obj = {};
require('events').EventEmitter.call(obj, true).createEvent('loggedInUsers_Updated');
obj.on('loggedInUsers_Updated', function ()
{
var users = []
for(var i = 0; i < obj.loggedInUsers.length; ++i)
{
users.push((obj.loggedInUsers[i].Domain ? (obj.loggedInUsers[i].Domain + '\\') : '') + obj.loggedInUsers[i].Username);
}
sendConsoleText('LogOn Status Changed. Active Users => [' + users.join(', ') + ']');
});
obj.borderManager = new borderController();
// MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent.
obj.meshCoreInfo = "MeshCore v5";
obj.meshCoreCapabilities = 14; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
obj.loggedInUsers = [];
var meshServerConnectionState = 0;
var tunnels = {};
var lastSelfInfo = null;
@ -863,9 +910,36 @@ function createMeshCore(agent) {
var response = null;
switch (cmd) {
case 'help': { // Displays available commands
response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock.';
response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, border.';
break;
}
case 'border':
{
if ((args['_'].length == 1) && (args['_'][0] == 'on')) {
if (obj.loggedInUsers.length > 0) {
obj.borderManager.Start(obj.loggedInUsers[0]);
response = 'Border blinking is on.';
} else {
response = 'Cannot turn on border blinking, no logged in users.';
}
} else if ((args['_'].length == 1) && (args['_'][0] == 'off')) {
obj.borderManager.Stop();
response = 'Border blinking is off.';
} else {
response = 'Proper usage: border "on|off"'; // Display correct command usage
}
}
break;
case 'users':
{
var retList = [];
for(var i = 0; i < obj.loggedInUsers.length; ++i)
{
retList.push((obj.loggedInUsers[i].Domain ? (obj.loggedInUsers[i].Domain + '\\') : '') + obj.loggedInUsers[i].Username);
}
response = 'Active Users => [' + retList.join(', ') + ']';
}
break;
case 'toast': {
if (process.platform == 'win32') {
if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else {
@ -878,8 +952,8 @@ function createMeshCore(agent) {
break;
}
case 'setdebug': {
if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = StdOut, 1 = This Console, * = All Consoles, 2 = WebLog, 3 = Disabled'; } // Display usage
else { if (args['_'][0] == '*') { console.setDestination(1); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } }
if (args['_'].length < 1) { response = 'Proper usage: setdebug (target), 0 = Disabled, 1 = StdOut, 2 = This Console, * = All Consoles, 4 = WebLog, 8 = Logfile'; } // Display usage
else { if (args['_'][0] == '*') { console.setDestination(2); } else { console.setDestination(parseInt(args['_'][0]), sessionid); } }
break;
}
case 'ps': {
@ -1373,6 +1447,16 @@ function createMeshCore(agent) {
sendPeriodicServerUpdate(true); // Send the server update
}
require('user-sessions').on('changed', function onUserSessionChanged()
{
require('user-sessions').enumerateUsers().then(function (users)
{
obj.loggedInUsers = users.Active;
obj.emit('loggedInUsers_Updated');
});
});
require('user-sessions').emit('changed');
//console.log('Stopping.');
//process.exit();
}

View File

@ -1,24 +1,61 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var SERVICE_WIN32 = 0x00000010 | 0x00000020;
var SERVICE_STATE = { STOPPED: 0x00000001, SERVICE_START_PENDING: 0x00000002, SERVICE_STOP_PENDING: 0x00000003, RUNNING: 0x00000004 };
var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004 };
var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001 };
var SERVICE_ACCEPT = { SERVICE_ACCEPT_STOP: 0x00000001, SERVICE_ACCEPT_SHUTDOWN: 0x00000004, SERVICE_ACCEPT_POWEREVENT: 0x00000040, SERVICE_ACCEPT_SESSIONCHANGE: 0x00000080 };
var SERVICE_CONTROL = { SERVICE_CONTROL_SHUTDOWN: 0x00000005, SERVICE_CONTROL_STOP: 0x00000001, SERVICE_CONTROL_POWEREVENT: 0x0000000D, SERVICE_CONTROL_SESSIONCHANGE: 0x0000000E};
var SESSION_CHANGE_TYPE =
{
WTS_CONSOLE_CONNECT: 0x1,
WTS_CONSOLE_DISCONNECT: 0x2,
WTS_REMOTE_CONNECT: 0x3,
WTS_REMOTE_DISCONNECT: 0x4,
WTS_SESSION_LOGON: 0x5,
WTS_SESSION_LOGOFF: 0x6,
WTS_SESSION_LOCK: 0x7,
WTS_SESSION_UNLOCK: 0x8,
WTS_SESSION_REMOTE_CONTROL: 0x9,
WTS_SESSION_CREATE: 0xa,
WTS_SESSION_TERMINATE: 0xb
};
var NO_ERROR = 0;
var serviceManager = require('serviceManager');
var serviceManager = require('service-manager');
function serviceHost(serviceName) {
this._ObjectID = 'serviceHost';
function serviceHost(serviceName)
{
this._ObjectID = 'service-host';
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('serviceStart');
emitterUtils.createEvent('serviceStop');
emitterUtils.createEvent('normalStart');
emitterUtils.createEvent('session');
emitterUtils.createEvent('powerStateChange');
if (process.platform == 'win32') {
if (process.platform == 'win32')
{
this.GM = require('_GenericMarshal');
this.Advapi = this.GM.CreateNativeProxy('Advapi32.dll');
this.Advapi.CreateMethod({ method: 'StartServiceCtrlDispatcherA', threadDispatch: 1 });
this.Advapi.CreateMethod('RegisterServiceCtrlHandlerA');
this.Advapi.CreateMethod('RegisterServiceCtrlHandlerExA');
this.Advapi.CreateMethod('SetServiceStatus');
this.Kernel32 = this.GM.CreateNativeProxy('Kernel32.dll');
this.Kernel32.CreateMethod('GetLastError');
@ -31,7 +68,8 @@ function serviceHost(serviceName) {
this._ServiceMain = this.GM.GetGenericGlobalCallback(2);
this._ServiceMain.Parent = this;
this._ServiceMain.GM = this.GM;
this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv) {
this._ServiceMain.on('GlobalCallback', function onGlobalCallback(argc, argv)
{
//ToDo: Check to make sure this is for us
this.Parent._ServiceStatus = this.GM.CreateVariable(28);
@ -48,8 +86,9 @@ function serviceHost(serviceName) {
// Initialise service status
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32);
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED, 4);
this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerA(this.Parent._ServiceName, this.Parent._ServiceControlHandler);
if (this.Parent._ServiceStatusHandle.Val == 0) {
this.Parent._ServiceStatusHandle = this.Parent.Advapi.RegisterServiceCtrlHandlerExA(this.Parent._ServiceName, this.Parent._ServiceControlHandler, this.Parent.GM.StashObject(this.Parent._ServiceControlHandler));
if(this.Parent._ServiceStatusHandle.Val == 0)
{
process.exit(1);
}
@ -59,11 +98,12 @@ function serviceHost(serviceName) {
// Service running
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.RUNNING, 4);
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_ACCEPT.SERVICE_ACCEPT_STOP, 8);
this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_ACCEPT.SERVICE_ACCEPT_STOP | SERVICE_ACCEPT.SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT.SERVICE_ACCEPT_SESSIONCHANGE, 8);
this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
this.Parent.Ole32.CoInitializeEx(0, 2);
this.Parent.on('~', function OnServiceHostFinalizer() {
this.Parent.on('~', function OnServiceHostFinalizer()
{
var GM = require('_GenericMarshal');
var Advapi = GM.CreateNativeProxy('Advapi32.dll');
Advapi.CreateMethod('SetServiceStatus');
@ -82,22 +122,39 @@ function serviceHost(serviceName) {
this.Ole32.CoUninitialize();
});
this.Parent.emit('serviceStart');
});
this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(1);
this._ServiceControlHandler = this.GM.GetGenericGlobalCallback(4);
this._ServiceControlHandler.Parent = this;
this._ServiceControlHandler.GM = this.GM;
this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code) {
switch (code.Val) {
this._ServiceControlHandler.on('GlobalCallback', function onServiceControlHandler(code, eventType, eventData, context)
{
var j = this.Parent.GM.UnstashObject(context);
if (j != null && j == this)
{
switch (code.Val)
{
case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL.SERVICE_CONTROL_STOP:
this.Parent.emit('serviceStop');
return;
case SERVICE_CONTROL.SERVICE_CONTROL_SESSIONCHANGE:
var sessionId = eventData.Deref(4, 4).toBuffer().readUInt32LE();
switch(eventType.Val)
{
case SESSION_CHANGE_TYPE.WTS_SESSION_LOGON:
case SESSION_CHANGE_TYPE.WTS_SESSION_LOGOFF:
require('user-sessions').emit('changed');
break;
}
break;
default:
break;
}
this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle, this.Parent._ServiceStatus);
}
});
}
@ -106,42 +163,54 @@ function serviceHost(serviceName) {
{
throw ('Must specify either ServiceName or Options');
}
if (!this._ServiceOptions.servicePath) {
if (!this._ServiceOptions.servicePath)
{
this._ServiceOptions.servicePath = process.execPath;
}
this.run = function run() {
this.run = function run()
{
var serviceOperation = 0;
for (var i = 0; i < process.argv.length; ++i) {
switch (process.argv[i].toLowerCase()) {
case 'install':
for(var i = 0; i<process.argv.length; ++i)
{
switch(process.argv[i])
{
case '-install':
if (!this._svcManager) { this._svcManager = new serviceManager(); }
try {
try
{
this._svcManager.installService(this._ServiceOptions);
} catch (e) {
}
catch(e)
{
console.log(e);
process.exit();
}
if (process.platform == 'win32') {
if (process.platform == 'win32')
{
// Only do this on Windows, becuase Linux is async... It'll complete later
console.log(this._ServiceOptions.name + ' installed.');
console.log(this._ServiceOptions.name + ' installed');
process.exit();
}
i = process.argv.length;
serviceOperation = 1;
break;
case 'uninstall':
case '-uninstall':
if (!this._svcManager) { this._svcManager = new serviceManager(); }
try {
try
{
this._svcManager.uninstallService(this._ServiceOptions);
} catch (e) {
}
catch(e)
{
console.log(e);
process.exit();
}
if (process.platform == 'win32') {
if (process.platform == 'win32')
{
// Only do this on Windows, becuase Linux is async... It'll complete later
console.log(this._ServiceOptions.name + ' uninstalled.');
console.log(this._ServiceOptions.name + ' uninstalled');
process.exit();
}
i = process.argv.length;
@ -149,48 +218,59 @@ function serviceHost(serviceName) {
break;
case 'start':
case '-d':
if (process.platform != 'win32') { break; }
if (!this._svcManager) { this._svcManager = new serviceManager(); }
this._svcManager.getService(this._ServiceOptions.name).start();
console.log(this._ServiceOptions.name + ' starting.');
console.log(this._ServiceOptions.name + ' starting...');
process.exit();
break;
case 'stop':
case '-s':
if (process.platform != 'win32') { break; }
if (!this._svcManager) { this._svcManager = new serviceManager(); }
this._svcManager.getService(this._ServiceOptions.name).stop();
console.log(this._ServiceOptions.name + ' stopping.');
console.log(this._ServiceOptions.name + ' stopping...');
process.exit();
break;
}
}
if (process.platform == 'win32') {
if (process.platform == 'win32')
{
var serviceTable = this.GM.CreateVariable(4 * this.GM.PointerSize);
this._ServiceName.pointerBuffer().copy(serviceTable.toBuffer());
this._ServiceMain.pointerBuffer().copy(serviceTable.toBuffer(), this.GM.PointerSize);
this._sscd = this.Advapi.StartServiceCtrlDispatcherA(serviceTable);
this._sscd.parent = this;
this._sscd.on('done', function OnStartServiceCtrlDispatcherA(retVal) {
if (retVal.Val == 0) { this.parent.emit('normalStart'); }
if (retVal.Val == 0)
{
this.parent.emit('normalStart');
}
});
return;
}
var moduleName = this._ServiceOptions ? this._ServiceOptions.name : process.execPath.substring(1 + process.execPath.lastIndexOf('/'));
for (var i = 0; i < process.argv.length; ++i) {
switch (process.argv[i].toLowerCase()) {
for (var i = 0; i < process.argv.length; ++i)
{
switch(process.argv[i])
{
case 'start':
case '-d':
var child = require('child_process').execFile(process.execPath, [moduleName], { type: require('child_process').SpawnTypes.DETACHED });
var pstream = null;
try {
try
{
pstream = require('fs').createWriteStream('/var/run/' + moduleName + '.pid', { flags: 'w' });
}
catch (e) {
catch(e)
{
}
if (pstream == null) {
if (pstream == null)
{
pstream = require('fs').createWriteStream('.' + moduleName + '.pid', { flags: 'w' });
}
pstream.end(child.pid.toString());
@ -201,26 +281,33 @@ function serviceHost(serviceName) {
case 'stop':
case '-s':
var pid = null;
try {
try
{
pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
require('fs').unlinkSync('/var/run/' + moduleName + '.pid');
}
catch (e) {
catch(e)
{
}
if (pid == null) {
try {
if(pid == null)
{
try
{
pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
require('fs').unlinkSync('.' + moduleName + '.pid');
}
catch (e) {
catch(e)
{
}
}
if (pid) {
if(pid)
{
process.kill(pid);
console.log(moduleName + ' stopped');
}
else {
else
{
console.log(moduleName + ' not running');
}
process.exit();
@ -228,30 +315,56 @@ function serviceHost(serviceName) {
}
}
if (serviceOperation == 0) {
if(serviceOperation == 0)
{
// This is non-windows, so we need to check how this binary was started to determine if this was a service start
// Start by checking if we were started with start/stop
var pid = null;
try { pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' })); } catch (e) { }
if (pid == null) { try { pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' })); } catch (e) { } }
try
{
pid = parseInt(require('fs').readFileSync('/var/run/' + moduleName + '.pid', { flags: 'r' }));
}
catch (e)
{
}
if (pid == null)
{
try
{
pid = parseInt(require('fs').readFileSync('.' + moduleName + '.pid', { flags: 'r' }));
}
catch (e)
{
}
}
if (pid != null && pid == process.pid) {
if (pid != null && pid == process.pid)
{
this.emit('serviceStart');
} else {
}
else
{
// Now we need to check if we were started with systemd
if (require('processManager').getProcessInfo(1).Name == 'systemd') {
if (require('process-manager').getProcessInfo(1).Name == 'systemd')
{
this._checkpid = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._checkpid.result = '';
this._checkpid.parent = this;
this._checkpid.on('exit', function onCheckPIDExit() {
this._checkpid.on('exit', function onCheckPIDExit()
{
var lines = this.result.split('\r\n');
for (i in lines) {
if (lines[i].startsWith(' Main PID:')) {
for (i in lines)
{
if(lines[i].startsWith(' Main PID:'))
{
var tokens = lines[i].split(' ');
if (parseInt(tokens[3]) == process.pid) {
if (parseInt(tokens[3]) == process.pid)
{
this.parent.emit('serviceStart');
} else {
}
else
{
this.parent.emit('normalStart');
}
delete this.parent._checkpid;
@ -265,7 +378,8 @@ function serviceHost(serviceName) {
this._checkpid.stdin.write("systemctl status " + moduleName + " | grep 'Main PID:'\n");
this._checkpid.stdin.write('exit\n');
}
else {
else
{
// This isn't even a systemd platform, so this couldn't have been a service start
this.emit('normalStart');
}

View File

@ -1,6 +1,21 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
function parseServiceStatus(token) {
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
function parseServiceStatus(token)
{
var j = {};
var serviceType = token.Deref(0, 4).IntVal;
j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002);
@ -8,7 +23,8 @@ function parseServiceStatus(token) {
j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020);
j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010);
j.isInteractive = ((serviceType & 0x00000100) == 0x00000100);
switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE()) {
switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE())
{
case 0x00000005:
j.state = 'CONTINUE_PENDING';
break;
@ -33,7 +49,8 @@ function parseServiceStatus(token) {
}
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
j.controlsAccepted = [];
if ((controlsAccepted & 0x00000010) == 0x00000010) {
if ((controlsAccepted & 0x00000010) == 0x00000010)
{
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD');
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE');
j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE');
@ -51,8 +68,11 @@ function parseServiceStatus(token) {
return (j);
}
function serviceManager() {
if (process.platform == 'win32') {
function serviceManager()
{
this._ObjectID = 'service-manager';
if (process.platform == 'win32')
{
this.GM = require('_GenericMarshal');
this.proxy = this.GM.CreateNativeProxy('Advapi32.dll');
this.proxy.CreateMethod('OpenSCManagerA');
@ -78,21 +98,40 @@ function serviceManager() {
var AdministratorsGroup = this.GM.CreatePointer();
var admin = false;
if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) {
if (this.proxy.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
{
var member = this.GM.CreateInteger();
if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) {
if (this.proxy.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
{
if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
}
this.proxy.FreeSid(AdministratorsGroup.Deref());
}
return admin;
};
this.getProgramFolder = function getProgramFolder() {
if ((require('os').arch() == 'x64') && (this.GM.PointerSize == 4)) { return process.env['ProgramFiles(x86)']; } // 64 bit Windows with 32 Bit App
return process.env['ProgramFiles']; // All other cases: 32 bit Windows or 64 bit App
};
this.getServiceFolder = function getServiceFolder() {
return getProgramFolder() + '\\Open Source\\MeshCmd';
this.getServiceFolder = function getServiceFolder()
{
var destinationFolder = null;
if (require('os').arch() == 'x64')
{
// 64 bit Windows
if (this.GM.PointerSize == 4)
{
// 32 Bit App
destinationFolder = process.env['ProgramFiles(x86)'];
}
else
{
// 64 bit App
destinationFolder = process.env['ProgramFiles'];
}
}
else
{
// 32 bit Windows
destinationFolder = process.env['ProgramFiles'];
}
return (destinationFolder + '\\mesh');
};
this.enumerateService = function () {
@ -105,7 +144,9 @@ function serviceManager() {
var resumeHandle = this.GM.CreatePointer();
//var services = this.proxy.CreateVariable(262144);
var success = this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, 0x00, 0x00, bytesNeeded, servicesReturned, resumeHandle, 0x00);
if (bytesNeeded.IntVal <= 0) { throw('Error enumerating services'); }
if (bytesNeeded.IntVal <= 0) {
throw ('error enumerating services');
}
var sz = bytesNeeded.IntVal;
var services = this.GM.CreateVariable(sz);
this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00);
@ -131,7 +172,7 @@ function serviceManager() {
var ptr = this.GM.CreatePointer();
var bytesNeeded = this.GM.CreateVariable(ptr._size);
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004 | 0x0020 | 0x0010);
if (handle.Val == 0) { throw('Could not open ServiceManager'); }
if (handle.Val == 0) { throw ('could not open ServiceManager'); }
var h = this.proxy.OpenServiceA(handle, serviceName, 0x0004 | 0x0020 | 0x0010 | 0x00010000);
if (h.Val != 0) {
var success = this.proxy.QueryServiceStatusEx(h, 0, 0, 0, bytesNeeded);
@ -156,43 +197,46 @@ function serviceManager() {
}
}
else {
throw ('Cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
throw ('cannot call ' + this.name + '.stop(), when current state is: ' + this.status.state);
}
}
retVal.start = function () {
if (this.status.state == 'STOPPED') {
var success = this._proxy.StartServiceA(this._service, 0, 0);
if (success == 0) { throw (this.name + '.start() failed'); }
} else {
throw ('Cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
if (success == 0) {
throw (this.name + '.start() failed');
}
}
else {
throw ('cannot call ' + this.name + '.start(), when current state is: ' + this.status.state);
}
}
return (retVal);
} else {
}
else {
}
}
this.proxy.CloseServiceHandle(handle);
throw ('Could not find service: ' + name);
throw ('could not find service: ' + name);
}
}
this.installService = function installService(options) {
if (process.platform == 'win32') {
if (!this.isAdmin()) { throw ('Installing as Service, requires administrator permissions.'); }
this.installService = function installService(options)
{
if (process.platform == 'win32')
{
if (!this.isAdmin()) { throw ('Installing as Service, requires admin'); }
// Before we start, we need to copy the binary to the right place
var folder = this.getProgramFolder() + '\\Open Source';
if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); } // Create the "Open Source" folder
folder += '\\MeshCmd';
if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); } // Create the "MeshCmd" folder
var folder = this.getServiceFolder();
if (!require('fs').existsSync(folder)) { require('fs').mkdirSync(folder); }
require('fs').copyFileSync(options.servicePath, folder + '\\' + options.name + '.exe');
options.servicePath = folder + '\\' + options.name + '.exe';
console.log('Installing to "' + options.servicePath + '"');
var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"');
var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002);
if (handle.Val == 0) { throw ('Error opening SCManager'); }
if (handle.Val == 0) { throw ('error opening SCManager'); }
var serviceName = this.GM.CreateVariable(options.name);
var displayName = this.GM.CreateVariable(options.name);
var allAccess = 0x000F01FF;
@ -235,11 +279,13 @@ function serviceManager() {
this.proxy.CloseServiceHandle(handle);
return (this.getService(options.name));
}
if (process.platform == 'linux') {
switch (this.getServiceType()) {
if(process.platform == 'linux')
{
switch (this.getServiceType())
{
case 'init':
require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name);
console.log('Copying ' + options.servicePath);
console.log('copying ' + options.servicePath);
var m = require('fs').statSync('/etc/init.d/' + options.name).mode;
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP);
require('fs').chmodSync('/etc/init.d/' + options.name, m);
@ -274,25 +320,40 @@ function serviceManager() {
}
}
}
this.uninstallService = function uninstallService(name) {
this.uninstallService = function uninstallService(name)
{
if (typeof (name) == 'object') { name = name.name; }
if (process.platform == 'win32') {
if (!this.isAdmin()) { throw ('Uninstalling a service, requires administrator permissions.'); }
if (process.platform == 'win32')
{
if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); }
var service = this.getService(name);
if (service.status.state == undefined || service.status.state == 'STOPPED') {
if (this.proxy.DeleteService(service._service) == 0) {
if (service.status.state == undefined || service.status.state == 'STOPPED')
{
if (this.proxy.DeleteService(service._service) == 0)
{
throw ('Uninstall Service for: ' + name + ', failed with error: ' + this.proxy2.GetLastError());
} else {
try { require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe'); } catch (e) { }
}
else
{
try
{
require('fs').unlinkSync(this.getServiceFolder() + '\\' + name + '.exe');
}
catch(e)
{
}
}
else {
}
else
{
throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state);
}
}
else if (process.platform == 'linux') {
switch (this.getServiceType()) {
else if(process.platform == 'linux')
{
switch (this.getServiceType())
{
case 'init':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
@ -300,7 +361,11 @@ function serviceManager() {
try {
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
console.log(this._svcname + ' uninstalled');
} catch (e) { console.log(this._svcname + ' could not be uninstalled'); }
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { });
@ -316,7 +381,10 @@ function serviceManager() {
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
console.log(this._svcname + ' uninstalled');
} catch (e) { console.log(this._svcname + ' could not be uninstalled'); }
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { });
@ -329,9 +397,11 @@ function serviceManager() {
}
}
}
if (process.platform == 'linux') {
this.getServiceType = function getServiceType() {
return (require('processManager').getProcessInfo(1).Name);
if(process.platform == 'linux')
{
this.getServiceType = function getServiceType()
{
return (require('process-manager').getProcessInfo(1).Name);
};
}
}

View File

@ -16,9 +16,27 @@ limitations under the License.
function UserSessions()
{
this._ObjectID = 'UserSessions';
this._ObjectID = 'user-sessions';
require('events').EventEmitter.call(this, true).createEvent('changed');
if (process.platform == 'win32') {
this.enumerateUsers = function enumerateUsers()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res;
this.__rejector = rej;
});
p.__handler = function __handler(users)
{
p.__resolver(users);
};
this.Current(p.__handler);
return (p);
}
if (process.platform == 'win32')
{
this._marshal = require('_GenericMarshal');
this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
@ -77,7 +95,7 @@ function UserSessions()
return (retVal);
};
this.Current = function Current()
this.Current = function Current(cb)
{
var retVal = {};
var pinfo = this._marshal.CreatePointer();
@ -102,36 +120,152 @@ function UserSessions()
this._wts.WTSFreeMemory(pinfo.Deref());
Object.defineProperty(retVal, 'connected', { value: showActiveOnly(retVal) });
Object.defineProperty(retVal, 'Active', { value: showActiveOnly(retVal) });
if (cb) { cb(retVal); }
return (retVal);
};
}
else
{
this.Current = function Current()
this.Self = function Self()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch (e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
return (p);
};
this.Current = function Current(cb)
{
var retVal = {};
var emitterUtils = require('events').inherits(retVal);
emitterUtils.createEvent('logon');
retVal._ObjectID = 'UserSession'
Object.defineProperty(retVal, '_callback', { value: cb });
Object.defineProperty(retVal, '_child', { value: require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']) });
retVal._child = require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']);
retVal._child.Parent = retVal;
retVal._child._txt = '';
retVal._child.on('exit', function (code)
{
var lines = this._txt.split('\n');
var sessions = [];
var users = {};
for(var i in lines)
{
if (lines[i])
{
console.log(getTokens(lines[i]));
var user = lines[i].substring(0, lines[i].indexOf(' '));
sessions.push(user);
var tokens = getTokens(lines[i]);
var s = { Username: tokens[0], SessionId: tokens[1] }
if (tokens[3].includes('still logged in'))
{
s.State = 'Active';
}
else
{
s.LastActive = tokens[3];
}
sessions.push(s);
}
}
sessions.pop();
console.log(sessions);
var usernames = {};
var promises = [];
for (var i in sessions)
{
if (sessions[i].Username != 'reboot')
{
users[sessions[i].SessionId] = sessions[i];
if(usernames[sessions[i].Username] == null)
{
usernames[sessions[i].Username] = -1;
}
}
}
try
{
require('promise');
}
catch(e)
{
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (this.Parent._callback) { this.Parent._callback.call(this.Parent, users); }
return;
}
var promise = require('promise');
for (var n in usernames)
{
var p = new promise(function (res, rej)
{
this.__username = n;
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u', n]);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch(e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
promises.push(p);
}
promise.all(promises).then(function (plist)
{
// Done
var table = {};
for(var i in plist)
{
table[plist[i].__username] = plist[i]._internal.completedArgs[0];
}
for(var i in users)
{
users[i].uid = table[users[i].Username];
}
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (retVal._callback) { retVal._callback.call(retVal, users); }
}, function (reason)
{
// Failed
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (retVal._callback) { retVal._callback.call(retVal, users); }
});
});
retVal._child.stdout.Parent = retVal._child;
retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); });
@ -145,7 +279,7 @@ function showActiveOnly(source)
var retVal = [];
for (var i in source)
{
if (source[i].State == 'Active' || source[i].State == 'Connected')
if (source[i].State == 'Active')
{
retVal.push(source[i]);
}
@ -159,7 +293,12 @@ function getTokens(str)
columns.push(str.substring(0, (i=str.indexOf(' '))));
while (str[++i] == ' ');
columns.push(str.substring(i, str.substring(i).indexOf(' ') + i));
columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
while (str[++i] == ' ');
columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
while (str[++i] == ' ');
var status = str.substring(i).trim();
columns.push(status);
return (columns);
}

View File

@ -0,0 +1,319 @@
var red = 0xFF;
var yellow = 0xFFFF;
var GXxor = 0x6; // src XOR dst
var GXclear = 0x0;
var ExposureMask = (1 << 15);
function windows_monitorborder()
{
this._ObjectID = 'monitor-info';
var info = require('monitor-info');
var gm = require('_GenericMarshal');
var user32 = gm.CreateNativeProxy('user32.dll');
info.monitors = [];
user32.CreateMethod('GetDC');
user32.CreateMethod('ReleaseDC');
user32.CreateMethod('FillRect');
user32.CreateMethod('InvalidateRect');
var gdi32 = gm.CreateNativeProxy('gdi32.dll');
gdi32.CreateMethod('CreateSolidBrush');
var redBrush = gdi32.CreateSolidBrush(red);
var yellowBrush = gdi32.CreateSolidBrush(yellow);
require('events').EventEmitter.call(this);
this.on('~', function () { this.Stop(); });
this.Stop = function Stop()
{
info.redInterval = null;
var drawRect = gm.CreateVariable(16);
var drawRectBuffer = drawRect.toBuffer();
for (var i in info.monitors)
{
// Top
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left), 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom - info.monitors[i].top, 12);
user32.InvalidateRect(0, drawRect, 0);
}
}
this.Start = function Start()
{
info.getInfo().then(function (mon)
{
var drawRect = gm.CreateVariable(16);
info.monitors = mon;
info.dc = user32.GetDC(0);
info.state = 0;
info.redInterval = setInterval(function ()
{
info.state = (info.state + 1) % 8;
var drawRectBuffer = drawRect.toBuffer();
for(var i in info.monitors)
{
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left)/2, 8);
drawRectBuffer.writeInt32LE(5, 12);
user32.FillRect(info.dc, drawRect, (info.state == 0 || info.state == 4) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(5, 12);
user32.FillRect(info.dc, drawRect, (info.state == 1 || info.state == 5) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top)/2, 12);
user32.FillRect(info.dc, drawRect, (info.state == 2 || info.state == 6) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 3 || info.state == 7) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 4 || info.state == 0) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 5 || info.state == 1) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 6 || info.state == 2) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 12);
user32.FillRect(info.dc, drawRect, (info.state == 7 || info.state == 3) ? yellowBrush : redBrush);
}
}, 450);
});
}
}
function linux_monitorborder()
{
var self = this;
this.displays = [];
this._ObjectID = 'monitor-info';
this._info = require('monitor-info');
this._isUnity = this._info.isUnity();
console.log('isUnity = ' + this._isUnity);
require('events').EventEmitter.call(this);
this.on('~', function () { this.Stop(); });
this.Stop = function Stop()
{
this._timeout = null;
if(!this._isUnity)
{
for(var i=0; i < this.displays.length; ++i)
{
if(this.displays[i].GC1 && this.displays[i].rootWindow)
{
self._info._X11.XSetFunction(self.displays[i].display, self.displays[i].GC1, GXclear);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right, 0);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, 0, self.displays[i].right, self.displays[i].bottom);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom, self.displays[i].right, self.displays[i].bottom);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom);
this._info._X11.XFlush(this.displays[i].display);
}
}
}
}
this.Start = function Start()
{
this._info.getInfo().then(function (mon)
{
self.displays = mon;
console.log(mon.length + ' displays');
for(var i = 0; i<mon.length; ++i)
{
console.log('Width: ' + mon[i].right + ', Height: ' + mon[i].bottom);
mon[i].rootWindow = self._info._X11.XRootWindow(mon[i].display, mon[i].screenId);
if (self._isUnity)
{
// We are unity, so we have to fake the borders with borderless windows
var white = self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val;
// Top
mon[i].window_top = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, mon[i].right, 5, 0, white, white);
mon[i].window_top.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_top, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_top.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_top.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_top);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_top, 0, 0, mon[i].right, 5);
// Right
mon[i].window_right = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, mon[i].right - 5, 0, 5, mon[i].bottom, 0, white, white);
mon[i].window_right.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_right, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_right.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_right.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_right);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_right, mon[i].right - 5, 0, 5, mon[i].bottom);
// Left
mon[i].window_left = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, 5, mon[i].bottom, 0, white, white);
mon[i].window_left.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_left, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_left.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_left.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_left);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_left, 0, 0, 5, mon[i].bottom);
// Bottom
mon[i].window_bottom = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, mon[i].bottom - 5, mon[i].right, 5, 0, white, white);
mon[i].window_bottom.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_bottom, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_bottom.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_bottom.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_bottom);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_bottom, 0, mon[i].bottom - 5, mon[i].right, 5);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_top);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_right);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_left);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_bottom);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_top);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_top);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_right);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_right);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_left);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_left);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
self._info._X11.XFlush(mon[i].display);
mon[i].borderState = 0;
}
else
{
// If we aren't unity, then we can just draw
mon[i].GC1 = self._info._X11.XCreateGC(mon[i].display, mon[i].rootWindow, 0, 0);
mon[i].borderState = 0;
self._info._X11.XSetForeground(mon[i].display, mon[i].GC1, self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val); // White
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].GC1, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].GC1, 1);
}
}
self._info._XEvent = self._info._gm.CreateVariable(192);
self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 250);
});
}
this.timeoutHandler = function()
{
for (var i = 0; i < self.displays.length; ++i) {
self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
// Top
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right / 2, 0);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right / 2, 0, self.displays[i].right, 0);
// Right
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, 0, self.displays[i].right, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, self.displays[i].bottom / 2, self.displays[i].right, self.displays[i].bottom);
// Bottom
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom, self.displays[i].right / 2, self.displays[i].bottom);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right / 2, self.displays[i].bottom, self.displays[i].right, self.displays[i].bottom);
// Left
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
self._info._X11.XFlush(self.displays[i].display);
}
self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
}
this.unity_drawBorder = function unity_drawBorder()
{
for (var i = 0; i < self.displays.length; ++i)
{
self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
// Top
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_top.gc, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_top, self.displays[i].window_top.gc, 0, 0, self.displays[i].right / 2, 0);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_top.gc, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_top, self.displays[i].window_top.gc, self.displays[i].right / 2, 0, self.displays[i].right, 0);
self._info._X11.XFlush(self.displays[i].display);
// Right
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_right.gc, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_right, self.displays[i].window_right.gc, 0, 0, 0, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_right.gc, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_right, self.displays[i].window_right.gc, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
self._info._X11.XFlush(self.displays[i].display);
// Bottom
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_bottom.gc, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_bottom, self.displays[i].window_bottom.gc, 0, 0, self.displays[i].right / 2, 0);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_bottom.gc, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_bottom, self.displays[i].window_bottom.gc, self.displays[i].right / 2, 0, self.displays[i].right, 0);
self._info._X11.XFlush(self.displays[i].display);
// Left
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_left.gc, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_left, self.displays[i].window_left.gc, 0, 0, 0, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_left.gc, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_left, self.displays[i].window_left.gc, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
self._info._X11.XFlush(self.displays[i].display);
}
self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
}
}
switch(process.platform)
{
case 'win32':
module.exports = new windows_monitorborder();
break;
case 'linux':
module.exports = new linux_monitorborder();
break;
default:
break;
}

View File

@ -0,0 +1,194 @@
var promise = require('promise');
var PPosition = 4;
var PSize = 8;
var _NET_WM_STATE_REMOVE = 0; // remove/unset property
var _NET_WM_STATE_ADD = 1; // add/set property
var _NET_WM_STATE_TOGGLE = 2; // toggle property
var SubstructureRedirectMask = (1 << 20);
var SubstructureNotifyMask = (1 << 19);
function monitorinfo()
{
this._ObjectID = 'monitor-info';
this._gm = require('_GenericMarshal');
if (process.platform == 'win32')
{
this._user32 = this._gm.CreateNativeProxy('user32.dll');
this._user32.CreateMethod('EnumDisplayMonitors');
this._kernel32 = this._gm.CreateNativeProxy('kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
this.getInfo = function getInfo()
{
var info = this;
return (new promise(function (resolver, rejector) {
this._monitorinfo = { resolver: resolver, rejector: rejector, self: info, callback: info._gm.GetGenericGlobalCallback(4) };
this._monitorinfo.callback.info = this._monitorinfo;
this._monitorinfo.dwData = info._gm.ObjectToPtr(this._monitorinfo);
this._monitorinfo.callback.results = [];
this._monitorinfo.callback.on('GlobalCallback', function OnMonitorInfo(hmon, hdc, r, user) {
if (this.ObjectToPtr_Verify(this.info, user)) {
var rb = r.Deref(0, 16).toBuffer();
this.results.push({ left: rb.readInt32LE(0), top: rb.readInt32LE(4), right: rb.readInt32LE(8), bottom: rb.readInt32LE(12) });
var r = this.info.self._gm.CreateInteger();
r.Val = 1;
return (r);
}
});
if (info._user32.EnumDisplayMonitors(0, 0, this._monitorinfo.callback, this._monitorinfo.dwData).Val == 0) {
rejector('LastError=' + info._kernel32.GetLastError().Val);
return;
}
else {
resolver(this._monitorinfo.callback.results);
}
}));
}
}
else if(process.platform == 'linux')
{
this._X11 = this._gm.CreateNativeProxy('libX11.so');
this._X11.CreateMethod('XChangeProperty');
this._X11.CreateMethod('XCloseDisplay');
this._X11.CreateMethod('XCreateGC');
this._X11.CreateMethod('XCreateWindow');
this._X11.CreateMethod('XCreateSimpleWindow');
this._X11.CreateMethod('XDefaultColormap');
this._X11.CreateMethod('XDefaultScreen');
this._X11.CreateMethod('XDrawLine');
this._X11.CreateMethod('XDisplayHeight');
this._X11.CreateMethod('XDisplayWidth');
this._X11.CreateMethod('XFetchName');
this._X11.CreateMethod('XFlush');
this._X11.CreateMethod('XFree');
this._X11.CreateMethod('XCreateGC');
this._X11.CreateMethod('XGetWindowProperty');
this._X11.CreateMethod('XInternAtom');
this._X11.CreateMethod('XMapWindow');
this._X11.CreateMethod({ method: 'XNextEvent', threadDispatch: true });
this._X11.CreateMethod('XOpenDisplay');
this._X11.CreateMethod('XRootWindow');
this._X11.CreateMethod('XScreenCount');
this._X11.CreateMethod('XScreenOfDisplay');
this._X11.CreateMethod('XSelectInput');
this._X11.CreateMethod('XSendEvent');
this._X11.CreateMethod('XSetForeground');
this._X11.CreateMethod('XSetFunction');
this._X11.CreateMethod('XSetLineAttributes');
this._X11.CreateMethod('XSetNormalHints');
this._X11.CreateMethod('XSetSubwindowMode');
this._X11.CreateMethod('XBlackPixel');
this._X11.CreateMethod('XWhitePixel');
this.isUnity = function isUnity()
{
var ret = false;
var display = this._X11.XOpenDisplay(this._gm.CreateVariable(':0'));
var rootWindow = this._X11.XRootWindow(display, this._X11.XDefaultScreen(display));
var a = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_CLIENT_LIST'), 1);
var actualType = this._gm.CreateVariable(8);
var format = this._gm.CreateVariable(4);
var numItems = this._gm.CreateVariable(8);
var bytesAfter = this._gm.CreateVariable(8);
var data = this._gm.CreatePointer();
this._X11.XGetWindowProperty(display, rootWindow, a, 0, ~0, 0, 0, actualType, format, numItems, bytesAfter, data);
for (var i = 0; i < numItems.Deref(0, 4).toBuffer().readUInt32LE(0) ; ++i)
{
var w = data.Deref().Deref(i * 8, 8).Deref(8);
var name = this._gm.CreatePointer();
var ns = this._X11.XFetchName(display, w, name);
if (name.Deref().String == 'unity-launcher')
{
ret = true;
break;
}
}
this._X11.XCloseDisplay(display);
return (ret);
}
this.unDecorateWindow = function unDecorateWindow(display, window)
{
var MwmHints = this._gm.CreateVariable(40);
var mwmHintsProperty = this._X11.XInternAtom(display, this._gm.CreateVariable('_MOTIF_WM_HINTS'), 0);
MwmHints.Deref(0, 4).toBuffer().writeUInt32LE(1 << 1);
this._X11.XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32, 0, MwmHints, 5);
}
this.setWindowSizeHints = function setWindowSizeHints(display, window, x, y, width, height)
{
var sizeHints = this._gm.CreateVariable(80);
sizeHints.Deref(0, 4).toBuffer().writeUInt32LE(PPosition | PSize);
sizeHints.Deref(8, 4).toBuffer().writeUInt32LE(x);
sizeHints.Deref(12, 4).toBuffer().writeUInt32LE(y);
sizeHints.Deref(16, 4).toBuffer().writeUInt32LE(width);
sizeHints.Deref(20, 4).toBuffer().writeUInt32LE(height);
this._X11.XSetNormalHints(display, window, sizeHints);
}
this.setAlwaysOnTop = function setAlwaysOnTop(display, rootWindow, window)
{
var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1);
var wmStateAbove = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_ABOVE'), 1);
var xclient = this._gm.CreateVariable(96);
xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type
xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32
wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type
xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0]
wmStateAbove.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1]
window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window
this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient);
}
this.hideWindowIcon = function hideWindowIcon(display, rootWindow, window)
{
var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1);
var wmStateSkip = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_SKIP_TASKBAR'), 1);
var xclient = this._gm.CreateVariable(96);
xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type
xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32
wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type
xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0]
wmStateSkip.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1]
window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window
this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient);
}
this.getInfo = function getInfo()
{
var info = this;
return (new promise(function (resolver, rejector)
{
var display = info._X11.XOpenDisplay(info._gm.CreateVariable(':0'));
var screenCount = info._X11.XScreenCount(display).Val;
var ret = [];
for(var i=0;i<screenCount;++i)
{
var screen = info._X11.XScreenOfDisplay(display, i);
ret.push({ left: 0, top: 0, right: info._X11.XDisplayWidth(display, i).Val, bottom: info._X11.XDisplayHeight(display, i).Val, screen: screen, screenId: i, display: display });
}
resolver(ret);
}));
}
}
else
{
throw (process.platform + ' not supported');
}
}
module.exports = new monitorinfo();

View File

@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// JavaScript source code
var GM = require('_GenericMarshal');
function processManager() {
this._ObjectID = 'processManager';
switch (process.platform) {
function processManager()
{
this._ObjectID = 'process-manager';
switch(process.platform)
{
case 'win32':
this._kernel32 = GM.CreateNativeProxy('kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
@ -32,19 +34,24 @@ function processManager() {
break;
default:
throw (process.platform + ' not supported');
break;
}
this.getProcesses = function getProcesses(callback) {
switch (process.platform) {
this.getProcesses = function getProcesses(callback)
{
switch(process.platform)
{
default:
throw ('Enumerating processes on ' + process.platform + ' not supported');
break;
case 'win32':
var retVal = {};
var retVal = [];
var h = this._kernel32.CreateToolhelp32Snapshot(2, 0);
var info = GM.CreateVariable(304);
info.toBuffer().writeUInt32LE(304, 0);
var nextProcess = this._kernel32.Process32First(h, info);
while (nextProcess.Val) {
retVal[info.Deref(8, 4).toBuffer().readUInt32LE(0)] = { cmd: info.Deref(GM.PointerSize == 4 ? 36 : 44, 260).String };
while (nextProcess.Val)
{
retVal.push({ pid: info.Deref(8, 4).toBuffer().readUInt32LE(0), command: info.Deref(GM.PointerSize == 4 ? 36 : 44, 260).String });
nextProcess = this._kernel32.Process32Next(h, info);
}
if (callback) { callback.apply(this, [retVal]); }
@ -58,21 +65,32 @@ function processManager() {
p.callback = callback;
p.args = [];
for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
p.on('exit', function onGetProcesses() {
p.on('exit', function onGetProcesses()
{
delete this.Parent._psp[this.pid];
var retVal = {}, lines = this.ps.split('\x0D\x0A'), key = {}, keyi = 0;
for (var i in lines) {
var retVal = [];
var lines = this.ps.split('\x0D\x0A');
var key = {};
var keyi = 0;
for (var i in lines)
{
var tokens = lines[i].split(' ');
var tokenList = [];
for (var x in tokens) {
for(var x in tokens)
{
if (i == 0 && tokens[x]) { key[tokens[x]] = keyi++; }
if (i > 0 && tokens[x]) { tokenList.push(tokens[x]); }
if (i > 0 && tokens[x]) { tokenList.push(tokens[x]);}
}
if ((i > 0) && (tokenList[key.PID])) {
retVal[tokenList[key.PID]] = { user: tokenList[key.USER], cmd: tokenList[key.COMMAND] };
if(i>0)
{
if (tokenList[key.PID])
{
retVal.push({ pid: tokenList[key.PID], user: tokenList[key.USER], command: tokenList[key.COMMAND] });
}
}
if (this.callback) {
}
if (this.callback)
{
this.args.unshift(retVal);
this.callback.apply(this.parent, this.args);
}
@ -81,18 +99,25 @@ function processManager() {
break;
}
};
this.getProcessInfo = function getProcessInfo(pid) {
switch (process.platform) {
this.getProcessInfo = function getProcessInfo(pid)
{
switch(process.platform)
{
default:
throw ('getProcessInfo() not supported for ' + process.platform);
break;
case 'linux':
var status = require('fs').readFileSync('/proc/' + pid + '/status'), info = {}, lines = status.toString().split('\n');
for (var i in lines) {
var status = require('fs').readFileSync('/proc/' + pid + '/status');
var info = {};
var lines = status.toString().split('\n');
for(var i in lines)
{
var tokens = lines[i].split(':');
if (tokens.length > 1) { tokens[1] = tokens[1].trim(); }
info[tokens[0]] = tokens[1];
}
return (info);
break;
}
};
}

View File

@ -0,0 +1,185 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var refTable = {};
function Promise(promiseFunc)
{
this._ObjectID = 'promise';
this._internal = { promise: this, func: promiseFunc, completed: false, errors: false, completedArgs: [] };
require('events').EventEmitter.call(this._internal);
this._internal.on('_eventHook', function (eventName, eventCallback)
{
//console.log('hook', eventName, 'errors/' + this.errors + ' completed/' + this.completed);
var r = null;
if (eventName == 'resolved' && !this.errors && this.completed)
{
r = eventCallback.apply(this, this.completedArgs);
if(r!=null)
{
this.emit_returnValue('resolved', r);
}
}
if (eventName == 'rejected' && this.errors && this.completed)
{
eventCallback.apply(this, this.completedArgs);
}
if (eventName == 'settled' && this.completed)
{
eventCallback.apply(this, []);
}
});
this._internal.resolver = function _resolver()
{
_resolver._self.errors = false;
_resolver._self.completed = true;
_resolver._self.completedArgs = [];
var args = ['resolved'];
if (this.emit_returnValue && this.emit_returnValue('resolved') != null)
{
_resolver._self.completedArgs.push(this.emit_returnValue('resolved'));
args.push(this.emit_returnValue('resolved'));
}
else
{
for (var a in arguments)
{
_resolver._self.completedArgs.push(arguments[a]);
args.push(arguments[a]);
}
}
_resolver._self.emit.apply(_resolver._self, args);
_resolver._self.emit('settled');
};
this._internal.rejector = function _rejector()
{
_rejector._self.errors = true;
_rejector._self.completed = true;
_rejector._self.completedArgs = [];
var args = ['rejected'];
for (var a in arguments)
{
_rejector._self.completedArgs.push(arguments[a]);
args.push(arguments[a]);
}
_rejector._self.emit.apply(_rejector._self, args);
_rejector._self.emit('settled');
};
this.catch = function(func)
{
this._internal.once('settled', func);
}
this.finally = function (func)
{
this._internal.once('settled', func);
};
this.then = function (resolved, rejected)
{
if (resolved) { this._internal.once('resolved', resolved); }
if (rejected) { this._internal.once('rejected', rejected); }
var retVal = new Promise(function (r, j) { });
this._internal.once('resolved', retVal._internal.resolver);
this._internal.once('rejected', retVal._internal.rejector);
return (retVal);
};
this._internal.resolver._self = this._internal;
this._internal.rejector._self = this._internal;;
try
{
promiseFunc.call(this, this._internal.resolver, this._internal.rejector);
}
catch(e)
{
this._internal.errors = true;
this._internal.completed = true;
this._internal.completedArgs = [e];
this._internal.emit('rejected', e);
this._internal.emit('settled');
}
if(!this._internal.completed)
{
// Save reference of this object
refTable[this._internal._hashCode()] = this._internal;
this._internal.once('settled', function () { refTable[this._hashCode()] = null; });
}
}
Promise.resolve = function resolve()
{
var retVal = new Promise(function (r, j) { });
var args = [];
for (var i in arguments)
{
args.push(arguments[i]);
}
retVal._internal.resolver.apply(retVal._internal, args);
return (retVal);
};
Promise.reject = function reject() {
var retVal = new Promise(function (r, j) { });
var args = [];
for (var i in arguments) {
args.push(arguments[i]);
}
retVal._internal.rejector.apply(retVal._internal, args);
return (retVal);
};
Promise.all = function all(promiseList)
{
var ret = new Promise(function (res, rej)
{
this.__rejector = rej;
this.__resolver = res;
this.__promiseList = promiseList;
this.__done = false;
this.__count = 0;
});
for (var i in promiseList)
{
promiseList[i].then(function ()
{
// Success
if(++ret.__count == ret.__promiseList.length)
{
ret.__done = true;
ret.__resolver(ret.__promiseList);
}
}, function (arg)
{
// Failure
if(!ret.__done)
{
ret.__done = true;
ret.__rejector(arg);
}
});
}
if (promiseList.length == 0)
{
ret.__resolver(promiseList);
}
return (ret);
};
module.exports = Promise;

View File

@ -16,9 +16,27 @@ limitations under the License.
function UserSessions()
{
this._ObjectID = 'UserSessions';
this._ObjectID = 'user-sessions';
require('events').EventEmitter.call(this, true).createEvent('changed');
if (process.platform == 'win32') {
this.enumerateUsers = function enumerateUsers()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res;
this.__rejector = rej;
});
p.__handler = function __handler(users)
{
p.__resolver(users);
};
this.Current(p.__handler);
return (p);
}
if (process.platform == 'win32')
{
this._marshal = require('_GenericMarshal');
this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
@ -77,7 +95,7 @@ function UserSessions()
return (retVal);
};
this.Current = function Current()
this.Current = function Current(cb)
{
var retVal = {};
var pinfo = this._marshal.CreatePointer();
@ -102,36 +120,152 @@ function UserSessions()
this._wts.WTSFreeMemory(pinfo.Deref());
Object.defineProperty(retVal, 'connected', { value: showActiveOnly(retVal) });
Object.defineProperty(retVal, 'Active', { value: showActiveOnly(retVal) });
if (cb) { cb(retVal); }
return (retVal);
};
}
else
{
this.Current = function Current()
this.Self = function Self()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch (e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
return (p);
};
this.Current = function Current(cb)
{
var retVal = {};
var emitterUtils = require('events').inherits(retVal);
emitterUtils.createEvent('logon');
retVal._ObjectID = 'UserSession'
Object.defineProperty(retVal, '_callback', { value: cb });
Object.defineProperty(retVal, '_child', { value: require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']) });
retVal._child = require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']);
retVal._child.Parent = retVal;
retVal._child._txt = '';
retVal._child.on('exit', function (code)
{
var lines = this._txt.split('\n');
var sessions = [];
var users = {};
for(var i in lines)
{
if (lines[i])
{
console.log(getTokens(lines[i]));
var user = lines[i].substring(0, lines[i].indexOf(' '));
sessions.push(user);
var tokens = getTokens(lines[i]);
var s = { Username: tokens[0], SessionId: tokens[1] }
if (tokens[3].includes('still logged in'))
{
s.State = 'Active';
}
else
{
s.LastActive = tokens[3];
}
sessions.push(s);
}
}
sessions.pop();
console.log(sessions);
var usernames = {};
var promises = [];
for (var i in sessions)
{
if (sessions[i].Username != 'reboot')
{
users[sessions[i].SessionId] = sessions[i];
if(usernames[sessions[i].Username] == null)
{
usernames[sessions[i].Username] = -1;
}
}
}
try
{
require('promise');
}
catch(e)
{
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (this.Parent._callback) { this.Parent._callback.call(this.Parent, users); }
return;
}
var promise = require('promise');
for (var n in usernames)
{
var p = new promise(function (res, rej)
{
this.__username = n;
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u', n]);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch(e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
promises.push(p);
}
promise.all(promises).then(function (plist)
{
// Done
var table = {};
for(var i in plist)
{
table[plist[i].__username] = plist[i]._internal.completedArgs[0];
}
for(var i in users)
{
users[i].uid = table[users[i].Username];
}
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (retVal._callback) { retVal._callback.call(retVal, users); }
}, function (reason)
{
// Failed
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (retVal._callback) { retVal._callback.call(retVal, users); }
});
});
retVal._child.stdout.Parent = retVal._child;
retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); });
@ -145,7 +279,7 @@ function showActiveOnly(source)
var retVal = [];
for (var i in source)
{
if (source[i].State == 'Active' || source[i].State == 'Connected')
if (source[i].State == 'Active')
{
retVal.push(source[i]);
}
@ -159,7 +293,12 @@ function getTokens(str)
columns.push(str.substring(0, (i=str.indexOf(' '))));
while (str[++i] == ' ');
columns.push(str.substring(i, str.substring(i).indexOf(' ') + i));
columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
while (str[++i] == ' ');
columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
while (str[++i] == ' ');
var status = str.substring(i).trim();
columns.push(status);
return (columns);
}

View File

@ -0,0 +1,893 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var MemoryStream = require('MemoryStream');
var lme_id = 0; // Our next channel identifier
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
var xmlParser = require('amt-xml');
// Documented in: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf
var APF_DISCONNECT = 1;
var APF_SERVICE_REQUEST = 5;
var APF_SERVICE_ACCEPT = 6;
var APF_USERAUTH_REQUEST = 50;
var APF_USERAUTH_FAILURE = 51;
var APF_USERAUTH_SUCCESS = 52;
var APF_GLOBAL_REQUEST = 80;
var APF_REQUEST_SUCCESS = 81;
var APF_REQUEST_FAILURE = 82;
var APF_CHANNEL_OPEN = 90;
var APF_CHANNEL_OPEN_CONFIRMATION = 91;
var APF_CHANNEL_OPEN_FAILURE = 92;
var APF_CHANNEL_WINDOW_ADJUST = 93;
var APF_CHANNEL_DATA = 94;
var APF_CHANNEL_CLOSE = 97;
var APF_PROTOCOLVERSION = 192;
function lme_object() {
this.ourId = ++lme_id;
this.amtId = -1;
this.LME_CHANNEL_STATUS = 'LME_CS_FREE';
this.txWindow = 0;
this.rxWindow = 0;
this.localPort = 0;
this.errorCount = 0;
}
function stream_bufferedWrite() {
var emitterUtils = require('events').inherits(this);
this.buffer = [];
this._readCheckImmediate = undefined;
this._ObjectID = "bufferedWriteStream";
// Writable Events
emitterUtils.createEvent('close');
emitterUtils.createEvent('drain');
emitterUtils.createEvent('error');
emitterUtils.createEvent('finish');
emitterUtils.createEvent('pipe');
emitterUtils.createEvent('unpipe');
// Readable Events
emitterUtils.createEvent('readable');
this.isEmpty = function () {
return (this.buffer.length == 0);
};
this.isWaiting = function () {
return (this._readCheckImmediate == undefined);
};
this.write = function (chunk) {
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
var tmp = Buffer.alloc(chunk.length);
chunk.copy(tmp);
this.buffer.push({ offset: 0, data: tmp });
this.emit('readable');
return (this.buffer.length == 0 ? true : false);
};
this.read = function () {
var size = arguments.length == 0 ? undefined : arguments[0];
var bytesRead = 0;
var list = [];
while ((size == undefined || bytesRead < size) && this.buffer.length > 0) {
var len = this.buffer[0].data.length - this.buffer[0].offset;
var offset = this.buffer[0].offset;
if (len > (size - bytesRead)) {
// Only reading a subset
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
this.buffer[0].offset += (size - bytesRead);
bytesRead += (size - bytesRead);
} else {
// Reading the entire thing
list.push(this.buffer[0].data.slice(offset));
bytesRead += len;
this.buffer.shift();
}
}
this._readCheckImmediate = setImmediate(function (buffered) {
buffered._readCheckImmediate = undefined;
if (buffered.buffer.length == 0) {
buffered.emit('drain'); // Drained
} else {
buffered.emit('readable'); // Not drained
}
}, this);
return (Buffer.concat(list));
};
}
function lme_heci(options) {
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('error');
emitterUtils.createEvent('connect');
emitterUtils.createEvent('notify');
emitterUtils.createEvent('bind');
if ((options != null) && (options.debug == true)) { lme_port_offset = -100; } // LMS debug mode
var heci = require('heci');
this.INITIAL_RXWINDOW_SIZE = 4096;
this._ObjectID = "lme";
this._LME = heci.create();
this._LME._binded = {};
this._LME.LMS = this;
this._LME.on('error', function (e) { this.LMS.emit('error', e); });
this._LME.on('connect', function () {
this.on('data', function (chunk) {
// this = HECI
var cmd = chunk.readUInt8(0);
//console.log('LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
switch (cmd) {
default:
console.log('Unhandled LME Command ' + cmd + ', ' + chunk.length + ' byte(s).');
break;
case APF_SERVICE_REQUEST:
var nameLen = chunk.readUInt32BE(1);
var name = chunk.slice(5, nameLen + 5);
//console.log("Service Request for: " + name);
if (name == 'pfwd@amt.intel.com' || name == 'auth@amt.intel.com') {
var outBuffer = Buffer.alloc(5 + nameLen);
outBuffer.writeUInt8(6, 0);
outBuffer.writeUInt32BE(nameLen, 1);
outBuffer.write(name.toString(), 5);
this.write(outBuffer);
//console.log('Answering APF_SERVICE_REQUEST');
} else {
//console.log('UNKNOWN APF_SERVICE_REQUEST');
}
break;
case APF_GLOBAL_REQUEST:
var nameLen = chunk.readUInt32BE(1);
var name = chunk.slice(5, nameLen + 5).toString();
switch (name) {
case 'tcpip-forward':
var len = chunk.readUInt32BE(nameLen + 6);
var port = chunk.readUInt32BE(nameLen + 10 + len);
//console.log("[" + chunk.length + "/" + len + "] APF_GLOBAL_REQUEST for: " + name + " on port " + port);
if (this[name] == undefined) { this[name] = {}; }
if (this[name][port] != null) { // Close the existing binding
for (var i in this.sockets) {
var channel = this.sockets[i];
if (channel.localPort == port) { this.sockets[i].end(); delete this.sockets[i]; } // Close this socket
}
}
if (this[name][port] == null)
{ // Bind a new server socket if not already present
this[name][port] = require('net').createServer();
this[name][port].HECI = this;
if (lme_port_offset == 0) {
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
} else {
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
}
this[name][port].on('connection', function (socket) {
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
});
this._binded[port] = true;
this.LMS.emit('bind', this._binded);
}
var outBuffer = Buffer.alloc(5);
outBuffer.writeUInt8(81, 0);
outBuffer.writeUInt32BE(port, 1);
this.write(outBuffer);
break;
case 'cancel-tcpip-forward':
var outBuffer = Buffer.alloc(1);
outBuffer.writeUInt8(APF_REQUEST_SUCCESS, 0);
this.write(outBuffer);
break;
case 'udp-send-to@amt.intel.com':
var outBuffer = Buffer.alloc(1);
outBuffer.writeUInt8(APF_REQUEST_FAILURE, 0);
this.write(outBuffer);
break;
default:
//console.log("Unknown APF_GLOBAL_REQUEST for: " + name);
break;
}
break;
case APF_CHANNEL_OPEN_CONFIRMATION:
var rChannel = chunk.readUInt32BE(1);
var sChannel = chunk.readUInt32BE(5);
var wSize = chunk.readUInt32BE(9);
//console.log('rChannel/' + rChannel + ', sChannel/' + sChannel + ', wSize/' + wSize);
if (this.sockets[rChannel] != undefined) {
this.sockets[rChannel].lme.amtId = sChannel;
this.sockets[rChannel].lme.rxWindow = wSize;
this.sockets[rChannel].lme.txWindow = wSize;
this.sockets[rChannel].lme.LME_CHANNEL_STATUS = 'LME_CS_CONNECTED';
//console.log('LME_CS_CONNECTED');
this.sockets[rChannel].bufferedStream = new stream_bufferedWrite();
this.sockets[rChannel].bufferedStream.socket = this.sockets[rChannel];
this.sockets[rChannel].bufferedStream.on('readable', function () {
if (this.socket.lme.txWindow > 0) {
var buffer = this.read(this.socket.lme.txWindow);
var packet = Buffer.alloc(9 + buffer.length);
packet.writeUInt8(APF_CHANNEL_DATA, 0);
packet.writeUInt32BE(this.socket.lme.amtId, 1);
packet.writeUInt32BE(buffer.length, 5);
buffer.copy(packet, 9);
this.socket.lme.txWindow -= buffer.length;
this.socket.HECI.write(packet);
}
});
this.sockets[rChannel].bufferedStream.on('drain', function () {
this.socket.resume();
});
this.sockets[rChannel].on('data', function (chunk) {
if (!this.bufferedStream.write(chunk)) { this.pause(); }
});
this.sockets[rChannel].on('end', function () {
var outBuffer = Buffer.alloc(5);
outBuffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
outBuffer.writeUInt32BE(this.lme.amtId, 1);
this.HECI.write(outBuffer);
});
this.sockets[rChannel].resume();
}
break;
case APF_PROTOCOLVERSION:
var major = chunk.readUInt32BE(1);
var minor = chunk.readUInt32BE(5);
var reason = chunk.readUInt32BE(9);
var outBuffer = Buffer.alloc(93);
outBuffer.writeUInt8(192, 0);
outBuffer.writeUInt32BE(1, 1);
outBuffer.writeUInt32BE(0, 5);
outBuffer.writeUInt32BE(reason, 9);
//console.log('Answering PROTOCOL_VERSION');
this.write(outBuffer);
break;
case APF_CHANNEL_WINDOW_ADJUST:
var rChannelId = chunk.readUInt32BE(1);
var bytesToAdd = chunk.readUInt32BE(5);
if (this.sockets[rChannelId] != undefined) {
this.sockets[rChannelId].lme.txWindow += bytesToAdd;
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
this.sockets[rChannelId].bufferedStream.emit('readable');
}
} else {
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
}
break;
case APF_CHANNEL_DATA:
var rChannelId = chunk.readUInt32BE(1);
var dataLen = chunk.readUInt32BE(5);
var data = chunk.slice(9, 9 + dataLen);
if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
this.sockets[rChannelId].pendingBytes.push(data.length);
this.sockets[rChannelId].write(data, function () {
var written = this.pendingBytes.shift();
//console.log('adjust', this.lme.amtId, written);
var outBuffer = Buffer.alloc(9);
outBuffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
outBuffer.writeUInt32BE(this.lme.amtId, 1);
outBuffer.writeUInt32BE(written, 5);
this.HECI.write(outBuffer);
});
} else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
var channel = this.insockets[rChannelId];
if (channel.data == null) { channel.data = data.toString(); } else { channel.data += data.toString(); }
channel.rxWindow += dataLen;
//console.log('IN DATA', channel.rxWindow, channel.data.length, dataLen, channel.amtId, data.toString());
var httpData = parseHttp(channel.data);
if ((httpData != null) || (channel.data.length >= 8000)) {
// Parse the WSMAN
var notify = null;
try { notify = xmlParser.ParseWsman(httpData); } catch (e) { }
// Event the http data
if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToString(notify), _lmsNotifyToCode(notify)); }
// Send channel close
var buffer = Buffer.alloc(5);
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
buffer.writeUInt32BE(amtId, 1);
this.write(buffer);
} else {
if (channel.rxWindow > 6000) {
// Send window adjust
var buffer = Buffer.alloc(9);
buffer.writeUInt8(APF_CHANNEL_WINDOW_ADJUST, 0);
buffer.writeUInt32BE(channel.amtId, 1);
buffer.writeUInt32BE(channel.rxWindow, 5);
this.write(buffer);
channel.rxWindow = 0;
}
}
} else {
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
}
break;
case APF_CHANNEL_OPEN_FAILURE:
var rChannelId = chunk.readUInt32BE(1);
var reasonCode = chunk.readUInt32BE(5);
if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
this.sockets[rChannelId].end();
delete this.sockets[rChannelId];
} else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
delete this.insockets[rChannelId];
} else {
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_OPEN_FAILURE');
}
break;
case APF_CHANNEL_CLOSE:
var rChannelId = chunk.readUInt32BE(1);
if ((this.sockets != null) && (this.sockets[rChannelId] != undefined)) {
this.sockets[rChannelId].end();
var amtId = this.sockets[rChannelId].lme.amtId;
var buffer = Buffer.alloc(5);
delete this.sockets[rChannelId];
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0); // ????????????????????????????
buffer.writeUInt32BE(amtId, 1);
this.write(buffer);
} else if ((this.insockets != null) && (this.insockets[rChannelId] != undefined)) {
delete this.insockets[rChannelId];
// Should I send a close back????
} else {
console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
}
break;
case APF_CHANNEL_OPEN:
var nameLen = chunk.readUInt32BE(1);
var name = chunk.slice(5, nameLen + 5).toString();
var channelSender = chunk.readUInt32BE(nameLen + 5);
var initialWindowSize = chunk.readUInt32BE(nameLen + 9);
var hostToConnectLen = chunk.readUInt32BE(nameLen + 17);
var hostToConnect = chunk.slice(nameLen + 21, nameLen + 21 + hostToConnectLen).toString();
var portToConnect = chunk.readUInt32BE(nameLen + 21 + hostToConnectLen);
var originatorIpLen = chunk.readUInt32BE(nameLen + 25 + hostToConnectLen);
var originatorIp = chunk.slice(nameLen + 29 + hostToConnectLen, nameLen + 29 + hostToConnectLen + originatorIpLen).toString();
var originatorPort = chunk.readUInt32BE(nameLen + 29 + hostToConnectLen + originatorIpLen);
//console.log('APF_CHANNEL_OPEN', name, channelSender, initialWindowSize, 'From: ' + originatorIp + ':' + originatorPort, 'To: ' + hostToConnect + ':' + portToConnect);
if (this.insockets == null) { this.insockets = {}; }
var ourId = ++lme_id;
var insocket = new lme_object();
insocket.ourId = ourId;
insocket.amtId = channelSender;
insocket.txWindow = initialWindowSize;
insocket.rxWindow = 0;
insocket.options = { target: hostToConnect, targetPort: portToConnect, source: originatorIp, sourcePort: originatorPort };
this.insockets[ourId] = insocket;
var buffer = Buffer.alloc(17);
buffer.writeUInt8(APF_CHANNEL_OPEN_CONFIRMATION, 0);
buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
buffer.writeUInt32BE(ourId, 5); // Our receiver channel id
buffer.writeUInt32BE(4000, 9); // Initial Window Size
buffer.writeUInt32BE(0xFFFFFFFF, 13); // Reserved
this.write(buffer);
//var buffer = Buffer.alloc(17);
//buffer.writeUInt8(APF_CHANNEL_OPEN_FAILURE, 0);
//buffer.writeUInt32BE(channelSender, 1); // Intel AMT sender channel
//buffer.writeUInt32BE(2, 5); // Reason code
//buffer.writeUInt32BE(0, 9); // Reserved
//buffer.writeUInt32BE(0, 13); // Reserved
//this.write(buffer);
//console.log('Sent APF_CHANNEL_OPEN_FAILURE', channelSender);
break;
}
});
this.LMS.emit('connect');
this.resume();
});
this.bindDuplexStream = function (duplexStream, remoteFamily, localPort) {
var socket = duplexStream;
//console.log('New [' + remoteFamily + '] Virtual Connection/' + socket.localPort);
socket.pendingBytes = [];
socket.HECI = this._LME;
socket.LMS = this;
socket.lme = new lme_object();
socket.lme.Socket = socket;
socket.localPort = localPort;
var buffer = new MemoryStream();
buffer.writeUInt8(0x5A);
buffer.writeUInt32BE(15);
buffer.write('forwarded-tcpip');
buffer.writeUInt32BE(socket.lme.ourId);
buffer.writeUInt32BE(this.INITIAL_RXWINDOW_SIZE);
buffer.writeUInt32BE(0xFFFFFFFF);
for (var i = 0; i < 2; ++i) {
if (remoteFamily == 'IPv6') {
buffer.writeUInt32BE(3);
buffer.write('::1');
} else {
buffer.writeUInt32BE(9);
buffer.write('127.0.0.1');
}
buffer.writeUInt32BE(localPort);
}
this._LME.write(buffer.buffer);
if (this._LME.sockets == undefined) { this._LME.sockets = {}; }
this._LME.sockets[socket.lme.ourId] = socket;
socket.pause();
};
this._LME.connect(heci.GUIDS.LME, { noPipeline: 0 });
}
function parseHttp(httpData) {
var i = httpData.indexOf('\r\n\r\n');
if ((i == -1) || (httpData.length < (i + 2))) { return null; }
var headers = require('http-headers')(httpData.substring(0, i), true);
var contentLength = parseInt(headers['content-length']);
if (httpData.length >= contentLength + i + 4) { return httpData.substring(i + 4, i + 4 + contentLength); }
return null;
}
function _lmsNotifyToCode(notify) {
if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
var msgid = notify.Body.MessageID;
try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
return msgid;
}
function _lmsNotifyToString(notify) {
if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
var msgid = notify.Body.MessageID;
try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
if (lmsEvents[msgid]) { return lmsEvents[msgid]; }
return null;
}
var lmsEvents = {
"iAMT0001": "System Defense Policy %1s triggered.",
"iAMT0002": "Agent Presence Agent %1s not started.",
"iAMT0003": "Agent Presence Agent %1s stopped.",
"iAMT0004": "Agent Presence Agent %1s running.",
"iAMT0005": "Agent Presence Agent %1s expired.",
"iAMT0006": "Agent Presence Agent %1s suspended.",
"iAMT0007": "Host software attempt to disable AMT Network link detected.",
"iAMT0008": "Host software attempt to disable AMT Network link detected -- Host Network link blocked.",
"iAMT0009": "AMT clock or FLASH wear-out protection disabled.",
"iAMT0010": "Intel(R) AMT Network Interface %1s heuristics defense slow threshold trespassed.",
"iAMT0011": "Intel(R) AMT Network Interface %1s heuristics defense fast threshold trespassed.",
"iAMT0012": "Intel(R) AMT Network Interface %1s heuristics defense factory defined threshold trespassed.",
"iAMT0013": "Intel(R) AMT Network Interface %1s heuristics defense Encounter timeout expired.",
"iAMT0014": "General certificate error.",
"iAMT0015": "Certificate expired.",
"iAMT0016": "No trusted root certificate.",
"iAMT0017": "Not configured to work with server certificate.",
"iAMT0018": "Certificate revoked.",
"iAMT0019": "RSA exponent too large.",
"iAMT0020": "RSA modulus too large.",
"iAMT0021": "Unsupported digest.",
"iAMT0022": "Distinguished name too long.",
"iAMT0023": "Key usage missing.",
"iAMT0024": "General SSL handshake error.",
"iAMT0025": "General 802.1x error.",
"iAMT0026": "AMT Diagnostic AlertEAC error - General NAC error.",
"iAMT0027": "AMT Diagnostic AlertEAC error - attempt to get a NAC posture while AMT NAC is disabled.",
"iAMT0028": "AMT Diagnostic AlertEAC error - attempt to get a posture of an unsupported type.",
"iAMT0029": "Audit log storage is 50% full.",
"iAMT0030": "Audit log storage is 75% full.",
"iAMT0031": "Audit log storage is 85% full.",
"iAMT0032": "Audit log storage is 95% full.",
"iAMT0033": "Audit log storage is full.",
"iAMT0034": "Firmware Update Event - Partial.",
"iAMT0035": "Firmware Update Event - Failure.",
"iAMT0036": "Remote connectivity initiated.",
"iAMT0037": "ME Presence event.",
"iAMT0038-0": "AMT is being unprovisioned using BIOS command.",
"iAMT0038-1": "AMT is being unprovisioned using Local MEI command.",
"iAMT0038-2": "AMT is being unprovisioned using Local WS-MAN/SOAP command.",
"iAMT0038-3": "AMT is being unprovisioned using Remote WS-MAN/SOAP command.",
"iAMT0039": "HW Asset Error.",
"iAMT0050": "User Notification Alert - General Notification.",
"iAMT0050-16": "User Notification Alert - Circuit Breaker notification (CB Drop TX filter hit.).",
"iAMT0050-17": "User Notification Alert - Circuit Breaker notification (CB Rate Limit TX filter hit.).",
"iAMT0050-18": "User Notification Alert - Circuit Breaker notification (CB Drop RX filter hit.).",
"iAMT0050-19": "User Notification Alert - Circuit Breaker notification (CB Rate Limit RX filter hit.).",
"iAMT0050-32": "User Notification Alert - EAC notification.",
"iAMT0050-48": "User Notification Alert - Remote diagnostics - (Remote Redirection session started - SOL).",
"iAMT0050-49": "User Notification Alert - Remote diagnostics - (Remote Redirection session stopped - SOL).",
"iAMT0050-50": "User Notification Alert - Remote diagnostics. (Remote Redirection session started - IDE-R).",
"iAMT0050-51": "User Notification Alert - Remote diagnostics. (Remote Redirection session stopped - IDE-R).",
"iAMT0050-66": "User Notification Alert - WLAN notification (Host profile mismatch - Management Interface ignored).",
"iAMT0050-67": "User Notification Alert - WLAN notification (Management device overrides host radio).",
"iAMT0050-68": "User Notification Alert - WLAN notification (Host profile security mismatch).",
"iAMT0050-69": "User Notification Alert - WLAN notification (Management device relinquishes control over host Radio).",
"iAMT0051": "User Notification Alert - SecIo event.",
"iAMT0051-0": "User Notification Alert - SecIo event semaphore at host.",
"iAMT0051-1": "User Notification Alert - semaphore at ME.",
"iAMT0051-2": "User Notification Alert - SecIo event - semaphore timeout.",
"iAMT0052": "User Notification Alert - KVM session event.",
"iAMT0052-0": "User Notification Alert - KVM session requested.",
"iAMT0052-1": "User Notification Alert - KVM session started.",
"iAMT0052-2": "User Notification Alert - KVM session stopped.",
"iAMT0052-3": "User Notification Alert - KVM data channel.",
"iAMT0053": "User Notification Alert - RCS notification.",
"iAMT0053-50": "User Notification Alert - RCS notification (HW button pressed. Connection initiated automatically).",
"iAMT0053-52": "User Notification Alert - RCS notification (HW button pressed. Connection wasn't initiated automatically).",
"iAMT0053-53": "User Notification Alert - RCS notification (Contracts updated).",
"iAMT0054": "User Notification Alert - WLAN notification. Wireless Profile sync enablement state changed.",
"iAMT0055": "User Notification Alert - Provisioning state change notification.",
"iAMT0055-0": "User Notification Alert - Provisioning state change notification - Pre-configuration.",
"iAMT0055-1": "User Notification Alert - Provisioning state change notification - In configuration.",
"iAMT0055-2": "User Notification Alert - Provisioning state change notification - Post-configuration.",
"iAMT0055-3": "User Notification Alert - Provisioning state change notification - Unprovision process has started.",
"iAMT0056": "User Notification Alert - System Defense change notification.",
"iAMT0057": "User Notification Alert - Network State change notification.",
"iAMT0058": "User Notification Alert - Remote Access change notification.",
"iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is closed.",
//"iAMT0058-1": "User Notification Alert - Remote Access change notification - tunnel is open.", // TODO
"iAMT0059": "User Notification Alert - KVM enabled event.",
"iAMT0059-0": "User Notification Alert - KVM enabled event - KVM disabled.",
"iAMT0059-1": "User Notification Alert - KVM enabled event - KVM enabled (both from MEBx and PTNI).",
"iAMT0060": "User Notification Alert - SecIO configuration event.",
"iAMT0061": "ME FW reset occurred.",
"iAMT0062": "User Notification Alert - IpSyncEnabled event.",
"iAMT0062-0": "User Notification Alert - IpSyncEnabled event - IpSync disabled.",
"iAMT0062-1": "User Notification Alert - IpSyncEnabled event - IpSync enabled.",
"iAMT0063": "User Notification Alert - HTTP Proxy sync enabled event.",
"iAMT0063-0": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync disabled.",
"iAMT0063-1": "User Notification Alert - HTTP Proxy sync enabled event - HTTP Proxy Sync enabled.",
"iAMT0064": "User Notification Alert - User Consent event.",
"iAMT0064-1": "User Notification Alert - User Consent event - User Consent granted.",
"iAMT0064-2": "User Notification Alert - User Consent event - User Consent ended.",
"iAMT0067-0": "Graceful Remote Control Operation - Shutdown.",
"iAMT0067-1": "Graceful Remote Control Operation - Reset.",
"iAMT0067-2": "Graceful Remote Control Operation - Hibernate.",
"iAMT0068-0": "Link Protection Notification - No link protection.",
"iAMT0068-1": "Link Protection Notification - Passive link protection.",
"iAMT0068-2": "Link Protection Notification - High link protection.",
"iAMT0069-0": "Local Time Sync Enablement Notification - Local Time Sync Disabled.",
"iAMT0069-1": "Local Time Sync Enablement Notification - Local Time Sync Enabled.",
"iAMT0070": "Host Reset Triggered by WD Expiration Notification.",
"PLAT0004": "The chassis %1s was opened.",
"PLAT0005": "The chassis %1s was closed.",
"PLAT0006": "The drive bay %1s was opened.",
"PLAT0007": "The drive bay %1s was closed.",
"PLAT0008": "The I/O card area %1s was opened.",
"PLAT0009": "The I/O card area %1s was closed.",
"PLAT0010": "The processor area %1s was opened.",
"PLAT0011": "The processor area %1s was closed.",
"PLAT0012": "The LAN %1s has been disconnected.",
"PLAT0013": "The LAN %1s has been connected.",
"PLAT0016": "The permission to insert package %1s has been granted.",
"PLAT0017": "The permission to insert package %1s has been removed.",
"PLAT0018": "The fan card area %1s is open.",
"PLAT0019": "The fan card area %1s is closed.",
"PLAT0022": "The computer system %1s has detected a secure mode violation.",
"PLAT0024": "The computer system %1s has detected a pre-boot user password violation.",
"PLAT0026": "The computer system %1s has detected a pre-boot setup password violation.",
"PLAT0028": "The computer system %1s has detected a network boot password violation.",
"PLAT0030": "The computer system %1s has detected a password violation.",
"PLAT0032": "The management controller %1s has detected an out-of-band password violation.",
"PLAT0034": "The processor %1s has been added.",
"PLAT0035": "The processor %1s has been removed.",
"PLAT0036": "An over-temperature condition has been detected on the processor %1s.",
"PLAT0037": "An over-temperature condition has been removed on the processor %1s.",
"PLAT0038": "The processor %1s is operating in a degraded State.",
"PLAT0039": "The processor %1s is no longer operating in a degraded State.",
"PLAT0040": "The processor %1s has failed.",
"PLAT0042": "The processor %1s has failed.",
"PLAT0044": "The processor %1s has failed.",
"PLAT0046": "The processor %1s has failed.",
"PLAT0048": "The processor %1s has failed.",
"PLAT0060": "The processor %1s has been enabled.",
"PLAT0061": "The processor %1s has been disabled.",
"PLAT0062": "The processor %1s has a configuration mismatch.",
"PLAT0064": "A terminator has been detected on the processor %1s.",
"PLAT0084": "The Power Supply %1s has been added.",
"PLAT0085": "The Power Supply %1s has been removed.",
"PLAT0086": "The Power Supply %1s has failed.",
"PLAT0088": "Failure predicted on power supply %1s.",
"PLAT0096": "The input to power supply %1s has been lost or fallen out of range.",
"PLAT0098": "The power supply %1s is operating in an input state that is out of range.",
"PLAT0099": "The power supply %1s has returned to a normal input state.",
"PLAT0100": "The power supply %1s has lost input.",
"PLAT0104": "The power supply %1s has a configuration mismatch.",
"PLAT0106": "Power supply %1s has been disabled.",
"PLAT0107": "Power supply %1s has been enabled.",
"PLAT0108": "Power supply %1s has been power cycled.",
"PLAT0110": "Power supply %1s has encountered an error during power down.",
"PLAT0112": "Power supply %1s has lost power.",
"PLAT0114": "Soft power control has failed for power supply %1s.",
"PLAT0116": "Power supply %1s has failed.",
"PLAT0118": "Failure predicted on power supply %1s.",
"PLAT0120": "Memory subsystem failure.",
"PLAT0122": "DIMM missing.",
"PLAT0124": "Memory error detected & corrected for DIMM %1s.",
"PLAT0128": "Memory DIMM %1s added.",
"PLAT0129": "Memory DIMM %1s removed.",
"PLAT0130": "Memory DIMM %1s enabled.",
"PLAT0131": "Memory DIMM %1s disabled.",
"PLAT0134": "Memory parity error for DIMM %1s.",
"PLAT0136": "Memory scrub failure for DIMM %1s.",
"PLAT0138": "Memory uncorrectable error detected for DIMM %1s.",
"PLAT0140": "Memory sparing initiated for DIMM %1s.",
"PLAT0141": "Memory sparing concluded for DIMM %1s.",
"PLAT0142": "Memory DIMM %1s Throttled.",
"PLAT0144": "Memory logging limit reached for DIMM %1s.",
"PLAT0145": "Memory logging limit removed for DIMM %1s.",
"PLAT0146": "An over-temperature condition has been detected on the Memory DIMM %1s.",
"PLAT0147": "An over-temperature condition has been removed on the Memory DIMM %1s.",
"PLAT0162": "The drive %1s has been added.",
"PLAT0163": "The drive %1s has been removed.",
"PLAT0164": "The drive %1s has been disabled due to a detected fault.",
"PLAT0167": "The drive %1s has been enabled.",
"PLAT0168": "Failure predicted on drive %1s.",
"PLAT0170": "Hot spare enabled for %1s.",
"PLAT0171": "Hot spare disabled for %1s.",
"PLAT0172": "Consistency check has begun for %1s.",
"PLAT0173": "Consistency check completed for %1s.",
"PLAT0174": "Array %1s is in critical condition.",
"PLAT0176": "Array %1s has failed.",
"PLAT0177": "Array %1s has been restored.",
"PLAT0178": "Rebuild in progress for array %1s.",
"PLAT0179": "Rebuild completed for array %1s.",
"PLAT0180": "Rebuild Aborted for array %1s.",
"PLAT0184": "The system %1s encountered a POST error.",
"PLAT0186": "The system %1s encountered a firmware hang.",
"PLAT0188": "The system %1s encountered firmware progress.",
"PLAT0192": "The log %1s has been disabled.",
"PLAT0193": "The log %1s has been enabled.",
"PLAT0194": "The log %1s has been disabled.",
"PLAT0195": "The log %1s has been enabled.",
"PLAT0196": "The log %1s has been disabled.",
"PLAT0198": "The log %1s has been enabled.",
"PLAT0200": "The log %1s has been cleared.",
"PLAT0202": "The log %1s is full.",
"PLAT0203": "The log %1s is no longer full.",
"PLAT0204": "The log %1s is almost full.",
"PLAT0208": "The log %1s has a configuration error.",
"PLAT0210": "The system %1s has been reconfigured.",
"PLAT0212": "The system %1s has encountered an OEM system boot event.",
"PLAT0214": "The system %1s has encountered an unknown system hardware fault.",
"PLAT0216": "The system %1s has generated an auxiliary log entry.",
"PLAT0218": "The system %1s has executed a PEF action.",
"PLAT0220": "The system %1s has synchronized the system clock.",
"PLAT0222": "A diagnostic interrupt has occurred on system %1s.",
"PLAT0224": "A bus timeout has occurred on system %1s.",
"PLAT0226": "An I/O channel check NMI has occurred on system %1s.",
"PLAT0228": "A software NMI has occurred on system %1s.",
"PLAT0230": "System %1s has recovered from an NMI.",
"PLAT0232": "A PCI PERR has occurred on system %1s.",
"PLAT0234": "A PCI SERR has occurred on system %1s.",
"PLAT0236": "An EISA fail safe timeout occurred on system %1s.",
"PLAT0238": "A correctable bus error has occurred on system %1s.",
"PLAT0240": "An uncorrectable bus error has occurred on system %1s.",
"PLAT0242": "A fatal NMI error has occurred on system %1s.",
"PLAT0244": "A fatal bus error has occurred on system %1s.",
"PLAT0246": "A bus on system %1s is operating in a degraded state.",
"PLAT0247": "A bus on system %1s is no longer operating in a degraded state.",
"PLAT0248": "The power button %1s has been pressed.",
"PLAT0249": "The power button %1s has been released.",
"PLAT0250": "The sleep button %1s has been pressed.",
"PLAT0251": "The sleep button %1s has been released.",
"PLAT0252": "The reset button %1s has been pressed.",
"PLAT0253": "The reset button %1s has been released.",
"PLAT0254": "The latch to %1s has been opened.",
"PLAT0255": "The latch to %1s has been closed.",
"PLAT0256": "The service request %1s has been enabled.",
"PLAT0257": "The service request %1s has been completed.",
"PLAT0258": "Power control of system %1s has failed.",
"PLAT0262": "The network port %1s has been connected.",
"PLAT0263": "The network port %1s has been disconnected.",
"PLAT0266": "The connector %1s has encountered a configuration error.",
"PLAT0267": "The connector %1s configuration error has been repaired.",
"PLAT0272": "Power on for system %1s.",
"PLAT0274": "Power cycle hard requested for system %1s.",
"PLAT0276": "Power cycle soft requested for system %1s.",
"PLAT0278": "PXE boot requested for system %1s.",
"PLAT0280": "Diagnostics boot requested for system %1s.",
"PLAT0282": "System restart requested for system %1s.",
"PLAT0284": "System restart begun for system %1s.",
"PLAT0286": "No bootable media available for system %1s.",
"PLAT0288": "Non-bootable media selected for system %1s.",
"PLAT0290": "PXE server not found for system %1s.",
"PLAT0292": "User timeout on boot for system %1s.",
"PLAT0296": "System %1s boot from floppy initiated.",
"PLAT0298": "System %1s boot from local drive initiated.",
"PLAT0300": "System %1s boot from PXE on network port initiated.",
"PLAT0302": "System %1s boot diagnostics initiated.",
"PLAT0304": "System %1s boot from CD initiated.",
"PLAT0306": "System %1s boot from ROM initiated.",
"PLAT0312": "System %1s boot initiated.",
"PLAT0320": "Critical stop during OS load on system %1s.",
"PLAT0322": "Run-time critical stop on system %1s.",
"PLAT0324": "OS graceful stop on system %1s.",
"PLAT0326": "OS graceful shutdown begun on system %1s.",
"PLAT0327": "OS graceful shutdown completed on system %1s.",
"PLAT0328": "Agent not responding on system %1s.",
"PLAT0329": "Agent has begun responding on system %1s.",
"PLAT0330": "Fault in slot on system %1s.",
"PLAT0331": "Fault condition removed on system %1s.",
"PLAT0332": "Identifying slot on system %1s.",
"PLAT0333": "Identify stopped on slot for system %1s.",
"PLAT0334": "Package installed in slot for system %1s.",
"PLAT0336": "Slot empty system %1s.",
"PLAT0338": "Slot in system %1s is ready for installation.",
"PLAT0340": "Slot in system %1s is ready for removal.",
"PLAT0342": "Power is off on slot of system %1s.",
"PLAT0344": "Power is on for slot of system %1s.",
"PLAT0346": "Removal requested for slot of system %1s.",
"PLAT0348": "Interlock activated on slot of system %1s.",
"PLAT0349": "Interlock de-asserted on slot of system %1s.",
"PLAT0350": "Slot disabled on system %1s.",
"PLAT0351": "Slot enabled on system %1s.",
"PLAT0352": "Slot of system %1s holds spare.",
"PLAT0353": "Slot of system %1s no longer holds spare.",
"PLAT0354": "Computer system %1s enabled.",
"PLAT0356": "Computer system %1s is in sleep - light mode.",
"PLAT0358": "Computer system %1s is in hibernate.",
"PLAT0360": "Computer system %1s is in standby.",
"PLAT0362": "Computer system %1s is in soft off mode.",
"PLAT0364": "Computer system %1s is in hard off mode.",
"PLAT0366": "Computer system %1s is sleeping.",
"PLAT0368": "Watchdog timer expired for %1s.",
"PLAT0370": "Reboot of system initiated by watchdog %1s.",
"PLAT0372": "Powering off system initiated by watchdog %1s.",
"PLAT0374": "Power cycle of system initiated by watchdog %1s.",
"PLAT0376": "Watchdog timer interrupt occurred for %1s.",
"PLAT0378": "A page alert has been generated for system %1s.",
"PLAT0380": "A LAN alert has been generated for system %1s.",
"PLAT0382": "An event trap has been generated for system %1s.",
"PLAT0384": "An SNMP trap has been generated for system %1s.",
"PLAT0390": "%1s detected as present.",
"PLAT0392": "%1s detected as absent.",
"PLAT0394": "%1s has been disabled.",
"PLAT0395": "%1s has been enabled.",
"PLAT0396": "Heartbeat lost for LAN %1s.",
"PLAT0397": "Heartbeat detected for LAN %1s.",
"PLAT0398": "Sensor %1s is unavailable or degraded on management system.",
"PLAT0399": "Sensor %1s has returned to normal on management system.",
"PLAT0400": "Controller %1s is unavailable or degraded on management system.",
"PLAT0401": "Controller %1s has returned to normal on management system.",
"PLAT0402": "Management system %1s is off-line.",
"PLAT0404": "Management system %1s is disabled.",
"PLAT0405": "Management system %1s is enabled.",
"PLAT0406": "Sensor %1s has failed on management system.",
"PLAT0408": "FRU %1s has failed on management system.",
"PLAT0424": "The battery %1s is critically low.",
"PLAT0427": "The battery %1s is no longer critically low.",
"PLAT0430": "The battery %1s has been removed from unit.",
"PLAT0431": "The battery %1s has been added.",
"PLAT0432": "The battery %1s has failed.",
"PLAT0434": "Session audit is deactivated on system %1s.",
"PLAT0435": "Session audit is activated on system %1s.",
"PLAT0436": "A hardware change occurred on system %1s.",
"PLAT0438": "A firmware or software change occurred on system %1s.",
"PLAT0440": "A hardware incompatibility was detected on system %1s.",
"PLAT0442": "A firmware or software incompatibility was detected on system %1s.",
"PLAT0444": "Invalid or unsupported hardware was detected on system %1s.",
"PLAT0446": "Invalid or unsupported firmware or software was detected on system %1s.",
"PLAT0448": "A successful hardware change was detected on system %1s.",
"PLAT0450": "A successful software or firmware change was detected on system %1s.",
"PLAT0464": "FRU %1s not installed on system.",
"PLAT0465": "FRU %1s installed on system.",
"PLAT0466": "Activation requested for FRU %1s on system.",
"PLAT0467": "FRU %1s on system is active.",
"PLAT0468": "Activation in progress for FRU %1s on system.",
"PLAT0470": "Deactivation request for FRU %1s on system.",
"PLAT0471": "FRU %1s on system is in standby or \"hot spare\" state.",
"PLAT0472": "Deactivation in progress for FRU %1s on system.",
"PLAT0474": "Communication lost with FRU %1s on system.",
"PLAT0476": "Numeric sensor %1s going low (lower non-critical).",
"PLAT0478": "Numeric sensor %1s going high (lower non-critical).",
"PLAT0480": "Numeric sensor %1s going low (lower critical).",
"PLAT0482": "Numeric sensor %1s going high (lower critical).",
"PLAT0484": "Numeric sensor %1s going low (lower non-recoverable).",
"PLAT0486": "Numeric sensor %1s going high (lower non-critical).",
"PLAT0488": "Numeric sensor %1s going low (upper non-critical).",
"PLAT0490": "Numeric sensor %1s going high (upper non-critical).",
"PLAT0492": "Numeric sensor %1s going low (upper critical).",
"PLAT0494": "Numeric sensor %1s going high (upper critical).",
"PLAT0496": "Numeric sensor %1s going low (upper non-recoverable).",
"PLAT0498": "Numeric sensor %1s going high (upper non-recoverable).",
"PLAT0500": "Sensor %1s has transitioned to idle.",
"PLAT0502": "Sensor %1s has transitioned to active.",
"PLAT0504": "Sensor %1s has transitioned to busy.",
"PLAT0508": "Sensor %1s has asserted.",
"PLAT0509": "Sensor %1s has de-asserted.",
"PLAT0510": "Sensor %1s is asserting predictive failure.",
"PLAT0511": "Sensor %1s is de-asserting predictive failure.",
"PLAT0512": "Sensor %1s has indicated limit exceeded.",
"PLAT0513": "Sensor %1s has indicated limit no longer exceeded.",
"PLAT0514": "Sensor %1s has indicated performance met.",
"PLAT0516": "Sensor %1s has indicated performance lags.",
"PLAT0518": "Sensor %1s has transitioned to normal state.",
"PLAT0520": "Sensor %1s has transitioned from normal to non-critical state.",
"PLAT0522": "Sensor %1s has transitioned to critical from a less severe state.",
"PLAT0524": "Sensor %1s has transitioned to non-recoverable from a less severe state.",
"PLAT0526": "Sensor %1s has transitioned to non-critical from a more severe state.",
"PLAT0528": "Sensor %1s has transitioned to critical from a non-recoverable state.",
"PLAT0530": "Sensor %1s has transitioned to non-recoverable.",
"PLAT0532": "Sensor %1s indicates a monitor state.",
"PLAT0534": "Sensor %1s has an informational state.",
"PLAT0536": "Device %1s has been added.",
"PLAT0537": "Device %1s has been removed from unit.",
"PLAT0538": "Device %1s has been enabled.",
"PLAT0539": "Device %1s has been disabled.",
"PLAT0540": "Sensor %1s has indicated a running state.",
"PLAT0544": "Sensor %1s has indicated a power off state.",
"PLAT0546": "Sensor %1s has indicated an on-line state.",
"PLAT0548": "Sensor %1s has indicated an off-line state.",
"PLAT0550": "Sensor %1s has indicated an off-duty state.",
"PLAT0552": "Sensor %1s has indicated a degraded state.",
"PLAT0554": "Sensor %1s has indicated a power save state.",
"PLAT0556": "Sensor %1s has indicated an install error.",
"PLAT0558": "Redundancy %1s has been lost.",
"PLAT0560": "Redundancy %1s has been reduced.",
"PLAT0561": "Redundancy %1s has been restored.",
"PLAT0562": "%1s has transitioned to a D0 power state.",
"PLAT0564": "%1s has transitioned to a D1 power state.",
"PLAT0566": "%1s has transitioned to a D2 power state.",
"PLAT0568": "%1s has transitioned to a D3 power state.",
"PLAT0720": "The System %1s encountered firmware progress - memory initialization entry.",
"PLAT0721": "The System %1s encountered firmware progress - memory initialization exit.",
"PLAT0722": "The System %1s encountered firmware progress - hard drive initialization entry.",
"PLAT0723": "The System %1s encountered firmware progress - hard drive initialization exit.",
"PLAT0724": "The System %1s encountered firmware progress - user authentication.",
"PLAT0728": "The System %1s encountered firmware progress - USR resource configuration entry.",
"PLAT0729": "The System %1s encountered firmware progress - USR resource configuration exit.",
"PLAT0730": "The System %1s encountered firmware progress - PCI recource configuration entry.",
"PLAT0731": "The System %1s encountered firmware progress - PCI recource configuration exit.",
"PLAT0732": "The System %1s encountered firmware progress - Option ROM initialization entry.",
"PLAT0733": "The System %1s encountered firmware progress - Option ROM initialization entry exit.",
"PLAT0734": "The System %1s encountered firmware progress -video initialization entry entry.",
"PLAT0735": "The System %1s encountered firmware progress - video initialization entry exit.",
"PLAT0736": "The System %1s encountered firmware progress - cache initialization entry.",
"PLAT0737": "The System %1s encountered firmware progress - cache initialization exit.",
"PLAT0738": "The System %1s encountered firmware progress - keyboard controller initialization entry.",
"PLAT0739": "The System %1s encountered firmware progress - keyboard controller initialization exit.",
"PLAT0740": "The System %1s encountered firmware progress - motherboard initialization entry.",
"PLAT0741": "The System %1s encountered firmware progress - motherboard initialization exit.",
"PLAT0742": "The System %1s encountered firmware progress - floppy disk initialization entry.",
"PLAT0743": "The System %1s encountered firmware progress - floppy disk initialization exit.",
"PLAT0744": "The System %1s encountered firmware progress - keyboard test entry.",
"PLAT0745": "The System %1s encountered firmware progress - keyboard test exit.",
"PLAT0746": "The System %1s encountered firmware progress - pointing device test entry.",
"PLAT0747": "The System %1s encountered firmware progress - pointing device test exit.",
"PLAT0750": "The System %1s encountered firmware progress - dock enable entry.",
"PLAT0751": "The System %1s encountered firmware progress - dock enable exit.",
"PLAT0752": "The System %1s encountered firmware progress - dock disable entry.",
"PLAT0753": "The System %1s encountered firmware progress - dock disable exit.",
"PLAT0760": "The System %1s encountered firmware progress - start OS boot process.",
"PLAT0762": "The System %1s encountered firmware progress - call OS wake vector.",
"PLAT0764": "The System %1s encountered firmware progress - unrecoverable keyboard failure.",
"PLAT0766": "The System %1s encountered firmware progress - no video device detected.",
"PLAT0768": "The System %1s encountered firmware progress - SMART alert detected on drive.",
"PLAT0770": "The System %1s encountered firmware progress - unrecoverable boot device failure.",
"PLAT0789": "Corrupt BIOS detected.",
"PLAT0790": "The System %1s encountered PCI configuration failure.",
"PLAT0791": "The System %1s encountered a video subsystem failure.",
"PLAT0792": "The System %1s encountered a storage subsystem failure.",
"PLAT0793": "The System %1s encountered a USB subsystem failure.",
"PLAT0794": "The System %1s has detected no memory in the system.",
"PLAT0795": "The System %1s encountered a motherboard failure.",
"PLAT0796": "The System %1s encountered a memory Regulator Voltage Bad.",
"PLAT0797": "%1s PCI reset is not deasserting.",
"PLAT0798": "%1s Non-Motherboard Regulator Failure.",
"PLAT0799": "%1s Power Supply Cable failure.",
"PLAT0800": "%1s Motherboard regulator failure.",
"PLAT0801": "%1s System component compatibility mismatch."
}
module.exports = lme_heci;

View File

@ -0,0 +1,387 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var Q = require('queue');
function amt_heci() {
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('error');
var heci = require('heci');
this._ObjectID = "pthi";
this._rq = new Q();
this._setupPTHI = function _setupPTHI()
{
this._amt = heci.create();
this._amt.BiosVersionLen = 65;
this._amt.UnicodeStringLen = 20;
this._amt.Parent = this;
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
this._amt.on('connect', function _amtOnConnect()
{
this.on('data', function _amtOnData(chunk)
{
//console.log("Received: " + chunk.length + " bytes");
var header = this.Parent.getCommand(chunk);
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
var user = this.Parent._rq.deQueue();
var params = user.optional;
var callback = user.func;
params.unshift(header);
callback.apply(this.Parent, params);
if(this.Parent._rq.isEmpty())
{
// No More Requests, we can close PTHI
this.Parent._amt.disconnect();
this.Parent._amt = null;
}
else
{
// Send the next request
this.write(this.Parent._rq.peekQueue().send);
}
});
// Start sending requests
this.write(this.Parent._rq.peekQueue().send);
});
};
function trim(x) { var y = x.indexOf('\0'); if (y >= 0) { return x.substring(0, y); } else { return x; } }
this.getCommand = function getCommand(chunk) {
var command = chunk.length == 0 ? (this._rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
var ret = { IsResponse: (command & 0x800000) == 0x800000 ? true : false, Command: (command & 0x7FFFFF), Status: chunk.length != 0 ? chunk.readUInt32LE(12) : -1, Data: chunk.length != 0 ? chunk.slice(16) : null };
return (ret);
};
this.sendCommand = function sendCommand() {
if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
var args = [];
for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
var header = Buffer.from('010100000000000000000000', 'hex');
header.writeUInt32LE(arguments[0] | 0x04000000, 4);
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args , send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]]))});
if(!this._amt)
{
this._setupPTHI();
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
}
}
this.getVersion = function getVersion(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(26, null, function (header, fn, opt) {
if (header.Status == 0) {
var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
}
if (val.BiosVersion.indexOf('\0') > 0) { val.BiosVersion = val.BiosVersion.substring(0, val.BiosVersion.indexOf('\0')); }
opt.unshift(val);
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
// Fill the left with zeros until the string is of a given length
function zeroLeftPad(str, len) {
if ((len == null) && (typeof (len) != 'number')) { return null; }
if (str == null) str = ''; // If null, this is to generate zero leftpad string
var zlp = '';
for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
return zlp + str;
}
this.getUuid = function getUuid(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x5c, null, function (header, fn, opt) {
if (header.Status == 0) {
var result = {};
result.uuid = [zeroLeftPad(header.Data.readUInt32LE(0).toString(16), 8),
zeroLeftPad(header.Data.readUInt16LE(4).toString(16), 4),
zeroLeftPad(header.Data.readUInt16LE(6).toString(16), 4),
zeroLeftPad(header.Data.readUInt16BE(8).toString(16), 4),
zeroLeftPad(header.Data.slice(10).toString('hex').toLowerCase(), 12)].join('-');
opt.unshift(result);
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getProvisioningState = function getProvisioningState(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(17, null, function (header, fn, opt) {
if (header.Status == 0) {
var result = {};
result.state = header.Data.readUInt32LE(0);
if (result.state < 3) { result.stateStr = ["PRE", "IN", "POST"][result.state]; }
opt.unshift(result);
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getProvisioningMode = function getProvisioningMode(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(8, null, function (header, fn, opt) {
if (header.Status == 0) {
var result = {};
result.mode = header.Data.readUInt32LE(0);
if (result.mode < 4) { result.modeStr = ["NONE", "ENTERPRISE", "SMALL_BUSINESS", "REMOTE_ASSISTANCE"][result.mode]; }
result.legacy = header.Data.readUInt32LE(4) == 0 ? false : true;
opt.unshift(result);
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getEHBCState = function getEHBCState(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(132, null, function (header, fn, opt) {
if (header.Status == 0) {
opt.unshift({ EHBC: header.Data.readUInt32LE(0) != 0 });
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getControlMode = function getControlMode(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(107, null, function (header, fn, opt) {
if (header.Status == 0) {
var result = {};
result.controlMode = header.Data.readUInt32LE(0);
if (result.controlMode < 3) { result.controlModeStr = ["NONE_RPAT", "CLIENT", "ADMIN", "REMOTE_ASSISTANCE"][result.controlMode]; }
opt.unshift(result);
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getMACAddresses = function getMACAddresses(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(37, null, function (header, fn, opt) {
if (header.Status == 0) {
opt.unshift({ DedicatedMAC: header.Data.slice(0, 6).toString('hex:'), HostMAC: header.Data.slice(6, 12).toString('hex:') });
} else { opt.unshift({ DedicatedMAC: null, HostMAC: null }); }
fn.apply(this, opt);
}, callback, optional);
};
this.getDnsSuffix = function getDnsSuffix(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(54, null, function (header, fn, opt) {
if (header.Status == 0) {
var resultLen = header.Data.readUInt16LE(0);
if (resultLen > 0) { opt.unshift(header.Data.slice(2, 2 + resultLen).toString()); } else { opt.unshift(null); }
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getHashHandles = function getHashHandles(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x2C, null, function (header, fn, opt) {
var result = [];
if (header.Status == 0) {
var resultLen = header.Data.readUInt32LE(0);
for (var i = 0; i < resultLen; ++i) {
result.push(header.Data.readUInt32LE(4 + (4 * i)));
}
}
opt.unshift(result);
fn.apply(this, opt);
}, callback, optional);
};
this.getCertHashEntry = function getCertHashEntry(handle, callback) {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
var data = new Buffer(4);
data.writeUInt32LE(handle, 0);
this.sendCommand(0x2D, data, function (header, fn, opt) {
if (header.Status == 0) {
var result = {};
result.isDefault = header.Data.readUInt32LE(0);
result.isActive = header.Data.readUInt32LE(4);
result.hashAlgorithm = header.Data.readUInt8(72);
if (result.hashAlgorithm < 4) {
result.hashAlgorithmStr = ["MD5", "SHA1", "SHA256", "SHA512"][result.hashAlgorithm];
result.hashAlgorithmSize = [16, 20, 32, 64][result.hashAlgorithm];
result.certificateHash = header.Data.slice(8, 8 + result.hashAlgorithmSize).toString('hex');
}
result.name = header.Data.slice(73 + 2, 73 + 2 + header.Data.readUInt16LE(73)).toString();
opt.unshift(result);
} else {
opt.unshift(null);
}
fn.apply(this, opt);
}, callback, optional);
};
this.getCertHashEntries = function getCertHashEntries(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.getHashHandles(function (handles, fn, opt) {
var entries = [];
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
}, callback, optional);
};
this._getHashEntrySink = function _getHashEntrySink(result, fn, opt, entries, handles) {
entries.push(result);
if (handles.length > 0) {
this.getCertHashEntry(handles.shift(), this._getHashEntrySink, fn, opt, entries, handles);
} else {
opt.unshift(entries);
fn.apply(this, opt);
}
}
this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
if (header.Data.length == 68) { opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data }); } else { opt.unshift(null); }
fn.apply(this, opt);
}, callback, optional);
}
this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback)
{
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
var ifx = Buffer.alloc(4);
ifx.writeUInt32LE(index);
this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt)
{
if(header.Status == 0)
{
var info = {};
info.enabled = header.Data.readUInt32LE(0);
info.dhcpEnabled = header.Data.readUInt32LE(8);
switch(header.Data[12])
{
case 1:
info.dhcpMode = 'ACTIVE'
break;
case 2:
info.dhcpMode = 'PASSIVE'
break;
default:
info.dhcpMode = 'UNKNOWN';
break;
}
info.mac = header.Data.slice(14).toString('hex:');
var addr = header.Data.readUInt32LE(4);
info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255);
opt.unshift(info);
fn.apply(this, opt);
}
else
{
opt.unshift(null);
fn.apply(this, opt);
}
}, callback, optional);
};
this.unprovision = function unprovision(mode, callback) {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
var data = new Buffer(4);
data.writeUInt32LE(mode, 0);
this.sendCommand(16, data, function (header, fn, opt) {
opt.unshift(header.Status);
fn.apply(this, opt);
}, callback, optional);
}
this.startConfiguration = function startConfiguration() {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
}
this.stopConfiguration = function stopConfiguration() {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
}
this.openUserInitiatedConnection = function openUserInitiatedConnection() {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
}
this.closeUserInitiatedConnection = function closeUnserInitiatedConnected() {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
}
this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus() {
var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
this.sendCommand(0x46, data, function (header, fn, opt) {
if (header.Status == 0) {
var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data });
} else {
opt.unshift({ status: header.Status });
}
fn.apply(this, opt);
}, callback, optional);
}
this.getProtocolVersion = function getProtocolVersion(callback) {
var optional = [];
for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
heci.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
if (status == 0) {
var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
opt.unshift(result);
fn.apply(self, opt);
}
else {
opt.unshift(null);
fn.apply(self, opt);
}
}, this, callback, optional);
}
}
module.exports = amt_heci;

View File

@ -0,0 +1,105 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @description Meshcentral Intel AMT Local Scanner
* @author Ylian Saint-Hilaire & Joko Sastriawan
* @version v0.0.1
*/
// Construct a Intel AMT Scanner object
function AMTScanner() {
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('found');
this.dgram = require('dgram');
this.buildRmcpPing = function (tag) {
var packet = Buffer.from('06000006000011BE80000000', 'hex');
packet[9] = tag;
return packet;
};
this.parseRmcpPacket = function (server, data, rinfo, func) {
if (data == null || data.length < 20) return;
var res = {};
if (((data[12] == 0) || (data[13] != 0) || (data[14] != 1) || (data[15] != 0x57)) && (data[21] & 32)) {
res.servertag = data[9];
res.minorVersion = data[18] & 0x0F;
res.majorVersion = (data[18] >> 4) & 0x0F;
res.provisioningState = data[19] & 0x03; // Pre = 0, In = 1, Post = 2
var openPort = (data[16] * 256) + data[17];
var dualPorts = ((data[19] & 0x04) != 0) ? true : false;
res.openPorts = [openPort];
res.address = rinfo.address;
if (dualPorts == true) { res.openPorts = [16992, 16993]; }
if (func !== undefined) {
func(server, res);
}
}
}
this.parseIPv4Range = function (range) {
if (range == undefined || range == null) return null;
var x = range.split('-');
if (x.length == 2) { return { min: this.parseIpv4Addr(x[0]), max: this.parseIpv4Addr(x[1]) }; }
x = range.split('/');
if (x.length == 2) {
var ip = this.parseIpv4Addr(x[0]), masknum = parseInt(x[1]), mask = 0;
if (masknum <= 16 || masknum > 32) return null;
masknum = 32 - masknum;
for (var i = 0; i < masknum; i++) { mask = (mask << 1); mask++; }
return { min: ip & (0xFFFFFFFF - mask), max: (ip & (0xFFFFFFFF - mask)) + mask };
}
x = this.parseIpv4Addr(range);
if (x == null) return null;
return { min: x, max: x };
};
// Parse IP address. Takes a
this.parseIpv4Addr = function (addr) {
var x = addr.split('.');
if (x.length == 4) { return (parseInt(x[0]) << 24) + (parseInt(x[1]) << 16) + (parseInt(x[2]) << 8) + (parseInt(x[3]) << 0); }
return null;
}
// IP address number to string
this.IPv4NumToStr = function (num) {
return ((num >> 24) & 0xFF) + '.' + ((num >> 16) & 0xFF) + '.' + ((num >> 8) & 0xFF) + '.' + (num & 0xFF);
}
this.scan = function (rangestr, timeout) {
var iprange = this.parseIPv4Range(rangestr);
var rmcp = this.buildRmcpPing(0);
var server = this.dgram.createSocket({ type: 'udp4' });
server.parent = this;
server.scanResults = [];
server.on('error', function (err) { console.log('Error:' + err); });
server.on('message', function (msg, rinfo) { if (rinfo.size > 4) { this.parent.parseRmcpPacket(this, msg, rinfo, function (s, res) { s.scanResults.push(res); }) }; });
server.on('listening', function () { for (var i = iprange.min; i <= iprange.max; i++) { server.send(rmcp, 623, server.parent.IPv4NumToStr(i)); } });
server.bind({ address: '0.0.0.0', port: 0, exclusive: true });
var tmout = setTimeout(function cb() {
//console.log("Server closed");
server.close();
server.parent.emit('found', server.scanResults);
delete server;
}, timeout);
};
}
module.exports = AMTScanner;

View File

@ -0,0 +1,148 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @description WSMAN communication using duktape http
* @author Ylian Saint-Hilaire
* @version v0.2.0c
*/
// Construct a WSMAN communication object
function CreateWsmanComm(/*host, port, user, pass, tls, extra*/)
{
var obj = {};
obj.PendingAjax = []; // List of pending AJAX calls. When one frees up, another will start.
obj.ActiveAjaxCount = 0; // Number of currently active AJAX calls
obj.MaxActiveAjaxCount = 1; // Maximum number of activate AJAX calls at the same time.
obj.FailAllError = 0; // Set this to non-zero to fail all AJAX calls with that error status, 999 causes responses to be silent.
obj.digest = null;
obj.RequestCount = 0;
obj.requests = {};
if (arguments.length == 1 && typeof(arguments[0] == 'object'))
{
obj.host = arguments[0].host;
obj.port = arguments[0].port;
obj.authToken = arguments[0].authToken;
obj.tls = arguments[0].tls;
}
else
{
obj.host = arguments[0];
obj.port = arguments[1];
obj.user = arguments[2];
obj.pass = arguments[3];
obj.tls = arguments[4];
}
// Private method
// pri = priority, if set to 1, the call is high priority and put on top of the stack.
obj.PerformAjax = function (postdata, callback, tag, pri, url, action) {
if ((obj.ActiveAjaxCount == 0 || ((obj.ActiveAjaxCount < obj.MaxActiveAjaxCount) && (obj.challengeParams != null))) && obj.PendingAjax.length == 0) {
// There are no pending AJAX calls, perform the call now.
obj.PerformAjaxEx(postdata, callback, tag, url, action);
} else {
// If this is a high priority call, put this call in front of the array, otherwise put it in the back.
if (pri == 1) { obj.PendingAjax.unshift([postdata, callback, tag, url, action]); } else { obj.PendingAjax.push([postdata, callback, tag, url, action]); }
}
}
// Private method
obj.PerformNextAjax = function () {
if (obj.ActiveAjaxCount >= obj.MaxActiveAjaxCount || obj.PendingAjax.length == 0) return;
var x = obj.PendingAjax.shift();
obj.PerformAjaxEx(x[0], x[1], x[2], x[3], x[4]);
obj.PerformNextAjax();
}
// Private method
obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
if (!postdata) postdata = "";
//console.log("SEND: " + postdata); // DEBUG
// We are in a DukTape environement
if (obj.digest == null)
{
if (obj.authToken)
{
obj.digest = require('http-digest').create({ authToken: obj.authToken });
}
else
{
obj.digest = require('http-digest').create(obj.user, obj.pass);
}
obj.digest.http = require('http');
}
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { console.log('checkServerIdentity', JSON.stringify(cert)); } };
var req = obj.digest.request(request);
req.reqid = obj.RequestCount++;
obj.requests[req.reqid] = req; // Keep a reference to the request object so it does not get disposed.
//console.log('Request ' + (obj.RequestCount++));
req.on('error', function (e) { delete obj.requests[this.reqid]; obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
req.on('response', function (response) {
response.reqid = this.reqid;
//console.log('Response: ' + response.statusCode);
if (response.statusCode != 200) {
//console.log('ERR:' + JSON.stringify(response));
obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
} else {
response.acc = '';
response.on('data', function (data2) { this.acc += data2; });
response.on('end', function () { delete obj.requests[this.reqid]; obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
}
});
// Send POST body, this work with binary.
req.end(postdata);
obj.ActiveAjaxCount++;
return req;
}
// AJAX specific private method
obj.pendingAjaxCall = [];
// Private method
obj.gotNextMessages = function (data, status, request, callArgs) {
obj.ActiveAjaxCount--;
if (obj.FailAllError == 999) return;
//console.log("RECV: " + data); // DEBUG
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
if (request.status != 200) { callArgs[1](null, request.status, callArgs[2]); return; }
callArgs[1](data, 200, callArgs[2]);
obj.PerformNextAjax();
}
// Private method
obj.gotNextMessagesError = function (request, status, errorThrown, callArgs) {
obj.ActiveAjaxCount--;
if (obj.FailAllError == 999) return;
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
//if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); }
obj.PerformNextAjax();
}
// Cancel all pending queries with given status
obj.CancelAllQueries = function (s) {
while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
}
return obj;
}
module.exports = CreateWsmanComm;

View File

@ -0,0 +1,211 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @description Intel(r) AMT WSMAN Stack
* @author Ylian Saint-Hilaire
* @version v0.2.0
*/
// Construct a MeshServer object
function WsmanStackCreateService(/*CreateWsmanComm, host, port, user, pass, tls, extra*/)
{
var obj = {_ObjectID: 'WSMAN'};
//obj.onDebugMessage = null; // Set to a function if you want to get debug messages.
obj.NextMessageId = 1; // Next message number, used to label WSMAN calls.
obj.Address = '/wsman';
obj.xmlParser = require('amt-xml');
if (arguments.length == 1 && typeof (arguments[0] == 'object'))
{
var CreateWsmanComm = arguments[0].transport;
if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[0]); }
}
else
{
var CreateWsmanComm = arguments[0];
if (CreateWsmanComm) { obj.comm = new CreateWsmanComm(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]); }
}
obj.PerformAjax = function PerformAjax(postdata, callback, tag, pri, namespaces) {
if (namespaces == null) namespaces = '';
obj.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns=\"http://www.w3.org/2003/05/soap-envelope\" ' + namespaces + '><Header><a:Action>' + postdata, function (data, status, tag) {
if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; }
var wsresponse = obj.xmlParser.ParseWsman(data);
if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); }
}, tag, pri);
}
// Private method
//obj.Debug = function (msg) { /*console.log(msg);*/ }
// Cancel all pending queries with given status
obj.CancelAllQueries = function CancelAllQueries(s) { obj.comm.CancelAllQueries(s); }
// Get the last element of a URI string
obj.GetNameFromUrl = function (resuri) {
var x = resuri.lastIndexOf("/");
return (x == -1)?resuri:resuri.substring(x + 1);
}
// Perform a WSMAN Subscribe operation
obj.ExecSubscribe = function ExecSubscribe(resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) {
var digest = "", digest2 = "", opaque = "";
if (user != null && pass != null) { digest = '<t:IssuedTokens xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>' + user + '</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">' + pass + '</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>'; digest2 = '<w:Auth Profile="http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/digest"/>'; }
if (opaque != null) { opaque = '<a:ReferenceParameters><m:arg>' + opaque + '</m:arg></a:ReferenceParameters>'; }
if (delivery == 'PushWithAck') { delivery = 'dmtf.org/wbem/wsman/1/wsman/PushWithAck'; } else if (delivery == 'Push') { delivery = 'xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push'; }
var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + digest + '</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address>' + opaque + '</e:NotifyTo>' + digest2 + '</e:Delivery></e:Subscribe>';
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"');
}
// Perform a WSMAN UnSubscribe operation
obj.ExecUnSubscribe = function ExecUnSubscribe(resuri, callback, tag, pri, selectors) {
var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + '</Header><Body><e:Unsubscribe/>';
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"');
}
// Perform a WSMAN PUT operation
obj.ExecPut = function ExecPut(resuri, putobj, callback, tag, pri, selectors) {
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + '</Header><Body>' + _PutObjToBodyXml(resuri, putobj);
obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri);
}
// Perform a WSMAN CREATE operation
obj.ExecCreate = function ExecCreate(resuri, putobj, callback, tag, pri, selectors) {
var objname = obj.GetNameFromUrl(resuri);
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><g:" + objname + " xmlns:g=\"" + resuri + "\">";
for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" }
obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri);
}
// Perform a WSMAN DELETE operation
obj.ExecDelete = function ExecDelete(resuri, putobj, callback, tag, pri) {
var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(putobj) + "</Header><Body /></Envelope>";
obj.PerformAjax(data, callback, tag, pri);
}
// Perform a WSMAN GET operation
obj.ExecGet = function ExecGet(resuri, callback, tag, pri) {
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>", callback, tag, pri);
}
// Perform a WSMAN method call operation
obj.ExecMethod = function ExecMethod(resuri, method, args, callback, tag, pri, selectors) {
var argsxml = "";
for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "<r:" + i + ">" + args[i][x] + "</r:" + i + ">"; } } else { argsxml += "<r:" + i + ">" + args[i] + "</r:" + i + ">"; } } }
obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors);
}
// Perform a WSMAN method call operation. The arguments are already formatted in XML.
obj.ExecMethodXml = function ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors) {
obj.PerformAjax(resuri + "/" + method + "</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><r:" + method + '_INPUT' + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + method + "_INPUT></Body></Envelope>", callback, tag, pri);
}
// Perform a WSMAN ENUM operation
obj.ExecEnum = function ExecEnum(resuri, callback, tag, pri) {
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" /></Body></Envelope>", callback, tag, pri);
}
// Perform a WSMAN PULL operation
obj.ExecPull = function ExecPull(resuri, enumctx, callback, tag, pri) {
obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
}
function _PutObjToBodyXml(resuri, putObj) {
if (!resuri || putObj == null) return '';
var objname = obj.GetNameFromUrl(resuri);
var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
for (var prop in putObj) {
if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
if (Array.isArray(selectorArray)) {
for (var i=0; i< selectorArray.length; i++) {
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
}
}
else {
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
}
result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
}
else {
if (Array.isArray(putObj[prop])) {
for (var i = 0; i < putObj[prop].length; i++) {
result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
}
} else {
result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
}
}
}
result += '</r:' + objname + '>';
return result;
}
/*
convert
{ @Name: 'InstanceID', @AttrName: 'Attribute Value'}
into
' Name="InstanceID" AttrName="Attribute Value" '
*/
function _ObjectToXmlAttributes(objWithAttributes) {
if(!objWithAttributes) return '';
var result = ' ';
for (var propName in objWithAttributes) {
if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue;
result += propName.substring(1) + '="' + objWithAttributes[propName] + '" ';
}
return result;
}
function _PutObjToSelectorsXml(selectorSet) {
if (!selectorSet) return '';
if (typeof selectorSet == 'string') return selectorSet;
if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>";
var result = '<w:SelectorSet>';
for(var propName in selectorSet) {
if (!selectorSet.hasOwnProperty(propName)) continue;
result += '<w:Selector Name="' + propName + '">';
if (selectorSet[propName]['ReferenceParameters']) {
result += '<a:EndpointReference>';
result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>';
var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector'];
if (Array.isArray(selectorArray)) {
for (var i = 0; i < selectorArray.length; i++) {
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
}
} else {
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
}
result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>';
} else {
result += selectorSet[propName];
}
result += '</w:Selector>';
}
result += '</w:SelectorSet>';
return result;
}
return obj;
}
module.exports = WsmanStackCreateService;

View File

@ -0,0 +1,183 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Parse XML and return JSON
module.exports.ParseWsman = function (xml) {
try {
if (!xml.childNodes) xml = _turnToXml(xml);
var r = { Header: {} }, header = xml.getElementsByTagName("Header")[0], t;
if (!header) header = xml.getElementsByTagName("a:Header")[0];
if (!header) return null;
for (var i = 0; i < header.childNodes.length; i++) {
var child = header.childNodes[i];
r.Header[child.localName] = child.textContent;
}
var body = xml.getElementsByTagName("Body")[0];
if (!body) body = xml.getElementsByTagName("a:Body")[0];
if (!body) return null;
if (body.childNodes.length > 0) {
t = body.childNodes[0].localName;
if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); }
r.Header['Method'] = t;
r.Body = _ParseWsmanRec(body.childNodes[0]);
}
return r;
} catch (e) {
console.log("Unable to parse XML: " + xml);
return null;
}
}
// Private method
function _ParseWsmanRec(node) {
var data, r = {};
for (var i = 0; i < node.childNodes.length; i++) {
var child = node.childNodes[i];
if ((child.childElementCount == null) || (child.childElementCount == 0)) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
if (data == 'true') data = true; // Convert 'true' into true
if (data == 'false') data = false; // Convert 'false' into false
if ((parseInt(data) + '') === data) data = parseInt(data); // Convert integers
var childObj = data;
if ((child.attributes != null) && (child.attributes.length > 0)) {
childObj = { 'Value': data };
for (var j = 0; j < child.attributes.length; j++) {
childObj['@' + child.attributes[j].name] = child.attributes[j].value;
}
}
if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
else if (r[child.localName] == null) { r[child.localName] = childObj; }
else { r[child.localName] = [r[child.localName], childObj]; }
}
return r;
}
function _PutObjToBodyXml(resuri, putObj) {
if (!resuri || putObj == null) return '';
var objname = obj.GetNameFromUrl(resuri);
var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
for (var prop in putObj) {
if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
if (putObj[prop] == null || typeof putObj[prop] === 'function') continue;
if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
if (Array.isArray(selectorArray)) {
for (var i = 0; i < selectorArray.length; i++) {
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
}
}
else {
result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
}
result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
}
else {
if (Array.isArray(putObj[prop])) {
for (var i = 0; i < putObj[prop].length; i++) {
result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
}
} else {
result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
}
}
}
result += '</r:' + objname + '>';
return result;
}
// This is a drop-in replacement to _turnToXml() that works without xml parser dependency.
try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : null); } }); } catch (ex) { }
function _treeBuilder() {
this.tree = [];
this.push = function (element) { this.tree.push(element); };
this.pop = function () { var element = this.tree.pop(); if (this.tree.length > 0) { var x = this.tree.peek(); x.childNodes.push(element); x.childElementCount = x.childNodes.length; } return (element); };
this.peek = function () { return (this.tree.peek()); }
this.addNamespace = function (prefix, namespace) { this.tree.peek().nsTable[prefix] = namespace; if (this.tree.peek().attributes.length > 0) { for (var i = 0; i < this.tree.peek().attributes; ++i) { var a = this.tree.peek().attributes[i]; if (prefix == '*' && a.name == a.localName) { a.namespace = namespace; } else if (prefix != '*' && a.name != a.localName) { var pfx = a.name.split(':')[0]; if (pfx == prefix) { a.namespace = namespace; } } } } }
this.getNamespace = function (prefix) { for (var i = this.tree.length - 1; i >= 0; --i) { if (this.tree[i].nsTable[prefix] != null) { return (this.tree[i].nsTable[prefix]); } } return null; }
}
function _turnToXml(text) { if (text == null) return null; return ({ childNodes: [_turnToXmlRec(text)], getElementsByTagName: _getElementsByTagName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS }); }
function _getElementsByTagNameNS(ns, name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name && (node.namespace == ns || ns == '*')) { ret.push(node); } }); return ret; }
function _getElementsByTagName(name) { var ret = []; _xmlTraverseAllRec(this.childNodes, function (node) { if (node.localName == name) { ret.push(node); } }); return ret; }
function _getChildElementsByTagName(name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name) { ret.push(this.childNodes[node]); } } } return (ret); }
function _getChildElementsByTagNameNS(ns, name) { var ret = []; if (this.childNodes != null) { for (var node in this.childNodes) { if (this.childNodes[node].localName == name && (ns == '*' || this.childNodes[node].namespace == ns)) { ret.push(this.childNodes[node]); } } } return (ret); }
function _xmlTraverseAllRec(nodes, func) { for (var i in nodes) { func(nodes[i]); if (nodes[i].childNodes) { _xmlTraverseAllRec(nodes[i].childNodes, func); } } }
function _turnToXmlRec(text) {
var elementStack = new _treeBuilder(), lastElement = null, x1 = text.split('<'), ret = [], element = null, currentElementName = null;
for (var i in x1) {
var x2 = x1[i].split('>'), x3 = x2[0].split(' '), elementName = x3[0];
if ((elementName.length > 0) && (elementName[0] != '?')) {
if (elementName[0] != '/') {
var attributes = [], localName, localname2 = elementName.split(' ')[0].split(':'), localName = (localname2.length > 1) ? localname2[1] : localname2[0];
Object.defineProperty(attributes, "get",
{
value: function () {
if (arguments.length == 1) {
for (var a in this) { if (this[a].name == arguments[0]) { return (this[a]); } }
}
else if (arguments.length == 2) {
for (var a in this) { if (this[a].name == arguments[1] && (arguments[0] == '*' || this[a].namespace == arguments[0])) { return (this[a]); } }
}
else {
throw ('attributes.get(): Invalid number of parameters');
}
}
});
elementStack.push({ name: elementName, localName: localName, getChildElementsByTagName: _getChildElementsByTagName, getElementsByTagNameNS: _getElementsByTagNameNS, getChildElementsByTagNameNS: _getChildElementsByTagNameNS, attributes: attributes, childNodes: [], nsTable: {} });
// Parse Attributes
if (x3.length > 0) {
var skip = false;
for (var j in x3) {
if (x3[j] == '/') {
// This is an empty Element
elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
elementStack.peek().textContent = '';
lastElement = elementStack.pop();
skip = true;
break;
}
var k = x3[j].indexOf('=');
if (k > 0) {
var attrName = x3[j].substring(0, k);
var attrValue = x3[j].substring(k + 2, x3[j].length - 1);
var attrNS = elementStack.getNamespace('*');
if (attrName == 'xmlns') {
elementStack.addNamespace('*', attrValue);
attrNS = attrValue;
} else if (attrName.startsWith('xmlns:')) {
elementStack.addNamespace(attrName.substring(6), attrValue);
} else {
var ax = attrName.split(':');
if (ax.length == 2) { attrName = ax[1]; attrNS = elementStack.getNamespace(ax[0]); }
}
var x = { name: attrName, value: attrValue }
if (attrNS != null) x.namespace = attrNS;
elementStack.peek().attributes.push(x);
}
}
if (skip) { continue; }
}
elementStack.peek().namespace = elementStack.peek().name == elementStack.peek().localName ? elementStack.getNamespace('*') : elementStack.getNamespace(elementStack.peek().name.substring(0, elementStack.peek().name.indexOf(':')));
if (x2[1]) { elementStack.peek().textContent = x2[1]; }
} else { lastElement = elementStack.pop(); }
}
}
return lastElement;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// JavaScript source code
var GM = require('_GenericMarshal');
function processManager() {
this._ObjectID = 'processManager';
switch (process.platform) {
case 'win32':
this._kernel32 = GM.CreateNativeProxy('kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
this._kernel32.CreateMethod('CreateToolhelp32Snapshot');
this._kernel32.CreateMethod('Process32First');
this._kernel32.CreateMethod('Process32Next');
break;
case 'linux':
this._childProcess = require('child_process');
break;
default:
throw (process.platform + ' not supported');
}
this.getProcesses = function getProcesses(callback) {
switch (process.platform) {
default:
throw ('Enumerating processes on ' + process.platform + ' not supported');
case 'win32':
var retVal = {};
var h = this._kernel32.CreateToolhelp32Snapshot(2, 0);
var info = GM.CreateVariable(304);
info.toBuffer().writeUInt32LE(304, 0);
var nextProcess = this._kernel32.Process32First(h, info);
while (nextProcess.Val) {
retVal[info.Deref(8, 4).toBuffer().readUInt32LE(0)] = { cmd: info.Deref(GM.PointerSize == 4 ? 36 : 44, 260).String };
nextProcess = this._kernel32.Process32Next(h, info);
}
if (callback) { callback.apply(this, [retVal]); }
break;
case 'linux':
if (!this._psp) { this._psp = {}; }
var p = this._childProcess.execFile("/bin/ps", ["ps", "-uxa"], { type: this._childProcess.SpawnTypes.TERM });
this._psp[p.pid] = p;
p.Parent = this;
p.ps = '';
p.callback = callback;
p.args = [];
for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
p.on('exit', function onGetProcesses() {
delete this.Parent._psp[this.pid];
var retVal = {}, lines = this.ps.split('\x0D\x0A'), key = {}, keyi = 0;
for (var i in lines) {
var tokens = lines[i].split(' ');
var tokenList = [];
for (var x in tokens) {
if (i == 0 && tokens[x]) { key[tokens[x]] = keyi++; }
if (i > 0 && tokens[x]) { tokenList.push(tokens[x]); }
}
if ((i > 0) && (tokenList[key.PID])) {
retVal[tokenList[key.PID]] = { user: tokenList[key.USER], cmd: tokenList[key.COMMAND] };
}
}
if (this.callback) {
this.args.unshift(retVal);
this.callback.apply(this.parent, this.args);
}
});
p.stdout.on('data', function (chunk) { this.parent.ps += chunk.toString(); });
break;
}
};
this.getProcessInfo = function getProcessInfo(pid) {
switch (process.platform) {
default:
throw ('getProcessInfo() not supported for ' + process.platform);
case 'linux':
var status = require('fs').readFileSync('/proc/' + pid + '/status'), info = {}, lines = status.toString().split('\n');
for (var i in lines) {
var tokens = lines[i].split(':');
if (tokens.length > 1) { tokens[1] = tokens[1].trim(); }
info[tokens[0]] = tokens[1];
}
return (info);
}
};
}
module.exports = new processManager();

View File

@ -0,0 +1,284 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
try { Object.defineProperty(String.prototype, "replaceAll", { value: function replaceAll(oldVal, newVal) { return (this.split(oldVal).join(newVal)); } }); } catch (e) { }
var RSMB = 1381190978;
var memoryLocation = { 0x1: 'Other', 0x2: 'Unknown', 0x3: 'System Board', 0x4: 'ISA', 0x5: 'EISA', 0x6: 'PCI', 0x7: 'MCA', 0x8: 'PCMCIA', 0x9: 'Proprietary', 0xA: 'NuBus', 0xA0: 'PC-98/C20', 0xA1: 'PC-98/C24', 0xA2: 'PC-98/E', 0xA3: 'PC-98/LB' };
var wakeReason = ['Reserved', 'Other', 'Unknown', 'APM Timer', 'Modem Ring', 'LAN', 'Power Switch', 'PCI', 'AC Power'];
function SMBiosTables() {
this._ObjectID = 'SMBiosTable';
if (process.platform == 'win32') {
this._marshal = require('_GenericMarshal');
this._native = this._marshal.CreateNativeProxy("Kernel32.dll");
this._native.CreateMethod('EnumSystemFirmwareTables');
this._native.CreateMethod('GetSystemFirmwareTable');
}
if (process.platform == 'linux') {
this._canonicalizeData = function _canonicalizeData(data) {
var lines = data.toString().split('Header and Data:\x0A');
var MemoryStream = require('MemoryStream');
var ms = new MemoryStream();
for (var i = 1; i < lines.length; ++i) {
var tokens = lines[i].split('Strings:\x0A');
var header = tokens[0].split('\x0A\x0A')[0].replaceAll('\x0A', '').trim().replaceAll(' ', '').replaceAll('\x09', '');
ms.write(Buffer.from(header, 'hex'));
if (tokens.length > 1) {
var strings = tokens[1].split('\x0A\x0A')[0].split('\x0A');
var stringsFinal = [];
for (var strx in strings) {
var tmp = strings[strx].trim().replaceAll(' ', '').replaceAll('\x09', '');
if (!(tmp[0] == '"')) { stringsFinal.push(tmp); }
}
ms.write(Buffer.from(stringsFinal.join(''), 'hex'));
ms.write(Buffer.from('00', 'hex'));
}
else {
ms.write(Buffer.from('0000', 'hex'));
}
}
var retVal = ms.buffer;
retVal.ms = ms;
return (retVal);
};
}
this._parse = function _parse(SMData) {
var ret = {};
var pbyte;
var i = 0
var SMData;
var structcount = 0;
while (SMData && i < SMData.length) {
var SMtype = SMData[i];
var SMlength = SMData[i + 1];
if (!ret[SMtype]) { ret[SMtype] = []; }
ret[SMtype].push(SMData.slice(i + 4, i + SMlength));
if (process.platform == 'win32') { ret[SMtype].peek()._ext = pbyte; }
i += SMlength;
ret[SMtype].peek()._strings = [];
while (SMData[i] != 0) {
var strstart = i;
// Start of String, find end of string
while (SMData[i++] != 0);
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
}
i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
++structcount;
//console.log('End of Table[' + SMtype + ']: ' + i);
}
//console.log('Struct Count = ' + structcount);
return (ret);
};
this.get = function get(callback) {
if (process.platform == 'win32') {
var size = this._native.GetSystemFirmwareTable(RSMB, 0, 0, 0).Val;
//console.log('Table Size: ' + size);
var PtrSize = this._marshal.CreatePointer()._size;
var buffer = this._marshal.CreateVariable(size);
var written = this._native.GetSystemFirmwareTable(RSMB, 0, buffer, size).Val;
//console.log('Written Size: ' + written);
var rawBuffer = buffer.toBuffer();
var length = buffer.Deref(4, 4).toBuffer().readUInt32LE(0);
pbyte = buffer.Deref(8, length);
SMData = pbyte.toBuffer();
if (callback) { callback.apply(this, [this._parse(SMData)]); return; } else { return (this._parse(SMData)); }
}
if (process.platform == 'linux') {
var MemoryStream = require('MemoryStream');
this.child = require('child_process').execFile('/usr/sbin/dmidecode', ['dmidecode', '-u']);
this.child.SMBiosTable = this;
this.child.ms = new MemoryStream();
this.child.ms.callback = callback
this.child.ms.child = this.child;
this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
this.child.on('exit', function () { this.ms.end(); });
this.child.ms.on('end', function () {
//console.log('read ' + this.buffer.length + ' bytes');
if (this.buffer.length < 300) { // TODO: Trap error message better that this.
console.log('Not enough permission to read SMBiosTable');
if (this.callback) { this.callback.apply(this.child.SMBiosTable, []); }
}
else {
var SMData = this.child.SMBiosTable._canonicalizeData(this.buffer);
var j = this.child.SMBiosTable._parse(SMData);
if (this.callback) { this.callback.apply(this.child.SMBiosTable, [j]); }
}
});
return;
}
throw (process.platform + ' not supported');
};
this.parse = function parse(data) {
var r = {};
r.processorInfo = this.processorInfo(data);
r.memoryInfo = this.memoryInfo(data);
r.systemInfo = this.systemInfo(data);
r.systemSlots = this.systemInfo(data);
r.amtInfo = this.amtInfo(data);
return r;
}
this.processorInfo = function processorInfo(data) {
if (!data) { throw ('no data'); }
var ret = [];
var ptype = ['ERROR', 'Other', 'Unknown', 'CPU', 'ALU', 'DSP', 'GPU'];
var statusString = ['Unknown', 'Enabled', 'Disabled by user', 'Disabled by BIOS', 'Idle', 'Reserved', 'Reserved', 'Other'];
var cpuid = 0;
while (data[4] && data[4].length > 0) {
var p = data[4].pop();
var populated = p[20] & 0x40;
var status = p[20] & 0x07
if (populated) {
var j = { _ObjectID: 'SMBiosTables.processorInfo' };
j.Processor = ptype[p[1]];
j.MaxSpeed = p.readUInt16LE(16) + ' Mhz';
if (p[31]) { j.Cores = p[31]; }
if (p[33]) { j.Threads = p[33]; }
j.Populated = 1;
j.Status = statusString[status];
j.Socket = p._strings[p[0] - 1];
j.Manufacturer = p._strings[p[3] - 1];
j.Version = p._strings[p[12] - 1];
ret.push(j);
}
}
return (ret);
};
this.memoryInfo = function memoryInfo(data) {
if (!data) { throw ('no data'); }
var retVal = { _ObjectID: 'SMBiosTables.memoryInfo' };
if (data[16]) {
var m = data[16].peek();
retVal.location = memoryLocation[m[0]];
if ((retVal.maxCapacityKb = m.readUInt32LE(3)) == 0x80000000) {
retVal.maxCapacityKb = 'A really big number';
}
}
return (retVal);
};
this.systemInfo = function systemInfo(data) {
if (!data) { throw ('no data'); }
var retVal = { _ObjectID: 'SMBiosTables.systemInfo' };
if (data[1]) {
var si = data[1].peek();
retVal.uuid = si.slice(4, 20).toString('hex');
retVal.wakeReason = wakeReason[si[20]];
}
return (retVal);
};
this.systemSlots = function systemSlots(data) {
if (!data) { throw ('no data'); }
var retVal = [];
if (data[9]) {
while (data[9].length > 0) {
var ss = data[9].pop();
retVal.push({ name: ss._strings[ss[0] - 1] });
}
}
return (retVal);
};
this.amtInfo = function amtInfo(data) {
if (!data) { throw ('no data'); }
var retVal = { AMT: false };
if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') {
var amt = data[130].peek();
retVal.AMT = amt[4] ? true : false;
if (retVal.AMT) {
retVal.enabled = amt[5] ? true : false;
retVal.storageRedirection = amt[6] ? true : false;
retVal.serialOverLan = amt[7] ? true : false;
retVal.kvm = amt[14] ? true : false;
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') {
var settings = data[131].peek();
if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; }
if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; }
retVal.MEBX = settings.readUInt16LE(10).toString() + '.' + settings.readUInt16LE(8).toString() + '.' + settings.readUInt16LE(6).toString() + '.' + settings.readUInt16LE(4).toString();
var mecap = settings.slice(20, 32);
retVal.ManagementEngine = mecap.readUInt16LE(6).toString() + '.' + mecap.readUInt16LE(4).toString() + '.' + mecap.readUInt16LE(2).toString() + '.' + mecap.readUInt16LE(0).toString();
//var lan = settings.slice(36, 48);
//console.log(lan.toString('hex'));
//retVal.LAN = (lan.readUInt16LE(10) & 0x03).toString() + '/' + ((lan.readUInt16LE(10) & 0xF8) >> 3).toString();
//console.log(lan.readUInt16LE(3));
//retVal.WLAN = (lan.readUInt16LE(3) & 0x07).toString() + '/' + ((lan.readUInt16LE(3) & 0xF8) >> 3).toString() + '/' + (lan.readUInt16LE(3) >> 8).toString();
}
}
}
return (retVal);
};
this.smTableTypes = {
0: 'BIOS information',
1: 'System information',
2: 'Baseboard (or Module) information',
4: 'Processor information',
5: 'memory controller information',
6: 'Memory module information',
7: 'Cache information',
8: 'Port connector information',
9: 'System slots',
10: 'On board devices information',
11: 'OEM strings',
12: 'System configuration options',
13: 'BIOS language information',
14: 'Group associations',
15: 'System event log',
16: 'Physical memory array',
17: 'Memory device',
18: '32bit memory error information',
19: 'Memory array mapped address',
20: 'Memory device mapped address',
21: 'Built-in pointing device',
22: 'Portable battery',
23: 'System reset',
24: 'Hardware security',
25: 'System power controls',
26: 'Voltage probe',
27: 'Cooling device',
28: 'Temperature probe',
29: 'Electrical current probe',
30: 'Out-of-band remote access',
31: 'Boot integrity services (BIS) entry point',
32: 'System boot information',
33: '64bit memory error information',
34: 'Management device',
35: 'Management device component',
36: 'Management device threshold data',
37: 'Memory channel',
38: 'IPMI device information',
39: 'System power supply',
40: 'Additional information',
41: 'Onboard devices extended information',
42: 'Management controller host interface',
126: 'Inactive',
127: 'End-of-table'
}
}
module.exports = new SMBiosTables();

View File

@ -0,0 +1,72 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var toasters = {};
function Toaster()
{
this._ObjectID = 'Toaster';
this.Toast = function Toast(title, caption)
{
if (process.platform != 'win32') return;
var retVal = {};
var emitter = require('events').inherits(retVal);
emitter.createEvent('Clicked');
emitter.createEvent('Dismissed');
var session = require('user-sessions').Current();
for (var i in session)
{
console.log(session[i]);
}
try
{
console.log('Attempting Toast Mechanism 1');
retVal._child = require('ScriptContainer').Create({ processIsolation: true, sessionId: session.connected[0].SessionId });
}
catch (e) {
console.log(e);
console.log('Attempting Toast Mechanism 2');
retVal._child = require('ScriptContainer').Create({ processIsolation: true });
}
retVal._child.parent = retVal;
retVal._child.on('exit', function (code) { this.parent.emit('Dismissed'); delete this.parent._child; });
retVal._child.addModule('win-console', getJSModule('win-console'));
retVal._child.addModule('win-messagepump', getJSModule('win-messagepump'));
var str = "\
try{\
var toast = require('win-console');\
var balloon = toast.SetTrayIcon({ szInfo: '" + caption + "', szInfoTitle: '" + title + "', balloonOnly: true });\
balloon.on('ToastDismissed', function(){process.exit();});\
}\
catch(e)\
{\
require('ScriptContainer').send(e);\
}\
require('ScriptContainer').send('done');\
";
retVal._child.ExecuteString(str);
toasters[retVal._hashCode()] = retVal;
retVal.on('Dismissed', function () { delete toasters[this._hashCode()]; });
console.log('Returning');
return (retVal);
};
}
module.exports = new Toaster();

View File

@ -0,0 +1,167 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
function UserSessions()
{
this._ObjectID = 'UserSessions';
if (process.platform == 'win32') {
this._marshal = require('_GenericMarshal');
this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll');
this._wts.CreateMethod('WTSEnumerateSessionsA');
this._wts.CreateMethod('WTSQuerySessionInformationA');
this._wts.CreateMethod('WTSFreeMemory');
this.SessionStates = ['Active', 'Connected', 'ConnectQuery', 'Shadow', 'Disconnected', 'Idle', 'Listening', 'Reset', 'Down', 'Init'];
this.InfoClass =
{
'WTSInitialProgram': 0,
'WTSApplicationName': 1,
'WTSWorkingDirectory': 2,
'WTSOEMId': 3,
'WTSSessionId': 4,
'WTSUserName': 5,
'WTSWinStationName': 6,
'WTSDomainName': 7,
'WTSConnectState': 8,
'WTSClientBuildNumber': 9,
'WTSClientName': 10,
'WTSClientDirectory': 11,
'WTSClientProductId': 12,
'WTSClientHardwareId': 13,
'WTSClientAddress': 14,
'WTSClientDisplay': 15,
'WTSClientProtocolType': 16,
'WTSIdleTime': 17,
'WTSLogonTime': 18,
'WTSIncomingBytes': 19,
'WTSOutgoingBytes': 20,
'WTSIncomingFrames': 21,
'WTSOutgoingFrames': 22,
'WTSClientInfo': 23,
'WTSSessionInfo': 24,
'WTSSessionInfoEx': 25,
'WTSConfigInfo': 26,
'WTSValidationInfo': 27,
'WTSSessionAddressV4': 28,
'WTSIsRemoteSession': 29
};
this.getSessionAttribute = function getSessionAttribute(sessionId, attr)
{
var buffer = this._marshal.CreatePointer();
var bytesReturned = this._marshal.CreateVariable(4);
if (this._wts.WTSQuerySessionInformationA(0, sessionId, attr, buffer, bytesReturned).Val == 0)
{
throw ('Error calling WTSQuerySessionInformation: ' + this._kernel32.GetLastError.Val);
}
var retVal = buffer.Deref().String;
this._wts.WTSFreeMemory(buffer.Deref());
return (retVal);
};
this.Current = function Current()
{
var retVal = {};
var pinfo = this._marshal.CreatePointer();
var count = this._marshal.CreateVariable(4);
if (this._wts.WTSEnumerateSessionsA(0, 0, 1, pinfo, count).Val == 0)
{
throw ('Error calling WTSEnumerateSessionsA: ' + this._kernel32.GetLastError().Val);
}
for (var i = 0; i < count.toBuffer().readUInt32LE() ; ++i)
{
var info = pinfo.Deref().Deref(i * (this._marshal.PointerSize == 4 ? 12 : 24), this._marshal.PointerSize == 4 ? 12 : 24);
var j = { SessionId: info.toBuffer().readUInt32LE() };
j.StationName = info.Deref(this._marshal.PointerSize == 4 ? 4 : 8, this._marshal.PointerSize).Deref().String;
j.State = this.SessionStates[info.Deref(this._marshal.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE()];
if (j.State == 'Active') {
j.Username = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSUserName);
j.Domain = this.getSessionAttribute(j.SessionId, this.InfoClass.WTSDomainName);
}
retVal[j.SessionId] = j;
}
this._wts.WTSFreeMemory(pinfo.Deref());
Object.defineProperty(retVal, 'connected', { value: showActiveOnly(retVal) });
return (retVal);
};
}
else
{
this.Current = function Current()
{
var retVal = {};
var emitterUtils = require('events').inherits(retVal);
emitterUtils.createEvent('logon');
retVal._child = require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']);
retVal._child.Parent = retVal;
retVal._child._txt = '';
retVal._child.on('exit', function (code)
{
var lines = this._txt.split('\n');
var sessions = [];
for(var i in lines)
{
if (lines[i])
{
console.log(getTokens(lines[i]));
var user = lines[i].substring(0, lines[i].indexOf(' '));
sessions.push(user);
}
}
sessions.pop();
console.log(sessions);
});
retVal._child.stdout.Parent = retVal._child;
retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); });
return (retVal);
}
}
}
function showActiveOnly(source)
{
var retVal = [];
for (var i in source)
{
if (source[i].State == 'Active' || source[i].State == 'Connected')
{
retVal.push(source[i]);
}
}
return (retVal);
}
function getTokens(str)
{
var columns = [];
var i;
columns.push(str.substring(0, (i=str.indexOf(' '))));
while (str[++i] == ' ');
columns.push(str.substring(i, str.substring(i).indexOf(' ') + i));
return (columns);
}
module.exports = new UserSessions();

View File

@ -0,0 +1,171 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
function _Scan()
{
var wlanInterfaces = this.Marshal.CreatePointer();
this.Native.WlanEnumInterfaces(this.Handle, 0, wlanInterfaces);
var count = wlanInterfaces.Deref().Deref(0, 4).toBuffer().readUInt32LE(0);
var info = wlanInterfaces.Deref().Deref(8, 532);
var iname = info.Deref(16, 512).AnsiString;
var istate;
switch (info.Deref(528, 4).toBuffer().readUInt32LE(0))
{
case 0:
istate = "NOT READY";
break;
case 1:
istate = "CONNECTED";
break;
case 2:
istate = "AD-HOC";
break;
case 3:
istate = "DISCONNECTING";
break;
case 4:
istate = "DISCONNECTED";
break;
case 5:
istate = "ASSOCIATING";
break;
case 6:
istate = "DISCOVERING";
break;
case 7:
istate = "AUTHENTICATING";
break;
default:
istate = "UNKNOWN";
break;
}
var iguid = info.Deref(0, 16);
if (this.Native.WlanScan(this.Handle, iguid, 0, 0, 0).Val == 0)
{
return (true);
}
else
{
return (false);
}
}
function AccessPoint(_ssid, _bssid, _rssi, _lq)
{
this.ssid = _ssid;
this.bssid = _bssid;
this.rssi = _rssi;
this.lq = _lq;
}
AccessPoint.prototype.toString = function()
{
return (this.ssid + " [" + this.bssid + "]: " + this.lq);
}
function OnNotify(NotificationData)
{
var NotificationSource = NotificationData.Deref(0, 4).toBuffer().readUInt32LE(0);
var NotificationCode = NotificationData.Deref(4, 4).toBuffer().readUInt32LE(0);
var dataGuid = NotificationData.Deref(8, 16);
if ((NotificationSource & 0X00000008) && (NotificationCode == 7))
{
var bss = this.Parent.Marshal.CreatePointer();
var result = this.Parent.Native.GetBSSList(this.Parent.Handle, dataGuid, 0, 3, 0, 0, bss).Val;
if (result == 0)
{
var totalSize = bss.Deref().Deref(0, 4).toBuffer().readUInt32LE(0);
var numItems = bss.Deref().Deref(4, 4).toBuffer().readUInt32LE(0);
for (i = 0; i < numItems; ++i)
{
var item = bss.Deref().Deref(8 + (360 * i), 360);
var ssid = item.Deref(4, 32).String.trim();
var bssid = item.Deref(40, 6).HexString2;
var rssi = item.Deref(56, 4).toBuffer().readUInt32LE(0);
var lq = item.Deref(60, 4).toBuffer().readUInt32LE(0);
this.Parent.emit('Scan', new AccessPoint(ssid, bssid, rssi, lq));
}
}
}
}
function Wireless()
{
var emitterUtils = require('events').inherits(this);
this.Marshal = require('_GenericMarshal');
this.Native = this.Marshal.CreateNativeProxy("wlanapi.dll");
this.Native.CreateMethod("WlanOpenHandle");
this.Native.CreateMethod("WlanGetNetworkBssList", "GetBSSList");
this.Native.CreateMethod("WlanRegisterNotification");
this.Native.CreateMethod("WlanEnumInterfaces");
this.Native.CreateMethod("WlanScan");
this.Native.CreateMethod("WlanQueryInterface");
var negotiated = this.Marshal.CreatePointer();
var h = this.Marshal.CreatePointer();
this.Native.WlanOpenHandle(2, 0, negotiated, h);
this.Handle = h.Deref();
this._NOTIFY_PROXY_OBJECT = this.Marshal.CreateCallbackProxy(OnNotify, 2);
this._NOTIFY_PROXY_OBJECT.Parent = this;
var PrevSource = this.Marshal.CreatePointer();
var result = this.Native.WlanRegisterNotification(this.Handle, 0X0000FFFF, 0, this._NOTIFY_PROXY_OBJECT.Callback, this._NOTIFY_PROXY_OBJECT.State, 0, PrevSource);
emitterUtils.createEvent('Scan');
emitterUtils.addMethod('Scan', _Scan);
this.GetConnectedNetwork = function ()
{
var interfaces = this.Marshal.CreatePointer();
console.log('Success = ' + this.Native.WlanEnumInterfaces(this.Handle, 0, interfaces).Val);
var count = interfaces.Deref().Deref(0, 4).toBuffer().readUInt32LE(0);
var info = interfaces.Deref().Deref(8, 532);
var iname = info.Deref(16, 512).AnsiString;
var istate = info.Deref(528, 4).toBuffer().readUInt32LE(0);
if(info.Deref(528, 4).toBuffer().readUInt32LE(0) == 1) // CONNECTED
{
var dataSize = this.Marshal.CreatePointer();
var pData = this.Marshal.CreatePointer();
var valueType = this.Marshal.CreatePointer();
var iguid = info.Deref(0, 16);
var retVal = this.Native.WlanQueryInterface(this.Handle, iguid, 7, 0, dataSize, pData, valueType).Val;
if (retVal == 0)
{
var associatedSSID = pData.Deref().Deref(524, 32).String;
var bssid = pData.Deref().Deref(560, 6).HexString;
var lq = pData.Deref().Deref(576, 4).toBuffer().readUInt32LE(0);
return (new AccessPoint(associatedSSID, bssid, 0, lq));
}
}
throw ("GetConnectedNetworks: FAILED (not associated to a network)");
};
return (this);
}
module.exports = new Wireless();

View File

@ -0,0 +1,126 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var MemoryStream = require('MemoryStream');
var WindowsChildScript = 'var parent = require("ScriptContainer");var Wireless = require("wifi-scanner-windows");Wireless.on("Scan", function (ap) { parent.send(ap); });Wireless.Scan();';
function AccessPoint(_ssid, _bssid, _lq)
{
this.ssid = _ssid;
this.bssid = _bssid;
this.lq = _lq;
}
AccessPoint.prototype.toString = function ()
{
return ("[" + this.bssid + "]: " + this.ssid + " (" + this.lq + ")");
//return (this.ssid + " [" + this.bssid + "]: " + this.lq);
}
function WiFiScanner()
{
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('accessPoint');
this.hasWireless = function ()
{
var retVal = false;
var interfaces = require('os').networkInterfaces();
for (var name in interfaces)
{
if (interfaces[name][0].type == 'wireless') { retVal = true; break; }
}
return (retVal);
};
this.Scan = function ()
{
if (process.platform == 'win32')
{
this.master = require('ScriptContainer').Create(15, ContainerPermissions.DEFAULT);
this.master.parent = this;
this.master.on('data', function (j) { this.parent.emit('accessPoint', new AccessPoint(j.ssid, j.bssid, j.lq)); });
this.master.addModule('wifi-scanner-windows', getJSModule('wifi-scanner-windows'));
this.master.ExecuteString(WindowsChildScript);
}
else if (process.platform == 'linux')
{
// Need to get the wireless interface name
var interfaces = require('os').networkInterfaces();
var wlan = null;
for (var i in interfaces)
{
if (interfaces[i][0].type == 'wireless')
{
wlan = i;
break;
}
}
if (wlan != null)
{
this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']);
this.child.parent = this;
this.child.ms = new MemoryStream();
this.child.ms.parent = this.child;
this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
this.child.on('exit', function () { this.ms.end(); });
this.child.ms.on('end', function ()
{
var str = this.buffer.toString();
tokens = str.split(' - Address: ');
for (var block in tokens)
{
if (block == 0) continue;
var ln = tokens[block].split('\n');
var _bssid = ln[0];
var _lq;
var _ssid;
for (var lnblock in ln)
{
lnblock = ln[lnblock].trim();
lnblock = lnblock.trim();
if (lnblock.startsWith('ESSID:'))
{
_ssid = lnblock.slice(7, lnblock.length - 1);
if (_ssid == '<hidden>') { _ssid = ''; }
}
if (lnblock.startsWith('Signal level='))
{
_lq = lnblock.slice(13,lnblock.length-4);
}
else if (lnblock.startsWith('Quality='))
{
_lq = lnblock.slice(8, 10);
var scale = lnblock.slice(11, 13);
}
}
this.parent.parent.emit('accessPoint', new AccessPoint(_ssid, _bssid, _lq));
}
});
}
}
}
}
module.exports = WiFiScanner;

View File

@ -0,0 +1,164 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var TrayIconFlags =
{
NIF_MESSAGE: 0x00000001,
NIF_ICON: 0x00000002,
NIF_TIP: 0x00000004,
NIF_STATE: 0x00000008,
NIF_INFO: 0x00000010,
NIF_GUID: 0x00000020,
NIF_REALTIME: 0x00000040,
NIF_SHOWTIP: 0x00000080,
NIM_ADD: 0x00000000,
NIM_MODIFY: 0x00000001,
NIM_DELETE: 0x00000002,
NIM_SETFOCUS: 0x00000003,
NIM_SETVERSION: 0x00000004
};
var NOTIFYICON_VERSION_4 = 4;
var MessageTypes = { WM_APP: 0x8000, WM_USER: 0x0400 };
function WindowsConsole()
{
if (process.platform == 'win32')
{
this._ObjectID = 'WindowsConsole';
this._Marshal = require('_GenericMarshal');
this._kernel32 = this._Marshal.CreateNativeProxy("kernel32.dll");
this._user32 = this._Marshal.CreateNativeProxy("user32.dll");
this._kernel32.CreateMethod("GetConsoleWindow");
this._kernel32.CreateMethod('GetCurrentThread');
this._user32.CreateMethod("ShowWindow");
this._user32.CreateMethod("LoadImageA");
this._user32.CreateMethod({ method: 'GetMessageA', threadDispatch: 1 });
this._shell32 = this._Marshal.CreateNativeProxy('Shell32.dll');
this._shell32.CreateMethod('Shell_NotifyIconA');
this._handle = this._kernel32.GetConsoleWindow();
this.minimize = function () {
this._user32.ShowWindow(this._handle, 6);
};
this.restore = function () {
this._user32.ShowWindow(this._handle, 9);
};
this.hide = function () {
this._user32.ShowWindow(this._handle, 0);
};
this.show = function () {
this._user32.ShowWindow(this._handle, 5);
};
this._loadicon = function (imagePath) {
var h = this._user32.LoadImageA(0, this._Marshal.CreateVariable(imagePath), 1, 0, 0, 0x00000010 | 0x00008000 | 0x00000040); // LR_LOADFROMFILE | LR_SHARED | LR_DEFAULTSIZE
return (h);
};
this.SetTrayIcon = function SetTrayIcon(options)
{
var data = this._Marshal.CreateVariable(this._Marshal.PointerSize == 4 ? 508 : 528);
//console.log('struct size = ' + data._size);
//console.log('TryIcon, WM_MESSAGE filter = ' + options.filter);
data.toBuffer().writeUInt32LE(data._size, 0);
var trayType = TrayIconFlags.NIF_TIP | TrayIconFlags.NIF_MESSAGE
options.filter = MessageTypes.WM_APP + 1;
data.Deref(this._Marshal.PointerSize == 4 ? 16 : 24, 4).toBuffer().writeUInt32LE(options.filter);
if (!options.noBalloon) { trayType |= TrayIconFlags.NIF_INFO; }
if (options.icon)
{
trayType |= TrayIconFlags.NIF_ICON;
var hIcon = data.Deref(this._Marshal.PointerSize == 4 ? 20 : 32, this._Marshal.PointerSize);
options.icon.pointerBuffer().copy(hIcon.toBuffer());
}
data.Deref(this._Marshal.PointerSize * 2, 4).toBuffer().writeUInt32LE(1);
data.Deref(this._Marshal.PointerSize == 4 ? 12 : 20, 4).toBuffer().writeUInt32LE(trayType);
data.Deref(this._Marshal.PointerSize == 4 ? 416 : 432, 4).toBuffer().writeUInt32LE(NOTIFYICON_VERSION_4);
var szTip = data.Deref(this._Marshal.PointerSize == 4 ? 24 : 40, 128);
var szInfo = data.Deref(this._Marshal.PointerSize == 4 ? 160 : 176, 256);
var szInfoTitle = data.Deref(this._Marshal.PointerSize == 4 ? 420 : 436, 64);
if (options.szTip) { Buffer.from(options.szTip).copy(szTip.toBuffer()); }
if (options.szInfo) { Buffer.from(options.szInfo).copy(szInfo.toBuffer()); }
if (options.szInfoTitle) { Buffer.from(options.szInfoTitle).copy(szInfoTitle.toBuffer()); }
var MessagePump = require('win-messagepump');
retVal = { _ObjectID: 'WindowsConsole.TrayIcon', MessagePump: new MessagePump(options) };
var retValEvents = require('events').inherits(retVal);
retValEvents.createEvent('ToastClicked');
retValEvents.createEvent('IconHover');
retValEvents.createEvent('ToastDismissed');
retVal.Options = options;
retVal.MessagePump.TrayIcon = retVal;
retVal.MessagePump.NotifyData = data;
retVal.MessagePump.WindowsConsole = this;
retVal.MessagePump.on('exit', function onExit(code) { console.log('Pump Exited'); if (this.TrayIcon) { this.TrayIcon.remove(); } });
retVal.MessagePump.on('hwnd', function onHwnd(h)
{
//console.log('Got HWND');
options.hwnd = h;
h.pointerBuffer().copy(this.NotifyData.Deref(this.WindowsConsole._Marshal.PointerSize, this.WindowsConsole._Marshal.PointerSize).toBuffer());
if(this.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_ADD, this.NotifyData).Val == 0)
{
// Something went wrong
}
});
retVal.MessagePump.on('message', function onWindowsMessage(msg)
{
if(msg.message == this.TrayIcon.Options.filter)
{
var handled = false;
if (msg.wparam == 1 && msg.lparam == 1029)
{
this.TrayIcon.emit('ToastClicked');
handled = true;
}
if (msg.wparam == 1 && msg.lparam == 512)
{
this.TrayIcon.emit('IconHover');
handled = true;
}
if (this.TrayIcon.Options.balloonOnly && msg.wparam == 1 && (msg.lparam == 1028 || msg.lparam == 1029))
{
this.TrayIcon.emit('ToastDismissed');
this.TrayIcon.remove();
handled = true;
}
if (!handled) { console.log(msg); }
}
});
retVal.remove = function remove()
{
this.MessagePump.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_DELETE, this.MessagePump.NotifyData);
this.MessagePump.stop();
delete this.MessagePump.TrayIcon;
delete this.MessagePump;
};
return (retVal);
};
}
}
module.exports = new WindowsConsole();

View File

@ -0,0 +1,122 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var WH_CALLWNDPROC = 4;
var WM_QUIT = 0x0012;
function WindowsMessagePump(options)
{
this._ObjectID = 'WindowsMessagePump';
this._options = options;
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('hwnd');
emitterUtils.createEvent('error');
emitterUtils.createEvent('message');
emitterUtils.createEvent('exit');
this._child = require('ScriptContainer').Create({ processIsolation: 0 });
this._child.MessagePump = this;
this._child.prependListener('~', function _childFinalizer() { this.MessagePump.emit('exit', 0); console.log('calling stop'); this.MessagePump.stop(); });
this._child.once('exit', function onExit(code) { this.MessagePump.emit('exit', code); });
this._child.once('ready', function onReady()
{
console.log('child ready');
var execString =
"var m = require('_GenericMarshal');\
var h = null;\
var k = m.CreateNativeProxy('Kernel32.dll');\
k.CreateMethod('GetLastError');\
k.CreateMethod('GetModuleHandleA');\
var u = m.CreateNativeProxy('User32.dll');\
u.CreateMethod('GetMessageA');\
u.CreateMethod('CreateWindowExA');\
u.CreateMethod('TranslateMessage');\
u.CreateMethod('DispatchMessageA');\
u.CreateMethod('RegisterClassExA');\
u.CreateMethod('DefWindowProcA');\
var wndclass = m.CreateVariable(m.PointerSize == 4 ? 48 : 80);\
wndclass.hinstance = k.GetModuleHandleA(0);\
wndclass.cname = m.CreateVariable('MainWWWClass');\
wndclass.wndproc = m.GetGenericGlobalCallback(4);\
wndclass.toBuffer().writeUInt32LE(wndclass._size);\
wndclass.cname.pointerBuffer().copy(wndclass.Deref(m.PointerSize == 4 ? 40 : 64, m.PointerSize).toBuffer());\
wndclass.wndproc.pointerBuffer().copy(wndclass.Deref(8, m.PointerSize).toBuffer());\
wndclass.hinstance.pointerBuffer().copy(wndclass.Deref(m.PointerSize == 4 ? 20 : 24, m.PointerSize).toBuffer());\
wndclass.wndproc.on('GlobalCallback', function onWndProc(xhwnd, xmsg, wparam, lparam)\
{\
if(h==null || h.Val == xhwnd.Val)\
{\
require('ScriptContainer').send({message: xmsg.Val, wparam: wparam.Val, lparam: lparam.Val});\
var retVal = u.DefWindowProcA(xhwnd, xmsg, wparam, lparam);\
return(retVal);\
}\
});\
u.RegisterClassExA(wndclass);\
h = u.CreateWindowExA(0x00000088, wndclass.cname, 0, 0x00800000, 0, 0, 100, 100, 0, 0, 0, 0);\
if(h.Val == 0)\
{\
require('ScriptContainer').send({error: 'Error Creating Hidden Window'});\
process.exit();\
}\
require('ScriptContainer').send({hwnd: h.pointerBuffer().toString('hex')});\
require('ScriptContainer').on('data', function onData(jmsg)\
{\
if(jmsg.listen)\
{\
var msg = m.CreateVariable(m.PointerSize == 4 ? 28 : 48);\
while(u.GetMessageA(msg, h, 0, 0).Val>0)\
{\
u.TranslateMessage(msg);\
u.DispatchMessageA(msg);\
}\
process.exit();\
}\
});";
this.ExecuteString(execString);
});
this._child.on('data', function onChildData(msg)
{
if (msg.hwnd)
{
var m = require('_GenericMarshal');
this._hwnd = m.CreatePointer(Buffer.from(msg.hwnd, 'hex'));
this.MessagePump.emit('hwnd', this._hwnd);
this.send({ listen: this.MessagePump._options.filter });
}
else if(msg.message)
{
this.MessagePump.emit('message', msg);
}
else
{
console.log('Received: ', msg);
}
});
this.stop = function stop()
{
if(this._child && this._child._hwnd)
{
console.log('posting WM_QUIT');
var marshal = require('_GenericMarshal');
var User32 = marshal.CreateNativeProxy('User32.dll');
User32.CreateMethod('PostMessageA');
User32.PostMessageA(this._child._hwnd, WM_QUIT, 0, 0);
}
};
}
module.exports = WindowsMessagePump;

View File

@ -0,0 +1,167 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var KEY_QUERY_VALUE = 0x0001;
var KEY_WRITE = 0x20006;
var KEY_DATA_TYPES =
{
REG_NONE: 0,
REG_SZ: 1,
REG_EXPAND_SZ: 2,
REG_BINARY: 3,
REG_DWORD: 4,
REG_DWORD_BIG_ENDIAN: 5,
REG_LINK: 6,
REG_MULTI_SZ: 7,
REG_RESOURCE_LIST: 8,
REG_FULL_RESOURCE_DESCRIPTOR: 9,
REG_RESOURCE_REQUIREMENTS_LIST: 10,
REG_QWORD: 11
};
function windows_registry()
{
this._ObjectId = 'windows_registry';
this._marshal = require('_GenericMarshal');
this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll');
this._AdvApi.CreateMethod('RegCreateKeyExA');
this._AdvApi.CreateMethod('RegOpenKeyExA');
this._AdvApi.CreateMethod('RegQueryValueExA');
this._AdvApi.CreateMethod('RegCloseKey');
this._AdvApi.CreateMethod('RegDeleteKeyA');
this._AdvApi.CreateMethod('RegDeleteValueA');
this._AdvApi.CreateMethod('RegSetValueExA');
this.HKEY = { Root: Buffer.from('80000000', 'hex').swap32(), CurrentUser: Buffer.from('80000001', 'hex').swap32(), LocalMachine: Buffer.from('80000002', 'hex').swap32(), Users: Buffer.from('80000003', 'hex').swap32() };
this.QueryKey = function QueryKey(hkey, path, key)
{
var h = this._marshal.CreatePointer();
var len = this._marshal.CreateVariable(4);
var valType = this._marshal.CreateVariable(4);
key = this._marshal.CreateVariable(key);
var HK = this._marshal.CreatePointer(hkey);
var retVal = null;
if (this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE, h).Val != 0)
{
throw ('Error Opening Registry Key: ' + path);
}
if(this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, 0, 0, len).Val == 0)
{
var data = this._marshal.CreateVariable(len.toBuffer().readUInt32LE());
if (this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, valType, data, len).Val == 0)
{
switch(valType.toBuffer().readUInt32LE())
{
case KEY_DATA_TYPES.REG_DWORD:
retVal = data.toBuffer().readUInt32LE();
break;
case KEY_DATA_TYPES.REG_DWORD_BIG_ENDIAN:
retVal = data.toBuffer().readUInt32BE();
break;
case KEY_DATA_TYPES.REG_SZ:
retVal = data.String;
break;
case KEY_DATA_TYPES.REG_BINARY:
default:
retVal = data.toBuffer();
retVal._data = data;
break;
}
}
}
else
{
this._AdvApi.RegCloseKey(h.Deref());
throw ('Not Found');
}
this._AdvApi.RegCloseKey(h.Deref());
return (retVal);
};
this.WriteKey = function WriteKey(hkey, path, key, value)
{
var result;
var h = this._marshal.CreatePointer();
if (this._AdvApi.RegCreateKeyExA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path), 0, 0, 0, KEY_WRITE, 0, h, 0).Val != 0)
{
throw ('Error Opening Registry Key: ' + path);
}
var data;
var dataType;
switch(typeof(value))
{
case 'boolean':
dataType = KEY_DATA_TYPES.REG_DWORD;
data = this._marshal.CreateVariable(4);
data.toBuffer().writeUInt32LE(value ? 1 : 0);
break;
case 'number':
dataType = KEY_DATA_TYPES.REG_DWORD;
data = this._marshal.CreateVariable(4);
data.toBuffer().writeUInt32LE(value);
break;
case 'string':
dataType = KEY_DATA_TYPES.REG_SZ;
data = this._marshal.CreateVariable(value);
break;
default:
dataType = KEY_DATA_TYPES.REG_BINARY;
data = this._marshal.CreateVariable(value.length);
value.copy(data.toBuffer());
break;
}
if(this._AdvApi.RegSetValueExA(h.Deref(), this._marshal.CreateVariable(key), 0, dataType, data, data._size).Val != 0)
{
this._AdvApi.RegCloseKey(h.Deref());
throw ('Error writing reg key: ' + key);
}
this._AdvApi.RegCloseKey(h.Deref());
};
this.DeleteKey = function DeleteKey(hkey, path, key)
{
if(!key)
{
if(this._AdvApi.RegDeleteKeyA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path)).Val != 0)
{
throw ('Error Deleting Key: ' + path);
}
}
else
{
var h = this._marshal.CreatePointer();
var result;
if (this._AdvApi.RegOpenKeyExA(this._marshal.CreatePointer(hkey), this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_WRITE, h).Val != 0)
{
throw ('Error Opening Registry Key: ' + path);
}
if ((result = this._AdvApi.RegDeleteValueA(h.Deref(), this._marshal.CreateVariable(key)).Val) != 0)
{
this._AdvApi.RegCloseKey(h.Deref());
throw ('Error[' + result + '] Deleting Key: ' + path + '.' + key);
}
this._AdvApi.RegCloseKey(h.Deref());
}
};
}
module.exports = new windows_registry();

View File

@ -71,7 +71,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
// Once the main web server is started, call this to hookup additional handlers
obj.hookMainWebServer = function (certs) {
obj.certificates = certs;
for (var i = 0; i < parent.config.domains.length; i++) {
for (var i in parent.config.domains) {
if (parent.config.domains[i].dns != null) { continue; }
var url = parent.config.domains[i].url;
obj.app.post(url + "amtevents.ashx", obj.parent.webserver.handleAmtEventRequest);
@ -82,7 +82,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
// Setup all HTTP redirection handlers
//obj.app.set("etag", false);
for (var i = 0; i < parent.config.domains; i++) {
for (var i in parent.config.domains) {
if (parent.config.domains[i].dns != null) { continue; }
var url = parent.config.domains[i].url;
obj.app.get(url, performRedirection);

View File

@ -927,7 +927,7 @@
// Poll the server, if it responds, refresh the page.
function serverPoll() {
xdr = null;
var xdr = null;
try { xdr = new XDomainRequest(); } catch (e) { }
if (!xdr) xdr = new XMLHttpRequest();
xdr.open("HEAD", window.location.href);
@ -2253,7 +2253,7 @@
try {
var loc = map_parseNodeLoc(nodes[i]);
var feature = xxmap.markersSource.getFeatureById(nodes[i]._id);
if ((loc != null) && ((nodes[i].meshid == selectedMesh) || (selectedMesh == null))) { // Draw markers for devices with locations
if ((typeof loc == 'object') && ((nodes[i].meshid == selectedMesh) || (selectedMesh == null))) { // Draw markers for devices with locations
var lat = loc[0], lon = loc[1], type = loc[2];
if (boundingBox == null) { boundingBox = [ lat, lon, lat, lon, 0 ]; } else { if (lat < boundingBox[0]) { boundingBox[0] = lat; } if (lon < boundingBox[1]) { boundingBox[1] = lon; } if (lat > boundingBox[2]) { boundingBox[2] = lat; } if (lon > boundingBox[3]) { boundingBox[3] = lon; } }
if (feature == null) { addFeature(nodes[i]); boundingBox[4] = 1; } else { updateFeature(nodes[i], feature); feature.setStyle(markerStyle(nodes[i], loc[2])); } // Update Feature