mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2024-11-25 14:16:53 +01:00
Improve error message when parsing a plugin failed
This commit is contained in:
parent
07de996bf9
commit
1e7c77b39f
@ -1,10 +1,12 @@
|
|||||||
#include "PluginManagement.h"
|
#include "PluginManagement.h"
|
||||||
|
#include "NotificationsUtils.h"
|
||||||
#include "hooks.h"
|
#include "hooks.h"
|
||||||
#include "patcher/hooks_patcher_static.h"
|
#include "patcher/hooks_patcher_static.h"
|
||||||
#include "plugin/PluginContainer.h"
|
#include "plugin/PluginContainer.h"
|
||||||
#include "plugin/PluginInformationFactory.h"
|
#include "plugin/PluginInformationFactory.h"
|
||||||
#include "plugin/PluginMetaInformationFactory.h"
|
#include "plugin/PluginMetaInformationFactory.h"
|
||||||
#include "utils/ElfUtils.h"
|
#include "utils/ElfUtils.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <coreinit/dynload.h>
|
#include <coreinit/dynload.h>
|
||||||
@ -152,8 +154,10 @@ PluginManagement::loadPlugins(const std::forward_list<std::shared_ptr<PluginData
|
|||||||
|
|
||||||
uint32_t trampolineID = 0;
|
uint32_t trampolineID = 0;
|
||||||
for (auto &pluginData : pluginList) {
|
for (auto &pluginData : pluginList) {
|
||||||
auto metaInfo = PluginMetaInformationFactory::loadPlugin(pluginData);
|
PluginParseErrors error = PLUGIN_PARSE_ERROR_UNKNOWN;
|
||||||
if (metaInfo) {
|
|
||||||
|
auto metaInfo = PluginMetaInformationFactory::loadPlugin(pluginData, error);
|
||||||
|
if (metaInfo && error == PLUGIN_PARSE_ERROR_NONE) {
|
||||||
auto info = PluginInformationFactory::load(pluginData, trampoline_data, trampoline_data_length, trampolineID++);
|
auto info = PluginInformationFactory::load(pluginData, trampoline_data, trampoline_data_length, trampolineID++);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
auto errMsg = string_format("Failed to load plugin: %s", metaInfo.value()->getName().c_str());
|
auto errMsg = string_format("Failed to load plugin: %s", metaInfo.value()->getName().c_str());
|
||||||
@ -168,7 +172,12 @@ PluginManagement::loadPlugins(const std::forward_list<std::shared_ptr<PluginData
|
|||||||
}
|
}
|
||||||
plugins.push_back(std::move(container));
|
plugins.push_back(std::move(container));
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to get meta information");
|
auto errMsg = string_format("Failed to load plugin: %s", pluginData->mSource.c_str());
|
||||||
|
if (error == PLUGIN_PARSE_ERROR_INCOMPATIBLE_VERSION) {
|
||||||
|
errMsg += ". Incompatible version.";
|
||||||
|
}
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("%s", errMsg.c_str());
|
||||||
|
DisplayErrorNotificationMessage(errMsg, 15.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
|
|
||||||
PluginData::PluginData(const std::vector<uint8_t> &input) : length(input.size()) {
|
PluginData::PluginData(const std::vector<uint8_t> &input, std::string source) : length(input.size()), mSource(std::move(source)) {
|
||||||
auto data_copy = make_unique_nothrow<uint8_t[]>(length);
|
auto data_copy = make_unique_nothrow<uint8_t[]>(length);
|
||||||
if (!data_copy) {
|
if (!data_copy) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to allocate space on default heap");
|
DEBUG_FUNCTION_LINE_ERR("Failed to allocate space on default heap");
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
class PluginData {
|
class PluginData {
|
||||||
public:
|
public:
|
||||||
explicit PluginData(const std::vector<uint8_t> &buffer);
|
explicit PluginData(const std::vector<uint8_t> &buffer, std::string source);
|
||||||
|
|
||||||
uint32_t getHandle() {
|
uint32_t getHandle() {
|
||||||
return (uint32_t) this;
|
return (uint32_t) this;
|
||||||
@ -33,4 +33,5 @@ public:
|
|||||||
|
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
std::unique_ptr<uint8_t[]> buffer;
|
std::unique_ptr<uint8_t[]> buffer;
|
||||||
|
std::string mSource;
|
||||||
};
|
};
|
||||||
|
@ -81,15 +81,15 @@ std::optional<std::unique_ptr<PluginData>> PluginDataFactory::load(const std::st
|
|||||||
|
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!");
|
DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!");
|
||||||
|
|
||||||
return load(result);
|
return load(result, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::unique_ptr<PluginData>> PluginDataFactory::load(const std::vector<uint8_t> &buffer) {
|
std::optional<std::unique_ptr<PluginData>> PluginDataFactory::load(const std::vector<uint8_t> &buffer, const std::string &source) {
|
||||||
if (buffer.empty()) {
|
if (buffer.empty()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto res = make_unique_nothrow<PluginData>(buffer);
|
auto res = make_unique_nothrow<PluginData>(buffer, source);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -31,5 +31,5 @@ public:
|
|||||||
|
|
||||||
static std::optional<std::unique_ptr<PluginData>> load(const std::string &path);
|
static std::optional<std::unique_ptr<PluginData>> load(const std::string &path);
|
||||||
|
|
||||||
static std::optional<std::unique_ptr<PluginData>> load(const std::vector<uint8_t> &buffer);
|
static std::optional<std::unique_ptr<PluginData>> load(const std::vector<uint8_t> &buffer, const std::string &source);
|
||||||
};
|
};
|
||||||
|
@ -22,50 +22,55 @@
|
|||||||
#include "utils/wiiu_zlib.hpp"
|
#include "utils/wiiu_zlib.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const std::shared_ptr<PluginData> &pluginData) {
|
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const std::shared_ptr<PluginData> &pluginData, PluginParseErrors &error) {
|
||||||
if (!pluginData->buffer) {
|
if (!pluginData->buffer) {
|
||||||
|
error = PLUGIN_PARSE_ERROR_BUFFER_EMPTY;
|
||||||
DEBUG_FUNCTION_LINE_ERR("Buffer is empty");
|
DEBUG_FUNCTION_LINE_ERR("Buffer is empty");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
ELFIO::elfio reader(new wiiu_zlib);
|
ELFIO::elfio reader(new wiiu_zlib);
|
||||||
if (!reader.load(reinterpret_cast<const char *>(pluginData->buffer.get()), pluginData->length)) {
|
if (!reader.load(reinterpret_cast<const char *>(pluginData->buffer.get()), pluginData->length)) {
|
||||||
|
error = PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED;
|
||||||
DEBUG_FUNCTION_LINE_ERR("Can't process PluginData in elfio");
|
DEBUG_FUNCTION_LINE_ERR("Can't process PluginData in elfio");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return loadPlugin(reader);
|
return loadPlugin(reader, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const std::string &filePath) {
|
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const std::string &filePath, PluginParseErrors &error) {
|
||||||
ELFIO::elfio reader(new wiiu_zlib);
|
ELFIO::elfio reader(new wiiu_zlib);
|
||||||
|
|
||||||
uint8_t *buffer = nullptr;
|
uint8_t *buffer = nullptr;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
if (FSUtils::LoadFileToMem(filePath.c_str(), &buffer, &length) < 0) {
|
if (FSUtils::LoadFileToMem(filePath.c_str(), &buffer, &length) < 0) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to load file to memory");
|
DEBUG_FUNCTION_LINE_ERR("Failed to load file to memory");
|
||||||
|
error = PLUGIN_PARSE_ERROR_IO_ERROR;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reader.load(reinterpret_cast<const char *>(buffer), length)) {
|
if (!reader.load(reinterpret_cast<const char *>(buffer), length)) {
|
||||||
|
error = PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED;
|
||||||
DEBUG_FUNCTION_LINE_ERR("Can't process PluginData in elfio");
|
DEBUG_FUNCTION_LINE_ERR("Can't process PluginData in elfio");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto res = loadPlugin(reader);
|
auto res = loadPlugin(reader, error);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(char *buffer, size_t size) {
|
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(char *buffer, size_t size, PluginParseErrors &error) {
|
||||||
ELFIO::elfio reader(new wiiu_zlib);
|
ELFIO::elfio reader(new wiiu_zlib);
|
||||||
|
|
||||||
if (!reader.load(reinterpret_cast<const char *>(buffer), size)) {
|
if (!reader.load(reinterpret_cast<const char *>(buffer), size)) {
|
||||||
|
error = PLUGIN_PARSE_ERROR_ELFIO_PARSE_FAILED;
|
||||||
DEBUG_FUNCTION_LINE_ERR("Can't find or process ELF file");
|
DEBUG_FUNCTION_LINE_ERR("Can't find or process ELF file");
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadPlugin(reader);
|
return loadPlugin(reader, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const ELFIO::elfio &reader) {
|
std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const ELFIO::elfio &reader, PluginParseErrors &error) {
|
||||||
size_t pluginSize = 0;
|
size_t pluginSize = 0;
|
||||||
|
|
||||||
auto pluginInfo = std::unique_ptr<PluginMetaInformation>(new PluginMetaInformation);
|
auto pluginInfo = std::unique_ptr<PluginMetaInformation>(new PluginMetaInformation);
|
||||||
@ -120,6 +125,7 @@ std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFacto
|
|||||||
pluginInfo->setStorageId(value);
|
pluginInfo->setStorageId(value);
|
||||||
} else if (key == "wups") {
|
} else if (key == "wups") {
|
||||||
if (value != "0.7.1") {
|
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());
|
DEBUG_FUNCTION_LINE_ERR("Warning: Ignoring plugin - Unsupported WUPS version: %s.", value.c_str());
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@ -132,5 +138,7 @@ std::optional<std::unique_ptr<PluginMetaInformation>> PluginMetaInformationFacto
|
|||||||
|
|
||||||
pluginInfo->setSize(pluginSize);
|
pluginInfo->setSize(pluginSize);
|
||||||
|
|
||||||
|
error = PLUGIN_PARSE_ERROR_NONE;
|
||||||
|
|
||||||
return pluginInfo;
|
return pluginInfo;
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,22 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
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 {
|
class PluginMetaInformationFactory {
|
||||||
public:
|
public:
|
||||||
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(const std::shared_ptr<PluginData> &pluginData);
|
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(const std::shared_ptr<PluginData> &pluginData, PluginParseErrors &error);
|
||||||
|
|
||||||
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(const std::string &filePath);
|
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(const std::string &filePath, PluginParseErrors &error);
|
||||||
|
|
||||||
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(char *buffer, size_t size);
|
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(char *buffer, size_t size, PluginParseErrors &error);
|
||||||
|
|
||||||
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(const ELFIO::elfio &reader);
|
static std::optional<std::unique_ptr<PluginMetaInformation>> loadPlugin(const ELFIO::elfio &reader, PluginParseErrors &error);
|
||||||
};
|
};
|
||||||
|
@ -67,7 +67,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationIn
|
|||||||
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
||||||
std::vector<uint8_t> data(size);
|
std::vector<uint8_t> data(size);
|
||||||
memcpy(&data[0], buffer, size);
|
memcpy(&data[0], buffer, size);
|
||||||
pluginData = PluginDataFactory::load(data);
|
pluginData = PluginDataFactory::load(data, "<UNKNOWN>");
|
||||||
} else {
|
} else {
|
||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
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) {
|
extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output) {
|
||||||
std::optional<std::unique_ptr<PluginMetaInformation>> pluginInfo;
|
std::optional<std::unique_ptr<PluginMetaInformation>> pluginInfo;
|
||||||
|
PluginParseErrors error = PLUGIN_PARSE_ERROR_UNKNOWN;
|
||||||
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
||||||
std::string pathStr(path);
|
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) {
|
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
||||||
pluginInfo = PluginMetaInformationFactory::loadPlugin(buffer, size);
|
pluginInfo = PluginMetaInformationFactory::loadPlugin(buffer, size, error);
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
|
DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
|
||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||||
|
Loading…
Reference in New Issue
Block a user