Let us start here, from square one. No, from Zero!
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#include "control.h"
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include "external/LuaBridge.h"
|
||||
#include "launcher/shutdown.h"
|
||||
|
||||
using namespace luabridge;
|
||||
|
||||
namespace script::api::control {
|
||||
|
||||
struct SignalMapping {
|
||||
int signum;
|
||||
const char* name;
|
||||
};
|
||||
static SignalMapping SIGNAL_MAPPINGS[] = {
|
||||
{ SIGABRT, "SIGABRT" },
|
||||
{ SIGFPE, "SIGFPE" },
|
||||
{ SIGILL, "SIGILL" },
|
||||
{ SIGINT, "SIGINT" },
|
||||
{ SIGSEGV, "SIGSEGV" },
|
||||
{ SIGTERM, "SIGTERM" },
|
||||
};
|
||||
|
||||
static inline bool acquire_shutdown_privs() {
|
||||
|
||||
// check if already acquired
|
||||
static bool acquired = false;
|
||||
if (acquired)
|
||||
return true;
|
||||
|
||||
// get process token
|
||||
HANDLE hToken;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
||||
return false;
|
||||
|
||||
// get the LUID for the shutdown privilege
|
||||
TOKEN_PRIVILEGES tkp;
|
||||
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
|
||||
tkp.PrivilegeCount = 1;
|
||||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
// get the shutdown privilege for this process
|
||||
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
|
||||
|
||||
// check for error
|
||||
bool success = GetLastError() == ERROR_SUCCESS;
|
||||
if (success)
|
||||
acquired = true;
|
||||
return success;
|
||||
}
|
||||
|
||||
void raise(const std::string &signal) {
|
||||
|
||||
// get signal
|
||||
int signal_val = -1;
|
||||
for (auto mapping : SIGNAL_MAPPINGS) {
|
||||
if (_stricmp(mapping.name, signal.c_str()) == 0) {
|
||||
signal_val = mapping.signum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// raise if found
|
||||
if (signal_val >= 0) {
|
||||
::raise(signal_val);
|
||||
}
|
||||
}
|
||||
|
||||
void exit(int code) {
|
||||
launcher::shutdown(code);
|
||||
}
|
||||
|
||||
void restart() {
|
||||
launcher::restart();
|
||||
}
|
||||
|
||||
bool shutdown() {
|
||||
|
||||
// acquire privileges
|
||||
if (!acquire_shutdown_privs())
|
||||
return false;
|
||||
|
||||
// exit windows
|
||||
if (!ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,
|
||||
SHTDN_REASON_MAJOR_APPLICATION |
|
||||
SHTDN_REASON_MINOR_MAINTENANCE))
|
||||
return false;
|
||||
|
||||
// terminate this process
|
||||
launcher::shutdown(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reboot() {
|
||||
|
||||
// acquire privileges
|
||||
if (!acquire_shutdown_privs())
|
||||
return false;
|
||||
|
||||
// exit windows
|
||||
if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE,
|
||||
SHTDN_REASON_MAJOR_APPLICATION |
|
||||
SHTDN_REASON_MINOR_MAINTENANCE))
|
||||
return false;
|
||||
|
||||
// terminate this process
|
||||
launcher::shutdown(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void init(lua_State *L) {
|
||||
getGlobalNamespace(L)
|
||||
.beginNamespace("control")
|
||||
.addFunction("raise", raise)
|
||||
.addFunction("exit", exit)
|
||||
.addFunction("restart", restart)
|
||||
.addFunction("shutdown", shutdown)
|
||||
.addFunction("reboot", reboot)
|
||||
.endNamespace();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user