Use smart pointers and unsure compatibility with latest WUPS backend

This commit is contained in:
Maschell 2022-05-14 12:06:16 +02:00
parent 4d3c85c793
commit ce0fdbc057
13 changed files with 227 additions and 197 deletions

View File

@ -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 :=
#---------------------------------------------------------------------------------

View File

@ -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 <cstdint>
#include <memory>
#include <utility>
#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<PluginData> data, std::shared_ptr<PluginMetaInformation> 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<PluginMetaInformation> &getMetaInformation() const {
return this->metaInformation;
}
[[nodiscard]] const PluginData &getPluginData() const {
[[nodiscard]] const std::shared_ptr<PluginData> &getPluginData() const {
return pluginData;
}
const PluginData pluginData;
const PluginMetaInformation metaInformation;
uint32_t handle = 0;
const std::shared_ptr<PluginData> pluginData;
const std::shared_ptr<PluginMetaInformation> metaInformation;
};

View File

@ -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 <cstdint>
#include <wups_backend/import_defines.h>
class PluginData {
public:
explicit PluginData(uint32_t handle);
~PluginData();
[[nodiscard]] uint32_t getHandle() const {
return handle;

View File

@ -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_) {

View File

@ -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<PluginMetaInformation> getMetaInformationForBuffer(char *buffer, size_t size);
static std::optional<std::unique_ptr<PluginMetaInformation>> getMetaInformationForBuffer(char *buffer, size_t size);
static std::optional<PluginMetaInformation> getMetaInformationForPath(const std::string &path);
static std::optional<std::unique_ptr<PluginMetaInformation>> getMetaInformationForPath(const std::string &path);
static std::vector<PluginContainer> getLoadedPlugins(uint32_t maxSize);
static std::vector<std::unique_ptr<PluginContainer>> getLoadedPlugins(uint32_t maxSize);
static std::optional<PluginContainer> getPluginForPath(const std::string &path);
static std::optional<std::unique_ptr<PluginContainer>> getPluginForPath(const std::string &path);
static std::optional<PluginContainer> getPluginForBuffer(char *buffer, size_t size);
static std::optional<std::unique_ptr<PluginContainer>> getPluginForBuffer(char *buffer, size_t size);
static void destroyPluginContainer(PluginContainer &plugin);
static void destroyPluginContainer(std::vector<PluginContainer> &vector);
static int32_t LoadAndLinkOnRestart(std::vector<PluginContainer> &plugins);
static int32_t LoadAndLinkOnRestart(const std::vector<std::unique_ptr<PluginContainer>> &plugins);
};

View File

@ -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 <cstddef>
#include <stdint.h>
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];

View File

@ -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 <coreinit/debug.h>
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");
}
}
}

View File

@ -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 <optional>
#include <utility>
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);
}

View File

@ -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 <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <cstring>
#include "imports.h"
#include "wups_backend/PluginUtils.h"
#include "imports.h"
#include "logger.h"
#include "utils.h"
#include <cstring>
#include <memory>
std::optional<PluginMetaInformation> 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<std::unique_ptr<PluginMetaInformation>> 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<PluginMetaInformation>(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<PluginMetaInformation> PluginUtils::getMetaInformationForPath(const std::string &path) {
plugin_information info;
memset(&info, 0, sizeof(info));
std::optional<std::unique_ptr<PluginMetaInformation>> 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<std::unique_ptr<PluginMetaInformation>> 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<PluginContainer> PluginUtils::getPluginForPath(const std::string &path) {
std::optional<std::unique_ptr<PluginContainer>> 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<PluginData>(dataHandle);
if (!pluginData) {
DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginData");
return {};
}
auto pluginContainer = make_unique_nothrow<PluginContainer>(std::move(pluginData), std::move(metaInfoOpt.value()));
if (!pluginContainer) {
DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginContainer");
return {};
}
return pluginContainer;
}
std::optional<PluginContainer> PluginUtils::getPluginForBuffer(char *buffer, size_t size) {
std::optional<std::unique_ptr<PluginContainer>> 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<PluginData>(dataHandle);
if (!pluginData) {
DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginData");
return {};
}
auto pluginContainer = make_unique_nothrow<PluginContainer>(std::move(pluginData), std::move(metaInfoOpt.value()));
if (!pluginContainer) {
DEBUG_FUNCTION_LINE_ERR("Failed to allocate PluginContainer");
return {};
}
return pluginContainer;
}
std::vector<PluginContainer> PluginUtils::getLoadedPlugins(uint32_t maxSize) {
std::vector<PluginContainer> result;
auto *handles = (plugin_container_handle *) malloc(maxSize * sizeof(plugin_container_handle));
if (handles == nullptr) {
std::vector<std::unique_ptr<PluginContainer>> PluginUtils::getLoadedPlugins(uint32_t maxSize) {
std::vector<std::unique_ptr<PluginContainer>> result;
auto handles = std::make_unique<plugin_container_handle[]>(maxSize);
if (!handles) {
DEBUG_FUNCTION_LINE_ERR("Not enough memory");
return result;
}
uint32_t realSize = 0;
@ -109,105 +135,79 @@ std::vector<PluginContainer> 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<plugin_data_handle[]>(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<plugin_information[]>(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<PluginMetaInformation>(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<PluginData>((uint32_t) dataHandles[i]);
if (!pluginData) {
DEBUG_FUNCTION_LINE_ERR("Skip, failed to allocate PluginData");
continue;
}
auto pluginContainer = make_unique_nothrow<PluginContainer>(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<PluginContainer> list;
list.push_back(plugin);
return destroyPluginContainer(list);
}
void PluginUtils::destroyPluginContainer(std::vector<PluginContainer> &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<PluginContainer> &plugins) {
int32_t PluginUtils::LoadAndLinkOnRestart(const std::vector<std::unique_ptr<PluginContainer>> &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<PluginContainer> &plugins)
}
return WUPSLoadAndLinkByDataHandle(handles, dataSize);
;
}

View File

@ -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);

11
source/logger.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include <coreinit/debug.h>
#include <cstring>
#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)

17
source/utils.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <memory>
template<class T, class... Args>
std::unique_ptr<T> make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}
template<typename T>
inline typename std::_MakeUniq<T>::__array make_unique_nothrow(size_t num) noexcept {
return std::unique_ptr<T>(new (std::nothrow) std::remove_extent_t<T>[num]());
}
template<class T, class... Args>
std::shared_ptr<T> make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}

View File

@ -5,7 +5,6 @@ WUPSLoadPluginAsDataByPath
WUPSLoadPluginAsDataByBuffer
WUPSLoadPluginAsData
WUPSLoadAndLinkByDataHandle
WUPSDeletePluginContainer
WUPSDeletePluginData
WUPSGetPluginMetaInformation
WUPSGetPluginMetaInformationByPath