aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/module/Module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/module/Module.cpp')
-rw-r--r--src/core/module/Module.cpp236
1 files changed, 232 insertions, 4 deletions
diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp
index 9076dc2c..9c875fce 100644
--- a/src/core/module/Module.cpp
+++ b/src/core/module/Module.cpp
@@ -29,6 +29,10 @@
#include "Module.h"
#include "core/module/GlobalModuleContext.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/IOUtils.h"
+#include "module/sdk/GFSDKModule.h"
+#include "utils/BuildInfoUtils.h"
namespace GpgFrontend::Module {
@@ -43,7 +47,127 @@ class Module::Impl {
: m_ptr_(m_ptr),
identifier_(std::move(id)),
version_(std::move(version)),
- meta_data_(std::move(meta_data)) {}
+ meta_data_(std::move(meta_data)),
+ good_(true) {}
+
+ Impl(ModuleRawPtr m_ptr, QLibrary& module_library)
+ : m_ptr_(m_ptr),
+ module_hash_(CalculateBinaryChacksum(module_library.fileName())),
+ module_library_path_(module_library.fileName()),
+ good_(false) {
+ for (auto& required_symbol : module_required_symbols_) {
+ *required_symbol.pointer =
+ reinterpret_cast<void*>(module_library.resolve(required_symbol.name));
+ if (*required_symbol.pointer == nullptr) {
+ GF_CORE_LOG_WARN(
+ "illegal module: {}, reason: cannot load symbol: {}, abort...",
+ module_library.fileName(), required_symbol.name);
+ return;
+ }
+ }
+
+ identifier_ = GFUnStrDup(get_id_api_());
+ version_ = GFUnStrDup(get_version_api_());
+ gf_sdk_ver_ = GFUnStrDup(get_sdk_ver_api_());
+ qt_env_ver_ = GFUnStrDup(get_qt_ver_api_());
+
+ if (!module_identifier_regex_exp_.match(identifier_).hasMatch()) {
+ GF_CORE_LOG_WARN(
+ "illegal module: {}, reasson invalid module id, abort...",
+ identifier_);
+ return;
+ }
+
+ if (!module_version_regex_exp_.match(version_).hasMatch()) {
+ GF_CORE_LOG_WARN(
+ "illegal module: {}, reasson invalid version: {}, abort...",
+ identifier_, version_);
+ return;
+ }
+
+ if (!module_version_regex_exp_.match(gf_sdk_ver_).hasMatch()) {
+ GF_CORE_LOG_WARN(
+ "illegal module: {}, reasson invalid sdk version: {}, abort...",
+ identifier_, gf_sdk_ver_);
+ return;
+ }
+
+ if (GFCompareSoftwareVersion(gf_sdk_ver_, GetProjectVersion()) > 0) {
+ GF_CORE_LOG_WARN(
+ "uncompatible module: {}, sdk version: {} greater than "
+ "current sdk version: {}, abort...",
+ identifier_, gf_sdk_ver_, GetProjectVersion());
+ return;
+ }
+
+ auto qt_env_ver_regex_match = module_version_regex_exp_.match(qt_env_ver_);
+ if (!qt_env_ver_regex_match.hasMatch()) {
+ GF_CORE_LOG_WARN(
+ "illegal module: {}, reasson invalid qt env version: {}, abort...",
+ identifier_, qt_env_ver_);
+ return;
+ }
+
+ auto qt_env_ver_major = qt_env_ver_regex_match.captured(1);
+ auto qt_env_ver_minor = qt_env_ver_regex_match.captured(2);
+
+ if (qt_env_ver_major != QString::number(QT_VERSION_MAJOR) + "." ||
+ qt_env_ver_minor != QString::number(QT_VERSION_MINOR) + ".") {
+ GF_CORE_LOG_WARN(
+ "uncompatible module: {}, qt version: {} is not binary uncompatible "
+ "with application's qt env version: {}, abort...",
+ identifier_, qt_env_ver_, QString::fromUtf8(QT_VERSION_STR));
+ return;
+ }
+
+ GF_CORE_LOG_INFO(
+ "module loaded, id: {}, version: {}, "
+ "sdk version: {}, qt env version: {}, hash: {}, path: {}",
+ identifier_, version_, gf_sdk_ver_, qt_env_ver_, module_hash_,
+ module_library_path_);
+
+ ::GFModuleMetaData* p_meta_data = get_metadata_api_();
+
+ while (p_meta_data != nullptr) {
+ ::GFModuleMetaData* l_meta_data;
+ meta_data_[QString::fromUtf8(p_meta_data->key)] =
+ QString::fromUtf8(p_meta_data->value);
+ l_meta_data = p_meta_data;
+ p_meta_data = p_meta_data->next;
+ SecureFree(l_meta_data);
+ }
+
+ good_ = true;
+ }
+
+ [[nodiscard]] auto IsGood() const -> bool { return good_; }
+
+ auto Register() -> int {
+ if (good_ && register_api_ != nullptr) return register_api_();
+ return -1;
+ }
+
+ auto Active() -> int {
+ if (good_ && activate_api_ != nullptr) return activate_api_();
+ return -1;
+ }
+
+ auto Exec(const EventReference& event) -> int {
+ if (good_ && execute_api_ != nullptr) {
+ return execute_api_(event->ToModuleEvent());
+ }
+ return -1;
+ }
+
+ auto Deactive() -> int {
+ if (good_ && deactivate_api_ != nullptr) return deactivate_api_();
+ return -1;
+ }
+
+ auto UnRegister() -> int {
+ if (good_ && unregister_api_ != nullptr) return unregister_api_();
+ return -1;
+ }
auto GetChannel() -> int { return get_gpc()->GetChannel(m_ptr_); }
@@ -63,14 +187,77 @@ class Module::Impl {
return identifier_;
}
+ [[nodiscard]] auto GetModuleVersion() const -> ModuleVersion {
+ return version_;
+ }
+
+ [[nodiscard]] auto GetModuleSDKVersion() const -> QString {
+ return gf_sdk_ver_;
+ }
+
+ [[nodiscard]] auto GetModuleQtEnvVersion() const -> QString {
+ return qt_env_ver_;
+ }
+
+ [[nodiscard]] auto GetModuleMetaData() const -> ModuleMetaData {
+ return meta_data_;
+ }
+
+ [[nodiscard]] auto GetModulePath() const -> QString {
+ return module_library_path_;
+ }
+
+ [[nodiscard]] auto GetModuleHash() const -> QString { return module_hash_; }
+
void SetGPC(GlobalModuleContext* gpc) { gpc_ = gpc; }
private:
GlobalModuleContext* gpc_{};
Module* m_ptr_;
- const ModuleIdentifier identifier_;
- const ModuleVersion version_;
- const ModuleMetaData meta_data_;
+ ModuleIdentifier identifier_;
+ ModuleVersion version_;
+ ModuleMetaData meta_data_;
+ QString module_hash_;
+ QString module_library_path_;
+ QString gf_sdk_ver_;
+ QString qt_env_ver_;
+
+ QRegularExpression module_identifier_regex_exp_ = QRegularExpression(
+ R"(^([A-Za-z]{1}[A-Za-z\d_]*\.)+[A-Za-z][A-Za-z\d_]*$)");
+ QRegularExpression module_version_regex_exp_ =
+ QRegularExpression(R"(^(\d+\.)?(\d+\.)?(\*|\d+)$)");
+
+ bool good_;
+
+ GFModuleAPIGetModuleGFSDKVersion get_sdk_ver_api_;
+ GFModuleAPIGetModuleQtEnvVersion get_qt_ver_api_;
+
+ GFModuleAPIGetModuleID get_id_api_;
+ GFModuleAPIGetModuleVersion get_version_api_;
+ GFModuleAPIGetModuleMetaData get_metadata_api_;
+ GFModuleAPIRegisterModule register_api_;
+ GFModuleAPIActivateModule activate_api_;
+ GFModuleAPIExecuteModule execute_api_;
+ GFModuleAPIDeactivateModule deactivate_api_;
+ GFModuleAPIUnregisterModule unregister_api_;
+
+ struct Symbol {
+ const char* name;
+ void** pointer;
+ };
+
+ QList<Symbol> module_required_symbols_ = {
+ {"GFGetModuleGFSDKVersion", reinterpret_cast<void**>(&get_sdk_ver_api_)},
+ {"GFGetModuleQtEnvVersion", reinterpret_cast<void**>(&get_qt_ver_api_)},
+ {"GFGetModuleID", reinterpret_cast<void**>(&get_id_api_)},
+ {"GFGetModuleVersion", reinterpret_cast<void**>(&get_version_api_)},
+ {"GFGetModuleMetaData", reinterpret_cast<void**>(&get_metadata_api_)},
+ {"GFRegisterModule", reinterpret_cast<void**>(&register_api_)},
+ {"GFActiveModule", reinterpret_cast<void**>(&activate_api_)},
+ {"GFExecuteModule", reinterpret_cast<void**>(&execute_api_)},
+ {"GFDeactiveModule", reinterpret_cast<void**>(&deactivate_api_)},
+ {"GFUnregisterModule", reinterpret_cast<void**>(&unregister_api_)},
+ };
auto get_gpc() -> GlobalModuleContext* {
if (gpc_ == nullptr) {
@@ -84,8 +271,25 @@ Module::Module(ModuleIdentifier id, ModuleVersion version,
const ModuleMetaData& meta_data)
: p_(SecureCreateUniqueObject<Impl>(this, id, version, meta_data)) {}
+Module::Module(QLibrary& module_library)
+ : p_(SecureCreateUniqueObject<Impl>(this, module_library)) {}
+
Module::~Module() = default;
+auto Module::IsGood() -> bool { return p_->IsGood(); }
+
+auto Module::Register() -> int { return p_->Register(); }
+
+auto Module::Active() -> int { return p_->Active(); }
+
+auto Module::Exec(EventReference event) -> int {
+ return p_->Exec(std::move(event));
+}
+
+auto Module::Deactive() -> int { return p_->Deactive(); }
+
+auto Module::UnRegister() -> int { return p_->UnRegister(); }
+
auto Module::getChannel() -> int { return p_->GetChannel(); }
auto Module::getDefaultChannel() -> int { return p_->GetDefaultChannel(); }
@@ -102,5 +306,29 @@ auto Module::GetModuleIdentifier() const -> ModuleIdentifier {
return p_->GetModuleIdentifier();
}
+[[nodiscard]] auto Module::GetModuleVersion() const -> ModuleVersion {
+ return p_->GetModuleVersion();
+}
+
+[[nodiscard]] auto Module::GetModuleMetaData() const -> ModuleMetaData {
+ return p_->GetModuleMetaData();
+}
+
+[[nodiscard]] auto Module::GetModulePath() const -> QString {
+ return p_->GetModulePath();
+}
+
+[[nodiscard]] auto Module::GetModuleHash() const -> QString {
+ return p_->GetModuleHash();
+}
+
+[[nodiscard]] auto Module::GetModuleSDKVersion() const -> QString {
+ return p_->GetModuleSDKVersion();
+}
+
+[[nodiscard]] auto Module::GetModuleQtEnvVersion() const -> QString {
+ return p_->GetModuleQtEnvVersion();
+}
+
void Module::SetGPC(GlobalModuleContext* gpc) { p_->SetGPC(gpc); }
} // namespace GpgFrontend::Module \ No newline at end of file