From 3dc32266978c1b27403df5d9917c50cf2652f349 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 17 Feb 2023 14:40:14 +0100 Subject: [PATCH] Add support for latest API --- include/wups_backend/api.h | 49 ++++++ include/wups_backend/import_defines.h | 33 +++- source/api.cpp | 223 ++++++++++++++++++++++++++ 3 files changed, 298 insertions(+), 7 deletions(-) create mode 100644 include/wups_backend/api.h create mode 100644 source/api.cpp diff --git a/include/wups_backend/api.h b/include/wups_backend/api.h new file mode 100644 index 0000000..863f5ab --- /dev/null +++ b/include/wups_backend/api.h @@ -0,0 +1,49 @@ +#pragma once +#include "import_defines.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +PluginBackendApiErrorType WUPSBackend_InitLibrary(); + +PluginBackendApiErrorType WUPSBackend_DeInitLibrary(); + +const char *WUPSBackend_GetStatusStr(PluginBackendApiErrorType status); + +PluginBackendApiErrorType WUPSBackend_GetSectionInformationForPlugin(plugin_container_handle handle, plugin_section_info *plugin_section_list, uint32_t buffer_size, uint32_t *out_count); + +PluginBackendApiErrorType WUPSBackend_GetApiVersion(WUPSBackendAPIVersion *outVersion); + +PluginBackendApiErrorType WUPSBackend_GetNumberOfLoadedPlugins(uint32_t *out_count); + +PluginBackendApiErrorType WUPSBackend_WillReloadPluginsOnNextLaunch(bool *out); + +PluginBackendApiErrorType WUPSBackend_GetSectionMemoryAddresses(plugin_container_handle handle, void **textAddress, void **dataAddress); + +PluginBackendApiErrorType WUPSBackend_LoadAndLinkByDataHandle(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size); + +PluginBackendApiErrorType WUPSBackend_DeletePluginData(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size); + +PluginBackendApiErrorType WUPSBackend_LoadPluginAsData(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_data_handle *out); + +PluginBackendApiErrorType WUPSBackend_LoadPluginAsDataByPath(plugin_data_handle *output, const char *path); + +PluginBackendApiErrorType WUPSBackend_LoadPluginAsDataByBuffer(plugin_data_handle *output, char *buffer, size_t size); + +PluginBackendApiErrorType WUPSBackend_GetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output); + +PluginBackendApiErrorType WUPSBackend_WUPSGetPluginMetaInformationByPath(plugin_information *output, const char *path); + +PluginBackendApiErrorType WUPSBackend_GetPluginMetaInformationByBuffer(plugin_information *output, char *buffer, size_t size); + +PluginBackendApiErrorType WUPSBackend_GetPluginDataForContainerHandles(const plugin_container_handle *plugin_container_handle_list, const plugin_data_handle *plugin_data_list, uint32_t buffer_size); + +PluginBackendApiErrorType WUPSBackend_GetMetaInformation(const plugin_container_handle *plugin_container_handle_list, plugin_information *plugin_information_list, uint32_t buffer_size); + +PluginBackendApiErrorType WUPSBackend_GetLoadedPlugins(const plugin_container_handle *io_handles, uint32_t buffer_size, uint32_t *outSize, uint32_t *plugin_information_version); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/wups_backend/import_defines.h b/include/wups_backend/import_defines.h index 26fc89e..dc0445b 100644 --- a/include/wups_backend/import_defines.h +++ b/include/wups_backend/import_defines.h @@ -17,7 +17,7 @@ #pragma once -#include +#include #include typedef enum GetPluginInformationInputType { @@ -27,8 +27,12 @@ typedef enum GetPluginInformationInputType { typedef uint32_t plugin_container_handle; typedef uint32_t plugin_data_handle; +typedef uint32_t WUPSBackendAPIVersion; -#define PLUGIN_INFORMATION_VERSION 0x00000002 +#define WUPS_BACKEND_MODULE_API_VERSION 0x00000002 +#define WUPS_BACKEND_MODULE_API_VERSION_ERROR 0xFFFFFFFF + +#define PLUGIN_INFORMATION_VERSION 0x00000002 /* plugin_information message */ typedef struct plugin_information { @@ -43,10 +47,25 @@ typedef struct plugin_information { size_t size; } plugin_information; +#define PLUGIN_SECTION_INFORMATION_VERSION 0x00000001 + +typedef struct plugin_section_info { + uint32_t plugin_section_info_version; + char name[32]; + void *address; + uint32_t size; +} plugin_section_info; + typedef enum PluginBackendApiErrorType { - PLUGIN_BACKEND_API_ERROR_NONE = 0, - PLUGIN_BACKEND_API_ERROR_INVALID_SIZE = 0xFFFFFFFF, - PLUGIN_BACKEND_API_ERROR_INVALID_ARG = 0xFFFFFFFE, - PLUGIN_BACKEND_API_ERROR_FAILED_ALLOC = 0xFFFFFFFD, - PLUGIN_BACKEND_API_ERROR_FILE_NOT_FOUND = 0xFFFFFFFC, + PLUGIN_BACKEND_API_ERROR_NONE = 0, + PLUGIN_BACKEND_API_ERROR_INVALID_SIZE = 0xFFFFFFFF, + PLUGIN_BACKEND_API_ERROR_INVALID_ARG = 0xFFFFFFFE, + PLUGIN_BACKEND_API_ERROR_FAILED_ALLOC = 0xFFFFFFFD, + PLUGIN_BACKEND_API_ERROR_FILE_NOT_FOUND = 0xFFFFFFFC, + PLUGIN_BACKEND_API_INVALID_HANDLE = 0xFFFFFFFB, + PLUGIN_BACKEND_API_ERROR_MODULE_NOT_FOUND = 0xFFFFFFFA, + PLUGIN_BACKEND_API_ERROR_MODULE_MISSING_EXPORT = 0xFFFFFFF9, + PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_VERSION = 0xFFFFFFF8, + PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED = 0xFFFFFFF7, + PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND = 0xFFFFFFF6, } PluginBackendApiErrorType; diff --git a/source/api.cpp b/source/api.cpp new file mode 100644 index 0000000..a9e1165 --- /dev/null +++ b/source/api.cpp @@ -0,0 +1,223 @@ +#include "wups_backend/api.h" +#include "imports.h" +#include "logger.h" +#include "wups_backend/import_defines.h" +#include +#include + +static OSDynLoad_Module sModuleHandle = nullptr; + +static PluginBackendApiErrorType (*sWUPSGetAPIVersion)(WUPSBackendAPIVersion *) = nullptr; +static PluginBackendApiErrorType (*sWUPSGetSectionInformationForPlugin)( + plugin_container_handle handle, + plugin_section_info *plugin_section_list, + uint32_t buffer_size, + uint32_t *out_count) = nullptr; + +static PluginBackendApiErrorType (*sWUPSGetNumberOfLoadedPlugins)(uint32_t *out) = nullptr; +static PluginBackendApiErrorType (*sWUPSWillReloadPluginsOnNextLaunch)(bool *out) = nullptr; +static PluginBackendApiErrorType (*sWUPSGetSectionMemoryAddresses)(plugin_container_handle handle, + void **textAddress, + void **dataAddress) = nullptr; + +static bool sLibInitDone = false; + +static WUPSBackendAPIVersion sWUPSAPIVersion = WUPS_BACKEND_MODULE_API_VERSION_ERROR; + +const char *WUPSBackend_GetStatusStr(PluginBackendApiErrorType status) { + switch (status) { + case PLUGIN_BACKEND_API_ERROR_NONE: + return "PLUGIN_BACKEND_API_ERROR_NONE"; + case PLUGIN_BACKEND_API_ERROR_INVALID_SIZE: + return "PLUGIN_BACKEND_API_ERROR_INVALID_SIZE"; + case PLUGIN_BACKEND_API_ERROR_INVALID_ARG: + return "PLUGIN_BACKEND_API_ERROR_INVALID_ARG"; + case PLUGIN_BACKEND_API_ERROR_FAILED_ALLOC: + return "PLUGIN_BACKEND_API_ERROR_FAILED_ALLOC"; + case PLUGIN_BACKEND_API_ERROR_FILE_NOT_FOUND: + return "PLUGIN_BACKEND_API_ERROR_FILE_NOT_FOUND"; + case PLUGIN_BACKEND_API_INVALID_HANDLE: + return "PLUGIN_BACKEND_API_INVALID_HANDLE"; + case PLUGIN_BACKEND_API_ERROR_MODULE_NOT_FOUND: + return "PLUGIN_BACKEND_API_ERROR_MODULE_NOT_FOUND"; + case PLUGIN_BACKEND_API_ERROR_MODULE_MISSING_EXPORT: + return "PLUGIN_BACKEND_API_ERROR_MODULE_MISSING_EXPORT"; + case PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_VERSION: + return "PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_VERSION"; + case PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED: + return "PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED"; + case PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND: + return "PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND"; + } + return "PLUGIN_BACKEND_API_ERROR_UNKNOWN_ERROR"; +} + +PluginBackendApiErrorType WUPSBackend_InitLibrary() { + if (sLibInitDone) { + return PLUGIN_BACKEND_API_ERROR_NONE; + } + if (OSDynLoad_Acquire("homebrew_wupsbackend", &sModuleHandle) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_ERR("OSDynLoad_Acquire failed."); + return PLUGIN_BACKEND_API_ERROR_MODULE_NOT_FOUND; + } + + if (OSDynLoad_FindExport(sModuleHandle, FALSE, "WUPSGetAPIVersion", (void **) &sWUPSGetAPIVersion) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_ERR("FindExport WUPSGetAPIVersion failed."); + return PLUGIN_BACKEND_API_ERROR_MODULE_MISSING_EXPORT; + } + + if (OSDynLoad_FindExport(sModuleHandle, FALSE, "WUPSWillReloadPluginsOnNextLaunch", (void **) &sWUPSWillReloadPluginsOnNextLaunch) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_WARN("FindExport WUPSWillReloadPluginsOnNextLaunch failed."); + sWUPSWillReloadPluginsOnNextLaunch = nullptr; + } + + if (OSDynLoad_FindExport(sModuleHandle, FALSE, "WUPSGetNumberOfLoadedPlugins", (void **) &sWUPSGetNumberOfLoadedPlugins) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_WARN("FindExport WUPSGetNumberOfLoadedPlugins failed."); + sWUPSGetNumberOfLoadedPlugins = nullptr; + } + + if (OSDynLoad_FindExport(sModuleHandle, FALSE, "WUPSGetSectionMemoryAddresses", (void **) &sWUPSGetSectionMemoryAddresses) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_WARN("FindExport WUPSGetSectionMemoryAddresses failed."); + sWUPSGetSectionMemoryAddresses = nullptr; + } + + auto res = WUPSBackend_GetApiVersion(&sWUPSAPIVersion); + if (res != PLUGIN_BACKEND_API_ERROR_NONE) { + sWUPSAPIVersion = WUPS_BACKEND_MODULE_API_VERSION_ERROR; + return PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_VERSION; + } + + sLibInitDone = true; + return PLUGIN_BACKEND_API_ERROR_NONE; +} + +PluginBackendApiErrorType WUPSBackend_DeInitLibrary() { + if (sLibInitDone) { + sWUPSGetAPIVersion = nullptr; + sWUPSAPIVersion = WUPS_BACKEND_MODULE_API_VERSION_ERROR; + OSDynLoad_Release(sModuleHandle); + sModuleHandle = nullptr; + sLibInitDone = false; + } + return PLUGIN_BACKEND_API_ERROR_NONE; +} + +PluginBackendApiErrorType WUPSBackend_GetApiVersion(WUPSBackendAPIVersion *outVersion) { + if (sWUPSGetAPIVersion == nullptr) { + if (OSDynLoad_Acquire("homebrew_wupsbackend", &sModuleHandle) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_WARN("OSDynLoad_Acquire failed."); + return PLUGIN_BACKEND_API_ERROR_MODULE_NOT_FOUND; + } + + if (OSDynLoad_FindExport(sModuleHandle, FALSE, "WUPSGetAPIVersion", (void **) &sWUPSGetAPIVersion) != OS_DYNLOAD_OK) { + DEBUG_FUNCTION_LINE_WARN("FindExport WUPSGetAPIVersion failed."); + return PLUGIN_BACKEND_API_ERROR_MODULE_MISSING_EXPORT; + } + } + + return reinterpret_cast(sWUPSGetAPIVersion)(outVersion); +} + +PluginBackendApiErrorType WUPSBackend_GetSectionInformationForPlugin(plugin_container_handle handle, plugin_section_info *plugin_section_list, uint32_t buffer_size, uint32_t *out_count) { + if (sWUPSAPIVersion == WUPS_BACKEND_MODULE_API_VERSION_ERROR) { + return PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED; + } + if (sWUPSGetSectionInformationForPlugin == nullptr || sWUPSAPIVersion < 2) { + return PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND; + } + + if (handle == 0) { + return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; + } + + return reinterpret_cast(sWUPSGetSectionInformationForPlugin)(handle, plugin_section_list, buffer_size, out_count); +} + +PluginBackendApiErrorType WUPSBackend_GetNumberOfLoadedPlugins(uint32_t *out_count) { + if (sWUPSAPIVersion == WUPS_BACKEND_MODULE_API_VERSION_ERROR) { + return PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED; + } + if (sWUPSGetNumberOfLoadedPlugins == nullptr || sWUPSAPIVersion < 2) { + return PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND; + } + + if (out_count == nullptr) { + return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; + } + + return reinterpret_cast(sWUPSGetNumberOfLoadedPlugins)(out_count); +} + +PluginBackendApiErrorType WUPSBackend_WillReloadPluginsOnNextLaunch(bool *out) { + if (sWUPSAPIVersion == WUPS_BACKEND_MODULE_API_VERSION_ERROR) { + return PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED; + } + if (sWUPSWillReloadPluginsOnNextLaunch == nullptr || sWUPSAPIVersion < 2) { + return PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND; + } + + if (out == nullptr) { + return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; + } + + return reinterpret_cast(sWUPSWillReloadPluginsOnNextLaunch)(out); +} + +PluginBackendApiErrorType WUPSBackend_GetSectionMemoryAddresses(plugin_container_handle handle, void **textAddress, void **dataAddress) { + if (sWUPSAPIVersion == WUPS_BACKEND_MODULE_API_VERSION_ERROR) { + return PLUGIN_BACKEND_API_ERROR_LIB_UNINITIALIZED; + } + if (sWUPSGetSectionMemoryAddresses == nullptr || sWUPSAPIVersion < 2) { + return PLUGIN_BACKEND_API_ERROR_UNSUPPORTED_COMMAND; + } + + if (handle == 0 || textAddress == nullptr || dataAddress == nullptr) { + return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; + } + + return reinterpret_cast(sWUPSGetSectionMemoryAddresses)(handle, textAddress, dataAddress); +} + +PluginBackendApiErrorType WUPSBackend_LoadAndLinkByDataHandle(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size) { + return WUPSLoadAndLinkByDataHandle(plugin_data_handle_list, plugin_data_handle_list_size); +} + +PluginBackendApiErrorType WUPSBackend_DeletePluginData(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size) { + return WUPSDeletePluginData(plugin_data_handle_list, plugin_data_handle_list_size); +} + +PluginBackendApiErrorType WUPSBackend_LoadPluginAsData(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_data_handle *out) { + return WUPSLoadPluginAsData(inputType, path, buffer, size, out); +} + +PluginBackendApiErrorType WUPSBackend_LoadPluginAsDataByPath(plugin_data_handle *output, const char *path) { + return WUPSLoadPluginAsDataByPath(output, path); +} + +PluginBackendApiErrorType WUPSBackend_LoadPluginAsDataByBuffer(plugin_data_handle *output, char *buffer, size_t size) { + return WUPSLoadPluginAsDataByBuffer(output, buffer, size); +} + +PluginBackendApiErrorType WUPSBackend_GetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output) { + return WUPSGetPluginMetaInformation(inputType, path, buffer, size, output); +} + +PluginBackendApiErrorType WUPSBackend_WUPSGetPluginMetaInformationByPath(plugin_information *output, const char *path) { + return WUPSGetPluginMetaInformationByPath(output, path); +} + +PluginBackendApiErrorType WUPSBackend_GetPluginMetaInformationByBuffer(plugin_information *output, char *buffer, size_t size) { + return WUPSGetPluginMetaInformationByBuffer(output, buffer, size); +} + +PluginBackendApiErrorType WUPSBackend_GetPluginDataForContainerHandles(const plugin_container_handle *plugin_container_handle_list, const plugin_data_handle *plugin_data_list, uint32_t buffer_size) { + return WUPSGetPluginDataForContainerHandles(plugin_container_handle_list, plugin_data_list, buffer_size); +} + +PluginBackendApiErrorType WUPSBackend_GetMetaInformation(const plugin_container_handle *plugin_container_handle_list, plugin_information *plugin_information_list, uint32_t buffer_size) { + return WUPSGetMetaInformation(plugin_container_handle_list, plugin_information_list, buffer_size); +} + +PluginBackendApiErrorType WUPSBackend_GetLoadedPlugins(const plugin_container_handle *io_handles, uint32_t buffer_size, uint32_t *outSize, uint32_t *plugin_information_version) { + return WUPSGetLoadedPlugins(io_handles, buffer_size, outSize, plugin_information_version); +}