mirror of
https://github.com/vxcontrol/soldr-modules.git
synced 2026-07-01 12:47:17 -04:00
171 lines
4.9 KiB
Lua
171 lines
4.9 KiB
Lua
require("yaci")
|
|
require("strict")
|
|
local ffi = require("ffi")
|
|
local lfs = require("lfs")
|
|
|
|
ffi.cdef [[
|
|
typedef long (*Module__transport_data_Ptr)(void *transport,
|
|
int type, void *data, long size);
|
|
|
|
typedef struct _api_module_transport {
|
|
Module__transport_data_Ptr to_module;
|
|
void *module_ptr;
|
|
Module__transport_data_Ptr to_client;
|
|
void *client_ptr;
|
|
} api_module_transport;
|
|
|
|
typedef bool (*Module__Init_Ptr)(api_module_transport *transport, const void *profile,
|
|
size_t profileSize);
|
|
typedef void (*Module__Void_Ptr)(api_module_transport *transport);
|
|
|
|
typedef struct _api_module_interface {
|
|
|
|
Module__Init_Ptr init;
|
|
Module__Void_Ptr start;
|
|
Module__Void_Ptr stop;
|
|
Module__Void_Ptr pause;
|
|
Module__Void_Ptr resume;
|
|
|
|
} api_module_interface;
|
|
|
|
typedef api_module_interface *(*Module_Create_Ptr)(api_module_transport *transport,
|
|
int argc, const char **argv);
|
|
typedef void(*Module_Destroy_Ptr)(api_module_transport *transport);
|
|
typedef int(*Module_Version_Ptr)();
|
|
|
|
api_module_interface* module_create(api_module_transport *transport, int argc, const char **argv);
|
|
void module_destroy(api_module_transport *transport);
|
|
int module_version();
|
|
]]
|
|
|
|
CModule = newclass("CModule")
|
|
|
|
function CModule:init(moduleName)
|
|
-- dependencies loading for linux agent because there is use custom folder for libs
|
|
if ffi.os == "Linux" then
|
|
self.deps = {}
|
|
local ld_lib_dir = __tmpdir .. "/lib"
|
|
for file in lfs.dir(ld_lib_dir) do
|
|
if file ~= "." and file ~= ".." then
|
|
table.insert(self.deps, ffi.load(ld_lib_dir .. "/" .. file))
|
|
end
|
|
end
|
|
end
|
|
|
|
self.wrap_load(function ()
|
|
self.module = ffi.load(moduleName)
|
|
end)
|
|
|
|
self.api = {
|
|
create = self.module.module_create,
|
|
destroy = self.module.module_destroy,
|
|
version = nil, --self.module.Module__Version,
|
|
is_inited = false,
|
|
}
|
|
self.transport = ffi.new("api_module_transport[1]", {})
|
|
end
|
|
|
|
function CModule:free()
|
|
__log.info("call CModule:free")
|
|
self:unregister()
|
|
end
|
|
|
|
function CModule:unregister()
|
|
__log.info("call CModule:unregister")
|
|
if self.module_i then
|
|
self.module_i.stop(self.transport)
|
|
self.api.destroy(self.transport)
|
|
__log.info("destroy successful")
|
|
end
|
|
|
|
if self.functions then
|
|
self.functions["receive"] = nil
|
|
end
|
|
self.functions = nil
|
|
self.transport = nil
|
|
|
|
if self.api then
|
|
self.api.create = nil
|
|
self.api.destroy = nil
|
|
self.api.version = nil
|
|
self.api.is_inited = nil
|
|
end
|
|
self.api = nil
|
|
|
|
self.module_i = nil
|
|
self.module = nil
|
|
self.profile = nil
|
|
collectgarbage("collect")
|
|
self.deps = nil
|
|
collectgarbage("collect")
|
|
end
|
|
|
|
function CModule:register(profile, callbacks)
|
|
__log.info("call CModule:register")
|
|
assert(type(profile) == "string", "module profile is invalid")
|
|
assert(type(callbacks) == "table", "callbacks is invalid")
|
|
|
|
if self.module == nil then
|
|
return false, "module not loaded"
|
|
end
|
|
|
|
self.functions = {}
|
|
|
|
self.functions["receive"] = function (transport, type, data, size)
|
|
if callbacks and transport == self.transport and callbacks["receive"] then
|
|
return callbacks["receive"](type, data, size)
|
|
end
|
|
return -1
|
|
end
|
|
|
|
self.transport[0].to_client = ffi.cast("Module__transport_data_Ptr", self.functions["receive"])
|
|
|
|
self.module_i = self.api.create(self.transport, 0, nil)
|
|
self.profile = ffi.new("const char[?]", #profile + 1, profile)
|
|
|
|
self.wrap_load(function ()
|
|
self.api.is_inited = self.module_i.init(self.transport, self.profile, #profile)
|
|
end)
|
|
|
|
return self.api.is_inited, ""
|
|
end
|
|
|
|
function CModule:start()
|
|
__log.info("call CModule:start")
|
|
if self.api.is_inited == false then
|
|
return
|
|
end
|
|
|
|
self.module_i.start(self.transport)
|
|
end
|
|
|
|
function CModule:send(type, data)
|
|
if self.transport[0].to_module == nil then
|
|
return
|
|
end
|
|
|
|
local _data
|
|
if #data ~= 0 then
|
|
_data = ffi.cast("void*", data)
|
|
end
|
|
|
|
return self.transport[0].to_module(self.transport, type, _data, #data)
|
|
end
|
|
|
|
if ffi.os == "Linux" then
|
|
function CModule.wrap_load(callback)
|
|
callback()
|
|
end
|
|
end
|
|
|
|
if ffi.os == "Windows" then
|
|
function CModule.wrap_load(callback)
|
|
local lk32 = require("waffi.windows.kernel32")
|
|
local ctmpdir = ffi.new("char[?]", 256)
|
|
lk32.GetDllDirectoryA(256, ctmpdir)
|
|
lk32.SetDllDirectoryA(__tmpdir)
|
|
callback()
|
|
lk32.SetDllDirectoryA(ctmpdir)
|
|
end
|
|
end
|