diff --git a/source/PluginManagement.cpp b/source/PluginManagement.cpp index dd922fc..262d6c1 100644 --- a/source/PluginManagement.cpp +++ b/source/PluginManagement.cpp @@ -1,10 +1,12 @@ #include "PluginManagement.h" +#include "NotificationsUtils.h" #include "hooks.h" #include "patcher/hooks_patcher_static.h" #include "plugin/PluginContainer.h" #include "plugin/PluginInformationFactory.h" #include "plugin/PluginMetaInformationFactory.h" #include "utils/ElfUtils.h" +#include "utils/StringTools.h" #include "utils/utils.h" #include #include @@ -152,8 +154,10 @@ PluginManagement::loadPlugins(const std::forward_listgetName().c_str()); @@ -168,7 +172,12 @@ PluginManagement::loadPlugins(const std::forward_listmSource.c_str()); + if (error == PLUGIN_PARSE_ERROR_INCOMPATIBLE_VERSION) { + errMsg += ". Incompatible version."; + } + DEBUG_FUNCTION_LINE_ERR("%s", errMsg.c_str()); + DisplayErrorNotificationMessage(errMsg, 15.0f); } } diff --git a/source/plugin/PluginData.cpp b/source/plugin/PluginData.cpp index 41c985f..2670d26 100644 --- a/source/plugin/PluginData.cpp +++ b/source/plugin/PluginData.cpp @@ -2,7 +2,7 @@ #include "utils/logger.h" #include "utils/utils.h" -PluginData::PluginData(const std::vector &input) : length(input.size()) { +PluginData::PluginData(const std::vector &input, std::string source) : length(input.size()), mSource(std::move(source)) { auto data_copy = make_unique_nothrow(length); if (!data_copy) { DEBUG_FUNCTION_LINE_ERR("Failed to allocate space on default heap"); diff --git a/source/plugin/PluginData.h b/source/plugin/PluginData.h index f0f144d..5b3ebae 100644 --- a/source/plugin/PluginData.h +++ b/source/plugin/PluginData.h @@ -25,7 +25,7 @@ class PluginData { public: - explicit PluginData(const std::vector &buffer); + explicit PluginData(const std::vector &buffer, std::string source); uint32_t getHandle() { return (uint32_t) this; @@ -33,4 +33,5 @@ public: size_t length = 0; std::unique_ptr buffer; + std::string mSource; }; diff --git a/source/plugin/PluginDataFactory.cpp b/source/plugin/PluginDataFactory.cpp index 858d1ee..6de7847 100644 --- a/source/plugin/PluginDataFactory.cpp +++ b/source/plugin/PluginDataFactory.cpp @@ -81,15 +81,15 @@ std::optional> PluginDataFactory::load(const std::st DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!"); - return load(result); + return load(result, filename); } -std::optional> PluginDataFactory::load(const std::vector &buffer) { +std::optional> PluginDataFactory::load(const std::vector &buffer, const std::string &source) { if (buffer.empty()) { return {}; } - auto res = make_unique_nothrow(buffer); + auto res = make_unique_nothrow(buffer, source); if (!res) { return {}; } diff --git a/source/plugin/PluginDataFactory.h b/source/plugin/PluginDataFactory.h index c67fec5..e09f46e 100644 --- a/source/plugin/PluginDataFactory.h +++ b/source/plugin/PluginDataFactory.h @@ -31,5 +31,5 @@ public: static std::optional> load(const std::string &path); - static std::optional> load(const std::vector &buffer); + static std::optional> load(const std::vector &buffer, const std::string &source); }; diff --git a/source/plugin/PluginMetaInformationFactory.cpp b/source/plugin/PluginMetaInformationFactory.cpp index b32129f..e9e72a0 100644 --- a/source/plugin/PluginMetaInformationFactory.cpp +++ b/source/plugin/PluginMetaInformationFactory.cpp @@ -22,50 +22,55 @@ #include "utils/wiiu_zlib.hpp" #include -std::optional> PluginMetaInformationFactory::loadPlugin(const std::shared_ptr &pluginData) { +std::optional> PluginMetaInformationFactory::loadPlugin(const std::shared_ptr &pluginData, PluginParseErrors &error) { if (!pluginData->buffer) { + error = PLUGIN_PARSE_ERROR_BUFFER_EMPTY; DEBUG_FUNCTION_LINE_ERR("Buffer is empty"); return {}; } ELFIO::elfio reader(new wiiu_zlib); if (!reader.load(reinterpret_cast(pluginData->buffer.get()), pluginData->length)) { + error = PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED; DEBUG_FUNCTION_LINE_ERR("Can't process PluginData in elfio"); return {}; } - return loadPlugin(reader); + return loadPlugin(reader, error); } -std::optional> PluginMetaInformationFactory::loadPlugin(const std::string &filePath) { +std::optional> PluginMetaInformationFactory::loadPlugin(const std::string &filePath, PluginParseErrors &error) { ELFIO::elfio reader(new wiiu_zlib); uint8_t *buffer = nullptr; uint32_t length = 0; if (FSUtils::LoadFileToMem(filePath.c_str(), &buffer, &length) < 0) { DEBUG_FUNCTION_LINE_ERR("Failed to load file to memory"); + error = PLUGIN_PARSE_ERROR_IO_ERROR; return {}; } if (!reader.load(reinterpret_cast(buffer), length)) { + error = PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED; DEBUG_FUNCTION_LINE_ERR("Can't process PluginData in elfio"); return {}; } - auto res = loadPlugin(reader); + auto res = loadPlugin(reader, error); free(buffer); return res; } -std::optional> PluginMetaInformationFactory::loadPlugin(char *buffer, size_t size) { +std::optional> PluginMetaInformationFactory::loadPlugin(char *buffer, size_t size, PluginParseErrors &error) { ELFIO::elfio reader(new wiiu_zlib); if (!reader.load(reinterpret_cast(buffer), size)) { + error = PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED; DEBUG_FUNCTION_LINE_ERR("Can't find or process ELF file"); return std::nullopt; } - return loadPlugin(reader); + return loadPlugin(reader, error); } -std::optional> PluginMetaInformationFactory::loadPlugin(const ELFIO::elfio &reader) { +std::optional> PluginMetaInformationFactory::loadPlugin(const ELFIO::elfio &reader, PluginParseErrors &error) { size_t pluginSize = 0; auto pluginInfo = std::unique_ptr(new PluginMetaInformation); @@ -120,6 +125,7 @@ std::optional> PluginMetaInformationFacto pluginInfo->setStorageId(value); } else if (key == "wups") { if (value != "0.7.1") { + error = PLUGIN_PARSE_ERROR_INCOMPATIBLE_VERSION; DEBUG_FUNCTION_LINE_ERR("Warning: Ignoring plugin - Unsupported WUPS version: %s.", value.c_str()); return std::nullopt; } @@ -132,5 +138,7 @@ std::optional> PluginMetaInformationFacto pluginInfo->setSize(pluginSize); + error = PLUGIN_PARSE_ERROR_NONE; + return pluginInfo; } diff --git a/source/plugin/PluginMetaInformationFactory.h b/source/plugin/PluginMetaInformationFactory.h index f0e6ae7..cf8a093 100644 --- a/source/plugin/PluginMetaInformationFactory.h +++ b/source/plugin/PluginMetaInformationFactory.h @@ -25,13 +25,22 @@ #include #include +enum PluginParseErrors { + PLUGIN_PARSE_ERROR_NONE, + PLUGIN_PARSE_ERROR_UNKNOWN, + PLUGIN_PARSE_ERROR_INCOMPATIBLE_VERSION, + PLUGIN_PARSE_ERROR_BUFFER_EMPTY, + PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED, + PLUGIN_PARSE_ERROR_IO_ERROR, +}; + class PluginMetaInformationFactory { public: - static std::optional> loadPlugin(const std::shared_ptr &pluginData); + static std::optional> loadPlugin(const std::shared_ptr &pluginData, PluginParseErrors &error); - static std::optional> loadPlugin(const std::string &filePath); + static std::optional> loadPlugin(const std::string &filePath, PluginParseErrors &error); - static std::optional> loadPlugin(char *buffer, size_t size); + static std::optional> loadPlugin(char *buffer, size_t size, PluginParseErrors &error); - static std::optional> loadPlugin(const ELFIO::elfio &reader); + static std::optional> loadPlugin(const ELFIO::elfio &reader, PluginParseErrors &error); }; diff --git a/source/utils/exports.cpp b/source/utils/exports.cpp index 5ed934a..940c8d4 100644 --- a/source/utils/exports.cpp +++ b/source/utils/exports.cpp @@ -67,7 +67,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationIn } else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) { std::vector data(size); memcpy(&data[0], buffer, size); - pluginData = PluginDataFactory::load(data); + pluginData = PluginDataFactory::load(data, ""); } else { return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; } @@ -95,11 +95,12 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsDataByBuffer(plugin_data_ha extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output) { std::optional> pluginInfo; + PluginParseErrors error = PLUGIN_PARSE_ERROR_UNKNOWN; if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) { std::string pathStr(path); - pluginInfo = PluginMetaInformationFactory::loadPlugin(pathStr); + pluginInfo = PluginMetaInformationFactory::loadPlugin(pathStr, error); } else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) { - pluginInfo = PluginMetaInformationFactory::loadPlugin(buffer, size); + pluginInfo = PluginMetaInformationFactory::loadPlugin(buffer, size, error); } else { DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG"); return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;