mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-17 16:53:13 +00:00
Updated documentation
This commit is contained in:
@@ -16,18 +16,28 @@ limitations under the License.
|
||||
|
||||
const SYNCHRONIZE = 0x00100000;
|
||||
|
||||
//
|
||||
// util-descriptors is a helper module that will enable enumeration of all open descriptors, as well as a means to close them
|
||||
//
|
||||
|
||||
|
||||
function invalid()
|
||||
{
|
||||
throw ('Not supported on ' + process.platform);
|
||||
}
|
||||
|
||||
//
|
||||
// Returns an array containing all the open descriptors for the current process
|
||||
//
|
||||
function getOpenDescriptors()
|
||||
{
|
||||
|
||||
switch (process.platform)
|
||||
{
|
||||
case "freebsd":
|
||||
//
|
||||
// BSD will use the system utility procstat to fetch the list of descriptors
|
||||
//
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.on('data', function (c) { });
|
||||
@@ -61,6 +71,9 @@ function getOpenDescriptors()
|
||||
}
|
||||
break;
|
||||
case "linux":
|
||||
//
|
||||
// Linux we will just rely on procfs to find the descriptors for our PID
|
||||
//
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.on('data', function (c) { });
|
||||
@@ -92,6 +105,9 @@ function getOpenDescriptors()
|
||||
return ([]);
|
||||
}
|
||||
}
|
||||
//
|
||||
// This function will enumerate the specified array of descriptors, and close each one
|
||||
//
|
||||
function closeDescriptors(fdArray)
|
||||
{
|
||||
var fd = null;
|
||||
@@ -102,10 +118,14 @@ function closeDescriptors(fdArray)
|
||||
fd = fdArray.pop();
|
||||
if (fd > 2)
|
||||
{
|
||||
this.libc.close(fd);
|
||||
this.libc.close(fd); // use glibc to close the descriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// execv helper function, which will close all open descriptors immediately before invoking execv()
|
||||
//
|
||||
function _execv(exePath, argarr)
|
||||
{
|
||||
if (this.libc == null)
|
||||
@@ -119,11 +139,16 @@ function _execv(exePath, argarr)
|
||||
var args = require('_GenericMarshal').CreateVariable((1 + argarr.length) * require('_GenericMarshal').PointerSize);
|
||||
for (i = 0; i < argarr.length; ++i)
|
||||
{
|
||||
// convert the JS array into a native array to be passed to execv
|
||||
var arg = require('_GenericMarshal').CreateVariable(argarr[i]);
|
||||
tmp.push(arg);
|
||||
arg.pointerBuffer().copy(args.toBuffer(), i * require('_GenericMarshal').PointerSize);
|
||||
}
|
||||
|
||||
//
|
||||
// Fetch the list of all open descriptors, then close all of them. We need to do this, becuase
|
||||
// execv() is going to inherit all the descriptors, so they will probably leak if the new process doesn't know what to do with them
|
||||
//
|
||||
var fds = this.getOpenDescriptors();
|
||||
this.closeDescriptors(fds);
|
||||
|
||||
@@ -131,15 +156,22 @@ function _execv(exePath, argarr)
|
||||
throw('exec error');
|
||||
}
|
||||
|
||||
//
|
||||
// This function returns the native marshaler for glibc, specifically for 'execv' and 'close'
|
||||
//
|
||||
function getLibc()
|
||||
{
|
||||
var libs = require('monitor-info').getLibInfo('libc');
|
||||
var libs = require('monitor-info').getLibInfo('libc'); // This will fetch the location of all the libc modules on the platform.
|
||||
var libc = null;
|
||||
|
||||
while (libs.length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
//
|
||||
// We need to enumerate each libc module, and try to load it, becuase it is common for a linux distribution
|
||||
// to include modules for several different architectures. So only the correct one will load. We need to find it.
|
||||
//
|
||||
libc = require('_GenericMarshal').CreateNativeProxy(libs.pop().path);
|
||||
libc.CreateMethod('execv');
|
||||
libc.CreateMethod('close');
|
||||
@@ -155,16 +187,24 @@ function getLibc()
|
||||
return (libc);
|
||||
}
|
||||
|
||||
//
|
||||
// Windows helper function to fetch a HANDLE to the specified process
|
||||
//
|
||||
function win_getProcessHandle(pid)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!this.kernel32)
|
||||
{
|
||||
//
|
||||
// Reference to OpenProcess() can be found at:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
|
||||
//
|
||||
this.kernel32 = require('_GenericMarshal').CreateNativeProxy('kernel32.dll');
|
||||
this.kernel32.CreateMethod('OpenProcess');
|
||||
}
|
||||
|
||||
// This will return a HANDLE to the specified prcoess
|
||||
return (this.kernel32.OpenProcess(SYNCHRONIZE, 0, pid));
|
||||
}
|
||||
catch(e)
|
||||
@@ -177,9 +217,11 @@ switch (process.platform)
|
||||
{
|
||||
case 'linux':
|
||||
case 'freebsd':
|
||||
// Only Linux and FreeBSD support finding the list of open descriptors
|
||||
module.exports = { getOpenDescriptors: getOpenDescriptors, closeDescriptors: closeDescriptors, _execv: _execv, libc: getLibc() };
|
||||
break;
|
||||
default:
|
||||
// For other platforms, we will return an error
|
||||
module.exports = { getOpenDescriptors: invalid, closeDescriptors: invalid };
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,20 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// util-language is a helper module to fetch the currently configured Language Locale of the Operating System
|
||||
//
|
||||
|
||||
//
|
||||
// This is a windows helper function to convert LCID to language name
|
||||
//
|
||||
function toLang(val)
|
||||
{
|
||||
//
|
||||
// Windows Language codes can be found at:
|
||||
// https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a
|
||||
//
|
||||
|
||||
var ret;
|
||||
switch (val)
|
||||
{
|
||||
@@ -959,10 +970,15 @@ function toLang(val)
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
//
|
||||
// Try to determine the current language locale
|
||||
//
|
||||
function getCurrent()
|
||||
{
|
||||
if(process.platform == 'win32')
|
||||
{
|
||||
// On windows wi will use WMI via WMIC to get the LCID.
|
||||
var child = require('child_process').execFile(process.env['windir'] + '\\system32\\wbem\\wmic.exe', ['wmic', 'os', 'get', 'oslanguage','/FORMAT:LIST']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
|
||||
@@ -975,6 +991,7 @@ function getCurrent()
|
||||
tokens = lines[i].split('=');
|
||||
if(tokens[0]=='OSLanguage')
|
||||
{
|
||||
// Convert LCID to language string
|
||||
return (toLang(tokens[1]));
|
||||
}
|
||||
}
|
||||
@@ -983,12 +1000,14 @@ function getCurrent()
|
||||
|
||||
if(process.env['LANG'])
|
||||
{
|
||||
// If 'LANG" is defined in the environment variable, we can just return that
|
||||
return (process.env['LANG'].split('.')[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (process.platform == 'darwin')
|
||||
{
|
||||
// On macOS we can use the system utility 'osascript' to fetch the current locale of the system
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
|
||||
@@ -1000,6 +1019,7 @@ function getCurrent()
|
||||
{
|
||||
try
|
||||
{
|
||||
// On Linux/BSD, we are goign to fetch the environment variables of the Display Manager process, and see what locale was set for it
|
||||
var uid = require('user-sessions').gdmUid;
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
@@ -1019,7 +1039,7 @@ function getCurrent()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This property will fetch the current locale the first time, and cache the results
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, 'current', {
|
||||
get: function ()
|
||||
@@ -1039,6 +1059,9 @@ module.exports = obj;
|
||||
|
||||
if (process.platform == 'win32')
|
||||
{
|
||||
//
|
||||
// On Windows, we will set a property to fetch/cache the wmicXslPath
|
||||
//
|
||||
Object.defineProperty(module.exports, 'wmicXslPath',
|
||||
{
|
||||
get: function ()
|
||||
|
||||
@@ -15,21 +15,40 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// This is a windows helper that will try to determine the service name for the currently running service
|
||||
//
|
||||
|
||||
//
|
||||
// Will return the name of the currently running service if it can be determined, null otherwise
|
||||
//
|
||||
function win_serviceCheck()
|
||||
{
|
||||
var s;
|
||||
var reg = require('win-registry');
|
||||
var path;
|
||||
var values = reg.QueryKey(reg.HKEY.LocalMachine, 'SOFTWARE\\Open Source');
|
||||
|
||||
//
|
||||
// The MeshAgent will normally add a registry entry into the above registry path, at installation time
|
||||
//
|
||||
|
||||
if (values.subkeys)
|
||||
{
|
||||
for (var i in values.subkeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
//
|
||||
// We are enumerating all the Mesh Agents listed in the registry above, and check with the
|
||||
// windows service manager to see if the PID matches the PID of the current process
|
||||
//
|
||||
s = require('service-manager').manager.getService(values.subkeys[i]);
|
||||
if(s.isMe())
|
||||
{
|
||||
//
|
||||
// This service is us, so we can return the results
|
||||
//
|
||||
s.close();
|
||||
return (values.subkeys[i]);
|
||||
}
|
||||
@@ -48,10 +67,16 @@ function win_serviceCheck()
|
||||
values = reg.QueryKey(reg.HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Services');
|
||||
if (values.subkeys)
|
||||
{
|
||||
//
|
||||
// We couldn't find a match in the registry where the Mesh Agent normally saves information about installation,
|
||||
// so we're going to just enumerate all the windows services, and try to manually brute force it
|
||||
//
|
||||
|
||||
for(var i in values.subkeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
// We're going to look at the exe path for each enumerated service
|
||||
path = reg.QueryKey(reg.HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Services\\' + values.subkeys[i], 'ImagePath');
|
||||
}
|
||||
catch(xx)
|
||||
@@ -65,13 +90,16 @@ function win_serviceCheck()
|
||||
if (path.startsWith('"')) { path = path.substring(1); }
|
||||
if(path == process.execPath)
|
||||
{
|
||||
//
|
||||
// If the service's exe path matches the exe path of the current process, we'll check the PID to see if it is indeed us
|
||||
//
|
||||
try
|
||||
{
|
||||
s = require('service-manager').manager.getService(values.subkeys[i]);
|
||||
if(s.isMe())
|
||||
{
|
||||
s.close();
|
||||
return (values.subkeys[i]);
|
||||
return (values.subkeys[i]); // It is a match!
|
||||
}
|
||||
s.close();
|
||||
}
|
||||
@@ -82,7 +110,7 @@ function win_serviceCheck()
|
||||
}
|
||||
}
|
||||
}
|
||||
return (null);
|
||||
return (null); // We couldn't find the right service
|
||||
}
|
||||
|
||||
switch(process.platform)
|
||||
|
||||
Reference in New Issue
Block a user