mirror of
https://github.com/wiiu-env/ContentRedirectionModule.git
synced 2024-11-17 17:09:23 +01:00
Add support for /vol/aoc redirection
This commit is contained in:
parent
8811d7ae0a
commit
f5266db613
@ -3,6 +3,6 @@ FROM wiiuenv/devkitppc:20220917
|
||||
COPY --from=wiiuenv/libfunctionpatcher:20220904 /artifacts $DEVKITPRO
|
||||
COPY --from=wiiuenv/wiiumodulesystem:20220904 /artifacts $DEVKITPRO
|
||||
COPY --from=wiiuenv/libromfs_wiiu:20220904 /artifacts $DEVKITPRO
|
||||
COPY --from=wiiuenv/libcontentredirection:20220916 /artifacts $DEVKITPRO
|
||||
COPY --from=wiiuenv/libcontentredirection:20221010 /artifacts $DEVKITPRO
|
||||
|
||||
WORKDIR project
|
||||
|
@ -2,12 +2,92 @@
|
||||
#include "FSWrapperMergeDirsWithParent.h"
|
||||
#include "FileUtils.h"
|
||||
#include "IFSWrapper.h"
|
||||
#include "malloc.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/utils.h"
|
||||
#include <content_redirection/redirection.h>
|
||||
#include <coreinit/dynload.h>
|
||||
#include <mutex>
|
||||
#include <wums/exports.h>
|
||||
|
||||
struct AOCTitle {
|
||||
WUT_UNKNOWN_BYTES(0x68);
|
||||
};
|
||||
WUT_CHECK_SIZE(AOCTitle, 0x68);
|
||||
|
||||
bool getAOCPath(std::string &outStr) {
|
||||
int32_t (*AOC_Initialize)() = nullptr;
|
||||
int32_t (*AOC_Finalize)() = nullptr;
|
||||
int32_t (*AOC_ListTitle)(uint32_t * titleCountOut, AOCTitle * titleList, uint32_t maxCount, void *workBuffer, uint32_t workBufferSize) = nullptr;
|
||||
int32_t (*AOC_OpenTitle)(char *pathOut, AOCTitle *aocTitleInfo, void *workBuffer, uint32_t workBufferSize) = nullptr;
|
||||
int32_t (*AOC_CalculateWorkBufferSize)(uint32_t count) = nullptr;
|
||||
int32_t (*AOC_CloseTitle)(AOCTitle * aocTitleInfo) = nullptr;
|
||||
|
||||
AOCTitle title{};
|
||||
char aocPath[256];
|
||||
aocPath[0] = '\0';
|
||||
uint32_t outCount = 0;
|
||||
uint32_t workBufferSize = 0;
|
||||
void *workBuffer = nullptr;
|
||||
bool result = false;
|
||||
|
||||
OSDynLoad_Module aoc_handle;
|
||||
if (OSDynLoad_Acquire("nn_aoc.rpl", &aoc_handle) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_Acquire failed");
|
||||
return false;
|
||||
}
|
||||
if (OSDynLoad_FindExport(aoc_handle, false, "AOC_Initialize", reinterpret_cast<void **>(&AOC_Initialize)) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_FindExport failed");
|
||||
goto end;
|
||||
}
|
||||
if (OSDynLoad_FindExport(aoc_handle, false, "AOC_Finalize", reinterpret_cast<void **>(&AOC_Finalize)) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_FindExport failed");
|
||||
goto end;
|
||||
}
|
||||
if (OSDynLoad_FindExport(aoc_handle, false, "AOC_OpenTitle", reinterpret_cast<void **>(&AOC_OpenTitle)) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_FindExport failed");
|
||||
goto end;
|
||||
}
|
||||
if (OSDynLoad_FindExport(aoc_handle, false, "AOC_ListTitle", reinterpret_cast<void **>(&AOC_ListTitle)) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_FindExport failed");
|
||||
goto end;
|
||||
}
|
||||
if (OSDynLoad_FindExport(aoc_handle, false, "AOC_CalculateWorkBufferSize", reinterpret_cast<void **>(&AOC_CalculateWorkBufferSize)) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_FindExport failed");
|
||||
goto end;
|
||||
}
|
||||
if (OSDynLoad_FindExport(aoc_handle, false, "AOC_CloseTitle", reinterpret_cast<void **>(&AOC_CloseTitle)) != OS_DYNLOAD_OK) {
|
||||
DEBUG_FUNCTION_LINE_WARN("OSDynLoad_FindExport failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
AOC_Initialize();
|
||||
|
||||
workBufferSize = AOC_CalculateWorkBufferSize(1);
|
||||
workBuffer = memalign(0x40, workBufferSize);
|
||||
if (!workBuffer) {
|
||||
DEBUG_FUNCTION_LINE_WARN("Failed to alloc workBuffer");
|
||||
goto end;
|
||||
}
|
||||
if (AOC_ListTitle(&outCount, &title, 1, workBuffer, workBufferSize) < 0) {
|
||||
DEBUG_FUNCTION_LINE_WARN("AOC_ListTitle failed");
|
||||
goto end;
|
||||
}
|
||||
if (AOC_OpenTitle(aocPath, &title, workBuffer, workBufferSize) < 0) {
|
||||
DEBUG_FUNCTION_LINE_WARN("AOC_OpenTitle failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = true;
|
||||
outStr = aocPath;
|
||||
AOC_CloseTitle(&title);
|
||||
end:
|
||||
free(workBuffer);
|
||||
AOC_Finalize();
|
||||
OSDynLoad_Release(aoc_handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
ContentRedirectionApiErrorType CRAddFSLayer(CRLayerHandle *handle, const char *layerName, const char *replacementDir, FSLayerType layerType) {
|
||||
if (!handle || layerName == nullptr || replacementDir == nullptr) {
|
||||
DEBUG_FUNCTION_LINE_WARN("CONTENT_REDIRECTION_API_ERROR_INVALID_ARG");
|
||||
@ -15,10 +95,25 @@ ContentRedirectionApiErrorType CRAddFSLayer(CRLayerHandle *handle, const char *l
|
||||
}
|
||||
std::unique_ptr<IFSWrapper> ptr;
|
||||
if (layerType == FS_LAYER_TYPE_CONTENT_REPLACE) {
|
||||
DEBUG_FUNCTION_LINE_INFO("Redirecting \"/vol/content\" to \"%s\", mode: \"replace\"", replacementDir);
|
||||
ptr = make_unique_nothrow<FSWrapper>(layerName, "/vol/content", replacementDir, false, false);
|
||||
} else if (layerType == FS_LAYER_TYPE_CONTENT_MERGE) {
|
||||
DEBUG_FUNCTION_LINE_INFO("Redirecting \"/vol/content\" to \"%s\", mode: \"merge\"", replacementDir);
|
||||
ptr = make_unique_nothrow<FSWrapperMergeDirsWithParent>(layerName, "/vol/content", replacementDir, true);
|
||||
} else if (layerType == FS_LAYER_TYPE_AOC_MERGE || layerType == FS_LAYER_TYPE_AOC_REPLACE) {
|
||||
std::string targetPath;
|
||||
if (!getAOCPath(targetPath)) {
|
||||
DEBUG_FUNCTION_LINE_ERR("(%s) Failed to get the AOC path. Not redirecting /vol/aoc", layerName);
|
||||
return CONTENT_REDIRECTION_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
DEBUG_FUNCTION_LINE_INFO("Redirecting \"%s\" to \"%s\", mode: \"%s\"", targetPath.c_str(), replacementDir, layerType == FS_LAYER_TYPE_AOC_MERGE ? "merge" : "replace");
|
||||
if (layerType == FS_LAYER_TYPE_AOC_MERGE) {
|
||||
ptr = make_unique_nothrow<FSWrapperMergeDirsWithParent>(layerName, targetPath.c_str(), replacementDir, true);
|
||||
} else {
|
||||
ptr = make_unique_nothrow<FSWrapper>(layerName, targetPath.c_str(), replacementDir, false, false);
|
||||
}
|
||||
} else if (layerType == FS_LAYER_TYPE_SAVE_REPLACE) {
|
||||
DEBUG_FUNCTION_LINE_INFO("Redirecting \"/vol/save\" to \"%s\", mode: \"replace\"", replacementDir);
|
||||
ptr = make_unique_nothrow<FSWrapper>(layerName, "/vol/save", replacementDir, false, true);
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_ERR("CONTENT_REDIRECTION_API_ERROR_UNKNOWN_LAYER_DIR_TYPE: %s %s %d", layerName, replacementDir, layerType);
|
||||
|
Loading…
Reference in New Issue
Block a user