MeshCentral/agents/modules_meshcmd_min/service-host.min.js

1 line
8.1 KiB
JavaScript

var SERVICE_WIN32=16|32;var SERVICE_STATE={STOPPED:1,SERVICE_START_PENDING:2,SERVICE_STOP_PENDING:3,RUNNING:4};var SERVICE_ACCEPT={SERVICE_ACCEPT_STOP:1,SERVICE_ACCEPT_SHUTDOWN:4,SERVICE_ACCEPT_POWEREVENT:64,SERVICE_ACCEPT_SESSIONCHANGE:128};var SERVICE_CONTROL={SERVICE_CONTROL_SHUTDOWN:5,SERVICE_CONTROL_STOP:1,SERVICE_CONTROL_POWEREVENT:13,SERVICE_CONTROL_SESSIONCHANGE:14};var SESSION_CHANGE_TYPE={WTS_CONSOLE_CONNECT:1,WTS_CONSOLE_DISCONNECT:2,WTS_REMOTE_CONNECT:3,WTS_REMOTE_DISCONNECT:4,WTS_SESSION_LOGON:5,WTS_SESSION_LOGOFF:6,WTS_SESSION_LOCK:7,WTS_SESSION_UNLOCK:8,WTS_SESSION_REMOTE_CONTROL:9,WTS_SESSION_CREATE:10,WTS_SESSION_TERMINATE:11};var NO_ERROR=0;var serviceManager=require("service-manager");function serviceHost(e){this._ObjectID="service-host";var a=require("events").inherits(this);a.createEvent("serviceStart");a.createEvent("serviceStop");a.createEvent("normalStart");a.createEvent("session");a.createEvent("powerStateChange");if(process.platform=="win32"){this.GM=require("_GenericMarshal");this.Advapi=this.GM.CreateNativeProxy("Advapi32.dll");this.Advapi.CreateMethod({method:"StartServiceCtrlDispatcherA",threadDispatch:1});this.Advapi.CreateMethod("RegisterServiceCtrlHandlerExA");this.Advapi.CreateMethod("SetServiceStatus");this.Kernel32=this.GM.CreateNativeProxy("Kernel32.dll");this.Kernel32.CreateMethod("GetLastError");this.Ole32=this.GM.CreateNativeProxy("Ole32.dll");this.Ole32.CreateMethod("CoInitializeEx");this.Ole32.CreateMethod("CoUninitialize");this._ServiceName=this.GM.CreateVariable(typeof(e)=="string"?e:e.name);this._ServiceMain=this.GM.GetGenericGlobalCallback(2);this._ServiceMain.Parent=this;this._ServiceMain.GM=this.GM;this._ServiceMain.on("GlobalCallback",function b(f,g){this.Parent._ServiceStatus=this.GM.CreateVariable(28);this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_WIN32);this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_STOPPED,4);this.Parent._ServiceStatusHandle=this.Parent.Advapi.RegisterServiceCtrlHandlerExA(this.Parent._ServiceName,this.Parent._ServiceControlHandler,this.Parent.GM.StashObject(this.Parent._ServiceControlHandler));if(this.Parent._ServiceStatusHandle.Val==0){process.exit(1)}this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.SERVICE_START_PENDING,4);this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle,this.Parent._ServiceStatus);this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_STATE.RUNNING,4);this.Parent._ServiceStatus.toBuffer().writeUInt32LE(SERVICE_ACCEPT.SERVICE_ACCEPT_STOP|SERVICE_ACCEPT.SERVICE_ACCEPT_POWEREVENT|SERVICE_ACCEPT.SERVICE_ACCEPT_SESSIONCHANGE,8);this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle,this.Parent._ServiceStatus);this.Parent.Ole32.CoInitializeEx(0,2);this.Parent.on("~",function h(){var j=require("_GenericMarshal");var i=j.CreateNativeProxy("Advapi32.dll");i.CreateMethod("SetServiceStatus");Kernel32=this.GM.CreateNativeProxy("Kernel32.dll");Kernel32.CreateMethod("GetLastError");var k=j.CreateVariable(28);k.toBuffer().writeUInt32LE(SERVICE_WIN32);k.toBuffer().writeUInt32LE(1,4);k.toBuffer().writeUInt32LE(0,8);i.SetServiceStatus(this._ServiceStatusHandle,k);this.Ole32.CoUninitialize()});this.Parent.emit("serviceStart")});this._ServiceControlHandler=this.GM.GetGenericGlobalCallback(4);this._ServiceControlHandler.Parent=this;this._ServiceControlHandler.GM=this.GM;this._ServiceControlHandler.on("GlobalCallback",function c(f,i,h,g){var k=this.Parent.GM.UnstashObject(g);if(k!=null&&k==this){switch(f.Val){case SERVICE_CONTROL.SERVICE_CONTROL_SHUTDOWN:case SERVICE_CONTROL.SERVICE_CONTROL_STOP:this.Parent.emit("serviceStop");return;case SERVICE_CONTROL.SERVICE_CONTROL_SESSIONCHANGE:var l=h.Deref(4,4).toBuffer().readUInt32LE();switch(i.Val){case SESSION_CHANGE_TYPE.WTS_SESSION_LOGON:case SESSION_CHANGE_TYPE.WTS_SESSION_LOGOFF:require("user-sessions").emit("changed");break}break;default:break}this.Parent.Advapi.SetServiceStatus(this.Parent._ServiceStatusHandle,this.Parent._ServiceStatus)}})}if(e){this._ServiceOptions=typeof(e)=="object"?e:{name:e}}else{throw ("Must specify either ServiceName or Options")}if(!this._ServiceOptions.servicePath){this._ServiceOptions.servicePath=process.execPath}this.run=function d(){var r=0;for(var h=0;h<process.argv.length;++h){switch(process.argv[h]){case"-install":if(!this._svcManager){this._svcManager=new serviceManager()}try{this._svcManager.installService(this._ServiceOptions)}catch(g){console.log(g);process.exit()}console.log(this._ServiceOptions.name+" installed");process.exit();break;case"-uninstall":if(!this._svcManager){this._svcManager=new serviceManager()}try{this._svcManager.uninstallService(this._ServiceOptions)}catch(g){console.log(g);process.exit()}if(process.platform=="win32"||process.platform=="darwin"){console.log(this._ServiceOptions.name+" uninstalled");process.exit()}h=process.argv.length;r=1;break;case"start":case"-d":if(process.platform!="win32"){break}if(!this._svcManager){this._svcManager=new serviceManager()}this._svcManager.getService(this._ServiceOptions.name).start();console.log(this._ServiceOptions.name+" starting...");process.exit();break;case"stop":case"-s":if(process.platform!="win32"){break}if(!this._svcManager){this._svcManager=new serviceManager()}this._svcManager.getService(this._ServiceOptions.name).stop();console.log(this._ServiceOptions.name+" stopping...");process.exit();break}}if(process.platform=="win32"){var s=this.GM.CreateVariable(4*this.GM.PointerSize);this._ServiceName.pointerBuffer().copy(s.toBuffer());this._ServiceMain.pointerBuffer().copy(s.toBuffer(),this.GM.PointerSize);this._sscd=this.Advapi.StartServiceCtrlDispatcherA(s);this._sscd.parent=this;this._sscd.on("done",function m(i){if(i.Val==0){this.parent.emit("normalStart")}});return}else{if(process.platform=="linux"){var k=this._ServiceOptions?this._ServiceOptions.name:process.execPath.substring(1+process.execPath.lastIndexOf("/"));for(var h=0;h<process.argv.length;++h){switch(process.argv[h]){case"start":case"-d":var f=require("child_process").execFile(process.execPath,[k],{type:require("child_process").SpawnTypes.DETACHED});var q=null;try{q=require("fs").createWriteStream("/var/run/"+k+".pid",{flags:"w"})}catch(g){}if(q==null){q=require("fs").createWriteStream("."+k+".pid",{flags:"w"})}q.end(f.pid.toString());console.log(k+" started!");process.exit();break;case"stop":case"-s":var o=null;try{o=parseInt(require("fs").readFileSync("/var/run/"+k+".pid",{flags:"r"}));require("fs").unlinkSync("/var/run/"+k+".pid")}catch(g){}if(o==null){try{o=parseInt(require("fs").readFileSync("."+k+".pid",{flags:"r"}));require("fs").unlinkSync("."+k+".pid")}catch(g){}}if(o){process.kill(o);console.log(k+" stopped")}else{console.log(k+" not running")}process.exit();break}}if(r==0){var o=null;try{o=parseInt(require("fs").readFileSync("/var/run/"+k+".pid",{flags:"r"}))}catch(g){}if(o==null){try{o=parseInt(require("fs").readFileSync("."+k+".pid",{flags:"r"}))}catch(g){}}if(o!=null&&o==process.pid){this.emit("serviceStart")}else{if(require("process-manager").getProcessInfo(1).Name=="systemd"){this._checkpid=require("child_process").execFile("/bin/sh",["sh"],{type:require("child_process").SpawnTypes.TERM});this._checkpid.result="";this._checkpid.parent=this;this._checkpid.on("exit",function l(){var i=this.result.split("\r\n");for(h in i){if(i[h].startsWith(" Main PID:")){var p=i[h].split(" ");if(parseInt(p[3])==process.pid){this.parent.emit("serviceStart")}else{this.parent.emit("normalStart")}delete this.parent._checkpid;return}}this.parent.emit("normalStart");delete this.parent._checkpid});this._checkpid.stdout.on("data",function(i){this.parent.result+=i.toString()});this._checkpid.stdin.write("systemctl status "+k+" | grep 'Main PID:'\n");this._checkpid.stdin.write("exit\n")}else{this.emit("normalStart")}}}}else{if(process.platform=="darwin"){var f=require("child_process").execFile("/bin/sh",["sh"]);f.stdout.str="";f.stdout.on("data",function(i){this.str+=i.toString()});f.stdin.write("launchctl list\nexit\n");f.waitExit();var j=f.stdout.str.split("\n");var t,h;var n={};for(h=1;h<j.length;++h){t=j[h].split("\t");if(t[0]&&t[0]!="-"){n[t[0]]=t[0]}}if(n[process.pid.toString()]){this.emit("serviceStart")}else{this.emit("normalStart")}}}}}}module.exports=serviceHost;