impr: Merge in script loader structure improvements from python branch

This commit is contained in:
WerWolv 2024-05-17 21:01:35 +02:00
parent 663b99ed64
commit f6953fd829
20 changed files with 130 additions and 80 deletions

View File

@ -2,11 +2,6 @@ cmake_minimum_required(VERSION 3.16)
include(ImHexPlugin)
find_file(DEFAULT_MAGIC_FILE_PATH magic.mgc HINTS ${LIBMAGIC_INCLUDE_DIR}/../share/misc)
if (DEFAULT_MAGIC_FILE_PATH)
add_romfs_resource(${DEFAULT_MAGIC_FILE_PATH} always_auto_extract/magic/magic.mgc)
endif ()
add_imhex_plugin(
NAME
builtin
@ -126,6 +121,11 @@ add_imhex_plugin(
LLVMDemangle
)
find_file(DEFAULT_MAGIC_FILE_PATH magic.mgc HINTS ${LIBMAGIC_INCLUDE_DIR}/../share/misc)
if (DEFAULT_MAGIC_FILE_PATH)
add_romfs_resource(${DEFAULT_MAGIC_FILE_PATH} always_auto_extract/magic/magic.mgc)
endif ()
if (WIN32)
target_link_libraries(builtin PRIVATE setupapi)
endif ()

View File

@ -184,7 +184,7 @@ namespace hex::plugin::builtin {
}
}
} else {
const auto& error = m_runtime.getError();
const auto& error = m_runtime.getEvalError();
log::error("Failed to execute custom inspector file '{}'!", wolv::util::toUTF8String(filePath));
if (error.has_value())

View File

@ -1662,7 +1662,7 @@ namespace hex::plugin::builtin {
m_lastEvaluationResult = runtime.executeString(code, pl::api::Source::DefaultSource, envVars, inVariables);
if (!m_lastEvaluationResult) {
*m_lastEvaluationError = runtime.getError();
*m_lastEvaluationError = runtime.getEvalError();
*m_lastCompileError = runtime.getCompileErrors();
}

View File

@ -1,24 +1,11 @@
cmake_minimum_required(VERSION 3.16)
include(ImHexPlugin)
find_package(CoreClrEmbed)
add_imhex_plugin(
NAME
script_loader
SOURCES
source/plugin_script_loader.cpp
INCLUDES
include
LIBRARIES
fonts
ui
)
if (CoreClrEmbed_FOUND)
set(IMHEX_DOTNET_SCRIPT_SUPPORT ON)
add_library(nethost SHARED IMPORTED)
target_include_directories(nethost INTERFACE "${CoreClrEmbed_INCLUDE_DIRS}")
get_filename_component(CoreClrEmbed_FOLDER ${CoreClrEmbed_SHARED_LIBRARIES} DIRECTORY)
@ -29,25 +16,43 @@ if (CoreClrEmbed_FOUND)
BUILD_RPATH ${CoreClrEmbed_FOLDER}
INSTALL_RPATH ${CoreClrEmbed_FOLDER})
target_link_directories(script_loader PRIVATE ${CoreClrEmbed_FOLDER})
target_include_directories(script_loader PRIVATE ${CoreClrEmbed_INCLUDE_DIRS})
target_compile_definitions(script_loader PRIVATE DOTNET_PLUGINS=1)
target_sources(script_loader PRIVATE
source/loaders/dotnet/dotnet_loader.cpp
source/script_api/v1/mem.cpp
source/script_api/v1/bookmarks.cpp
source/script_api/v1/ui.cpp
source/script_api/v1/logger.cpp
)
set(EXTRA_BUNDLE_LIBRARY_PATHS "${CoreClrEmbed_FOLDER}" PARENT_SCOPE)
if (IMHEX_BUNDLE_DOTNET)
install(FILES ${CoreClrEmbed_SHARED_LIBRARIES} DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif ()
endif()
endif()
add_subdirectory(dotnet)
add_subdirectory(support/c)
add_imhex_plugin(
NAME
script_loader
SOURCES
source/plugin_script_loader.cpp
INCLUDES
include
LIBRARIES
c_api
fonts
)
if (IMHEX_DOTNET_SCRIPT_SUPPORT)
message(STATUS "Enabling .NET Scripting support!")
target_link_directories(script_loader PRIVATE ${CoreClrEmbed_FOLDER})
target_include_directories(script_loader PRIVATE ${CoreClrEmbed_INCLUDE_DIRS})
target_compile_definitions(script_loader PRIVATE IMHEX_DOTNET_SCRIPT_SUPPORT=1)
target_sources(script_loader PRIVATE
source/loaders/dotnet/dotnet_loader.cpp
)
add_subdirectory(support/dotnet)
add_dependencies(script_loader AssemblyLoader)
endif ()
endif()

View File

@ -10,7 +10,7 @@ namespace hex::script::loader {
class DotNetLoader : public ScriptLoader {
public:
DotNetLoader() = default;
DotNetLoader() : ScriptLoader(".NET") {}
~DotNetLoader() override = default;
bool initialize() override;

View File

@ -3,31 +3,45 @@
#include <functional>
#include <string>
#include <vector>
#include <hex/helpers/utils.hpp>
#if defined(OS_WINDOWS)
#include <Windows.h>
#else
#include <dlfcn.h>
#endif
namespace hex::script::loader {
class ScriptLoader;
struct Script {
std::string name;
bool background;
std::function<void()> entryPoint;
const ScriptLoader *loader;
};
class ScriptLoader {
public:
ScriptLoader() = default;
ScriptLoader(std::string typeName) : m_typeName(std::move(typeName)) {}
virtual ~ScriptLoader() = default;
virtual bool initialize() = 0;
virtual bool loadAll() = 0;
void addScript(std::string name, bool background, std::function<void()> entryPoint) {
m_scripts.emplace_back(std::move(name), background, std::move(entryPoint));
m_scripts.emplace_back(std::move(name), background, std::move(entryPoint), this);
}
const auto& getScripts() const {
return m_scripts;
}
const std::string& getTypeName() const {
return m_typeName;
}
protected:
void clearScripts() {
m_scripts.clear();
@ -35,6 +49,49 @@ namespace hex::script::loader {
private:
std::vector<Script> m_scripts;
std::string m_typeName;
};
#if defined(OS_WINDOWS)
inline void *loadLibrary(const wchar_t *path) {
try {
HMODULE h = ::LoadLibraryW(path);
return h;
} catch (...) {
return nullptr;
}
}
inline void *loadLibrary(const char *path) {
try {
auto utf16Path = hex::utf8ToUtf16(path);
HMODULE h = ::LoadLibraryW(utf16Path.c_str());
return h;
} catch (...) {
return nullptr;
}
}
template<typename T>
T getExport(void *h, const char *name) {
try {
FARPROC f = ::GetProcAddress(static_cast<HMODULE>(h), name);
return reinterpret_cast<T>(reinterpret_cast<uintptr_t>(f));
} catch (...) {
return nullptr;
}
}
#else
inline void *loadLibrary(const char *path) {
void *h = dlopen(path, RTLD_LAZY);
return h;
}
template<typename T>
T getExport(void *h, const char *name) {
void *f = dlsym(h, name);
return reinterpret_cast<T>(f);
}
#endif
}

View File

@ -3,10 +3,8 @@
#include <stdexcept>
#if defined(OS_WINDOWS)
#include <Windows.h>
#define STRING(str) L##str
#else
#include <dlfcn.h>
#define STRING(str) str
#endif
@ -34,38 +32,6 @@ namespace hex::script::loader {
using get_hostfxr_path_fn = int(*)(char_t * buffer, size_t * buffer_size, const get_hostfxr_parameters *parameters);
#if defined(OS_WINDOWS)
void *loadLibrary(const char_t *path) {
try {
HMODULE h = ::LoadLibraryW(path);
return h;
} catch (...) {
return nullptr;
}
}
template<typename T>
T getExport(void *h, const char *name) {
try {
FARPROC f = ::GetProcAddress(static_cast<HMODULE>(h), name);
return reinterpret_cast<T>(reinterpret_cast<uintptr_t>(f));
} catch (...) {
return nullptr;
}
}
#else
void *loadLibrary(const char_t *path) {
void *h = dlopen(path, RTLD_LAZY);
return h;
}
template<typename T>
T getExport(void *h, const char *name) {
void *f = dlsym(h, name);
return reinterpret_cast<T>(f);
}
#endif
hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config = nullptr;
hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate = nullptr;
hostfxr_close_fn hostfxr_close = nullptr;

View File

@ -16,7 +16,7 @@ using namespace hex;
using namespace hex::script::loader;
using ScriptLoaders = std::tuple<
#if defined(DOTNET_PLUGINS)
#if defined(IMHEX_DOTNET_SCRIPT_SUPPORT)
DotNetLoader
#endif
>;
@ -106,11 +106,11 @@ namespace {
}
for (const auto &script : scripts) {
const auto &[name, background, entryPoint] = *script;
const auto &[name, background, entryPoint, loader] = *script;
if (background)
continue;
if (ImGui::MenuItem(name.c_str())) {
if (ImGui::MenuItem(name.c_str(), loader->getTypeName().c_str())) {
runnerTask = TaskManager::createTask("Running script...", TaskManager::NoProgress, [entryPoint](auto&) {
entryPoint();
});
@ -140,4 +140,4 @@ IMHEX_PLUGIN_SETUP("Script Loader", "WerWolv", "Script Loader plugin") {
if (initializeAllLoaders()) {
addScriptsMenu();
}
}
}

View File

@ -0,0 +1,14 @@
project(c_api)
add_library(c_api OBJECT
source/script_api/v1/bookmarks.cpp
source/script_api/v1/logger.cpp
source/script_api/v1/mem.cpp
source/script_api/v1/ui.cpp
)
target_include_directories(c_api PUBLIC
include
)
target_link_libraries(c_api PRIVATE libimhex ui)
target_compile_definitions(c_api PRIVATE IMHEX_PROJECT_NAME="Script")

View File

@ -26,6 +26,14 @@ SCRIPT_API(void writeMemory, u64 address, size_t size, const void *buffer) {
provider->write(address, buffer, size);
}
SCRIPT_API(u64 getBaseAddress) {
return hex::ImHexApi::Provider::get()->getBaseAddress();
}
SCRIPT_API(u64 getDataSize) {
return hex::ImHexApi::Provider::get()->getSize();
}
SCRIPT_API(bool getSelection, u64 *start, u64 *end) {
if (start == nullptr || end == nullptr)
return false;