diff --git a/Makefile b/Makefile index 5f655ed..0af4a7c 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ include $(DEVKITPRO)/wut/share/wut_rules WUPS_ROOT := $(DEVKITPRO)/wups export VER_MAJOR := 1 -export VER_MINOR := 1 +export VER_MINOR := 2 export VER_PATCH := 0 VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) @@ -30,7 +30,7 @@ BUILD := build SOURCES := source DATA := data INCLUDES := source \ - include \ + include #--------------------------------------------------------------------------------- # options for code generation @@ -48,7 +48,6 @@ ASFLAGS := $(MACHDEP) LDFLAGS = $(ARCH) -Wl,--gc-sections - LIBS := #--------------------------------------------------------------------------------- diff --git a/include/wups_backend/PluginContainer.h b/include/wups_backend/PluginContainer.h index fd13e94..c2c8c11 100644 --- a/include/wups_backend/PluginContainer.h +++ b/include/wups_backend/PluginContainer.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019-2021 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,8 @@ #pragma once #include +#include +#include #include "PluginData.h" #include "PluginMetaInformation.h" @@ -25,23 +27,18 @@ class PluginContainer { public: - PluginContainer(const PluginData &data, PluginMetaInformation metaInfo, uint32_t handle) : pluginData(data), metaInformation(std::move(metaInfo)) { - this->handle = handle; + PluginContainer(std::shared_ptr data, std::shared_ptr metaInfo) : pluginData(std::move(data)), + metaInformation(std::move(metaInfo)) { } - [[nodiscard]] uint32_t getHandle() const { - return this->handle; - } - - [[nodiscard]] const PluginMetaInformation &getMetaInformation() const { + [[nodiscard]] const std::shared_ptr &getMetaInformation() const { return this->metaInformation; } - [[nodiscard]] const PluginData &getPluginData() const { + [[nodiscard]] const std::shared_ptr &getPluginData() const { return pluginData; } - const PluginData pluginData; - const PluginMetaInformation metaInformation; - uint32_t handle = 0; + const std::shared_ptr pluginData; + const std::shared_ptr metaInformation; }; \ No newline at end of file diff --git a/include/wups_backend/PluginData.h b/include/wups_backend/PluginData.h index 330db05..2335b88 100644 --- a/include/wups_backend/PluginData.h +++ b/include/wups_backend/PluginData.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019-2021 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,11 +17,13 @@ #pragma once #include +#include class PluginData { public: explicit PluginData(uint32_t handle); + ~PluginData(); [[nodiscard]] uint32_t getHandle() const { return handle; diff --git a/include/wups_backend/PluginMetaInformation.h b/include/wups_backend/PluginMetaInformation.h index d7de8f2..b78d490 100644 --- a/include/wups_backend/PluginMetaInformation.h +++ b/include/wups_backend/PluginMetaInformation.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019-2021 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,44 +55,44 @@ public: return this->size; } - PluginMetaInformation(const std::string &name, - const std::string &author, - const std::string &version, - const std::string &license, - const std::string &buildtimestamp, - const std::string &description, - const std::string &storageId, + PluginMetaInformation(std::string name, + std::string author, + std::string version, + std::string license, + std::string buildtimestamp, + std::string description, + std::string storageId, size_t size); private: PluginMetaInformation() = default; - void setName(const std::string &name_) { - this->name = name_; + void setName(std::string name_) { + this->name = std::move(name_); } - void setAuthor(const std::string &author_) { - this->author = author_; + void setAuthor(std::string author_) { + this->author = std::move(author_); } - void setVersion(const std::string &version_) { - this->version = version_; + void setVersion(std::string version_) { + this->version = std::move(version_); } - void setLicense(const std::string &license_) { - this->license = license_; + void setLicense(std::string license_) { + this->license = std::move(license_); } - void setBuildTimestamp(const std::string &buildtimestamp_) { - this->buildtimestamp = buildtimestamp_; + void setBuildTimestamp(std::string buildtimestamp_) { + this->buildtimestamp = std::move(buildtimestamp_); } - void setDescription(const std::string &description_) { - this->description = description_; + void setDescription(std::string description_) { + this->description = std::move(description_); } - void setStorageId(const std::string &storageId_) { - this->storageId = storageId_; + void setStorageId(std::string storageId_) { + this->storageId = std::move(storageId_); } void setSize(size_t size_) { diff --git a/include/wups_backend/PluginUtils.h b/include/wups_backend/PluginUtils.h index feb93fe..29e470a 100644 --- a/include/wups_backend/PluginUtils.h +++ b/include/wups_backend/PluginUtils.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019,2020 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,19 +22,15 @@ class PluginUtils { public: - static std::optional getMetaInformationForBuffer(char *buffer, size_t size); + static std::optional> getMetaInformationForBuffer(char *buffer, size_t size); - static std::optional getMetaInformationForPath(const std::string &path); + static std::optional> getMetaInformationForPath(const std::string &path); - static std::vector getLoadedPlugins(uint32_t maxSize); + static std::vector> getLoadedPlugins(uint32_t maxSize); - static std::optional getPluginForPath(const std::string &path); + static std::optional> getPluginForPath(const std::string &path); - static std::optional getPluginForBuffer(char *buffer, size_t size); + static std::optional> getPluginForBuffer(char *buffer, size_t size); - static void destroyPluginContainer(PluginContainer &plugin); - - static void destroyPluginContainer(std::vector &vector); - - static int32_t LoadAndLinkOnRestart(std::vector &plugins); + static int32_t LoadAndLinkOnRestart(const std::vector> &plugins); }; diff --git a/include/wups_backend/import_defines.h b/include/wups_backend/import_defines.h index ebadcf0..26fc89e 100644 --- a/include/wups_backend/import_defines.h +++ b/include/wups_backend/import_defines.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019 - 2021 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,7 @@ #pragma once +#include #include typedef enum GetPluginInformationInputType { @@ -27,10 +28,10 @@ typedef enum GetPluginInformationInputType { typedef uint32_t plugin_container_handle; typedef uint32_t plugin_data_handle; -#define PLUGIN_INFORMATION_VERSION 0x00000001 +#define PLUGIN_INFORMATION_VERSION 0x00000002 /* plugin_information message */ -typedef struct __attribute__((__packed__)) plugin_information { +typedef struct plugin_information { uint32_t plugin_information_version; char name[256]; char author[256]; diff --git a/source/PluginData.cpp b/source/PluginData.cpp index 8959967..962a729 100644 --- a/source/PluginData.cpp +++ b/source/PluginData.cpp @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019,2020 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,18 @@ ****************************************************************************/ #include "wups_backend/PluginData.h" +#include "imports.h" +#include "logger.h" +#include PluginData::PluginData(uint32_t handle) { this->handle = handle; } + +PluginData::~PluginData() { + if (handle != 0) { + if (WUPSDeletePluginData(&handle, 1) != PLUGIN_BACKEND_API_ERROR_NONE) { + DEBUG_FUNCTION_LINE_ERR("### ERROR ###: Failed to delete plugin data"); + } + } +} \ No newline at end of file diff --git a/source/PluginMetaInformation.cpp b/source/PluginMetaInformation.cpp index f546a8d..a28296f 100644 --- a/source/PluginMetaInformation.cpp +++ b/source/PluginMetaInformation.cpp @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019,2020 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,20 +21,20 @@ #include #include -PluginMetaInformation::PluginMetaInformation(const std::string &name_, - const std::string &author_, - const std::string &version_, - const std::string &license_, - const std::string &buildtimestamp_, - const std::string &description_, - const std::string &storageId_, - size_t size_) { - this->name = name_; - this->author = author_; - this->size = size_; - this->buildtimestamp = buildtimestamp_; - this->description = description_; - this->license = license_; - this->version = version_; - this->storageId = storageId_; +PluginMetaInformation::PluginMetaInformation(std::string name, + std::string author, + std::string version, + std::string license, + std::string buildtimestamp, + std::string description, + std::string storageId, + size_t size) { + this->name = std::move(name); + this->author = std::move(author); + this->size = size; + this->buildtimestamp = std::move(buildtimestamp); + this->description = std::move(description); + this->license = std::move(license); + this->version = std::move(version); + this->storageId = std::move(storageId); } diff --git a/source/PluginUtils.cpp b/source/PluginUtils.cpp index 0752cfc..d04a2e4 100644 --- a/source/PluginUtils.cpp +++ b/source/PluginUtils.cpp @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019,2020 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,90 +15,116 @@ * along with this program. If not, see . ****************************************************************************/ -#include - -#include "imports.h" #include "wups_backend/PluginUtils.h" +#include "imports.h" +#include "logger.h" +#include "utils.h" +#include +#include -std::optional PluginUtils::getMetaInformationForBuffer(char *buffer, size_t size) { - plugin_information info; - memset(&info, 0, sizeof(info)); - if (WUPSGetPluginMetaInformationByBuffer(&info, buffer, size)) { - // DEBUG_FUNCTION_LINE("Failed to load meta infos for buffer %08X with size %08X\n", buffer, size); - return std::nullopt; - } - +std::optional> getMetaInformation(const plugin_information &info) { if (info.plugin_information_version != PLUGIN_INFORMATION_VERSION) { - return std::nullopt; + DEBUG_FUNCTION_LINE_ERR("Version mismatch"); + return {}; } - - PluginMetaInformation metaInfo(info.name, - info.author, - info.version, - info.license, - info.buildTimestamp, - info.description, - info.storageId, - info.size); - - return metaInfo; + auto res = make_unique_nothrow(info.name, + info.author, + info.version, + info.license, + info.buildTimestamp, + info.description, + info.storageId, + info.size); + if (!res) { + DEBUG_FUNCTION_LINE_ERR("Not enough memory"); + return {}; + } + return res; } -std::optional PluginUtils::getMetaInformationForPath(const std::string &path) { - plugin_information info; - memset(&info, 0, sizeof(info)); +std::optional> PluginUtils::getMetaInformationForBuffer(char *buffer, size_t size) { + plugin_information info = {}; + if (WUPSGetPluginMetaInformationByBuffer(&info, buffer, size) != PLUGIN_BACKEND_API_ERROR_NONE) { + DEBUG_FUNCTION_LINE_ERR("Failed to load meta infos for buffer %08X with size %08X", buffer, size); + return {}; + } + + return getMetaInformation(info); +} + +std::optional> PluginUtils::getMetaInformationForPath(const std::string &path) { + plugin_information info = {}; if (WUPSGetPluginMetaInformationByPath(&info, path.c_str()) != PLUGIN_BACKEND_API_ERROR_NONE) { - // DEBUG_FUNCTION_LINE("Failed to load meta infos for %s\n", path.c_str()); - return std::nullopt; + DEBUG_FUNCTION_LINE_ERR("Failed to load meta infos for %s", path.c_str()); + return {}; } - if (info.plugin_information_version != PLUGIN_INFORMATION_VERSION) { - return std::nullopt; - } - PluginMetaInformation metaInfo(info.name, - info.author, - info.version, - info.license, - info.buildTimestamp, - info.description, - info.storageId, - info.size); - return metaInfo; + + return getMetaInformation(info); } -std::optional PluginUtils::getPluginForPath(const std::string &path) { +std::optional> PluginUtils::getPluginForPath(const std::string &path) { auto metaInfoOpt = PluginUtils::getMetaInformationForPath(path); if (!metaInfoOpt) { - return std::nullopt; + DEBUG_FUNCTION_LINE_ERR("Failed to get MetaInformation for path %s", path.c_str()); + return {}; } plugin_data_handle dataHandle; if (WUPSLoadPluginAsDataByPath(&dataHandle, path.c_str()) != PLUGIN_BACKEND_API_ERROR_NONE) { - // DEBUG_FUNCTION_LINE("Failed to load data"); - return std::nullopt; + DEBUG_FUNCTION_LINE_ERR("WUPSLoadPluginAsDataByPath failed for path %s", path.c_str()); + return {}; } - return PluginContainer(PluginData(dataHandle), metaInfoOpt.value(), PLUGIN_BACKEND_API_ERROR_NONE); + auto pluginData = make_shared_nothrow(dataHandle); + if (!pluginData) { + DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginData"); + return {}; + } + + auto pluginContainer = make_unique_nothrow(std::move(pluginData), std::move(metaInfoOpt.value())); + if (!pluginContainer) { + DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginContainer"); + return {}; + } + + return pluginContainer; } -std::optional PluginUtils::getPluginForBuffer(char *buffer, size_t size) { +std::optional> PluginUtils::getPluginForBuffer(char *buffer, size_t size) { auto metaInfoOpt = PluginUtils::getMetaInformationForBuffer(buffer, size); if (!metaInfoOpt) { - return std::nullopt; + DEBUG_FUNCTION_LINE_ERR("Failed to get MetaInformation for buffer %08X (%d bytes)", buffer, size); + return {}; } plugin_data_handle dataHandle; if (WUPSLoadPluginAsDataByBuffer(&dataHandle, buffer, size) != PLUGIN_BACKEND_API_ERROR_NONE) { - // DEBUG_FUNCTION_LINE("Failed to load data"); - return std::nullopt; + DEBUG_FUNCTION_LINE_ERR("WUPSLoadPluginAsDataByBuffer failed for buffer %08X (%d bytes)", buffer, size); + return {}; } - return PluginContainer(PluginData(dataHandle), metaInfoOpt.value(), 0); + + auto pluginData = make_shared_nothrow(dataHandle); + if (!pluginData) { + DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginData"); + return {}; + } + + auto pluginContainer = make_unique_nothrow(std::move(pluginData), std::move(metaInfoOpt.value())); + if (!pluginContainer) { + DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginContainer"); + return {}; + } + + return pluginContainer; } -std::vector PluginUtils::getLoadedPlugins(uint32_t maxSize) { - std::vector result; - auto *handles = (plugin_container_handle *) malloc(maxSize * sizeof(plugin_container_handle)); - if (handles == nullptr) { +std::vector> PluginUtils::getLoadedPlugins(uint32_t maxSize) { + std::vector> result; + + auto handles = std::make_unique(maxSize); + if (!handles) { + DEBUG_FUNCTION_LINE_ERR("Not enough memory"); return result; } uint32_t realSize = 0; @@ -109,105 +135,79 @@ std::vector PluginUtils::getLoadedPlugins(uint32_t maxSize) { uint32_t plugin_information_version = 0; - if (WUPSGetLoadedPlugins(handles, maxSize, &realSize, &plugin_information_version) != PLUGIN_BACKEND_API_ERROR_NONE) { - free(handles); - // DEBUG_FUNCTION_LINE("Failed"); + if (WUPSGetLoadedPlugins(handles.get(), maxSize, &realSize, &plugin_information_version) != PLUGIN_BACKEND_API_ERROR_NONE) { + DEBUG_FUNCTION_LINE_ERR("WUPSGetLoadedPlugins: Failed"); return result; } if (realSize == 0 || plugin_information_version != PLUGIN_INFORMATION_VERSION) { - free(handles); - // DEBUG_FUNCTION_LINE("realsize is 0"); + DEBUG_FUNCTION_LINE_ERR("realSize is 0 or version mismatch"); return result; } - auto *dataHandles = (plugin_data_handle *) malloc(realSize * sizeof(plugin_data_handle)); + auto dataHandles = std::make_unique(realSize); if (!dataHandles) { - free(handles); + DEBUG_FUNCTION_LINE_ERR("Not enough memory"); return result; } - if (WUPSGetPluginDataForContainerHandles(handles, dataHandles, realSize) != PLUGIN_BACKEND_API_ERROR_NONE) { - free(handles); - free(dataHandles); - // DEBUG_FUNCTION_LINE("Failed to get plugin data"); + if (WUPSGetPluginDataForContainerHandles(handles.get(), dataHandles.get(), realSize) != PLUGIN_BACKEND_API_ERROR_NONE) { + DEBUG_FUNCTION_LINE_ERR("Failed to get plugin data"); return result; } - auto *information = (plugin_information *) malloc(realSize * sizeof(plugin_information)); + auto information = std::make_unique(realSize); if (!information) { - free(handles); - free(dataHandles); + DEBUG_FUNCTION_LINE_ERR("Not enough memory"); return result; } - if (WUPSGetMetaInformation(handles, information, realSize) != PLUGIN_BACKEND_API_ERROR_NONE) { - free(handles); - free(dataHandles); - free(information); - // DEBUG_FUNCTION_LINE("Failed to get meta information for handles"); + if (WUPSGetMetaInformation(handles.get(), information.get(), realSize) != PLUGIN_BACKEND_API_ERROR_NONE) { + DEBUG_FUNCTION_LINE_ERR("Failed to get meta information for handles"); return result; } for (uint32_t i = 0; i < realSize; i++) { if (information[i].plugin_information_version != PLUGIN_INFORMATION_VERSION) { + DEBUG_FUNCTION_LINE_ERR("Skip, wrong struct version."); continue; } - PluginMetaInformation metaInfo(information[i].name, - information[i].author, - information[i].version, - information[i].license, - information[i].buildTimestamp, - information[i].description, - information[i].storageId, - information[i].size); - PluginData pluginData((uint32_t) dataHandles[i]); - result.emplace_back(pluginData, metaInfo, handles[i]); - } + auto metaInfo = make_shared_nothrow(information[i].name, + information[i].author, + information[i].version, + information[i].license, + information[i].buildTimestamp, + information[i].description, + information[i].storageId, + information[i].size); - free(handles); - free(dataHandles); - free(information); + if (!metaInfo) { + DEBUG_FUNCTION_LINE_ERR("Skip, failed to allocate MetaInformation"); + continue; + } + + auto pluginData = std::make_shared((uint32_t) dataHandles[i]); + if (!pluginData) { + DEBUG_FUNCTION_LINE_ERR("Skip, failed to allocate PluginData"); + continue; + } + + auto pluginContainer = make_unique_nothrow(std::move(pluginData), std::move(metaInfo)); + if (!pluginContainer) { + DEBUG_FUNCTION_LINE_ERR("Skip, failed to allocate PluginContainer"); + continue; + } + + result.push_back(std::move(pluginContainer)); + } return result; } -void PluginUtils::destroyPluginContainer(PluginContainer &plugin) { - std::vector list; - list.push_back(plugin); - return destroyPluginContainer(list); -} - -void PluginUtils::destroyPluginContainer(std::vector &plugins) { - uint32_t containerSize = plugins.size(); - uint32_t dataSize = containerSize; - plugin_container_handle container_handles[containerSize]; - plugin_data_handle data_handles[dataSize]; - - uint32_t cntC = 0; - uint32_t cntD = 0; - for (auto &plugin : plugins) { - if (plugin.getHandle() != 0) { - container_handles[cntC] = plugin.getHandle(); - cntC++; - } else { - containerSize--; - } - if (plugin.pluginData.getHandle() != 0) { - data_handles[cntD] = plugin.pluginData.getHandle(); - cntD++; - } else { - dataSize--; - } - } - WUPSDeletePluginContainer(container_handles, containerSize); - WUPSDeletePluginData(data_handles, dataSize); -} - -int32_t PluginUtils::LoadAndLinkOnRestart(std::vector &plugins) { +int32_t PluginUtils::LoadAndLinkOnRestart(const std::vector> &plugins) { uint32_t dataSize = plugins.size(); plugin_data_handle handles[dataSize]; int i = 0; for (auto &plugin : plugins) { - plugin_data_handle handle = plugin.getPluginData().getHandle(); + plugin_data_handle handle = plugin->getPluginData()->getHandle(); if (handle == 0) { dataSize--; } else { @@ -217,5 +217,4 @@ int32_t PluginUtils::LoadAndLinkOnRestart(std::vector &plugins) } return WUPSLoadAndLinkByDataHandle(handles, dataSize); - ; } diff --git a/source/imports.h b/source/imports.h index 1b32c9e..98199c7 100644 --- a/source/imports.h +++ b/source/imports.h @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2019 - 2021 Maschell + * Copyright (C) 2019-2022 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,8 +25,6 @@ extern "C" { extern PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size); -extern PluginBackendApiErrorType WUPSDeletePluginContainer(const plugin_container_handle *handle_list, uint32_t handle_list_size); - extern PluginBackendApiErrorType WUPSDeletePluginData(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size); extern PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_data_handle *out); diff --git a/source/logger.h b/source/logger.h new file mode 100644 index 0000000..e1c2554 --- /dev/null +++ b/source/logger.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) + +#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) \ + do { \ + OSReport("[(%s)%18s][%23s]%30s@L%04d: ## ERROR ## " FMT "\n", "M", "libwupsbackend", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \ + } while (0) diff --git a/source/utils.h b/source/utils.h new file mode 100644 index 0000000..7b5f655 --- /dev/null +++ b/source/utils.h @@ -0,0 +1,17 @@ +#pragma once +#include + +template +std::unique_ptr make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward(args)...))) { + return std::unique_ptr(new (std::nothrow) T(std::forward(args)...)); +} + +template +inline typename std::_MakeUniq::__array make_unique_nothrow(size_t num) noexcept { + return std::unique_ptr(new (std::nothrow) std::remove_extent_t[num]()); +} + +template +std::shared_ptr make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward(args)...))) { + return std::shared_ptr(new (std::nothrow) T(std::forward(args)...)); +} \ No newline at end of file diff --git a/source/wupsbackend.def b/source/wupsbackend.def index 57752d5..161e38d 100644 --- a/source/wupsbackend.def +++ b/source/wupsbackend.def @@ -5,7 +5,6 @@ WUPSLoadPluginAsDataByPath WUPSLoadPluginAsDataByBuffer WUPSLoadPluginAsData WUPSLoadAndLinkByDataHandle -WUPSDeletePluginContainer WUPSDeletePluginData WUPSGetPluginMetaInformation WUPSGetPluginMetaInformationByPath