mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Clean up.
This commit is contained in:
		
							parent
							
								
									596b81c23d
								
							
						
					
					
						commit
						dfafc6372f
					
				
					 8 changed files with 0 additions and 2406 deletions
				
			
		|  | @ -1,163 +0,0 @@ | |||
| /* | ||||
| Copyright 2018-2019 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 GM = require('_GenericMarshal'); | ||||
| 
 | ||||
| // Used on Windows and Linux to get information about running processes
 | ||||
| function processManager() { | ||||
|     this._ObjectID = 'process-manager'; // Used for debugging, allows you to get the object type at runtime.
 | ||||
|      | ||||
|     // Setup the platform specific calls.
 | ||||
|     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': | ||||
|         case 'darwin': | ||||
|             this._childProcess = require('child_process'); | ||||
|             break; | ||||
|         default: | ||||
|             throw (process.platform + ' not supported'); | ||||
|             break; | ||||
|     } | ||||
|     this.enumerateProcesses = function enumerateProcesses() | ||||
|     { | ||||
|         var promise = require('promise'); | ||||
|         var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); | ||||
|         this.getProcesses(function (ps, prom) { prom._res(ps); }, ret); | ||||
|         return (ret); | ||||
|     } | ||||
|     // Return a object of: pid -> process information.
 | ||||
|     this.getProcesses = function getProcesses(callback) | ||||
|     { | ||||
|         switch(process.platform) | ||||
|         { | ||||
|             default: | ||||
|                 throw ('Enumerating processes on ' + process.platform + ' not supported'); | ||||
|                 break; | ||||
|             case 'win32': // Windows processes
 | ||||
|                 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)] = { pid: 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': // Linux processes
 | ||||
|                 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) { | ||||
|                             if (tokenList[key.PID]) { retVal[tokenList[key.PID]] = { pid: 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; | ||||
|             case 'darwin': | ||||
|                 var promise = require('promise'); | ||||
|                 var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); | ||||
|                 p.pm = this; | ||||
|                 p.callback = callback; | ||||
|                 p.args = []; | ||||
|                 for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); } | ||||
|                 p.child = this._childProcess.execFile("/bin/ps", ["ps", "-xa"]); | ||||
|                 p.child.promise = p; | ||||
|                 p.child.stdout.ps = ''; | ||||
|                 p.child.stdout.on('data', function (chunk) { this.ps += chunk.toString(); }); | ||||
|                 p.child.on('exit', function () | ||||
|                 { | ||||
|                     var lines = this.stdout.ps.split('\n'); | ||||
|                     var pidX = lines[0].split('PID')[0].length + 3; | ||||
|                     var cmdX = lines[0].split('CMD')[0].length; | ||||
|                     var ret = {}; | ||||
|                     for (var i = 1; i < lines.length; ++i) | ||||
|                     { | ||||
|                         if (lines[i].length > 0) | ||||
|                         { | ||||
|                             ret[lines[i].substring(0, pidX).trim()] = { pid: lines[i].substring(0, pidX).trim(), cmd: lines[i].substring(cmdX) }; | ||||
|                         } | ||||
|                     } | ||||
|                     this.promise._res(ret); | ||||
|                 }); | ||||
|                 p.then(function (ps) | ||||
|                 { | ||||
|                     this.args.unshift(ps); | ||||
|                     this.callback.apply(this.pm, this.args); | ||||
|                 }); | ||||
|                 break; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     // Get information about a specific process on Linux
 | ||||
|     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'); | ||||
|                 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; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| module.exports = new processManager(); | ||||
|  | @ -1,178 +0,0 @@ | |||
| /* | ||||
| Copyright 2019 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 promise = require('promise'); | ||||
| 
 | ||||
| function nativeAddModule(name) | ||||
| { | ||||
|     var value = getJSModule(name); | ||||
|     var ret = "duk_peval_string_noresult(ctx, \"addModule('" + name + "', Buffer.from('" + Buffer.from(value).toString('base64') + "', 'base64').toString());\");"; | ||||
|     module.exports(ret); | ||||
| } | ||||
| 
 | ||||
| function lin_readtext() | ||||
| { | ||||
|     var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); | ||||
|     try | ||||
|     { | ||||
|         require('monitor-info') | ||||
|     } | ||||
|     catch(exc) | ||||
|     { | ||||
|         ret._rej(exc); | ||||
|         return (ret); | ||||
|     } | ||||
| 
 | ||||
|     var X11 = require('monitor-info')._X11; | ||||
|     if (!X11) | ||||
|     { | ||||
|         ret._rej('X11 required for Clipboard Manipulation'); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         var SelectionNotify = 31; | ||||
|         var AnyPropertyType = 0; | ||||
|         var GM = require('monitor-info')._gm; | ||||
| 
 | ||||
|         ret._getInfoPromise = require('monitor-info').getInfo(); | ||||
|         ret._getInfoPromise._masterPromise = ret; | ||||
|         ret._getInfoPromise.then(function (mon) | ||||
|         { | ||||
|             if (mon.length > 0) | ||||
|             { | ||||
|                 var white = X11.XWhitePixel(mon[0].display, mon[0].screenId).Val; | ||||
| 
 | ||||
|                 this._masterPromise.CLIPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('CLIPBOARD'), 0); | ||||
|                 this._masterPromise.FMTID = X11.XInternAtom(mon[0].display, GM.CreateVariable('UTF8_STRING'), 0); | ||||
|                 this._masterPromise.PROPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('XSEL_DATA'), 0); | ||||
|                 this._masterPromise.INCRID = X11.XInternAtom(mon[0].display, GM.CreateVariable('INCR'), 0); | ||||
|                 this._masterPromise.ROOTWIN = X11.XRootWindow(mon[0].display, mon[0].screenId); | ||||
|                 this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white); | ||||
| 
 | ||||
|                 X11.XSync(mon[0].display, 0); | ||||
|                 X11.XConvertSelection(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FMTID, this._masterPromise.PROPID, this._masterPromise.FAKEWIN, 0); | ||||
|                 X11.XSync(mon[0].display, 0); | ||||
| 
 | ||||
|                 this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true }); | ||||
|                 this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise; | ||||
|                 this._masterPromise.DescriptorEvent._display = mon[0].display; | ||||
|                 this._masterPromise.DescriptorEvent.on('readset', function (fd) | ||||
|                 { | ||||
|                     var XE = GM.CreateVariable(1024); | ||||
|                     while (X11.XPending(this._display).Val) | ||||
|                     { | ||||
|                         X11.XNextEventSync(this._display, XE); | ||||
|                         if(XE.Deref(0, 4).toBuffer().readUInt32LE() == SelectionNotify) | ||||
|                         { | ||||
|                             var id = GM.CreatePointer(); | ||||
|                             var bits = GM.CreatePointer(); | ||||
|                             var sz = GM.CreatePointer(); | ||||
|                             var tail = GM.CreatePointer(); | ||||
|                             var result = GM.CreatePointer(); | ||||
| 
 | ||||
|                             X11.XGetWindowProperty(this._display, this._masterPromise.FAKEWIN, this._masterPromise.PROPID, 0, 65535, 0, AnyPropertyType, id, bits, sz, tail, result); | ||||
|                             this._masterPromise._res(result.Deref().String); | ||||
|                             X11.XFree(result.Deref()); | ||||
|                             X11.XDestroyWindow(this._display, this._masterPromise.FAKEWIN); | ||||
| 
 | ||||
|                             this.removeDescriptor(fd); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|     return (ret); | ||||
| } | ||||
| function lin_copytext() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| function win_readtext() | ||||
| { | ||||
|     var ret = ''; | ||||
|     var CF_TEXT = 1; | ||||
|     var GM = require('_GenericMarshal'); | ||||
|     var user32 = GM.CreateNativeProxy('user32.dll'); | ||||
|     var kernel32 = GM.CreateNativeProxy('kernel32.dll'); | ||||
|     kernel32.CreateMethod('GlobalAlloc'); | ||||
|     kernel32.CreateMethod('GlobalLock'); | ||||
|     kernel32.CreateMethod('GlobalUnlock'); | ||||
|     user32.CreateMethod('OpenClipboard'); | ||||
|     user32.CreateMethod('CloseClipboard'); | ||||
|     user32.CreateMethod('GetClipboardData'); | ||||
| 
 | ||||
|     user32.OpenClipboard(0); | ||||
|     var h = user32.GetClipboardData(CF_TEXT); | ||||
|     if(h.Val!=0) | ||||
|     { | ||||
|         var hbuffer = kernel32.GlobalLock(h); | ||||
|         ret = hbuffer.String; | ||||
|         kernel32.GlobalUnlock(h); | ||||
|     } | ||||
|     user32.CloseClipboard(); | ||||
| 
 | ||||
|     var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); | ||||
|     p._res(ret); | ||||
|     return (p); | ||||
| } | ||||
| 
 | ||||
| function win_copytext(txt) | ||||
| { | ||||
|     var GMEM_MOVEABLE = 0x0002; | ||||
|     var CF_TEXT = 1; | ||||
| 
 | ||||
|     var GM = require('_GenericMarshal'); | ||||
|     var user32 = GM.CreateNativeProxy('user32.dll'); | ||||
|     var kernel32 = GM.CreateNativeProxy('kernel32.dll'); | ||||
|     kernel32.CreateMethod('GlobalAlloc'); | ||||
|     kernel32.CreateMethod('GlobalLock'); | ||||
|     kernel32.CreateMethod('GlobalUnlock'); | ||||
|     user32.CreateMethod('OpenClipboard'); | ||||
|     user32.CreateMethod('EmptyClipboard'); | ||||
|     user32.CreateMethod('CloseClipboard'); | ||||
|     user32.CreateMethod('SetClipboardData'); | ||||
| 
 | ||||
|     var h = kernel32.GlobalAlloc(GMEM_MOVEABLE, txt.length + 2); | ||||
|     h.autoFree(false); | ||||
|     var hbuffer = kernel32.GlobalLock(h); | ||||
|     hbuffer.autoFree(false); | ||||
|     var tmp = Buffer.alloc(txt.length + 1); | ||||
|     Buffer.from(txt).copy(tmp); | ||||
|     tmp.copy(hbuffer.Deref(0, txt.length + 1).toBuffer()); | ||||
|     kernel32.GlobalUnlock(h); | ||||
| 
 | ||||
|     user32.OpenClipboard(0); | ||||
|     user32.EmptyClipboard(); | ||||
|     user32.SetClipboardData(CF_TEXT, h); | ||||
|     user32.CloseClipboard(); | ||||
| } | ||||
| 
 | ||||
| switch(process.platform) | ||||
| { | ||||
|     case 'win32': | ||||
|         module.exports = win_copytext; | ||||
|         module.exports.read = win_readtext; | ||||
|         break; | ||||
|     case 'linux': | ||||
|         module.exports = lin_copytext; | ||||
|         module.exports.read = lin_readtext; | ||||
|         break; | ||||
|     case 'darwin': | ||||
|         break; | ||||
| } | ||||
| module.exports.nativeAddModule = nativeAddModule; | ||||
|  | @ -1,313 +0,0 @@ | |||
| /* | ||||
| 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 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 getLibInfo(libname) | ||||
| { | ||||
|     if (process.platform != 'linux') { throw ('Only supported on linux'); } | ||||
| 
 | ||||
|     var child = require('child_process').execFile('/bin/sh', ['sh']); | ||||
|     child.stdout.str = ''; | ||||
|     child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|     child.stdin.write("ldconfig -p | grep '" + libname + ".so.'\nexit\n"); | ||||
|     child.waitExit(); | ||||
| 
 | ||||
|     var v = []; | ||||
|     var lines = child.stdout.str.split('\n'); | ||||
|     for (var i in lines) { | ||||
|         if (lines[i]) { | ||||
|             var info = lines[i].split('=>'); | ||||
|             var pth = info[1].trim(); | ||||
|             var libinfo = info[0].trim().split(' '); | ||||
|             var lib = libinfo[0]; | ||||
|             var plat = libinfo[1].substring(1, libinfo[1].length - 1).split(','); | ||||
| 
 | ||||
|             if (lib.startsWith(libname + '.so.')) { | ||||
|                 v.push({ lib: lib, path: pth, info: plat }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return (v); | ||||
| } | ||||
| 
 | ||||
| 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') | ||||
|     { | ||||
|         // First thing we need to do, is determine where the X11 libraries are
 | ||||
|         var askOS = false; | ||||
|         try | ||||
|         { | ||||
|             if (require('user-sessions').isRoot()) { askOS = true; } | ||||
|         } | ||||
|         catch (e) | ||||
|         { } | ||||
| 
 | ||||
|         if (askOS) | ||||
|         { | ||||
|             // Sufficient access rights to use ldconfig
 | ||||
|             var x11info = getLibInfo('libX11'); | ||||
|             var xtstinfo = getLibInfo('libXtst'); | ||||
|             var xextinfo = getLibInfo('libXext'); | ||||
|             var ix; | ||||
| 
 | ||||
|             for(ix in x11info) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     this._gm.CreateNativeProxy(x11info[ix].path); | ||||
|                     Object.defineProperty(this, 'Location_X11LIB', { value: x11info[ix].path }); | ||||
|                     break; | ||||
|                 } | ||||
|                 catch(ex) | ||||
|                 { | ||||
|                 } | ||||
|             } | ||||
|             for (ix in xtstinfo) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     this._gm.CreateNativeProxy(xtstinfo[ix].path); | ||||
|                     Object.defineProperty(this, 'Location_X11TST', { value: xtstinfo[ix].path }); | ||||
|                     break; | ||||
|                 } | ||||
|                 catch (ex) | ||||
|                 { | ||||
|                 } | ||||
|             } | ||||
|             for (ix in xextinfo) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     this._gm.CreateNativeProxy(xextinfo[ix].path); | ||||
|                     Object.defineProperty(this, 'Location_X11EXT', { value: xextinfo[ix].path }); | ||||
|                     break; | ||||
|                 } | ||||
|                 catch (ex) | ||||
|                 { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Not enough access rights to use ldconfig, so manually search
 | ||||
|             var fs = require('fs'); | ||||
|             var files = fs.readdirSync('/usr/lib'); | ||||
|             var files2; | ||||
| 
 | ||||
|             for (var i in files) { | ||||
|                 try { | ||||
|                     if (files[i].split('libX11.so.').length > 1 && files[i].split('.').length == 3) { | ||||
|                         Object.defineProperty(this, 'Location_X11LIB', { value: '/usr/lib/' + files[i] }); | ||||
|                     } | ||||
|                     if (files[i].split('libXtst.so.').length > 1 && files[i].split('.').length == 3) { | ||||
|                         Object.defineProperty(this, 'Location_X11TST', { value: '/usr/lib/' + files[i] }); | ||||
|                     } | ||||
|                     if (files[i].split('libXext.so.').length > 1 && files[i].split('.').length == 3) { | ||||
|                         Object.defineProperty(this, 'Location_X11EXT', { value: '/usr/lib/' + files[i] }); | ||||
|                     } | ||||
| 
 | ||||
|                     if (files[i].split('-linux-').length > 1) { | ||||
|                         files2 = fs.readdirSync('/usr/lib/' + files[i]); | ||||
|                         for (j in files2) { | ||||
|                             if (files2[j].split('libX11.so.').length > 1 && files2[j].split('.').length == 3) { | ||||
|                                 Object.defineProperty(this, 'Location_X11LIB', { value: '/usr/lib/' + files[i] + '/' + files2[j] }); | ||||
|                             } | ||||
|                             if (files2[j].split('libXtst.so.').length > 1 && files2[j].split('.').length == 3) { | ||||
|                                 Object.defineProperty(this, 'Location_X11TST', { value: '/usr/lib/' + files[i] + '/' + files2[j] }); | ||||
|                             } | ||||
|                             if (files2[j].split('libXext.so.').length > 1 && files2[j].split('.').length == 3) { | ||||
|                                 Object.defineProperty(this, 'Location_X11EXT', { value: '/usr/lib/' + files[i] + '/' + files2[j] }); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } catch (ex) { } | ||||
|             } | ||||
|         } | ||||
|         Object.defineProperty(this, 'kvm_x11_support', { value: (this.Location_X11LIB && this.Location_X11TST && this.Location_X11EXT)?true:false }); | ||||
| 
 | ||||
|         if (this.Location_X11LIB) | ||||
|         { | ||||
|             this._X11 = this._gm.CreateNativeProxy(this.Location_X11LIB); | ||||
|             this._X11.CreateMethod('XChangeProperty'); | ||||
|             this._X11.CreateMethod('XCloseDisplay'); | ||||
|             this._X11.CreateMethod('XConnectionNumber'); | ||||
|             this._X11.CreateMethod('XConvertSelection'); | ||||
|             this._X11.CreateMethod('XCreateGC'); | ||||
|             this._X11.CreateMethod('XCreateWindow'); | ||||
|             this._X11.CreateMethod('XCreateSimpleWindow'); | ||||
|             this._X11.CreateMethod('XDefaultColormap'); | ||||
|             this._X11.CreateMethod('XDefaultScreen'); | ||||
|             this._X11.CreateMethod('XDestroyWindow'); | ||||
|             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({ method: 'XNextEvent', newName: 'XNextEventSync' }); | ||||
|             this._X11.CreateMethod('XOpenDisplay'); | ||||
|             this._X11.CreateMethod('XPending'); | ||||
|             this._X11.CreateMethod('XRootWindow'); | ||||
|             this._X11.CreateMethod('XSelectInput'); | ||||
|             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('XSync'); | ||||
|             this._X11.CreateMethod('XBlackPixel'); | ||||
|             this._X11.CreateMethod('XWhitePixel'); | ||||
|         } | ||||
| 
 | ||||
|         this.isUnity = function isUnity() | ||||
|         { | ||||
|             return (process.env['XDG_CURRENT_DESKTOP'] == 'Unity'); | ||||
|         } | ||||
| 
 | ||||
|         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(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,163 +0,0 @@ | |||
| /* | ||||
| Copyright 2018-2019 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 GM = require('_GenericMarshal'); | ||||
| 
 | ||||
| // Used on Windows and Linux to get information about running processes
 | ||||
| function processManager() { | ||||
|     this._ObjectID = 'process-manager'; // Used for debugging, allows you to get the object type at runtime.
 | ||||
|      | ||||
|     // Setup the platform specific calls.
 | ||||
|     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': | ||||
|         case 'darwin': | ||||
|             this._childProcess = require('child_process'); | ||||
|             break; | ||||
|         default: | ||||
|             throw (process.platform + ' not supported'); | ||||
|             break; | ||||
|     } | ||||
|     this.enumerateProcesses = function enumerateProcesses() | ||||
|     { | ||||
|         var promise = require('promise'); | ||||
|         var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); | ||||
|         this.getProcesses(function (ps, prom) { prom._res(ps); }, ret); | ||||
|         return (ret); | ||||
|     } | ||||
|     // Return a object of: pid -> process information.
 | ||||
|     this.getProcesses = function getProcesses(callback) | ||||
|     { | ||||
|         switch(process.platform) | ||||
|         { | ||||
|             default: | ||||
|                 throw ('Enumerating processes on ' + process.platform + ' not supported'); | ||||
|                 break; | ||||
|             case 'win32': // Windows processes
 | ||||
|                 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)] = { pid: 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': // Linux processes
 | ||||
|                 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) { | ||||
|                             if (tokenList[key.PID]) { retVal[tokenList[key.PID]] = { pid: 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; | ||||
|             case 'darwin': | ||||
|                 var promise = require('promise'); | ||||
|                 var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); | ||||
|                 p.pm = this; | ||||
|                 p.callback = callback; | ||||
|                 p.args = []; | ||||
|                 for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); } | ||||
|                 p.child = this._childProcess.execFile("/bin/ps", ["ps", "-xa"]); | ||||
|                 p.child.promise = p; | ||||
|                 p.child.stdout.ps = ''; | ||||
|                 p.child.stdout.on('data', function (chunk) { this.ps += chunk.toString(); }); | ||||
|                 p.child.on('exit', function () | ||||
|                 { | ||||
|                     var lines = this.stdout.ps.split('\n'); | ||||
|                     var pidX = lines[0].split('PID')[0].length + 3; | ||||
|                     var cmdX = lines[0].split('CMD')[0].length; | ||||
|                     var ret = {}; | ||||
|                     for (var i = 1; i < lines.length; ++i) | ||||
|                     { | ||||
|                         if (lines[i].length > 0) | ||||
|                         { | ||||
|                             ret[lines[i].substring(0, pidX).trim()] = { pid: lines[i].substring(0, pidX).trim(), cmd: lines[i].substring(cmdX) }; | ||||
|                         } | ||||
|                     } | ||||
|                     this.promise._res(ret); | ||||
|                 }); | ||||
|                 p.then(function (ps) | ||||
|                 { | ||||
|                     this.args.unshift(ps); | ||||
|                     this.callback.apply(this.pm, this.args); | ||||
|                 }); | ||||
|                 break; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     // Get information about a specific process on Linux
 | ||||
|     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'); | ||||
|                 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; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| module.exports = new processManager(); | ||||
|  | @ -1,497 +0,0 @@ | |||
| /* | ||||
| 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 parseServiceStatus(token) | ||||
| { | ||||
|     var j = {}; | ||||
|     var serviceType = token.Deref(0, 4).IntVal; | ||||
|     j.isFileSystemDriver = ((serviceType & 0x00000002) == 0x00000002); | ||||
|     j.isKernelDriver = ((serviceType & 0x00000001) == 0x00000001); | ||||
|     j.isSharedProcess = ((serviceType & 0x00000020) == 0x00000020); | ||||
|     j.isOwnProcess = ((serviceType & 0x00000010) == 0x00000010); | ||||
|     j.isInteractive = ((serviceType & 0x00000100) == 0x00000100); | ||||
|     switch (token.Deref((1 * 4), 4).toBuffer().readUInt32LE()) | ||||
|     { | ||||
|         case 0x00000005: | ||||
|             j.state = 'CONTINUE_PENDING'; | ||||
|             break; | ||||
|         case 0x00000006: | ||||
|             j.state = 'PAUSE_PENDING'; | ||||
|             break; | ||||
|         case 0x00000007: | ||||
|             j.state = 'PAUSED'; | ||||
|             break; | ||||
|         case 0x00000004: | ||||
|             j.state = 'RUNNING'; | ||||
|             break; | ||||
|         case 0x00000002: | ||||
|             j.state = 'START_PENDING'; | ||||
|             break; | ||||
|         case 0x00000003: | ||||
|             j.state = 'STOP_PENDING'; | ||||
|             break; | ||||
|         case 0x00000001: | ||||
|             j.state = 'STOPPED'; | ||||
|             break; | ||||
|     } | ||||
|     var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE(); | ||||
|     j.controlsAccepted = []; | ||||
|     if ((controlsAccepted & 0x00000010) == 0x00000010) | ||||
|     { | ||||
|         j.controlsAccepted.push('SERVICE_CONTROL_NETBINDADD'); | ||||
|         j.controlsAccepted.push('SERVICE_CONTROL_NETBINDREMOVE'); | ||||
|         j.controlsAccepted.push('SERVICE_CONTROL_NETBINDENABLE'); | ||||
|         j.controlsAccepted.push('SERVICE_CONTROL_NETBINDDISABLE'); | ||||
|     } | ||||
|     if ((controlsAccepted & 0x00000008) == 0x00000008) { j.controlsAccepted.push('SERVICE_CONTROL_PARAMCHANGE'); } | ||||
|     if ((controlsAccepted & 0x00000002) == 0x00000002) { j.controlsAccepted.push('SERVICE_CONTROL_PAUSE'); j.controlsAccepted.push('SERVICE_CONTROL_CONTINUE'); } | ||||
|     if ((controlsAccepted & 0x00000100) == 0x00000100) { j.controlsAccepted.push('SERVICE_CONTROL_PRESHUTDOWN'); } | ||||
|     if ((controlsAccepted & 0x00000004) == 0x00000004) { j.controlsAccepted.push('SERVICE_CONTROL_SHUTDOWN'); } | ||||
|     if ((controlsAccepted & 0x00000001) == 0x00000001) { j.controlsAccepted.push('SERVICE_CONTROL_STOP'); } | ||||
|     if ((controlsAccepted & 0x00000020) == 0x00000020) { j.controlsAccepted.push('SERVICE_CONTROL_HARDWAREPROFILECHANGE'); } | ||||
|     if ((controlsAccepted & 0x00000040) == 0x00000040) { j.controlsAccepted.push('SERVICE_CONTROL_POWEREVENT'); } | ||||
|     if ((controlsAccepted & 0x00000080) == 0x00000080) { j.controlsAccepted.push('SERVICE_CONTROL_SESSIONCHANGE'); } | ||||
|     j.pid = token.Deref((7 * 4), 4).toBuffer().readUInt32LE(); | ||||
|     return (j); | ||||
| } | ||||
| 
 | ||||
| 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'); | ||||
|         this.proxy.CreateMethod('EnumServicesStatusExA'); | ||||
|         this.proxy.CreateMethod('OpenServiceA'); | ||||
|         this.proxy.CreateMethod('QueryServiceStatusEx'); | ||||
|         this.proxy.CreateMethod('ControlService'); | ||||
|         this.proxy.CreateMethod('StartServiceA'); | ||||
|         this.proxy.CreateMethod('CloseServiceHandle'); | ||||
|         this.proxy.CreateMethod('CreateServiceA'); | ||||
|         this.proxy.CreateMethod('ChangeServiceConfig2A'); | ||||
|         this.proxy.CreateMethod('DeleteService'); | ||||
|         this.proxy.CreateMethod('AllocateAndInitializeSid'); | ||||
|         this.proxy.CreateMethod('CheckTokenMembership'); | ||||
|         this.proxy.CreateMethod('FreeSid'); | ||||
| 
 | ||||
|         this.proxy2 = this.GM.CreateNativeProxy('Kernel32.dll'); | ||||
|         this.proxy2.CreateMethod('GetLastError'); | ||||
| 
 | ||||
|         this.isAdmin = function isAdmin() { | ||||
|             var NTAuthority = this.GM.CreateVariable(6); | ||||
|             NTAuthority.toBuffer().writeInt8(5, 5); | ||||
|             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) | ||||
|             { | ||||
|                 var member = this.GM.CreateInteger(); | ||||
|                 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') | ||||
|             { | ||||
|                 // 64 bit Windows
 | ||||
|                 if (this.GM.PointerSize == 4) | ||||
|                 { | ||||
|                     return process.env['ProgramFiles(x86)'];    // 32 Bit App
 | ||||
|                 }  | ||||
|                 return process.env['ProgramFiles'];             // 64 bit App
 | ||||
|             } | ||||
| 
 | ||||
|             // 32 bit Windows
 | ||||
|             return process.env['ProgramFiles'];                  | ||||
|         }; | ||||
|         this.getServiceFolder = function getServiceFolder() { return this.getProgramFolder() + '\\mesh'; }; | ||||
| 
 | ||||
|         this.enumerateService = function () { | ||||
|             var machineName = this.GM.CreatePointer(); | ||||
|             var dbName = this.GM.CreatePointer(); | ||||
|             var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0001 | 0x0004); | ||||
| 
 | ||||
|             var bytesNeeded = this.GM.CreatePointer(); | ||||
|             var servicesReturned = this.GM.CreatePointer(); | ||||
|             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'); | ||||
|             } | ||||
|             var sz = bytesNeeded.IntVal; | ||||
|             var services = this.GM.CreateVariable(sz); | ||||
|             this.proxy.EnumServicesStatusExA(handle, 0, 0x00000030, 0x00000003, services, sz, bytesNeeded, servicesReturned, resumeHandle, 0x00); | ||||
|             console.log("servicesReturned", servicesReturned.IntVal); | ||||
| 
 | ||||
|             var ptrSize = dbName._size; | ||||
|             var blockSize = 36 + (2 * ptrSize); | ||||
|             blockSize += ((ptrSize - (blockSize % ptrSize)) % ptrSize); | ||||
|             var retVal = []; | ||||
|             for (var i = 0; i < servicesReturned.IntVal; ++i) { | ||||
|                 var token = services.Deref(i * blockSize, blockSize); | ||||
|                 var j = {}; | ||||
|                 j.name = token.Deref(0, ptrSize).Deref().String; | ||||
|                 j.displayName = token.Deref(ptrSize, ptrSize).Deref().String; | ||||
|                 j.status = parseServiceStatus(token.Deref(2 * ptrSize, 36)); | ||||
|                 retVal.push(j); | ||||
|             } | ||||
|             this.proxy.CloseServiceHandle(handle); | ||||
|             return (retVal); | ||||
|         } | ||||
|         this.getService = function (name) { | ||||
|             var serviceName = this.GM.CreateVariable(name); | ||||
|             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'); } | ||||
|             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); | ||||
|                 var status = this.GM.CreateVariable(bytesNeeded.toBuffer().readUInt32LE()); | ||||
|                 success = this.proxy.QueryServiceStatusEx(h, 0, status, status._size, bytesNeeded); | ||||
|                 if (success != 0) { | ||||
|                     retVal = {}; | ||||
|                     retVal.status = parseServiceStatus(status); | ||||
|                     retVal._scm = handle; | ||||
|                     retVal._service = h; | ||||
|                     retVal._GM = this.GM; | ||||
|                     retVal._proxy = this.proxy; | ||||
|                     require('events').inherits(retVal); | ||||
|                     retVal.on('~', function () { this._proxy.CloseServiceHandle(this); this._proxy.CloseServiceHandle(this._scm); }); | ||||
|                     retVal.name = name; | ||||
|                     retVal.stop = function () { | ||||
|                         if (this.status.state == 'RUNNING') { | ||||
|                             var newstate = this._GM.CreateVariable(36); | ||||
|                             var success = this._proxy.ControlService(this._service, 0x00000001, newstate); | ||||
|                             if (success == 0) { | ||||
|                                 throw (this.name + '.stop() failed'); | ||||
|                             } | ||||
|                         } | ||||
|                         else { | ||||
|                             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); | ||||
|                         } | ||||
|                     } | ||||
|                     return (retVal); | ||||
|                 } | ||||
|                 else { | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             this.proxy.CloseServiceHandle(handle); | ||||
|             throw ('could not find service: ' + name); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         this.isAdmin = function isAdmin()  | ||||
|         { | ||||
|             return (require('user-sessions').isRoot()); | ||||
|         } | ||||
|     } | ||||
|     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.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'; | ||||
| 
 | ||||
|             var servicePath = this.GM.CreateVariable('"' + options.servicePath + '"'); | ||||
|             var handle = this.proxy.OpenSCManagerA(0x00, 0x00, 0x0002); | ||||
|             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; | ||||
|             var serviceType; | ||||
|              | ||||
| 
 | ||||
|             switch (options.startType) { | ||||
|                 case 'BOOT_START': | ||||
|                     serviceType = 0x00; | ||||
|                     break; | ||||
|                 case 'SYSTEM_START': | ||||
|                     serviceType = 0x01; | ||||
|                     break; | ||||
|                 case 'AUTO_START': | ||||
|                     serviceType = 0x02; | ||||
|                     break; | ||||
|                 case 'DEMAND_START': | ||||
|                     serviceType = 0x03; | ||||
|                     break; | ||||
|                 default: | ||||
|                     serviceType = 0x04; // Disabled
 | ||||
|                     break; | ||||
|             } | ||||
| 
 | ||||
|             var h = this.proxy.CreateServiceA(handle, serviceName, displayName, allAccess, 0x10 | 0x100, serviceType, 0, servicePath, 0, 0, 0, 0, 0); | ||||
|             if (h.Val == 0) { this.proxy.CloseServiceHandle(handle); throw ('Error Creating Service: ' + this.proxy2.GetLastError().Val); } | ||||
|             if (options.description) { | ||||
|                 console.log(options.description); | ||||
| 
 | ||||
|                 var dscPtr = this.GM.CreatePointer(); | ||||
|                 dscPtr.Val = this.GM.CreateVariable(options.description); | ||||
| 
 | ||||
|                 if (this.proxy.ChangeServiceConfig2A(h, 1, dscPtr) == 0) { | ||||
|                     this.proxy.CloseServiceHandle(h); | ||||
|                     this.proxy.CloseServiceHandle(handle); | ||||
|                     throw ('Unable to set description'); | ||||
|                 } | ||||
|             } | ||||
|             this.proxy.CloseServiceHandle(h); | ||||
|             this.proxy.CloseServiceHandle(handle); | ||||
|             return (this.getService(options.name)); | ||||
|         } | ||||
|         if(process.platform == 'linux') | ||||
|         { | ||||
|             if (!this.isAdmin()) { throw ('Installing as Service, requires root'); } | ||||
| 
 | ||||
|             switch (this.getServiceType()) | ||||
|             { | ||||
|                 case 'init': | ||||
|                     require('fs').copyFileSync(options.servicePath, '/etc/init.d/' + options.name); | ||||
|                     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); | ||||
|                     this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); | ||||
|                     this._update._moduleName = options.name; | ||||
|                     this._update.stdout.on('data', function (chunk) { }); | ||||
|                     this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n'); | ||||
|                     this._update.stdin.write('exit\n'); | ||||
|                     //update-rc.d meshagent defaults # creates symlinks for rc.d
 | ||||
|                     //service meshagent start
 | ||||
| 
 | ||||
|                     this._update.waitExit(); | ||||
| 
 | ||||
|                     break; | ||||
|                 case 'systemd': | ||||
|                     var serviceDescription = options.description ? options.description : 'MeshCentral Agent'; | ||||
|                     if (!require('fs').existsSync('/usr/local/mesh')) { require('fs').mkdirSync('/usr/local/mesh'); } | ||||
|                     require('fs').copyFileSync(options.servicePath, '/usr/local/mesh/' + options.name); | ||||
|                     var m = require('fs').statSync('/usr/local/mesh/' + options.name).mode; | ||||
|                     m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP); | ||||
|                     require('fs').chmodSync('/usr/local/mesh/' + options.name, m); | ||||
|                     require('fs').writeFileSync('/lib/systemd/system/' + options.name + '.service', '[Unit]\nDescription=' + serviceDescription + '\n[Service]\nExecStart=/usr/local/mesh/' + options.name + '\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=' + options.name + '.service\n', { flags: 'w' }); | ||||
|                     this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); | ||||
|                     this._update._moduleName = options.name; | ||||
|                     this._update.stdout.on('data', function (chunk) { }); | ||||
|                     this._update.stdin.write('systemctl enable ' + options.name + '.service\n'); | ||||
|                     this._update.stdin.write('exit\n'); | ||||
|                     this._update.waitExit(); | ||||
|                     break; | ||||
|                 default: // unknown platform service type
 | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         if(process.platform == 'darwin') | ||||
|         { | ||||
|             if (!this.isAdmin()) { throw ('Installing as Service, requires root'); } | ||||
| 
 | ||||
|             // Mac OS
 | ||||
|             var stdoutpath = (options.stdout ? ('<key>StandardOutPath</key>\n<string>' + options.stdout + '</string>') : ''); | ||||
|             var autoStart = (options.startType == 'AUTO_START' ? '<true/>' : '<false/>'); | ||||
|             var params =  '     <key>ProgramArguments</key>\n'; | ||||
|             params += '     <array>\n'; | ||||
|             params += ('         <string>/usr/local/mesh_services/' + options.name + '/' + options.name + '</string>\n'); | ||||
|             if(options.parameters) | ||||
|             { | ||||
|                 for(var itm in options.parameters) | ||||
|                 { | ||||
|                     params += ('         <string>' + options.parameters[itm] + '</string>\n'); | ||||
|                 } | ||||
|             }         | ||||
|             params += '     </array>\n'; | ||||
|              | ||||
|             var plist = '<?xml version="1.0" encoding="UTF-8"?>\n'; | ||||
|             plist += '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'; | ||||
|             plist += '<plist version="1.0">\n'; | ||||
|             plist += '  <dict>\n'; | ||||
|             plist += '      <key>Label</key>\n'; | ||||
|             plist += ('     <string>' + options.name + '</string>\n'); | ||||
|             plist += (params + '\n'); | ||||
|             plist += '      <key>WorkingDirectory</key>\n'; | ||||
|             plist += ('     <string>/usr/local/mesh_services/' + options.name + '</string>\n'); | ||||
|             plist += (stdoutpath + '\n'); | ||||
|             plist += '      <key>RunAtLoad</key>\n'; | ||||
|             plist += (autoStart + '\n'); | ||||
|             plist += '  </dict>\n'; | ||||
|             plist += '</plist>'; | ||||
| 
 | ||||
|             if (!require('fs').existsSync('/usr/local/mesh_services')) { require('fs').mkdirSync('/usr/local/mesh_services'); } | ||||
|             if (!require('fs').existsSync('/Library/LaunchDaemons/' + options.name + '.plist')) | ||||
|             { | ||||
|                 if (!require('fs').existsSync('/usr/local/mesh_services/' + options.name)) { require('fs').mkdirSync('/usr/local/mesh_services/' + options.name); } | ||||
|                 if (options.binary) | ||||
|                 { | ||||
|                     require('fs').writeFileSync('/usr/local/mesh_services/' + options.name + '/' + options.name, options.binary); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     require('fs').copyFileSync(options.servicePath, '/usr/local/mesh_services/' + options.name + '/' + options.name); | ||||
|                 } | ||||
|                 require('fs').writeFileSync('/Library/LaunchDaemons/' + options.name + '.plist', plist); | ||||
|                 var m = require('fs').statSync('/usr/local/mesh_services/' + options.name + '/' + options.name).mode; | ||||
|                 m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP); | ||||
|                 require('fs').chmodSync('/usr/local/mesh_services/' + options.name + '/' + options.name, m); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw ('Service: ' + options.name + ' already exists'); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     this.uninstallService = function uninstallService(name) | ||||
|     { | ||||
|         if (!this.isAdmin()) { throw ('Uninstalling a service, requires admin'); } | ||||
| 
 | ||||
|         if (typeof (name) == 'object') { name = name.name; } | ||||
|         if (process.platform == 'win32') | ||||
|         { | ||||
|             var service = this.getService(name); | ||||
|             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 | ||||
|             { | ||||
|                 throw ('Cannot uninstall service: ' + name + ', because it is: ' + service.status.state); | ||||
|             } | ||||
|         } | ||||
|         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.stdout.on('data', function (chunk) { }); | ||||
|                     this._update.stdin.write('service ' + name + ' stop\n'); | ||||
|                     this._update.stdin.write('update-rc.d -f ' + name + ' remove\n'); | ||||
|                     this._update.stdin.write('exit\n'); | ||||
|                     this._update.waitExit(); | ||||
|                     try | ||||
|                     { | ||||
|                         require('fs').unlinkSync('/etc/init.d/' + name); | ||||
|                         console.log(name + ' uninstalled'); | ||||
| 
 | ||||
|                     } | ||||
|                     catch (e) | ||||
|                     { | ||||
|                         console.log(name + ' could not be uninstalled', e) | ||||
|                     } | ||||
|                     break; | ||||
|                 case 'systemd': | ||||
|                     this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM }); | ||||
|                     this._update.stdout.on('data', function (chunk) { }); | ||||
|                     this._update.stdin.write('systemctl stop ' + name + '.service\n'); | ||||
|                     this._update.stdin.write('systemctl disable ' + name + '.service\n'); | ||||
|                     this._update.stdin.write('exit\n'); | ||||
|                     this._update.waitExit(); | ||||
|                     try | ||||
|                     { | ||||
|                         require('fs').unlinkSync('/usr/local/mesh/' + name); | ||||
|                         require('fs').unlinkSync('/lib/systemd/system/' + name + '.service'); | ||||
|                         console.log(name + ' uninstalled'); | ||||
|                     } | ||||
|                     catch (e) | ||||
|                     { | ||||
|                         console.log(name + ' could not be uninstalled', e) | ||||
|                     } | ||||
|                     break; | ||||
|                 default: // unknown platform service type
 | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         else if(process.platform == 'darwin') | ||||
|         { | ||||
|             if (require('fs').existsSync('/Library/LaunchDaemons/' + name + '.plist')) | ||||
|             { | ||||
|                 var child = require('child_process').execFile('/bin/sh', ['sh']); | ||||
|                 child.stdout.on('data', function (chunk) { }); | ||||
|                 child.stdin.write('launchctl stop ' + name + '\n'); | ||||
|                 child.stdin.write('launchctl unload /Library/LaunchDaemons/' + name + '.plist\n'); | ||||
|                 child.stdin.write('exit\n'); | ||||
|                 child.waitExit(); | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
|                     require('fs').unlinkSync('/usr/local/mesh_services/' + name + '/' + name); | ||||
|                     require('fs').unlinkSync('/Library/LaunchDaemons/' + name + '.plist'); | ||||
|                 } | ||||
|                 catch(e) | ||||
|                 { | ||||
|                     throw ('Error uninstalling service: ' + name + ' => ' + e); | ||||
|                 } | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
|                     require('fs').rmdirSync('/usr/local/mesh_services/' + name); | ||||
|                 } | ||||
|                 catch(e) | ||||
|                 {} | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw ('Service: ' + name + ' does not exist'); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     if(process.platform == 'linux') | ||||
|     { | ||||
|         this.getServiceType = function getServiceType() | ||||
|         { | ||||
|             return (require('process-manager').getProcessInfo(1).Name); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = serviceManager; | ||||
|  | @ -1,750 +0,0 @@ | |||
| /* | ||||
| 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 NOTIFY_FOR_THIS_SESSION = 0; | ||||
| var NOTIFY_FOR_ALL_SESSIONS = 1; | ||||
| var WM_WTSSESSION_CHANGE = 0x02B1; | ||||
| var WM_POWERBROADCAST = 0x218; | ||||
| var PBT_POWERSETTINGCHANGE = 0x8013; | ||||
| var PBT_APMSUSPEND = 0x4; | ||||
| var PBT_APMRESUMESUSPEND = 0x7; | ||||
| var PBT_APMRESUMEAUTOMATIC = 0x12; | ||||
| var PBT_APMPOWERSTATUSCHANGE = 0xA; | ||||
| 
 | ||||
| var WTS_CONSOLE_CONNECT         = (0x1); | ||||
| var WTS_CONSOLE_DISCONNECT      = (0x2); | ||||
| var WTS_REMOTE_CONNECT          = (0x3); | ||||
| var WTS_REMOTE_DISCONNECT       = (0x4); | ||||
| var WTS_SESSION_LOGON           = (0x5); | ||||
| var WTS_SESSION_LOGOFF          = (0x6); | ||||
| var WTS_SESSION_LOCK            = (0x7); | ||||
| var WTS_SESSION_UNLOCK          = (0x8); | ||||
| var WTS_SESSION_REMOTE_CONTROL  = (0x9); | ||||
| var WTS_SESSION_CREATE          = (0xA); | ||||
| var WTS_SESSION_TERMINATE       = (0xB); | ||||
| 
 | ||||
| var GUID_ACDC_POWER_SOURCE; | ||||
| var GUID_BATTERY_PERCENTAGE_REMAINING; | ||||
| var GUID_CONSOLE_DISPLAY_STATE; | ||||
| 
 | ||||
| function UserSessions() | ||||
| { | ||||
|     this._ObjectID = 'user-sessions'; | ||||
|     require('events').EventEmitter.call(this, true) | ||||
|         .createEvent('changed') | ||||
|         .createEvent('locked') | ||||
|         .createEvent('unlocked'); | ||||
| 
 | ||||
|     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); | ||||
|         }; | ||||
|         try | ||||
|         { | ||||
|             this.Current(p.__handler); | ||||
|         } | ||||
|         catch(e) | ||||
|         { | ||||
|             p.__rejector(e); | ||||
|         } | ||||
|         p.parent = this; | ||||
|         return (p); | ||||
|     } | ||||
| 
 | ||||
|     if (process.platform == 'win32') | ||||
|     { | ||||
|         this._serviceHooked = false; | ||||
|         this._marshal = require('_GenericMarshal'); | ||||
|         this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll'); | ||||
|         this._kernel32.CreateMethod('GetLastError'); | ||||
|          | ||||
|         try | ||||
|         { | ||||
|             this._wts = this._marshal.CreateNativeProxy('Wtsapi32.dll'); | ||||
|             this._wts.CreateMethod('WTSEnumerateSessionsA'); | ||||
|             this._wts.CreateMethod('WTSQuerySessionInformationA'); | ||||
|             this._wts.CreateMethod('WTSRegisterSessionNotification'); | ||||
|             this._wts.CreateMethod('WTSUnRegisterSessionNotification'); | ||||
|             this._wts.CreateMethod('WTSFreeMemory'); | ||||
|         } | ||||
|         catch(exc) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll'); | ||||
|         this._advapi.CreateMethod('AllocateAndInitializeSid'); | ||||
|         this._advapi.CreateMethod('CheckTokenMembership'); | ||||
|         this._advapi.CreateMethod('FreeSid'); | ||||
| 
 | ||||
|         this._user32 = this._marshal.CreateNativeProxy('user32.dll'); | ||||
|         this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1}); | ||||
|         this._user32.CreateMethod('UnregisterPowerSettingNotification'); | ||||
|         this._rpcrt = this._marshal.CreateNativeProxy('Rpcrt4.dll'); | ||||
|         this._rpcrt.CreateMethod('UuidFromStringA'); | ||||
|         this._rpcrt.StringToUUID = function StringToUUID(guid) | ||||
|         { | ||||
|             var retVal = StringToUUID.us._marshal.CreateVariable(16); | ||||
|             if(StringToUUID.us._rpcrt.UuidFromStringA(StringToUUID.us._marshal.CreateVariable(guid), retVal).Val == 0) | ||||
|             { | ||||
|                 return (retVal); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw ('Could not convert string to UUID'); | ||||
|             } | ||||
|         } | ||||
|         this._rpcrt.StringToUUID.us = this; | ||||
| 
 | ||||
|         GUID_ACDC_POWER_SOURCE = this._rpcrt.StringToUUID('5d3e9a59-e9D5-4b00-a6bd-ff34ff516548'); | ||||
|         GUID_BATTERY_PERCENTAGE_REMAINING = this._rpcrt.StringToUUID('a7ad8041-b45a-4cae-87a3-eecbb468a9e1'); | ||||
|         GUID_CONSOLE_DISPLAY_STATE = this._rpcrt.StringToUUID('6fe69556-704a-47a0-8f24-c28d936fda47'); | ||||
| 
 | ||||
|         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.isRoot = function isRoot() | ||||
|         { | ||||
|             var NTAuthority = this._marshal.CreateVariable(6); | ||||
|             NTAuthority.toBuffer().writeInt8(5, 5); | ||||
| 
 | ||||
|             var AdministratorsGroup = this._marshal.CreatePointer(); | ||||
|             var admin = false; | ||||
| 
 | ||||
|             if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0) | ||||
|             { | ||||
|                 var member = this._marshal.CreateInteger(); | ||||
|                 if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0) | ||||
|                 { | ||||
|                     if (member.toBuffer().readUInt32LE() != 0) { admin = true; } | ||||
|                 } | ||||
|                 this._advapi.FreeSid(AdministratorsGroup.Deref()); | ||||
|             } | ||||
|             return admin; | ||||
|         } | ||||
| 
 | ||||
|         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(cb) | ||||
|         { | ||||
|             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, 'Active', { value: showActiveOnly(retVal) }); | ||||
|             if (cb) { cb(retVal); } | ||||
|             return (retVal); | ||||
|         }; | ||||
| 
 | ||||
| 
 | ||||
|         // We need to spin up a message pump, and fetch a window handle
 | ||||
|         var message_pump = require('win-message-pump'); | ||||
|         this._messagepump = new message_pump({ filter: WM_WTSSESSION_CHANGE }); this._messagepump.parent = this;      | ||||
|         this._messagepump.on('exit', function (code) { this.parent._wts.WTSUnRegisterSessionNotification(this.parent.hwnd); }); | ||||
|         this._messagepump.on('hwnd', function (h) | ||||
|         { | ||||
|             this.parent.hwnd = h; | ||||
| 
 | ||||
|             // 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
 | ||||
|                 if (self.parent._wts) { 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) | ||||
|         { | ||||
|             switch(msg.message) | ||||
|             { | ||||
|                 case WM_WTSSESSION_CHANGE: | ||||
|                     switch(msg.wparam) | ||||
|                     { | ||||
|                         case WTS_SESSION_LOCK: | ||||
|                             this.parent.enumerateUsers().then(function (users) | ||||
|                             { | ||||
|                                 if (users[msg.lparam]) { this.parent.emit('locked', users[msg.lparam]); } | ||||
|                             }); | ||||
|                             break; | ||||
|                         case WTS_SESSION_UNLOCK: | ||||
|                             this.parent.enumerateUsers().then(function (users) | ||||
|                             { | ||||
|                                 if (users[msg.lparam]) { this.parent.emit('unlocked', users[msg.lparam]); } | ||||
|                             }); | ||||
|                             break; | ||||
|                         case WTS_SESSION_LOGON: | ||||
|                         case WTS_SESSION_LOGOFF: | ||||
|                             this.parent.emit('changed'); | ||||
|                             break; | ||||
|                     } | ||||
|                     break; | ||||
|                 case WM_POWERBROADCAST: | ||||
|                     switch(msg.wparam) | ||||
|                     { | ||||
|                         default: | ||||
|                             console.log('WM_POWERBROADCAST [UNKNOWN wparam]: ' + msg.wparam); | ||||
|                             break; | ||||
|                         case PBT_APMSUSPEND: | ||||
|                             require('power-monitor').emit('sx', 'SLEEP'); | ||||
|                             break; | ||||
|                         case PBT_APMRESUMEAUTOMATIC: | ||||
|                             require('power-monitor').emit('sx', 'RESUME_NON_INTERACTIVE'); | ||||
|                             break; | ||||
|                         case PBT_APMRESUMESUSPEND: | ||||
|                             require('power-monitor').emit('sx', 'RESUME_INTERACTIVE'); | ||||
|                             break; | ||||
|                         case PBT_APMPOWERSTATUSCHANGE: | ||||
|                             require('power-monitor').emit('changed'); | ||||
|                             break; | ||||
|                         case PBT_POWERSETTINGCHANGE: | ||||
|                             var lparam = this.parent._marshal.CreatePointer(Buffer.from(msg.lparam_hex, 'hex')); | ||||
|                             var data = lparam.Deref(20, lparam.Deref(16, 4).toBuffer().readUInt32LE(0)).toBuffer(); | ||||
|                             switch(lparam.Deref(0, 16).toBuffer().toString('hex')) | ||||
|                             { | ||||
|                                 case GUID_ACDC_POWER_SOURCE.Deref(0, 16).toBuffer().toString('hex'): | ||||
|                                     switch(data.readUInt32LE(0)) | ||||
|                                     { | ||||
|                                         case 0: | ||||
|                                             require('power-monitor').emit('acdc', 'AC'); | ||||
|                                             break; | ||||
|                                         case 1: | ||||
|                                             require('power-monitor').emit('acdc', 'BATTERY'); | ||||
|                                             break; | ||||
|                                         case 2: | ||||
|                                             require('power-monitor').emit('acdc', 'HOT'); | ||||
|                                             break; | ||||
|                                     } | ||||
|                                     break; | ||||
|                                 case GUID_BATTERY_PERCENTAGE_REMAINING.Deref(0, 16).toBuffer().toString('hex'): | ||||
|                                     require('power-monitor').emit('batteryLevel', data.readUInt32LE(0)); | ||||
|                                     break; | ||||
|                                 case GUID_CONSOLE_DISPLAY_STATE.Deref(0, 16).toBuffer().toString('hex'): | ||||
|                                     switch(data.readUInt32LE(0)) | ||||
|                                     { | ||||
|                                         case 0: | ||||
|                                             require('power-monitor').emit('display', 'OFF'); | ||||
|                                             break; | ||||
|                                         case 1: | ||||
|                                             require('power-monitor').emit('display', 'ON'); | ||||
|                                             break; | ||||
|                                         case 2: | ||||
|                                             require('power-monitor').emit('display', 'DIMMED'); | ||||
|                                             break; | ||||
|                                     } | ||||
|                                     break; | ||||
|                             } | ||||
|                             break; | ||||
|                     } | ||||
|                     break; | ||||
|                 default: | ||||
|                     break; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|     else if(process.platform == 'linux') | ||||
|     { | ||||
|         var dbus = require('linux-dbus'); | ||||
|         this._linuxWatcher = require('fs').watch('/var/run/utmp'); | ||||
|         this._linuxWatcher.user_session = this; | ||||
|         this._linuxWatcher.on('change', function (a, b) | ||||
|         { | ||||
|             this.user_session.emit('changed'); | ||||
|         }); | ||||
|         this._users = function _users() | ||||
|         { | ||||
|             var child = require('child_process').execFile('/bin/sh', ['sh']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n'); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n'); | ||||
|             var ret = {}, tokens; | ||||
|             for (var ln in lines) | ||||
|             { | ||||
|                 tokens = lines[ln].split(':'); | ||||
|                 if (tokens[0]) { ret[tokens[0]] = tokens[1]; }            | ||||
|             } | ||||
|             return (ret); | ||||
|         } | ||||
|         this._uids = function _uids() { | ||||
|             var child = require('child_process').execFile('/bin/sh', ['sh']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.stdin.write('awk -F: \'($3 >= 0) {printf "%s:%s\\n", $1, $3}\' /etc/passwd\nexit\n'); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n'); | ||||
|             var ret = {}, tokens; | ||||
|             for (var ln in lines) { | ||||
|                 tokens = lines[ln].split(':'); | ||||
|                 if (tokens[0]) { ret[tokens[1]] = tokens[0]; } | ||||
|             } | ||||
|             return (ret); | ||||
|         } | ||||
|         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 = {}; | ||||
|             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.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]) | ||||
|                     { | ||||
|                         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(); | ||||
| 
 | ||||
| 
 | ||||
|                 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(); }); | ||||
| 
 | ||||
|             return (retVal); | ||||
|         } | ||||
|         this._recheckLoggedInUsers = function _recheckLoggedInUsers() | ||||
|         { | ||||
|             this.enumerateUsers().then(function (u) | ||||
|             { | ||||
| 
 | ||||
|                 if (u.Active.length > 0) | ||||
|                 { | ||||
|                     // There is already a user logged in, so we can monitor DBUS for lock/unlock
 | ||||
|                     if (this.parent._linux_lock_watcher != null && this.parent._linux_lock_watcher.uid != u.Active[0].uid) | ||||
|                     { | ||||
|                         delete this.parent._linux_lock_watcher; | ||||
|                     } | ||||
|                     this.parent._linux_lock_watcher = new dbus(process.env['XDG_CURRENT_DESKTOP'] == 'Unity' ? 'com.ubuntu.Upstart0_6' : 'org.gnome.ScreenSaver', u.Active[0].uid); | ||||
|                     this.parent._linux_lock_watcher.user_session = this.parent; | ||||
|                     this.parent._linux_lock_watcher.on('signal', function (s) | ||||
|                     { | ||||
|                         var p = this.user_session.enumerateUsers(); | ||||
|                         p.signalData = s.data[0]; | ||||
|                         p.then(function (u) | ||||
|                         { | ||||
|                             switch (this.signalData) | ||||
|                             { | ||||
|                                 case true: | ||||
|                                 case 'desktop-lock': | ||||
|                                     this.parent.emit('locked', u.Active[0]); | ||||
|                                     break; | ||||
|                                 case false: | ||||
|                                 case 'desktop-unlock': | ||||
|                                     this.parent.emit('unlocked', u.Active[0]); | ||||
|                                     break; | ||||
|                             } | ||||
|                         }); | ||||
|                     }); | ||||
|                 } | ||||
|                 else if (this.parent._linux_lock_watcher != null) | ||||
|                 { | ||||
|                     delete this.parent._linux_lock_watcher; | ||||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|         }; | ||||
|         this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID.
 | ||||
| 
 | ||||
|          | ||||
|         // First step, is to see if there is a user logged in:
 | ||||
|         this._recheckLoggedInUsers(); | ||||
|     } | ||||
|     else if(process.platform == 'darwin') | ||||
|     { | ||||
|         this._users = function () | ||||
|         { | ||||
|             var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.stdin.write('exit\n'); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n'); | ||||
|             var tokens, i; | ||||
|             var users = {}; | ||||
| 
 | ||||
|             for (i = 0; i < lines.length; ++i) { | ||||
|                 tokens = lines[i].split(' '); | ||||
|                 if (tokens[0]) { users[tokens[0]] = tokens[tokens.length - 1]; } | ||||
|             } | ||||
| 
 | ||||
|             return (users); | ||||
|         } | ||||
|         this._uids = function () { | ||||
|             var child = require('child_process').execFile('/usr/bin/dscl', ['dscl', '.', 'list', '/Users', 'UniqueID']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.stdin.write('exit\n'); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n'); | ||||
|             var tokens, i; | ||||
|             var users = {}; | ||||
| 
 | ||||
|             for (i = 0; i < lines.length; ++i) { | ||||
|                 tokens = lines[i].split(' '); | ||||
|                 if (tokens[0]) { users[tokens[tokens.length - 1]] = tokens[0]; } | ||||
|             } | ||||
| 
 | ||||
|             return (users); | ||||
|         } | ||||
|         this._idTable = function() | ||||
|         { | ||||
|             var table = {}; | ||||
|             var child = require('child_process').execFile('/usr/bin/id', ['id']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n')[0].split(' '); | ||||
|             for (var i = 0; i < lines.length; ++i) { | ||||
|                 var types = lines[i].split('='); | ||||
|                 var tokens = types[1].split(','); | ||||
|                 table[types[0]] = {}; | ||||
| 
 | ||||
|                 for (var j in tokens) { | ||||
|                     var idarr = tokens[j].split('('); | ||||
|                     var id = idarr[0]; | ||||
|                     var name = idarr[1].substring(0, idarr[1].length - 1).trim(); | ||||
|                     table[types[0]][name] = id; | ||||
|                     table[types[0]][id] = name; | ||||
|                 } | ||||
|             } | ||||
|             return (table); | ||||
|         } | ||||
|         this.Current = function (cb) | ||||
|         { | ||||
|             var users = {}; | ||||
|             var table = this._idTable(); | ||||
|             var child = require('child_process').execFile('/usr/bin/last', ['last']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n'); | ||||
|             for (var i = 0; i < lines.length && lines[i].length > 0; ++i) | ||||
|             { | ||||
|                 if (!users[lines[i].split(' ')[0]]) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         users[lines[i].split(' ')[0]] = { Username: lines[i].split(' ')[0], State: lines[i].split('still logged in').length > 1 ? 'Active' : 'Inactive', uid: table.uid[lines[i].split(' ')[0]] }; | ||||
|                     } | ||||
|                     catch(e) | ||||
|                     {} | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if(users[lines[i].split(' ')[0]].State != 'Active' && lines[i].split('still logged in').length > 1) | ||||
|                     { | ||||
|                         users[lines[i].split(' ')[0]].State = 'Active'; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             Object.defineProperty(users, 'Active', { value: showActiveOnly(users) }); | ||||
|             if (cb) { cb.call(this, users); } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(process.platform == 'linux' || process.platform == 'darwin') | ||||
|     { | ||||
|         this._self = function _self() | ||||
|         { | ||||
|             var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.waitExit(); | ||||
|             return (parseInt(child.stdout.str)); | ||||
|         } | ||||
|         this.isRoot = function isRoot() | ||||
|         { | ||||
|             return (this._self() == 0); | ||||
|         } | ||||
|         this.consoleUid = function consoleUid() | ||||
|         { | ||||
|             var checkstr = process.platform == 'darwin' ? 'console' : ((process.env['DISPLAY'])?process.env['DISPLAY']:':0') | ||||
|             var child = require('child_process').execFile('/bin/sh', ['sh']); | ||||
|             child.stdout.str = ''; | ||||
|             child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); | ||||
|             child.stdin.write('who\nexit\n'); | ||||
|             child.waitExit(); | ||||
| 
 | ||||
|             var lines = child.stdout.str.split('\n'); | ||||
|             var tokens, i, j; | ||||
|             for (i in lines) | ||||
|             { | ||||
|                 tokens = lines[i].split(' '); | ||||
|                 for (j = 1; j < tokens.length; ++j) | ||||
|                 { | ||||
|                     if (tokens[j].length > 0) | ||||
|                     { | ||||
|                         return (parseInt(this._users()[tokens[0]])); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             throw ('nobody logged into console'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| function showActiveOnly(source) | ||||
| { | ||||
|     var retVal = []; | ||||
|     var unique = {}; | ||||
|     var usernames = []; | ||||
|     var tmp; | ||||
| 
 | ||||
|     for (var i in source) | ||||
|     { | ||||
|         if (source[i].State == 'Active') | ||||
|         { | ||||
|             retVal.push(source[i]); | ||||
|             tmp = (source[i].Domain ? (source[i].Domain + '\\') : '') + source[i].Username; | ||||
|             if (!unique[tmp]) { unique[tmp] = tmp;} | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (var i in unique) | ||||
|     { | ||||
|         usernames.push(i); | ||||
|     } | ||||
| 
 | ||||
|     Object.defineProperty(retVal, 'usernames', { value: usernames }); | ||||
|     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, (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); | ||||
| } | ||||
| 
 | ||||
| module.exports = new UserSessions(); | ||||
|  | @ -1,124 +0,0 @@ | |||
| /* | ||||
| Copyright 2018-2019 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; | ||||
| 
 | ||||
| var GM = require('_GenericMarshal'); | ||||
| 
 | ||||
| function WindowsMessagePump(options) | ||||
| { | ||||
|     this._ObjectID = 'win-message-pump'; | ||||
|     this._options = options; | ||||
|     var emitterUtils = require('events').inherits(this); | ||||
|     emitterUtils.createEvent('hwnd'); | ||||
|     emitterUtils.createEvent('error'); | ||||
|     emitterUtils.createEvent('message'); | ||||
|     emitterUtils.createEvent('exit'); | ||||
| 
 | ||||
|     this._msg = GM.CreateVariable(GM.PointerSize == 4 ? 28 : 48); | ||||
|     this._kernel32 = GM.CreateNativeProxy('Kernel32.dll'); | ||||
|     this._kernel32.mp = this; | ||||
|     this._kernel32.CreateMethod('GetLastError'); | ||||
|     this._kernel32.CreateMethod('GetModuleHandleA'); | ||||
| 
 | ||||
|     this._user32 = GM.CreateNativeProxy('User32.dll'); | ||||
|     this._user32.mp = this; | ||||
|     this._user32.CreateMethod('GetMessageA'); | ||||
|     this._user32.CreateMethod('CreateWindowExA'); | ||||
|     this._user32.CreateMethod('TranslateMessage'); | ||||
|     this._user32.CreateMethod('DispatchMessageA'); | ||||
|     this._user32.CreateMethod('RegisterClassExA'); | ||||
|     this._user32.CreateMethod('DefWindowProcA'); | ||||
|     this._user32.CreateMethod('PostMessageA'); | ||||
| 
 | ||||
| 
 | ||||
|     this.wndclass = GM.CreateVariable(GM.PointerSize == 4 ? 48 : 80); | ||||
|     this.wndclass.mp = this; | ||||
|     this.wndclass.hinstance = this._kernel32.GetModuleHandleA(0); | ||||
|     this.wndclass.cname = GM.CreateVariable('MainWWWClass'); | ||||
|     this.wndclass.wndproc = GM.GetGenericGlobalCallback(4); | ||||
|     this.wndclass.wndproc.mp = this; | ||||
|     this.wndclass.toBuffer().writeUInt32LE(this.wndclass._size); | ||||
|     this.wndclass.cname.pointerBuffer().copy(this.wndclass.Deref(GM.PointerSize == 4 ? 40 : 64, GM.PointerSize).toBuffer()); | ||||
|     this.wndclass.wndproc.pointerBuffer().copy(this.wndclass.Deref(8, GM.PointerSize).toBuffer()); | ||||
|     this.wndclass.hinstance.pointerBuffer().copy(this.wndclass.Deref(GM.PointerSize == 4 ? 20 : 24, GM.PointerSize).toBuffer()); | ||||
|     this.wndclass.wndproc.on('GlobalCallback', function onWndProc(xhwnd, xmsg, wparam, lparam) | ||||
|     { | ||||
|         if (this.mp._hwnd != null && this.mp._hwnd.Val == xhwnd.Val) | ||||
|         { | ||||
|             // This is for us
 | ||||
|             this.mp.emit('message', { message: xmsg.Val, wparam: wparam.Val, lparam: lparam.Val, lparam_hex: lparam.pointerBuffer().toString('hex') }); | ||||
|             return (this.mp._user32.DefWindowProcA(xhwnd, xmsg, wparam, lparam)); | ||||
|         } | ||||
|         else if(this.mp._hwnd == null && this.CallingThread() == this.mp._user32.RegisterClassExA.async.threadId()) | ||||
|         { | ||||
|             // This message was generated from our CreateWindowExA method
 | ||||
|             return (this.mp._user32.DefWindowProcA(xhwnd, xmsg, wparam, lparam)); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     this._user32.RegisterClassExA.async(this.wndclass).then(function () | ||||
|     { | ||||
|         this.nativeProxy.CreateWindowExA.async(this.nativeProxy.RegisterClassExA.async, 0x00000088, this.nativeProxy.mp.wndclass.cname, 0, 0x00800000, 0, 0, 100, 100, 0, 0, 0, 0) | ||||
|             .then(function(h) | ||||
|             { | ||||
|                 if (h.Val == 0) | ||||
|                 { | ||||
|                     // Error creating hidden window
 | ||||
|                     this.nativeProxy.mp.emit('error', 'Error creating hidden window'); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     this.nativeProxy.mp._hwnd = h; | ||||
|                     this.nativeProxy.mp.emit('hwnd', h); | ||||
|                     this.nativeProxy.mp._startPump(); | ||||
|                 } | ||||
|             }); | ||||
|     }); | ||||
|     this._startPump = function _startPump() | ||||
|     { | ||||
|         this._user32.GetMessageA.async(this._user32.RegisterClassExA.async, this._msg, this._hwnd, 0, 0).then(function (r) | ||||
|         { | ||||
|             if(r.Val > 0) | ||||
|             { | ||||
|                 this.nativeProxy.TranslateMessage.async(this.nativeProxy.RegisterClassExA.async, this.nativeProxy.mp._msg).then(function () | ||||
|                 { | ||||
|                     this.nativeProxy.DispatchMessageA.async(this.nativeProxy.RegisterClassExA.async, this.nativeProxy.mp._msg).then(function () | ||||
|                     { | ||||
|                         this.nativeProxy.mp._startPump(); | ||||
|                     }); | ||||
|                 }); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // We got a 'QUIT' message
 | ||||
|                 delete this.nativeProxy.mp._hwnd; | ||||
|                 this.nativeProxy.mp.emit('exit', 0); | ||||
|             } | ||||
|         }, function (err) { this.nativeProxy.mp.stop(); }); | ||||
|     } | ||||
| 
 | ||||
|     this.stop = function stop() | ||||
|     { | ||||
|         if (this._hwnd) | ||||
|         { | ||||
|             this._user32.PostMessageA(this._hwnd, WM_QUIT, 0, 0); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| module.exports = WindowsMessagePump; | ||||
|  | @ -1,218 +0,0 @@ | |||
| /* | ||||
| 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_ENUMERATE_SUB_KEYS = 0x0008; | ||||
| 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 = 'win-registry'; | ||||
|     this._marshal = require('_GenericMarshal'); | ||||
|     this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll'); | ||||
|     this._AdvApi.CreateMethod('RegCreateKeyExA'); | ||||
|     this._AdvApi.CreateMethod('RegEnumKeyExA'); | ||||
|     this._AdvApi.CreateMethod('RegEnumValueA'); | ||||
|     this._AdvApi.CreateMethod('RegOpenKeyExA'); | ||||
|     this._AdvApi.CreateMethod('RegQueryInfoKeyA'); | ||||
|     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 err; | ||||
|         var h = this._marshal.CreatePointer(); | ||||
|         var len = this._marshal.CreateVariable(4); | ||||
|         var valType = this._marshal.CreateVariable(4); | ||||
|         var HK = this._marshal.CreatePointer(hkey); | ||||
|         var retVal = null; | ||||
|         if (key) { key = this._marshal.CreateVariable(key); } | ||||
|         if (!path) { path = ''; } | ||||
| 
 | ||||
| 
 | ||||
|         if ((err = this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, h).Val) != 0) | ||||
|         { | ||||
|             throw ('Opening Registry Key: ' + path + ' => Returned Error: ' + err); | ||||
|         } | ||||
|    | ||||
|         if ((path == '' && !key) || !key) | ||||
|         { | ||||
|             var result = { subkeys: [], values: [] }; | ||||
| 
 | ||||
|             // Enumerate  keys
 | ||||
|             var achClass = this._marshal.CreateVariable(1024); | ||||
|             var achKey = this._marshal.CreateVariable(1024); | ||||
|             var achValue = this._marshal.CreateVariable(32768); | ||||
|             var achValueSize = this._marshal.CreateVariable(4); | ||||
|             var nameSize = this._marshal.CreateVariable(4);  | ||||
|             var achClassSize = this._marshal.CreateVariable(4); achClassSize.toBuffer().writeUInt32LE(1024); | ||||
|             var numSubKeys = this._marshal.CreateVariable(4); | ||||
|             var numValues = this._marshal.CreateVariable(4); | ||||
|             var longestSubkeySize = this._marshal.CreateVariable(4); | ||||
|             var longestClassString = this._marshal.CreateVariable(4); | ||||
|             var longestValueName = this._marshal.CreateVariable(4); | ||||
|             var longestValueData = this._marshal.CreateVariable(4); | ||||
|             var securityDescriptor = this._marshal.CreateVariable(4); | ||||
|             var lastWriteTime = this._marshal.CreateVariable(8); | ||||
| 
 | ||||
|             retVal = this._AdvApi.RegQueryInfoKeyA(h.Deref(), achClass, achClassSize, 0, | ||||
|                 numSubKeys, longestSubkeySize, longestClassString, numValues, | ||||
|                 longestValueName, longestValueData, securityDescriptor, lastWriteTime); | ||||
|             if (retVal.Val != 0) { throw ('RegQueryInfoKeyA() returned error: ' + retVal.Val); } | ||||
|             for(var i = 0; i < numSubKeys.toBuffer().readUInt32LE(); ++i) | ||||
|             { | ||||
|                 nameSize.toBuffer().writeUInt32LE(1024); | ||||
|                 retVal = this._AdvApi.RegEnumKeyExA(h.Deref(), i, achKey, nameSize, 0, 0, 0, lastWriteTime); | ||||
|                 if(retVal.Val == 0) | ||||
|                 { | ||||
|                     result.subkeys.push(achKey.String); | ||||
|                 } | ||||
|             } | ||||
|             for (var i = 0; i < numValues.toBuffer().readUInt32LE() ; ++i) | ||||
|             { | ||||
|                 achValueSize.toBuffer().writeUInt32LE(32768); | ||||
|                 if(this._AdvApi.RegEnumValueA(h.Deref(), i, achValue, achValueSize, 0, 0, 0, 0).Val == 0) | ||||
|                 { | ||||
|                     result.values.push(achValue.String); | ||||
|                 } | ||||
|             } | ||||
|             return (result); | ||||
|         } | ||||
| 
 | ||||
|         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(); | ||||
| 
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue