Improve checking if a function is available with the loaded module

This commit is contained in:
Maschell 2022-09-03 18:21:59 +02:00
parent d6de8b7504
commit 9765bbcfe4
3 changed files with 104 additions and 50 deletions

View File

@ -46,6 +46,7 @@ typedef enum ContentRedirectionStatus {
CONTENT_REDIRECTION_RESULT_UNKNOWN_FS_LAYER_TYPE = -0x12,
CONTENT_REDIRECTION_RESULT_LAYER_NOT_FOUND = -0x13,
CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED = -0x20,
CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND = -0x21,
CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR = -0x1000,
} ContentRedirectionStatus;
@ -81,32 +82,33 @@ ContentRedirectionStatus ContentRedirection_DeInitLibrary();
* <br>
* @param outVersion pointer to the variable where the version will be stored.
*
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: The API version has been store in the version ptr.<br>
* CONTENT_REDIRECTION_RESULT_INVALID_ARGUMENT: Invalid version pointer.<br>
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Retrieving the module version failed.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: The API version has been store in the version ptr.<br>
* CONTENT_REDIRECTION_RESULT_MODULE_NOT_FOUND: The module could not be found. Make sure the module is loaded.<br>
* CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT: The module is missing an expected export.<br>
* CONTENT_REDIRECTION_RESULT_INVALID_ARGUMENT: Invalid version pointer.<br>
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Retrieving the module version failed.
*/
ContentRedirectionStatus ContentRedirection_GetVersion(ContentRedirectionVersion *outVersion);
/**
* Adds a a FSLayers that redirects the /vol/content or /vol/save fs calles for the Game/Wii U Menu process.
* Make sure to remove all added the layers before the application ends.
* The replacement dir has be to valid in the ContentRedirection Module, use "ContentRedirection_AddDevice" to add a Device for the ContentRedirection Module.
* Multiple layers can be added. Each layer is valid system wide for the Game/Wii U Menu process.
* The layers will be processed in reverse adding order. e.g. when you add Layer1, Layer2 and then Layer3; Layer3, Layer2 and finally Layer1 will be processed.
* Adds a a FSLayers that redirects the /vol/content or /vol/save fs calles for the Game/Wii U Menu process. <br>
* Make sure to remove all added the layers before the application ends. <br>
* The replacement dir has be to valid in the ContentRedirection Module, use "ContentRedirection_AddDevice" to add a Device for the ContentRedirection Module. <br>
* Multiple layers can be added. Each layer is valid system wide for the Game/Wii U Menu process. <br>
* The layers will be processed in reverse adding order. e.g. when you add Layer1, Layer2 and then Layer3; Layer3, Layer2 and finally Layer1 will be processed. <br>
* An added layer is active by default.
*
* @param handlePtr The handle of the layer is written to this pointer.
* @param layerName Name of the layer, used for debugging.
* @param replacementDir Path to the directory that will replace / merge into the original one.
* @param layerType Type of the layer, see FSLayerType for more information.
*
* @param layerType Type of the layer, see FSLayerType for more information. <br>
* If set to to false, errors of this layer will be returned to the OS.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: The layer had been added successfully.
* The layer has to be removed before the currently running application ends.
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_Init()" was not called.
* CONTENT_REDIRECTION_API_ERROR_INVALID_ARG: "handlePtr", "layerName" or "replacementDir" is NULL
* CONTENT_REDIRECTION_API_ERROR_NO_MEMORY: Not enough memory to create this layer.
* CONTENT_REDIRECTION_API_ERROR_UNKNOWN_LAYER_TYPE: Unknown/invalid LayerType. See FSLayerType for all supported layers.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: The layer had been added successfully. <br>
* The layer has to be removed before the currently running application ends. <br>
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_InitLibrary()" was not called. <br>
* CONTENT_REDIRECTION_RESULT_INVALID_ARGUMENT: "handlePtr", "layerName" or "replacementDir" is NULL <br>
* CONTENT_REDIRECTION_API_ERROR_NO_MEMORY: Not enough memory to create this layer. <br>
* CONTENT_REDIRECTION_API_ERROR_UNKNOWN_LAYER_TYPE: Unknown/invalid LayerType. See FSLayerType for all supported layers. <br>
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Unknown error.
*/
ContentRedirectionStatus ContentRedirection_AddFSLayer(CRLayerHandle *handlePtr, const char *layerName, const char *replacementDir, FSLayerType layerType);
@ -119,28 +121,30 @@ ContentRedirectionStatus ContentRedirection_AddFSLayer(CRLayerHandle *handlePtr,
ContentRedirectionStatus ContentRedirection_RemoveFSLayer(CRLayerHandle handle);
/**
* Set the "active" flag for a given FSLayer.
* Set the "active" flag for a given FSLayer. <br>
*
* @param handle Handle of the FSLayer.
* @param active New "active"-state of the layer
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: The active state has been set successfully.
* CONTENT_REDIRECTION_RESULT_LAYER_NOT_FOUND: Invalid FSLayer handle.
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_Init()" was not called.
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Unknown error.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: The active state has been set successfully. <br>
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_InitLibrary()" was not called. <br>
* CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND: This command is not supported by the currently loaded Module. <br>
* CONTENT_REDIRECTION_RESULT_LAYER_NOT_FOUND: Invalid FSLayer handle. <br>
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Unknown error.
*/
ContentRedirectionStatus ContentRedirection_SetActive(CRLayerHandle handle, bool active);
/**
* Calls "AddDevice" for the ContentRedirection Module.
* When a device is added for the ContentRedirection Module, it can be used in FSLayers.
* Calls "AddDevice" for the ContentRedirection Module. <br>
* When a device is added for the ContentRedirection Module, it can be used in FSLayers. <br>
*
* @param device Device that will be added
* @param resultOut Will hold the result of the "AddDevice" call.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: AddDevice has been called, result is written to resultOut.
* See documentation of AddDevice for more information
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_Init()" was not called.
* CONTENT_REDIRECTION_RESULT_INVALID_ARG: resultOut is NULL.
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Unknown error.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: AddDevice has been called, result is written to resultOut. <br>
* See documentation of AddDevice for more information <br>
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_InitLibrary()" was not called. <br>
* CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND: This command is not supported by the currently loaded Module. <br>
* CONTENT_REDIRECTION_RESULT_INVALID_ARG: resultOut is NULL. <br>
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Unknown error. <br>
*/
ContentRedirectionStatus ContentRedirection_AddDevice(const devoptab_t *device, int *resultOut);
@ -149,10 +153,11 @@ ContentRedirectionStatus ContentRedirection_AddDevice(const devoptab_t *device,
*
* @param name name of the device that will be added. e.g. "romfs:"
* @param resultOut Will hold the result of the "AddDevice" call.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: RemoveDevice has been called, result is written to resultOut.
* See documentation of RemoveDevice for more information
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_Init()" was not called.
* CONTENT_REDIRECTION_RESULT_INVALID_ARG: resultOut is NULL.
* @return CONTENT_REDIRECTION_RESULT_SUCCESS: RemoveDevice has been called, result is written to resultOut. <br>
* See documentation of RemoveDevice for more information <br>
* CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED: "ContentRedirection_InitLibrary()" was not called. <br>
* CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND: This command is not supported by the currently loaded Module. <br>
* CONTENT_REDIRECTION_RESULT_INVALID_ARG: resultOut is NULL. <br>
* CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR: Unknown error.
*/
ContentRedirectionStatus ContentRedirection_RemoveDevice(const char *name, int *resultOut);

23
source/logger.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <coreinit/debug.h>
#include <cstring>
#define __FILENAME__ ({ \
const char *__filename = __FILE__; \
const char *__pos = strrchr(__filename, '/'); \
if (!__pos) __pos = strrchr(__filename, '\\'); \
__pos ? __pos + 1 : __filename; \
})
#define LOG_APP_TYPE "L"
#define LOG_APP_NAME "libcontentredirection"
#define LOG_EX(FILENAME, FUNCTION, LINE, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) \
do { \
LOG_FUNC("[(%s)%18s][%23s]%30s@L%04d: " LOG_LEVEL "" FMT "" LINE_END, LOG_APP_TYPE, LOG_APP_NAME, FILENAME, FUNCTION, LINE, ##ARGS); \
} while (0)
#define LOG_EX_DEFAULT(LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) LOG_EX(__FILENAME__, __FUNCTION__, __LINE__, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ##ARGS)
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS)
#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##WARNING## ", "\n", FMT, ##ARGS)

View File

@ -1,4 +1,5 @@
#include "content_redirection/redirection.h"
#include "logger.h"
#include <coreinit/debug.h>
#include <coreinit/dynload.h>
#include <sys/iosupport.h>
@ -36,18 +37,20 @@ const char *ContentRedirection_GetStatusStr(ContentRedirectionStatus status) {
return "CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED";
case CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR:
return "CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR";
case CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND:
return "CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND";
}
return "CONTENT_REDIRECTION_RESULT_UNKNOWN_ERROR";
}
ContentRedirectionStatus ContentRedirection_InitLibrary() {
if (OSDynLoad_Acquire("homebrew_content_redirection", &sModuleHandle) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: OSDynLoad_Acquire failed.\n");
DEBUG_FUNCTION_LINE_ERR("OSDynLoad_Acquire failed.");
return CONTENT_REDIRECTION_RESULT_MODULE_NOT_FOUND;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRGetVersion", (void **) &sCRGetVersion) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: CRGetVersion failed.\n");
DEBUG_FUNCTION_LINE_ERR("FindExport CRGetVersion failed.");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
}
auto res = ContentRedirection_GetVersion(&sContentRedirectionVersion);
@ -56,28 +59,28 @@ ContentRedirectionStatus ContentRedirection_InitLibrary() {
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRAddFSLayer", (void **) &sCRAddFSLayer) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: CRAddFSLayer failed.\n");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
DEBUG_FUNCTION_LINE_ERR("FindExport CRAddFSLayer failed.");
sCRAddFSLayer = nullptr;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRRemoveFSLayer", (void **) &sCRRemoveFSLayer) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: CRRemoveFSLayer failed.\n");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
DEBUG_FUNCTION_LINE_ERR("FindExport CRRemoveFSLayer failed.");
sCRRemoveFSLayer = nullptr;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRSetActive", (void **) &sCRSetActive) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: CRSetActive failed.\n");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
DEBUG_FUNCTION_LINE_ERR("FindExport CRSetActive failed.");
sCRSetActive = nullptr;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRAddDevice", (void **) &sCRAddDevice) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: CRAddDevice failed.\n");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
DEBUG_FUNCTION_LINE_ERR("FindExport CRAddDevice failed.");
sCRAddDevice = nullptr;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRRemoveDevice", (void **) &sCRRemoveDevice) != OS_DYNLOAD_OK) {
OSReport("ContentRedirection_Init: CRRemoveDevice failed.\n");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
DEBUG_FUNCTION_LINE_ERR("FindExport CRRemoveDevice failed.");
sCRRemoveDevice = nullptr;
}
return CONTENT_REDIRECTION_RESULT_SUCCESS;
@ -90,7 +93,15 @@ ContentRedirectionStatus ContentRedirection_DeInitLibrary() {
ContentRedirectionApiErrorType GetVersion(ContentRedirectionVersion *);
ContentRedirectionStatus ContentRedirection_GetVersion(ContentRedirectionVersion *outVariable) {
if (sCRGetVersion == nullptr) {
return CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED;
if (OSDynLoad_Acquire("homebrew_content_redirection", &sModuleHandle) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_Acquire failed.");
return CONTENT_REDIRECTION_RESULT_MODULE_NOT_FOUND;
}
if (OSDynLoad_FindExport(sModuleHandle, FALSE, "CRGetVersion", (void **) &sCRGetVersion) != OS_DYNLOAD_OK) {
DEBUG_FUNCTION_LINE_WARN("FindExport CRGetVersion failed.");
return CONTENT_REDIRECTION_RESULT_MODULE_MISSING_EXPORT;
}
}
auto res = reinterpret_cast<decltype(&GetVersion)>(sCRGetVersion)(outVariable);
@ -103,9 +114,12 @@ ContentRedirectionStatus ContentRedirection_GetVersion(ContentRedirectionVersion
ContentRedirectionApiErrorType AddFSLayer(CRLayerHandle *, const char *, const char *, FSLayerType);
ContentRedirectionStatus ContentRedirection_AddFSLayer(CRLayerHandle *handlePtr, const char *layerName, const char *replacementDir, FSLayerType layerType) {
if (sCRAddFSLayer == nullptr) {
if (sContentRedirectionVersion == CONTENT_REDIRECTION_MODULE_VERSION_ERROR) {
return CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED;
}
if (sCRAddFSLayer == nullptr || sContentRedirectionVersion < 1) {
return CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND;
}
auto res = reinterpret_cast<decltype(&AddFSLayer)>(sCRAddFSLayer)(handlePtr, layerName, replacementDir, layerType);
if (res == CONTENT_REDIRECTION_API_ERROR_NONE) {
return CONTENT_REDIRECTION_RESULT_SUCCESS;
@ -124,9 +138,12 @@ ContentRedirectionStatus ContentRedirection_AddFSLayer(CRLayerHandle *handlePtr,
ContentRedirectionApiErrorType RemoveFSLayer(CRLayerHandle);
ContentRedirectionStatus ContentRedirection_RemoveFSLayer(CRLayerHandle handlePtr) {
if (sCRAddFSLayer == nullptr) {
if (sContentRedirectionVersion == CONTENT_REDIRECTION_MODULE_VERSION_ERROR) {
return CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED;
}
if (sCRRemoveFSLayer == nullptr || sContentRedirectionVersion < 1) {
return CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND;
}
auto res = reinterpret_cast<decltype(&RemoveFSLayer)>(sCRRemoveFSLayer)(handlePtr);
if (res == CONTENT_REDIRECTION_API_ERROR_NONE) {
return CONTENT_REDIRECTION_RESULT_SUCCESS;
@ -141,9 +158,12 @@ ContentRedirectionStatus ContentRedirection_RemoveFSLayer(CRLayerHandle handlePt
ContentRedirectionApiErrorType SetActive(CRLayerHandle, bool);
ContentRedirectionStatus ContentRedirection_SetActive(CRLayerHandle handle, bool active) {
if (sCRAddFSLayer == nullptr) {
if (sContentRedirectionVersion == CONTENT_REDIRECTION_MODULE_VERSION_ERROR) {
return CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED;
}
if (sCRSetActive == nullptr || sContentRedirectionVersion < 1) {
return CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND;
}
auto res = reinterpret_cast<decltype(&SetActive)>(sCRSetActive)(handle, active);
if (res == CONTENT_REDIRECTION_API_ERROR_NONE) {
return CONTENT_REDIRECTION_RESULT_SUCCESS;
@ -157,9 +177,12 @@ ContentRedirectionStatus ContentRedirection_SetActive(CRLayerHandle handle, bool
}
ContentRedirectionStatus ContentRedirection_AddDevice(const devoptab_t *device, int *resultOut) {
if (sCRAddFSLayer == nullptr) {
if (sContentRedirectionVersion == CONTENT_REDIRECTION_MODULE_VERSION_ERROR) {
return CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED;
}
if (sCRAddDevice == nullptr || sContentRedirectionVersion < 1) {
return CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND;
}
if (resultOut == nullptr) {
return CONTENT_REDIRECTION_RESULT_INVALID_ARGUMENT;
@ -170,9 +193,12 @@ ContentRedirectionStatus ContentRedirection_AddDevice(const devoptab_t *device,
}
ContentRedirectionStatus ContentRedirection_RemoveDevice(const char *name, int *resultOut) {
if (sCRAddFSLayer == nullptr) {
if (sContentRedirectionVersion == CONTENT_REDIRECTION_MODULE_VERSION_ERROR) {
return CONTENT_REDIRECTION_RESULT_LIB_UNINITIALIZED;
}
if (sCRRemoveDevice == nullptr || sContentRedirectionVersion < 1) {
return CONTENT_REDIRECTION_RESULT_UNSUPPORTED_COMMAND;
}
if (resultOut == nullptr) {
return CONTENT_REDIRECTION_RESULT_INVALID_ARGUMENT;
}