mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-04-25 07:18:13 -05:00
feat: Add sdk-hook
Module to handle environment setup for hooks that use DllMain and calls the bemanitools 6 API for hooks. This way, all hooks that use inject (no AVS available) can be refactored and use the same API as any hooks that use launcher (with AVS available). Remark: Module namespacing is not proper. This should move to a separate part of the project that’s purely holding SDK related code that can be used by other developers on other projects without requiring the whole bemanitools project checkout. This problem is considered out of scope for now.
This commit is contained in:
parent
73da986d0b
commit
833fa2f99c
13
src/main/sdk-hook/Module.mk
Normal file
13
src/main/sdk-hook/Module.mk
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
libs += sdk-hook
|
||||
|
||||
ldflags_sdk-hook := \
|
||||
-lshlwapi \
|
||||
|
||||
libs_sdk-hook := \
|
||||
util \
|
||||
|
||||
src_sdk-hook := \
|
||||
dllentry.c \
|
||||
hooks-config.c \
|
||||
inject-config.c \
|
||||
logger-config.c \
|
||||
215
src/main/sdk-hook/dllentry.c
Normal file
215
src/main/sdk-hook/dllentry.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
#define LOG_MODULE "hook-dllentry"
|
||||
|
||||
// clang-format off
|
||||
// Don't format because the order is important here
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h>
|
||||
// clang-format on
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "core/boot.h"
|
||||
#include "core/config-property-node.h"
|
||||
#include "core/log-bt-ext.h"
|
||||
#include "core/log-bt.h"
|
||||
#include "core/property-ext.h"
|
||||
#include "core/property-node.h"
|
||||
|
||||
#include "iface-core/config.h"
|
||||
#include "iface-core/log.h"
|
||||
#include "iface-core/thread.h"
|
||||
|
||||
#include "iface/hook.h"
|
||||
|
||||
#include "iidxhook1/iidxhook1.h"
|
||||
|
||||
#include "main/module/core.h"
|
||||
#include "main/module/hook.h"
|
||||
|
||||
#include "sdk-hook/inject-config.h"
|
||||
|
||||
#include "util/str.h"
|
||||
|
||||
static HMODULE _bt_hook_dllentry_hook_module;
|
||||
static bt_hook_t *_bt_hook_dllentry_hook;
|
||||
static bt_hook_inject_config_t _bt_hook_dllentry_inject_config;
|
||||
|
||||
static void _bt_hook_dllentry_current_module_name_get(char *name, size_t len)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const char *filename;
|
||||
|
||||
log_assert(name);
|
||||
log_assert(len > 0);
|
||||
|
||||
if (GetModuleFileName(_bt_hook_dllentry_hook_module, path, MAX_PATH) != 0) {
|
||||
filename = PathFindFileName(path);
|
||||
|
||||
str_cpy(name, len, filename);
|
||||
} else {
|
||||
log_fatal("GetModuleFileName to get current module name failed");
|
||||
}
|
||||
}
|
||||
|
||||
static const core_property_t *_bt_hook_dllentry_hook_property_config_get()
|
||||
{
|
||||
char current_module_name[MAX_PATH];
|
||||
const struct bt_hook_hooks_hook_config *configs;
|
||||
const char *filename;
|
||||
int i;
|
||||
|
||||
_bt_hook_dllentry_current_module_name_get(current_module_name, sizeof(current_module_name));
|
||||
|
||||
configs = _bt_hook_dllentry_inject_config.hooks.hooks;
|
||||
|
||||
for (i = 0; i < BT_HOOK_HOOKS_CONFIG_MAX_HOOKS; i++) {
|
||||
filename = PathFindFileName(configs[i].path);
|
||||
|
||||
if (str_eq(current_module_name, filename)) {
|
||||
log_misc("Property hook config for %s", configs[i].path);
|
||||
core_property_ext_log(configs[i].config, log_misc_func);
|
||||
|
||||
return configs[i].config;
|
||||
}
|
||||
}
|
||||
|
||||
log_fatal("Could not find hook configuration for module %s in inject configuration", current_module_name);
|
||||
}
|
||||
|
||||
static void _bt_hook_dllentry_config_load()
|
||||
{
|
||||
char inject_config_path[MAX_PATH];
|
||||
|
||||
// Duct-tape to allow access to config path and load config in hook dlls
|
||||
GetEnvironmentVariable("INJECT_CONFIG_PATH", inject_config_path, sizeof(inject_config_path));
|
||||
|
||||
// With DllMain as the only callable entry point from inject,
|
||||
// the only way to get the configuration for the hook is through
|
||||
// injects configuration file + command line arguments
|
||||
// Thus, the whole loading process (that is also done in inject)
|
||||
// is replicated here (inject config etc. are also copy-pasted from
|
||||
// the inject module)
|
||||
bt_hook_inject_config_init(&_bt_hook_dllentry_inject_config);
|
||||
bt_hook_inject_config_file_load(inject_config_path, &_bt_hook_dllentry_inject_config);
|
||||
}
|
||||
|
||||
static void _bt_hook_dllentry_logger_reinit()
|
||||
{
|
||||
// Apply same logger configurations as inject
|
||||
if (!_bt_hook_dllentry_inject_config.logger.enable) {
|
||||
core_log_bt_fini();
|
||||
|
||||
core_log_bt_ext_init_with_null();
|
||||
} else {
|
||||
// Logger already initialized previously, just switch log level
|
||||
core_log_bt_level_set(_bt_hook_dllentry_inject_config.logger.level);
|
||||
}
|
||||
}
|
||||
|
||||
void bt_hook_dllentry_init(
|
||||
HMODULE module,
|
||||
const char* name,
|
||||
bt_module_core_config_api_set_t hook_config_api_set,
|
||||
bt_module_core_log_api_set_t hook_log_api_set,
|
||||
bt_module_core_thread_api_set_t hook_thread_api_set,
|
||||
bt_module_hook_api_get_t hook_api_get)
|
||||
{
|
||||
bt_core_config_api_t config_api;
|
||||
bt_core_log_api_t log_api;
|
||||
bt_core_thread_api_t thread_api;
|
||||
bt_hook_api_t hook_api;
|
||||
|
||||
core_boot_dll(name);
|
||||
|
||||
// Debug logging is captured by debugger in inject and actually
|
||||
// sunk to outputs there, e.g. terminal/file
|
||||
core_log_bt_ext_init_with_debug();
|
||||
core_log_bt_core_api_set();
|
||||
// TODO change log level according to how inject is configured, read from config + command line args
|
||||
core_log_bt_level_set(CORE_LOG_BT_LOG_LEVEL_MISC);
|
||||
|
||||
_bt_hook_dllentry_config_load();
|
||||
|
||||
_bt_hook_dllentry_logger_reinit();
|
||||
|
||||
// Assert after log init to get visible error output if these fail
|
||||
log_assert(module);
|
||||
log_assert(hook_config_api_set);
|
||||
log_assert(hook_log_api_set);
|
||||
log_assert(hook_thread_api_set);
|
||||
log_assert(hook_api_get);
|
||||
|
||||
_bt_hook_dllentry_hook_module = module;
|
||||
|
||||
bt_core_config_api_get(&config_api);
|
||||
bt_core_log_api_get(&log_api);
|
||||
bt_core_thread_api_get(&thread_api);
|
||||
|
||||
hook_config_api_set(&config_api);
|
||||
hook_log_api_set(&log_api);
|
||||
hook_thread_api_set(&thread_api);
|
||||
|
||||
hook_api_get(&hook_api);
|
||||
|
||||
bt_hook_init(&hook_api, name, &_bt_hook_dllentry_hook);
|
||||
|
||||
log_misc("<<< bt_hook_dllentry_boot_init");
|
||||
}
|
||||
|
||||
void bt_hook_dllentry_fini()
|
||||
{
|
||||
log_misc(">>> bt_hook_dllentry_fini");
|
||||
|
||||
bt_hook_inject_config_fini(&_bt_hook_dllentry_inject_config);
|
||||
|
||||
bt_hook_fini(&_bt_hook_dllentry_hook);
|
||||
|
||||
core_log_bt_fini();
|
||||
|
||||
bt_core_config_api_clear();
|
||||
bt_core_log_api_clear();
|
||||
bt_core_thread_api_clear();
|
||||
}
|
||||
|
||||
void bt_hook_dllentry_main_init()
|
||||
{
|
||||
bool result;
|
||||
const core_property_t *property;
|
||||
core_property_node_t root_node;
|
||||
bt_core_config_t *config;
|
||||
core_property_result_t result_prop;
|
||||
HMODULE game_module;
|
||||
|
||||
log_misc(">>> bt_hook_dllentry_main_init");
|
||||
|
||||
property = _bt_hook_dllentry_hook_property_config_get();
|
||||
|
||||
result_prop = core_property_root_node_get(property, &root_node);
|
||||
core_property_fatal_on_error(result_prop);
|
||||
|
||||
core_config_property_node_init(&root_node, &config);
|
||||
|
||||
// Because this is loaded into the game's process space, this yields the executable module
|
||||
game_module = GetModuleHandle(NULL);
|
||||
|
||||
result = bt_hook_main_init(_bt_hook_dllentry_hook, game_module, config);
|
||||
|
||||
core_config_property_node_free(&config);
|
||||
|
||||
if (!result) {
|
||||
log_fatal("Calling hook main init failed");
|
||||
}
|
||||
|
||||
log_misc("<<< bt_hook_dllentry_main_init");
|
||||
}
|
||||
|
||||
void bt_hook_dllentry_main_fini()
|
||||
{
|
||||
log_misc(">>> bt_hook_dllentry_boot_fini");
|
||||
|
||||
bt_hook_main_fini(_bt_hook_dllentry_hook);
|
||||
|
||||
bt_hook_fini(&_bt_hook_dllentry_hook);
|
||||
|
||||
log_misc("<<< bt_hook_dllentry_boot_fini");
|
||||
}
|
||||
23
src/main/sdk-hook/dllentry.h
Normal file
23
src/main/sdk-hook/dllentry.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef BT_SDK_HOOK_DLLENTRY_H
|
||||
#define BT_SDK_HOOK_DLLENTRY_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "main/module/core.h"
|
||||
#include "main/module/hook.h"
|
||||
|
||||
void bt_hook_dllentry_init(
|
||||
HMODULE module,
|
||||
const char *name,
|
||||
bt_module_core_config_api_set_t hook_config_api_set,
|
||||
bt_module_core_log_api_set_t hook_log_api_set,
|
||||
bt_module_core_thread_api_set_t hook_thread_api_set,
|
||||
bt_module_hook_api_get_t hook_api_get);
|
||||
|
||||
void bt_hook_dllentry_fini();
|
||||
|
||||
void bt_hook_dllentry_main_init();
|
||||
|
||||
void bt_hook_dllentry_main_fini();
|
||||
|
||||
#endif
|
||||
161
src/main/sdk-hook/hooks-config.c
Normal file
161
src/main/sdk-hook/hooks-config.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
#define LOG_MODULE "bt-hook-inject-hooks-config"
|
||||
|
||||
#include "core/property-ext.h"
|
||||
#include "core/property-node-ext.h"
|
||||
|
||||
#include "iface-core/log.h"
|
||||
|
||||
#include "sdk-hook/hooks-config.h"
|
||||
|
||||
#define BT_HOOK_HOOKS_CONFIG_MAX_LAYER_CONFIG_NODES 8
|
||||
|
||||
static core_property_t *
|
||||
_bt_hook_hooks_config_layered_config_nodes_load(const core_property_node_t *node)
|
||||
{
|
||||
char kind[64];
|
||||
char file[MAX_PATH];
|
||||
int cnt;
|
||||
|
||||
core_property_node_t cur;
|
||||
core_property_node_t tmp;
|
||||
core_property_t *config_property[BT_HOOK_HOOKS_CONFIG_MAX_LAYER_CONFIG_NODES];
|
||||
core_property_t *merged_property;
|
||||
core_property_node_result_t result;
|
||||
core_property_result_t prop_result;
|
||||
|
||||
log_assert(node);
|
||||
|
||||
cnt = 0;
|
||||
result = core_property_node_search(node, "config", &cur);
|
||||
|
||||
if (result != CORE_PROPERTY_NODE_RESULT_NODE_NOT_FOUND) {
|
||||
core_property_node_fatal_on_error(result);
|
||||
}
|
||||
|
||||
while (result != CORE_PROPERTY_NODE_RESULT_NODE_NOT_FOUND) {
|
||||
if (cnt >= BT_HOOK_HOOKS_CONFIG_MAX_LAYER_CONFIG_NODES) {
|
||||
log_fatal(
|
||||
"Exceeding max supported config nodes for layering, max is %d",
|
||||
BT_HOOK_HOOKS_CONFIG_MAX_LAYER_CONFIG_NODES);
|
||||
}
|
||||
|
||||
result =
|
||||
core_property_node_attr_read(&cur, "kind", kind, sizeof(kind));
|
||||
|
||||
if (CORE_PROPERTY_NODE_RESULT_IS_ERROR(result)) {
|
||||
log_fatal("Failed reading 'kind' attribute value of config node");
|
||||
}
|
||||
|
||||
if (!strcmp(kind, "file")) {
|
||||
core_property_node_str_read(&cur, file, sizeof(file));
|
||||
|
||||
prop_result = core_property_file_load(file, &config_property[cnt]);
|
||||
core_property_fatal_on_error(prop_result);
|
||||
} else if (!strcmp(kind, "inline")) {
|
||||
// The nested child is the actual root of the inline, not the outer
|
||||
// <config> node
|
||||
result = core_property_node_child_get(&cur, &tmp);
|
||||
memcpy(&cur, &tmp, sizeof(core_property_node_t));
|
||||
|
||||
if (result != CORE_PROPERTY_NODE_RESULT_NODE_NOT_FOUND) {
|
||||
core_property_node_fatal_on_error(result);
|
||||
}
|
||||
|
||||
result =
|
||||
core_property_node_ext_extract(&cur, &config_property[cnt]);
|
||||
core_property_node_fatal_on_error(result);
|
||||
} else {
|
||||
log_fatal(
|
||||
"Unsupported 'kind' attribute value '%s' of config node", kind);
|
||||
}
|
||||
|
||||
cnt++;
|
||||
result = core_property_node_next_result_search(&cur, &tmp);
|
||||
memcpy(&cur, &tmp, sizeof(core_property_node_t));
|
||||
|
||||
if (result != CORE_PROPERTY_NODE_RESULT_NODE_NOT_FOUND) {
|
||||
core_property_node_fatal_on_error(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
prop_result = core_property_str_load("<hook></hook>", &merged_property);
|
||||
core_property_fatal_on_error(prop_result);
|
||||
} else {
|
||||
prop_result =
|
||||
core_property_ext_many_merge(config_property, cnt, &merged_property);
|
||||
core_property_fatal_on_error(prop_result);
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
core_property_free(&config_property[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return merged_property;
|
||||
}
|
||||
|
||||
static void _bt_hook_hooks_config_hooks_load(
|
||||
const core_property_node_t *node,
|
||||
struct bt_hook_hooks_hook_config *configs)
|
||||
{
|
||||
core_property_node_result_t result;
|
||||
core_property_node_t child;
|
||||
core_property_node_t tmp;
|
||||
uint8_t processed_hooks;
|
||||
|
||||
processed_hooks = 0;
|
||||
|
||||
result = core_property_node_search(node, "hook", &child);
|
||||
|
||||
do {
|
||||
if (processed_hooks >= BT_HOOK_HOOKS_CONFIG_MAX_HOOKS) {
|
||||
log_fatal("Cannot load more hooks, max supported capacity reached");
|
||||
}
|
||||
|
||||
if (result == CORE_PROPERTY_NODE_RESULT_NODE_NOT_FOUND) {
|
||||
return;
|
||||
} else {
|
||||
core_property_node_fatal_on_error(result);
|
||||
}
|
||||
|
||||
result = core_property_node_ext_bool_read(&child, "enable", &configs[processed_hooks].enable);
|
||||
core_property_node_fatal_on_error(result);
|
||||
|
||||
result = core_property_node_ext_str_read(&child, "path", configs[processed_hooks].path, sizeof(configs[processed_hooks].path));
|
||||
core_property_node_fatal_on_error(result);
|
||||
|
||||
configs[processed_hooks].config = _bt_hook_hooks_config_layered_config_nodes_load(&child);
|
||||
|
||||
result = core_property_node_next_result_search(&child, &tmp);
|
||||
memcpy(&child, &tmp, sizeof(core_property_node_t));
|
||||
|
||||
processed_hooks++;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void bt_hook_hooks_config_init(bt_hook_hooks_config_t *config)
|
||||
{
|
||||
log_assert(config);
|
||||
|
||||
memset(config, 0, sizeof(bt_hook_hooks_config_t));
|
||||
}
|
||||
|
||||
void bt_hook_hooks_config_load(
|
||||
const core_property_node_t *node, bt_hook_hooks_config_t *config)
|
||||
{
|
||||
log_assert(node);
|
||||
log_assert(config);
|
||||
|
||||
_bt_hook_hooks_config_hooks_load(node, config->hooks);
|
||||
}
|
||||
|
||||
void bt_hook_hooks_config_fini(bt_hook_hooks_config_t *config)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
log_assert(config);
|
||||
|
||||
for (i = 0; i < BT_HOOK_HOOKS_CONFIG_MAX_HOOKS; i++) {
|
||||
core_property_free(&config->hooks[i].config);
|
||||
}
|
||||
}
|
||||
28
src/main/sdk-hook/hooks-config.h
Normal file
28
src/main/sdk-hook/hooks-config.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef BT_SDK_HOOK_INJECT_HOOKS_CONFIG_H
|
||||
#define BT_SDK_HOOK_INJECT_HOOKS_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "core/property.h"
|
||||
#include "core/property-node.h"
|
||||
|
||||
#define BT_HOOK_HOOKS_CONFIG_MAX_HOOKS 16
|
||||
|
||||
typedef struct bt_hook_hooks_config {
|
||||
struct bt_hook_hooks_hook_config {
|
||||
bool enable;
|
||||
char path[MAX_PATH];
|
||||
core_property_t *config;
|
||||
} hooks[BT_HOOK_HOOKS_CONFIG_MAX_HOOKS];
|
||||
} bt_hook_hooks_config_t;
|
||||
|
||||
void bt_hook_hooks_config_init(bt_hook_hooks_config_t *config);
|
||||
|
||||
void bt_hook_hooks_config_load(
|
||||
const core_property_node_t *node, bt_hook_hooks_config_t *config);
|
||||
|
||||
void bt_hook_hooks_config_fini(bt_hook_hooks_config_t *config);
|
||||
|
||||
#endif
|
||||
61
src/main/sdk-hook/inject-config.c
Normal file
61
src/main/sdk-hook/inject-config.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#define LOG_MODULE "bt-hook-inject-config"
|
||||
|
||||
#include "core/property-ext.h"
|
||||
#include "core/property-node.h"
|
||||
#include "core/property.h"
|
||||
|
||||
#include "core/property-mxml-internal.h"
|
||||
#include "core/property-node-ext.h"
|
||||
|
||||
#include "iface-core/log.h"
|
||||
|
||||
#include "sdk-hook/hooks-config.h"
|
||||
#include "sdk-hook/inject-config.h"
|
||||
#include "sdk-hook/logger-config.h"
|
||||
|
||||
void bt_hook_inject_config_init(struct bt_hook_inject_config *config)
|
||||
{
|
||||
log_assert(config);
|
||||
|
||||
config->version = 1;
|
||||
|
||||
bt_hook_hooks_config_init(&config->hooks);
|
||||
bt_hook_logger_config_init(&config->logger);
|
||||
}
|
||||
|
||||
void bt_hook_inject_config_file_load(const char *path, bt_hook_inject_config_t *config)
|
||||
{
|
||||
core_property_result_t result_prop;
|
||||
core_property_node_result_t result;
|
||||
core_property_t *property;
|
||||
core_property_node_t root_node;
|
||||
core_property_node_t child_node;
|
||||
|
||||
log_info("Loading configuration file: %s", path);
|
||||
|
||||
result_prop = core_property_file_load(path, &property);
|
||||
core_property_fatal_on_error(result_prop);
|
||||
|
||||
result = core_property_root_node_get(property, &root_node);
|
||||
core_property_node_fatal_on_error(result);
|
||||
|
||||
result = core_property_node_search(&root_node, "hooks", &child_node);
|
||||
core_property_node_fatal_on_error(result);
|
||||
bt_hook_hooks_config_load(&child_node, &config->hooks);
|
||||
|
||||
result = core_property_node_search(&root_node, "logger", &child_node);
|
||||
core_property_node_fatal_on_error(result);
|
||||
bt_hook_logger_config_load(&child_node, &config->logger);
|
||||
|
||||
core_property_free(&property);
|
||||
|
||||
log_misc("Loading done");
|
||||
}
|
||||
|
||||
void bt_hook_inject_config_fini(bt_hook_inject_config_t *config)
|
||||
{
|
||||
log_assert(config);
|
||||
|
||||
// Other configs don't have a fini
|
||||
bt_hook_hooks_config_fini(&config->hooks);
|
||||
}
|
||||
22
src/main/sdk-hook/inject-config.h
Normal file
22
src/main/sdk-hook/inject-config.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef BT_SDK_HOOK_INJECT_CONFIG_H
|
||||
#define BT_SDK_HOOK_INJECT_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "sdk-hook/hooks-config.h"
|
||||
#include "sdk-hook/logger-config.h"
|
||||
|
||||
typedef struct bt_hook_inject_config {
|
||||
uint32_t version;
|
||||
|
||||
bt_hook_hooks_config_t hooks;
|
||||
bt_hook_logger_config_t logger;
|
||||
} bt_hook_inject_config_t;
|
||||
|
||||
void bt_hook_inject_config_init(struct bt_hook_inject_config *config);
|
||||
|
||||
void bt_hook_inject_config_file_load(const char *path, bt_hook_inject_config_t *config);
|
||||
|
||||
void bt_hook_inject_config_fini(bt_hook_inject_config_t *config);
|
||||
|
||||
#endif
|
||||
52
src/main/sdk-hook/logger-config.c
Normal file
52
src/main/sdk-hook/logger-config.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#define LOG_MODULE "bt-hook-inject-logger-config"
|
||||
|
||||
#include "core/property-node-ext.h"
|
||||
|
||||
#include "iface-core/log.h"
|
||||
|
||||
#include "sdk-hook/logger-config.h"
|
||||
|
||||
#include "util/str.h"
|
||||
|
||||
static enum core_log_bt_log_level _bt_hook_logger_config_str_to_loglevel(const char *str)
|
||||
{
|
||||
log_assert(str);
|
||||
|
||||
if (str_eq(str, "off")) {
|
||||
return CORE_LOG_BT_LOG_LEVEL_OFF;
|
||||
} else if (str_eq(str, "fatal")) {
|
||||
return CORE_LOG_BT_LOG_LEVEL_FATAL;
|
||||
} else if (str_eq(str, "warning")) {
|
||||
return CORE_LOG_BT_LOG_LEVEL_WARNING;
|
||||
} else if (str_eq(str, "info")) {
|
||||
return CORE_LOG_BT_LOG_LEVEL_INFO;
|
||||
} else if (str_eq(str, "misc")) {
|
||||
return CORE_LOG_BT_LOG_LEVEL_MISC;
|
||||
} else {
|
||||
log_fatal("Invalid log level string in config: %s", str);
|
||||
}
|
||||
}
|
||||
|
||||
void bt_hook_logger_config_init(bt_hook_logger_config_t *config)
|
||||
{
|
||||
log_assert(config);
|
||||
|
||||
memset(config, 0, sizeof(bt_hook_logger_config_t));
|
||||
}
|
||||
|
||||
void bt_hook_logger_config_load(
|
||||
const core_property_node_t *node, bt_hook_logger_config_t *config)
|
||||
{
|
||||
core_property_node_result_t result;
|
||||
char buffer[16];
|
||||
|
||||
log_assert(node);
|
||||
log_assert(config);
|
||||
|
||||
result = core_property_node_ext_bool_read(node, "enable", &config->enable);
|
||||
core_property_node_fatal_on_error(result);
|
||||
|
||||
result = core_property_node_ext_str_read(node, "level", buffer, sizeof(buffer));
|
||||
core_property_node_fatal_on_error(result);
|
||||
config->level = _bt_hook_logger_config_str_to_loglevel(buffer);
|
||||
}
|
||||
23
src/main/sdk-hook/logger-config.h
Normal file
23
src/main/sdk-hook/logger-config.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef BT_SDK_HOOK_INJECT_LOGGER_CONFIG_H
|
||||
#define BT_SDK_HOOK_INJECT_LOGGER_CONFIG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "core/log-bt.h"
|
||||
#include "core/log-sink-async.h"
|
||||
#include "core/property-node.h"
|
||||
|
||||
typedef struct bt_hook_logger_config {
|
||||
bool enable;
|
||||
enum core_log_bt_log_level level;
|
||||
} bt_hook_logger_config_t;
|
||||
|
||||
void bt_hook_logger_config_init(bt_hook_logger_config_t *config);
|
||||
|
||||
void bt_hook_logger_config_load(
|
||||
const core_property_node_t *node, bt_hook_logger_config_t *config);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user