mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-11-07 12:52:54 -05:00
Many agent & UI improvements
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
agents/meshagent_osx-x86-64
Normal file
BIN
agents/meshagent_osx-x86-64
Normal file
Binary file not shown.
@@ -29,9 +29,12 @@ function createMeshCore(agent) {
|
||||
this.Start = function Start(user) {
|
||||
if (this.container == null) {
|
||||
if (process.platform == 'win32') {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
|
||||
}
|
||||
else {
|
||||
try {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
|
||||
} catch (ex) {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1 });
|
||||
}
|
||||
} else {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid });
|
||||
}
|
||||
this.container.parent = this;
|
||||
@@ -47,33 +50,21 @@ function createMeshCore(agent) {
|
||||
this._container = this.container;
|
||||
this._container.parent = this;
|
||||
this.container = null;
|
||||
|
||||
this._container.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.borderManager = new borderController();
|
||||
*/
|
||||
|
||||
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 v6";
|
||||
obj.meshCoreCapabilities = 14; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
|
||||
obj.loggedInUsers = [];
|
||||
obj.loggedInUsers = null;
|
||||
|
||||
var meshServerConnectionState = 0;
|
||||
var tunnels = {};
|
||||
var lastSelfInfo = null;
|
||||
var lastMeInfo = null;
|
||||
var lastNetworkInfo = null;
|
||||
var lastPublicLocationInfo = null;
|
||||
var selfInfoUpdateTimer = null;
|
||||
@@ -92,10 +83,8 @@ function createMeshCore(agent) {
|
||||
var nextTunnelIndex = 1;
|
||||
|
||||
// Get the operating system description string
|
||||
// *** THIS CAUSES AGENT TO BE UNSTABLE!!!
|
||||
//obj.osDesc = null;
|
||||
//try { require('os').name().then(function (v) { obj.osDesc = v; }); } catch (ex) { }
|
||||
// *** THIS CAUSES AGENT TO BE UNSTABLE!!!
|
||||
var osDesc = null;
|
||||
try { require('os').name().then(function (v) { osDesc = v; if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo, "osdesc": osDesc }); } }); } catch (ex) { }
|
||||
|
||||
/*
|
||||
var AMTScanner = require("AMTScanner");
|
||||
@@ -128,23 +117,23 @@ function createMeshCore(agent) {
|
||||
var AMTScannerModule = require('amt-scanner');
|
||||
amtscanner = new AMTScannerModule();
|
||||
//amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); });
|
||||
} catch (e) { amtscanner = null; }
|
||||
} catch (ex) { amtscanner = null; }
|
||||
|
||||
// Try to load up the MEI module
|
||||
try {
|
||||
var amtMeiLib = require('amt-mei');
|
||||
amtMei = new amtMeiLib();
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; sendPeriodicServerUpdate(); });
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; });
|
||||
amtMeiConnected = 2;
|
||||
//amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); });
|
||||
} catch (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
|
||||
sendPeriodicServerUpdate(1);
|
||||
} catch (ex) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
|
||||
|
||||
// Try to load up the WIFI scanner
|
||||
try {
|
||||
var wifiScannerLib = require('wifi-scanner');
|
||||
wifiScanner = new wifiScannerLib();
|
||||
wifiScanner.on('accessPoint', function (data) { sendConsoleText(JSON.stringify(data)); });
|
||||
} catch (e) { wifiScannerLib = null; wifiScanner = null; }
|
||||
} catch (ex) { wifiScannerLib = null; wifiScanner = null; }
|
||||
|
||||
// If we are running in Duktape, agent will be null
|
||||
if (agent == null) {
|
||||
@@ -923,7 +912,7 @@ function createMeshCore(agent) {
|
||||
var response = null;
|
||||
switch (cmd) {
|
||||
case 'help': { // Displays available commands
|
||||
response = 'Available commands: help, info, osinfo, 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, sendinfo, sendcaps.';
|
||||
response = 'Available commands: help, info, osinfo, 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, sendcaps.';
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@@ -947,12 +936,7 @@ function createMeshCore(agent) {
|
||||
*/
|
||||
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(', ') + ']';
|
||||
if (obj.loggedInUsers == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + obj.loggedInUsers.join(', ') + '.'; }
|
||||
}
|
||||
break;
|
||||
case 'toast': {
|
||||
@@ -1038,10 +1022,10 @@ function createMeshCore(agent) {
|
||||
case 'info': { // Return information about the agent and agent core module
|
||||
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
|
||||
if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
|
||||
//if (obj.osDesc) { response += '\r\nOS: ' + obj.osDesc + '.'; }
|
||||
if (osDesc) { response += '\r\nOS: ' + osDesc + '.'; }
|
||||
response += '\r\nModules: ' + addedModules.join(', ') + '.';
|
||||
response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.';
|
||||
response += '\r\nLastInfo: ' + lastSelfInfo + '.';
|
||||
response += '\r\lastMeInfo: ' + lastMeInfo + '.';
|
||||
var oldNodeId = db.Get('OldNodeId');
|
||||
if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
|
||||
if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; }
|
||||
@@ -1049,7 +1033,7 @@ function createMeshCore(agent) {
|
||||
}
|
||||
case 'osinfo': { // Return the operating system information
|
||||
var i = 1;
|
||||
if (args['_'].length > 0) { i = parseInt(args['_'][0]); response = 'Calling ' + i + ' times.'; }
|
||||
if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
|
||||
for (var j = 0; j < i; j++) {
|
||||
var pr = require('os').name();
|
||||
pr.sessionid = sessionid;
|
||||
@@ -1057,30 +1041,24 @@ function createMeshCore(agent) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'selfinfo': { // Return self information block
|
||||
buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' ', true), sessionid); });
|
||||
break;
|
||||
}
|
||||
case 'sendinfo': { // Send our information to the server
|
||||
buildSelfInfo(function (selfInfo) {
|
||||
lastSelfInfo = JSON.stringify(selfInfo);
|
||||
sendConsoleText('Sent: ' + lastSelfInfo);
|
||||
mesh.SendCommand(lastSelfInfo);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'sendcaps': { // Send capability flags to the server
|
||||
if (args['_'].length == 0) {
|
||||
response = 'Proper usage: sendcaps (number)'; // Display correct command usage
|
||||
} else {
|
||||
var flags = 0;
|
||||
response = JSON.stringify(args);
|
||||
flags = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": parseInt(args['_'][0]) };
|
||||
var flags = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": parseInt(args['_'][0]) };
|
||||
mesh.SendCommand(flags);
|
||||
response = JSON.stringify(flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'sendosdesc': { // Send OS description
|
||||
var os = osDesc;
|
||||
if (args['_'].length > 0) { os = args['_'][0]; }
|
||||
var flags = { "action": "coreinfo", "value": obj.meshCoreInfo, "osdesc": os };
|
||||
mesh.SendCommand(flags);
|
||||
response = JSON.stringify(flags);
|
||||
break;
|
||||
}
|
||||
case 'args': { // Displays parsed command arguments
|
||||
response = 'args ' + objToString(args, 0, ' ', true);
|
||||
break;
|
||||
@@ -1380,31 +1358,22 @@ function createMeshCore(agent) {
|
||||
// Server connected, send mesh core information
|
||||
var oldNodeId = db.Get('OldNodeId');
|
||||
if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
|
||||
sendPeriodicServerUpdate(true);
|
||||
//if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 60000); } // Should be a long time, like 20 minutes. For now, 1 minute.
|
||||
|
||||
// Update the server wtih basic info
|
||||
var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
|
||||
if (osDesc != null) { r.osdesc = osDesc; }
|
||||
mesh.SendCommand(r);
|
||||
|
||||
// Update list of logged in users
|
||||
if (obj.loggedInUsers != null) { mesh.SendCommand({ "action": "coreinfo", "v": { "users": obj.loggedInUsers } }); }
|
||||
|
||||
// Update the server on more advanced stuff, like Intel ME and Network Settings
|
||||
meInfoStr = null;
|
||||
sendPeriodicServerUpdate();
|
||||
//if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes
|
||||
}
|
||||
}
|
||||
|
||||
// Build a bunch a self information data that will be sent to the server
|
||||
// We need to do this periodically and if anything changes, send the update to the server.
|
||||
function buildSelfInfo(func) {
|
||||
getAmtInfo(function (meinfo) {
|
||||
var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
|
||||
try {
|
||||
if (meinfo != null) {
|
||||
var intelamt = {}, p = false;
|
||||
if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
|
||||
if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
|
||||
if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
|
||||
if (p == true) { r.intelamt = intelamt }
|
||||
}
|
||||
} catch (ex) { }
|
||||
func(r);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Update the server with the latest network interface information
|
||||
var sendNetworkUpdateNagleTimer = null;
|
||||
function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); }
|
||||
@@ -1419,18 +1388,33 @@ function createMeshCore(agent) {
|
||||
}
|
||||
|
||||
// Called periodically to check if we need to send updates to the server
|
||||
function sendPeriodicServerUpdate(force) {
|
||||
if ((amtMeiConnected != 1) || (force == true)) { // If we are pending MEI connection, hold off on updating the server on self-info
|
||||
if (force == true) { lastSelfInfo = null; }
|
||||
// Update the self information data
|
||||
buildSelfInfo(function (selfInfo) {
|
||||
selfInfoStr = JSON.stringify(selfInfo);
|
||||
if (selfInfoStr != lastSelfInfo) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; }
|
||||
function sendPeriodicServerUpdate(flags) {
|
||||
if (meshServerConnectionState == 0) return; // Not connected to server, do nothing.
|
||||
if (!flags) { flags = 0xFFFFFFFF; }
|
||||
|
||||
if (flags & 1) {
|
||||
// If we have a connected MEI, get Intel ME information
|
||||
getAmtInfo(function (meinfo) {
|
||||
try {
|
||||
if (meinfo == null) return;
|
||||
var intelamt = {}, p = false;
|
||||
if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
|
||||
if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
|
||||
if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
|
||||
if (p == true) {
|
||||
var meInfoStr = JSON.stringify({ "action": "coreinfo", "value": obj.meshCoreInfo, "intelamt": intelamt });
|
||||
if (meInfoStr != lastMeInfo) { mesh.SendCommand(meInfoStr); lastMeInfo = meInfoStr; }
|
||||
}
|
||||
} catch (ex) { }
|
||||
});
|
||||
}
|
||||
|
||||
// Update network information
|
||||
sendNetworkUpdateNagle(force);
|
||||
|
||||
if (flags & 2) {
|
||||
// Update network information
|
||||
sendNetworkUpdateNagle(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Get Intel AMT information using MEI
|
||||
@@ -1492,25 +1476,23 @@ function createMeshCore(agent) {
|
||||
});
|
||||
} catch (e) { amtLmsState = -1; amtLms = null; }
|
||||
|
||||
// Check if the control channel is connected
|
||||
if (mesh.isControlChannelConnected) { handleServerConnection(1); }
|
||||
|
||||
// Setup logged in user monitoring
|
||||
/*
|
||||
require('user-sessions').on('changed', function onUserSessionChanged()
|
||||
{
|
||||
require('user-sessions').enumerateUsers().then(function (users)
|
||||
{
|
||||
obj.loggedInUsers = users.Active;
|
||||
obj.emit('loggedInUsers_Updated');
|
||||
try {
|
||||
var userSession = require('user-sessions');
|
||||
userSession.on('changed', function onUserSessionChanged() {
|
||||
userSession.enumerateUsers().then(function (users) {
|
||||
var u = [], a = users.Active;
|
||||
for (var i in a) { if (a[i].Domain) { u.push(a[i].Domain + '\\' + a[i].Username); } else { u.push(a[i].Username); } }
|
||||
obj.loggedInUsers = u;
|
||||
if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "coreinfo", "users": u }); }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
require('user-sessions').emit('changed');
|
||||
require('user-sessions').on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); });
|
||||
require('user-sessions').on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); });
|
||||
userSession.emit('changed');
|
||||
//userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); });
|
||||
//userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); });
|
||||
} catch (ex) { }
|
||||
*/
|
||||
//console.log('Stopping.');
|
||||
//process.exit();
|
||||
}
|
||||
|
||||
obj.stop = function () {
|
||||
@@ -1535,7 +1517,8 @@ function createMeshCore(agent) {
|
||||
// KVM Data Channel
|
||||
//
|
||||
|
||||
obj.setupMeiOsAdmin = function(func, state) {
|
||||
obj.setupMeiOsAdmin = function (func, state) {
|
||||
if ((amtMei == null) || (amtMeiConnected != 2)) { return; } // If there is no MEI, don't bother with this.
|
||||
amtMei.getLocalSystemAccount(function (x) {
|
||||
var transport = require('amt-wsman-duk');
|
||||
var wsman = require('amt-wsman');
|
||||
|
||||
@@ -30,7 +30,28 @@ function amt_heci() {
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('error', function _amtOnError(e)
|
||||
{
|
||||
if(this.Parent._rq.isEmpty())
|
||||
{
|
||||
this.Parent.emit('error', e); // No pending requests, so propagate the error up
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is a pending request, so fail the pending request
|
||||
var user = this.Parent._rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
params.unshift({ Status: -1 }); // Relay an error
|
||||
callback.apply(this.Parent, params);
|
||||
|
||||
if(!this.Parent._rq.isEmpty())
|
||||
{
|
||||
// There are still more pending requests, so try to re-helpconnect MEI
|
||||
this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
}
|
||||
}
|
||||
});
|
||||
this._amt.on('connect', function _amtOnConnect()
|
||||
{
|
||||
this.on('data', function _amtOnData(chunk)
|
||||
@@ -70,7 +91,8 @@ function amt_heci() {
|
||||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function sendCommand() {
|
||||
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]); }
|
||||
@@ -278,8 +300,16 @@ function amt_heci() {
|
||||
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); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
|
||||
{
|
||||
if (header.Status == 0 && 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);
|
||||
}
|
||||
|
||||
@@ -197,11 +197,18 @@ function UserSessions()
|
||||
{
|
||||
this.parent.hwnd = h;
|
||||
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
this.parent._wts.WTSRegisterSessionNotification(this.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
//this.parent._user32.ACDC_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
//this.parent._user32.BATT_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
//this.parent._user32.DISP_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); // Windows 8+ only, THIS WILL BLOCK ON WIN7
|
||||
// We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification'
|
||||
// from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding
|
||||
// on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately
|
||||
this.immediate = setImmediate(function (self)
|
||||
{
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0);
|
||||
console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val);
|
||||
}, this);
|
||||
});
|
||||
this._messagepump.on('message', function (msg)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,28 @@ function amt_heci() {
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('error', function _amtOnError(e)
|
||||
{
|
||||
if(this.Parent._rq.isEmpty())
|
||||
{
|
||||
this.Parent.emit('error', e); // No pending requests, so propagate the error up
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is a pending request, so fail the pending request
|
||||
var user = this.Parent._rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
params.unshift({ Status: -1 }); // Relay an error
|
||||
callback.apply(this.Parent, params);
|
||||
|
||||
if(!this.Parent._rq.isEmpty())
|
||||
{
|
||||
// There are still more pending requests, so try to re-helpconnect MEI
|
||||
this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
}
|
||||
}
|
||||
});
|
||||
this._amt.on('connect', function _amtOnConnect()
|
||||
{
|
||||
this.on('data', function _amtOnData(chunk)
|
||||
@@ -70,7 +91,8 @@ function amt_heci() {
|
||||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function sendCommand() {
|
||||
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]); }
|
||||
@@ -278,8 +300,16 @@ function amt_heci() {
|
||||
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); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
|
||||
{
|
||||
if (header.Status == 0 && 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);
|
||||
}
|
||||
|
||||
128
agents/modules_meshcore/linux-dbus.js
Normal file
128
agents/modules_meshcore/linux-dbus.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
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) { }
|
||||
|
||||
|
||||
|
||||
function dbus(address, uid)
|
||||
{
|
||||
this._ObjectID = 'linux-dbus';
|
||||
require('events').EventEmitter.call(this, true)
|
||||
.createEvent('signal');
|
||||
Object.defineProperty(this, "uid", { value: uid });
|
||||
this._child = require('child_process').execFile("/bin/sh", ["sh"], { type: require('child_process').SpawnTypes.TERM, uid: uid == null ? -1 : uid });
|
||||
this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while true; do read X; echo "$X"; done )\n');
|
||||
this._child.stdout.dbus = this;
|
||||
this._child.stdout.on('data', function (chunk)
|
||||
{
|
||||
// Parse DBUS Data
|
||||
if (!this.ready) { this.ready = true; return; }
|
||||
|
||||
var lines = [];
|
||||
var tokens = chunk.toString().split('\r\n');
|
||||
for (var i in tokens)
|
||||
{
|
||||
if (tokens[i] == '')
|
||||
{
|
||||
// End of record
|
||||
this.dbus.preParseRecords(lines);
|
||||
lines = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.push(tokens[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.preParseRecords = function (lines)
|
||||
{
|
||||
var record = [];
|
||||
for (var i in lines)
|
||||
{
|
||||
if(lines[i].startsWith('signal '))
|
||||
{
|
||||
if(record.length>0)
|
||||
{
|
||||
this.parseRecords(record);
|
||||
}
|
||||
record = [];
|
||||
}
|
||||
record.push(lines[i]);
|
||||
}
|
||||
if (record.length > 0)
|
||||
{
|
||||
this.parseRecords(record);
|
||||
}
|
||||
}
|
||||
this.parseRecords = function (lines)
|
||||
{
|
||||
if (lines[0].startsWith('signal '))
|
||||
{
|
||||
var signal = {};
|
||||
var sigtokens = lines[0].split(' ');
|
||||
sigtokens.shift();
|
||||
|
||||
for (var i in sigtokens) {
|
||||
var sigitems = sigtokens[i].split('=');
|
||||
if (sigitems.length == 2) {
|
||||
signal[sigitems[0]] = sigitems[1];
|
||||
}
|
||||
}
|
||||
|
||||
lines.shift();
|
||||
signal.data = lines;
|
||||
|
||||
this.parseSignal(signal);
|
||||
}
|
||||
}
|
||||
this.parseSignal = function(signal)
|
||||
{
|
||||
var data = signal.data;
|
||||
signal.data = [];
|
||||
|
||||
for(var i=0; i<data.length; ++i)
|
||||
{
|
||||
if (data[i].startsWith('array '))
|
||||
{
|
||||
signal.data.push([]);
|
||||
for(i=i+1; i<data.length; ++i)
|
||||
{
|
||||
this.parseSignal2(data[i], signal.data.peek());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parseSignal2(data[i], signal.data);
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('signal', signal);
|
||||
}
|
||||
this.parseSignal2 = function (inputStr, outArray)
|
||||
{
|
||||
if(inputStr.startsWith('string '))
|
||||
{
|
||||
outArray.push(JSON.parse(inputStr.slice(7)));
|
||||
}
|
||||
else if(inputStr.startsWith('boolean '))
|
||||
{
|
||||
outArray.push(JSON.parse(inputStr.slice(8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = dbus;
|
||||
@@ -197,11 +197,18 @@ function UserSessions()
|
||||
{
|
||||
this.parent.hwnd = h;
|
||||
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
this.parent._wts.WTSRegisterSessionNotification(this.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
//this.parent._user32.ACDC_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
//this.parent._user32.BATT_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
//this.parent._user32.DISP_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); // Windows 8+ only, THIS WILL BLOCK ON WIN7
|
||||
// We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification'
|
||||
// from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding
|
||||
// on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately
|
||||
this.immediate = setImmediate(function (self)
|
||||
{
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0);
|
||||
console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val);
|
||||
}, this);
|
||||
});
|
||||
this._messagepump.on('message', function (msg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user