mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
Many agent & UI improvements
This commit is contained in:
parent
8dcd8938a6
commit
23bc223f18
21 changed files with 450 additions and 155 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.
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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue