mirror of
https://github.com/wiiu-env/RPXLoadingModule.git
synced 2024-11-22 09:59:17 +01:00
Fix FSReadDir when redirecting the /vol/content directory to another path
This commit is contained in:
parent
91b7686e2e
commit
112c14498a
@ -11,8 +11,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ASYNC_RESULT_HANDLER [client, block, asyncData](FSStatus res) -> FSStatus { \
|
#define ASYNC_RESULT_HANDLER [client, block, asyncData](FSStatus res) -> FSStatus { \
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Result was %d", res); \
|
DEBUG_FUNCTION_LINE_VERBOSE("Result was %d", res); \
|
||||||
return send_result_async(client, block, asyncData, res);\
|
return send_result_async(client, block, asyncData, res); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSOpenDir, FSClient *client, FSCmdBlock *block, char *path, FSDirectoryHandle *handle, FSErrorFlag errorMask) {
|
DECL_FUNCTION(FSStatus, FSOpenDir, FSClient *client, FSCmdBlock *block, char *path, FSDirectoryHandle *handle, FSErrorFlag errorMask) {
|
||||||
@ -33,17 +33,24 @@ DECL_FUNCTION(FSStatus, FSOpenDir, FSClient *client, FSCmdBlock *block, char *pa
|
|||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSOpenDirAsync, FSClient *client, FSCmdBlock *block, char *path, FSDirectoryHandle *handle, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
DECL_FUNCTION(FSStatus, FSOpenDirAsync, FSClient *client, FSCmdBlock *block, char *path, FSDirectoryHandle *handle, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("%s", path);
|
DEBUG_FUNCTION_LINE_VERBOSE("%s", path);
|
||||||
FSStatus result = FSOpenDirWrapper(path, handle, errorMask,
|
FSErrorFlag realErrorMask = errorMask;
|
||||||
[client, block, handle, errorMask, asyncData]
|
|
||||||
(char *_path) -> FSStatus {
|
// Even real_FSOpenDir is still calling our FSOpenDirAsync hook. To bypass our code we use "FORCE_REAL_FUNC_WITH_FULL_ERRORS" as an errorMask.
|
||||||
return real_FSOpenDirAsync(client, block, _path, handle, errorMask, asyncData);
|
if ((errorMask & ERROR_FLAG_MASK) != FORCE_REAL_FUNC_MAGIC) {
|
||||||
},
|
FSStatus result = FSOpenDirWrapper(path, handle, errorMask,
|
||||||
ASYNC_RESULT_HANDLER);
|
[client, block, handle, errorMask, asyncData]
|
||||||
if (result != FS_STATUS_USE_REAL_OS) {
|
(char *_path) -> FSStatus {
|
||||||
return result;
|
return real_FSOpenDirAsync(client, block, _path, handle, errorMask, asyncData);
|
||||||
|
},
|
||||||
|
ASYNC_RESULT_HANDLER);
|
||||||
|
if (result != FS_STATUS_USE_REAL_OS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realErrorMask = FS_ERROR_FLAG_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return real_FSOpenDirAsync(client, block, path, handle, errorMask, asyncData);
|
return real_FSOpenDirAsync(client, block, path, handle, realErrorMask, asyncData);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSReadDir, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSDirectoryEntry *entry, FSErrorFlag errorMask) {
|
DECL_FUNCTION(FSStatus, FSReadDir, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSDirectoryEntry *entry, FSErrorFlag errorMask) {
|
||||||
@ -58,12 +65,18 @@ DECL_FUNCTION(FSStatus, FSReadDir, FSClient *client, FSCmdBlock *block, FSDirect
|
|||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSReadDirAsync, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSDirectoryEntry *entry, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
DECL_FUNCTION(FSStatus, FSReadDirAsync, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSDirectoryEntry *entry, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE();
|
DEBUG_FUNCTION_LINE_VERBOSE();
|
||||||
FSStatus result = FSReadDirWrapper(handle, entry, errorMask, ASYNC_RESULT_HANDLER);
|
FSErrorFlag realErrorMask = errorMask;
|
||||||
if (result != FS_STATUS_USE_REAL_OS) {
|
// Even real_FSReadDir is still calling our FSReadDirAsync hook. To bypass our code we use "FORCE_REAL_FUNC_WITH_FULL_ERRORS" as an errorMask.
|
||||||
return result;
|
if ((errorMask & ERROR_FLAG_MASK) != FORCE_REAL_FUNC_MAGIC) {
|
||||||
|
FSStatus result = FSReadDirWrapper(handle, entry, errorMask, ASYNC_RESULT_HANDLER);
|
||||||
|
if (result != FS_STATUS_USE_REAL_OS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realErrorMask = FS_ERROR_FLAG_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return real_FSReadDirAsync(client, block, handle, entry, errorMask, asyncData);
|
return real_FSReadDirAsync(client, block, handle, entry, realErrorMask, asyncData);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSCloseDir, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask) {
|
DECL_FUNCTION(FSStatus, FSCloseDir, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask) {
|
||||||
@ -78,12 +91,18 @@ DECL_FUNCTION(FSStatus, FSCloseDir, FSClient *client, FSCmdBlock *block, FSDirec
|
|||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSCloseDirAsync, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
DECL_FUNCTION(FSStatus, FSCloseDirAsync, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE();
|
DEBUG_FUNCTION_LINE_VERBOSE();
|
||||||
FSStatus result = FSCloseDirWrapper(handle, errorMask, ASYNC_RESULT_HANDLER);
|
FSErrorFlag realErrorMask = errorMask;
|
||||||
if (result != FS_STATUS_USE_REAL_OS) {
|
// Even real_FSCloseDir is still calling our FSCloseDirAsync hook. To bypass our code we use "FORCE_REAL_FUNC_WITH_FULL_ERRORS" as an errorMask.
|
||||||
return result;
|
if ((errorMask & ERROR_FLAG_MASK) != FORCE_REAL_FUNC_MAGIC) {
|
||||||
|
FSStatus result = FSCloseDirWrapper(handle, errorMask, ASYNC_RESULT_HANDLER);
|
||||||
|
if (result != FS_STATUS_USE_REAL_OS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realErrorMask = FS_ERROR_FLAG_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return real_FSCloseDirAsync(client, block, handle, errorMask, asyncData);
|
return real_FSCloseDirAsync(client, block, handle, realErrorMask, asyncData);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSRewindDir, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask) {
|
DECL_FUNCTION(FSStatus, FSRewindDir, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask) {
|
||||||
@ -98,12 +117,18 @@ DECL_FUNCTION(FSStatus, FSRewindDir, FSClient *client, FSCmdBlock *block, FSDire
|
|||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSRewindDirAsync, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
DECL_FUNCTION(FSStatus, FSRewindDirAsync, FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask, FSAsyncData *asyncData) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE();
|
DEBUG_FUNCTION_LINE_VERBOSE();
|
||||||
FSStatus result = FSRewindDirWrapper(handle, errorMask, ASYNC_RESULT_HANDLER);
|
FSErrorFlag realErrorMask = errorMask;
|
||||||
if (result != FS_STATUS_USE_REAL_OS) {
|
// Even real_FSRewindDir is still calling our FSRewindDirAsync hook. To bypass our code we use "FORCE_REAL_FUNC_WITH_FULL_ERRORS" as an errorMask.
|
||||||
return result;
|
if ((errorMask & ERROR_FLAG_MASK) != FORCE_REAL_FUNC_MAGIC) {
|
||||||
|
FSStatus result = FSRewindDirWrapper(handle, errorMask, ASYNC_RESULT_HANDLER);
|
||||||
|
if (result != FS_STATUS_USE_REAL_OS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
realErrorMask = FS_ERROR_FLAG_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return real_FSRewindDirAsync(client, block, handle, errorMask, asyncData);
|
return real_FSRewindDirAsync(client, block, handle, realErrorMask, asyncData);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(FSStatus, FSMakeDir, FSClient *client, FSCmdBlock *block, char *path, FSErrorFlag errorMask) {
|
DECL_FUNCTION(FSStatus, FSMakeDir, FSClient *client, FSCmdBlock *block, char *path, FSErrorFlag errorMask) {
|
||||||
|
@ -134,6 +134,8 @@ void freeDirHandle(uint32_t handle) {
|
|||||||
dir_handle_mutex.unlock();
|
dir_handle_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" FSStatus (*real_FSOpenDir)(FSClient *, FSCmdBlock *, char *, FSDirectoryHandle *, FSErrorFlag);
|
||||||
|
|
||||||
FSStatus FSOpenDirWrapper(char *path,
|
FSStatus FSOpenDirWrapper(char *path,
|
||||||
FSDirectoryHandle *handle,
|
FSDirectoryHandle *handle,
|
||||||
FSErrorFlag errorMask,
|
FSErrorFlag errorMask,
|
||||||
@ -177,10 +179,30 @@ FSStatus FSOpenDirWrapper(char *path,
|
|||||||
dir_handles[handle_index].path[0] = '\0';
|
dir_handles[handle_index].path[0] = '\0';
|
||||||
strncat(dir_handles[handle_index].path, pathForCheck, sizeof(dir_handles[handle_index].path) - 1);
|
strncat(dir_handles[handle_index].path, pathForCheck, sizeof(dir_handles[handle_index].path) - 1);
|
||||||
|
|
||||||
DCFlushRange(&dir_handles[handle_index], sizeof(dirMagic_t));
|
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto dir_info = &dir_handles[handle_index];
|
||||||
|
|
||||||
|
dir_info->readResult = nullptr;
|
||||||
|
dir_info->readResultCapacity = 0;
|
||||||
|
dir_info->readResultNumberOfEntries = 0;
|
||||||
|
|
||||||
|
dir_info->realDirHandle = 0;
|
||||||
|
|
||||||
|
if (gFSClient && gFSCmd) {
|
||||||
|
FSDirectoryHandle realHandle = 0;
|
||||||
|
if (real_FSOpenDir(gFSClient, gFSCmd, path, &realHandle, (FSErrorFlag) FORCE_REAL_FUNC_WITH_FULL_ERRORS) == FS_STATUS_OK) {
|
||||||
|
dir_info->realDirHandle = realHandle;
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE_VERBOSE("Failed to open real dir %s", path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Global FSClient or FSCmdBlock were null");
|
||||||
|
}
|
||||||
|
DCFlushRange(dir_info, sizeof(dirMagic_t));
|
||||||
|
}
|
||||||
|
|
||||||
OSUnlockMutex(dir_handles[handle_index].mutex);
|
OSUnlockMutex(dir_handles[handle_index].mutex);
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("Dir not found %s", pathForCheck);
|
|
||||||
if (gReplacementInfo.contentReplacementInfo.fallbackOnError) {
|
if (gReplacementInfo.contentReplacementInfo.fallbackOnError) {
|
||||||
return FS_STATUS_USE_REAL_OS;
|
return FS_STATUS_USE_REAL_OS;
|
||||||
}
|
}
|
||||||
@ -198,6 +220,8 @@ FSStatus FSOpenDirWrapper(char *path,
|
|||||||
return FS_STATUS_USE_REAL_OS;
|
return FS_STATUS_USE_REAL_OS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" FSStatus (*real_FSReadDir)(FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSDirectoryEntry *entry, FSErrorFlag errorMask);
|
||||||
|
|
||||||
FSStatus FSReadDirWrapper(FSDirectoryHandle handle,
|
FSStatus FSReadDirWrapper(FSDirectoryHandle handle,
|
||||||
FSDirectoryEntry *entry,
|
FSDirectoryEntry *entry,
|
||||||
FSErrorFlag errorMask,
|
FSErrorFlag errorMask,
|
||||||
@ -218,6 +242,19 @@ FSStatus FSReadDirWrapper(FSDirectoryHandle handle,
|
|||||||
OSLockMutex(dir_handles[handle_index].mutex);
|
OSLockMutex(dir_handles[handle_index].mutex);
|
||||||
DIR *dir = dir_handles[handle_index].dir;
|
DIR *dir = dir_handles[handle_index].dir;
|
||||||
|
|
||||||
|
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto dir_info = &dir_handles[handle_index];
|
||||||
|
|
||||||
|
// Init list if needed
|
||||||
|
if (dir_info->readResultCapacity == 0) {
|
||||||
|
dir_info->readResult = (FSDirectoryEntry *) malloc(sizeof(FSDirectoryEntry));
|
||||||
|
if (dir_info->readResult != nullptr) {
|
||||||
|
dir_info->readResultCapacity = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCFlushRange(dir_info, sizeof(dirMagic_t));
|
||||||
|
}
|
||||||
|
|
||||||
struct dirent *entry_ = readdir(dir);
|
struct dirent *entry_ = readdir(dir);
|
||||||
FSStatus result = FS_STATUS_END;
|
FSStatus result = FS_STATUS_END;
|
||||||
if (entry_) {
|
if (entry_) {
|
||||||
@ -244,13 +281,73 @@ FSStatus FSReadDirWrapper(FSDirectoryHandle handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto dir_info = &dir_handles[handle_index];
|
||||||
|
if (dir_info->readResultNumberOfEntries >= dir_info->readResultCapacity) {
|
||||||
|
auto newCapacity = dir_info->readResultCapacity * 2;
|
||||||
|
dir_info->readResult = (FSDirectoryEntry *) realloc(dir_info->readResult, newCapacity * sizeof(FSDirectoryEntry));
|
||||||
|
dir_info->readResultCapacity = newCapacity;
|
||||||
|
if (dir_info->readResult == nullptr) {
|
||||||
|
OSFatal("Failed to alloc memory for dir entry list");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&dir_info->readResult[dir_info->readResultNumberOfEntries], entry, sizeof(FSDirectoryEntry));
|
||||||
|
dir_info->readResultNumberOfEntries++;
|
||||||
|
|
||||||
|
DCFlushRange(dir_info->readResult, sizeof(FSDirectoryEntry) * dir_info->readResultNumberOfEntries);
|
||||||
|
DCFlushRange(dir_info, sizeof(dirMagic_t));
|
||||||
|
}
|
||||||
|
|
||||||
result = FS_STATUS_OK;
|
result = FS_STATUS_OK;
|
||||||
|
} else if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto dir_info = &dir_handles[handle_index];
|
||||||
|
// Read the real directory.
|
||||||
|
if (dir_info->realDirHandle != 0) {
|
||||||
|
if (gFSClient && gFSCmd) {
|
||||||
|
FSDirectoryEntry realDirEntry;
|
||||||
|
FSStatus readDirResult = FS_STATUS_OK;
|
||||||
|
result = FS_STATUS_END;
|
||||||
|
while (readDirResult == FS_STATUS_OK) {
|
||||||
|
readDirResult = real_FSReadDir(gFSClient, gFSCmd, dir_info->realDirHandle, &realDirEntry, (FSErrorFlag) FORCE_REAL_FUNC_WITH_FULL_ERRORS);
|
||||||
|
if (readDirResult == FS_STATUS_OK) {
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < dir_info->readResultNumberOfEntries; i++) {
|
||||||
|
auto curResult = &dir_info->readResult[i];
|
||||||
|
// Check if this is a new result
|
||||||
|
if (strncmp(curResult->name, realDirEntry.name, sizeof(realDirEntry.name) - 1) == 0) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If it's new we can use it :)
|
||||||
|
if (!found) {
|
||||||
|
memcpy(entry, &realDirEntry, sizeof(FSDirectoryEntry));
|
||||||
|
result = FS_STATUS_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (readDirResult == FS_STATUS_END) {
|
||||||
|
result = FS_STATUS_END;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("real_FSReadDir returned an unexpected error: %08X", readDirResult);
|
||||||
|
result = FS_STATUS_END;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Global FSClient or FSCmdBlock were null");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OSUnlockMutex(dir_handles[handle_index].mutex);
|
OSUnlockMutex(dir_handles[handle_index].mutex);
|
||||||
return result_handler(result);
|
return result_handler(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" FSStatus (*real_FSCloseDir)(FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask);
|
||||||
|
|
||||||
FSStatus FSCloseDirWrapper(FSDirectoryHandle handle,
|
FSStatus FSCloseDirWrapper(FSDirectoryHandle handle,
|
||||||
FSErrorFlag errorMask,
|
FSErrorFlag errorMask,
|
||||||
const std::function<FSStatus(FSStatus)> &result_handler) {
|
const std::function<FSStatus(FSStatus)> &result_handler) {
|
||||||
@ -274,11 +371,38 @@ FSStatus FSCloseDirWrapper(FSDirectoryHandle handle,
|
|||||||
result = FS_STATUS_MEDIA_ERROR;
|
result = FS_STATUS_MEDIA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto dir_info = &dir_handles[handle_index];
|
||||||
|
|
||||||
|
if (dir_info->realDirHandle != 0) {
|
||||||
|
if (gFSClient && gFSCmd) {
|
||||||
|
auto realResult = real_FSCloseDir(gFSClient, gFSCmd, dir_info->realDirHandle, (FSErrorFlag) FORCE_REAL_FUNC_WITH_FULL_ERRORS);
|
||||||
|
if (realResult == FS_STATUS_OK) {
|
||||||
|
dir_info->realDirHandle = 0;
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to closed dir %d", realResult);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Global FSClient or FSCmdBlock were null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir_info->readResult != nullptr) {
|
||||||
|
free(dir_info->readResult);
|
||||||
|
dir_info->readResult = nullptr;
|
||||||
|
dir_info->readResultCapacity = 0;
|
||||||
|
dir_info->readResultNumberOfEntries = 0;
|
||||||
|
}
|
||||||
|
DCFlushRange(dir_info, sizeof(dirMagic_t));
|
||||||
|
}
|
||||||
|
|
||||||
OSUnlockMutex(dir_handles[handle_index].mutex);
|
OSUnlockMutex(dir_handles[handle_index].mutex);
|
||||||
freeDirHandle(handle_index);
|
freeDirHandle(handle_index);
|
||||||
return result_handler(result);
|
return result_handler(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" FSStatus (*real_FSRewindDir)(FSClient *client, FSCmdBlock *block, FSDirectoryHandle handle, FSErrorFlag errorMask);
|
||||||
|
|
||||||
FSStatus FSRewindDirWrapper(FSDirectoryHandle handle,
|
FSStatus FSRewindDirWrapper(FSDirectoryHandle handle,
|
||||||
FSErrorFlag errorMask,
|
FSErrorFlag errorMask,
|
||||||
const std::function<FSStatus(FSStatus)> &result_handler) {
|
const std::function<FSStatus(FSStatus)> &result_handler) {
|
||||||
@ -297,6 +421,29 @@ FSStatus FSRewindDirWrapper(FSDirectoryHandle handle,
|
|||||||
|
|
||||||
DIR *dir = dir_handles[real_handle].dir;
|
DIR *dir = dir_handles[real_handle].dir;
|
||||||
rewinddir(dir);
|
rewinddir(dir);
|
||||||
|
|
||||||
|
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto dir_info = &dir_handles[handle_index];
|
||||||
|
|
||||||
|
if (dir_info->readResult != nullptr) {
|
||||||
|
dir_info->readResultNumberOfEntries = 0;
|
||||||
|
memset(dir_info->readResult, 0, sizeof(FSDirectoryEntry) * dir_info->readResultCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir_info->realDirHandle != 0) {
|
||||||
|
if (gFSClient && gFSCmd) {
|
||||||
|
if (real_FSRewindDir(gFSClient, gFSCmd, dir_info->realDirHandle, (FSErrorFlag) FORCE_REAL_FUNC_WITH_FULL_ERRORS) == FS_STATUS_OK) {
|
||||||
|
dir_info->realDirHandle = 0;
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to rewind dir");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE("Global FSClient or FSCmdBlock were null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCFlushRange(dir_info, sizeof(dirMagic_t));
|
||||||
|
}
|
||||||
|
|
||||||
OSUnlockMutex(dir_handles[handle_index].mutex);
|
OSUnlockMutex(dir_handles[handle_index].mutex);
|
||||||
return result_handler(FS_STATUS_OK);
|
return result_handler(FS_STATUS_OK);
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,18 @@
|
|||||||
#include <coreinit/mutex.h>
|
#include <coreinit/mutex.h>
|
||||||
|
|
||||||
typedef struct dirMagic {
|
typedef struct dirMagic {
|
||||||
uint32_t handle;
|
uint32_t handle{};
|
||||||
DIR *dir;
|
DIR *dir{};
|
||||||
bool in_use;
|
bool in_use{};
|
||||||
char path[256];
|
char path[256]{};
|
||||||
OSMutex *mutex;
|
|
||||||
|
OSMutex *mutex{};
|
||||||
|
|
||||||
|
FSDirectoryEntry * readResult = nullptr;
|
||||||
|
int readResultCapacity = 0;
|
||||||
|
int readResultNumberOfEntries = 0;
|
||||||
|
|
||||||
|
FSDirectoryHandle realDirHandle = 0;
|
||||||
} dirMagic_t;
|
} dirMagic_t;
|
||||||
|
|
||||||
typedef struct fileMagic {
|
typedef struct fileMagic {
|
||||||
@ -21,6 +28,12 @@ typedef struct fileMagic {
|
|||||||
OSMutex *mutex;
|
OSMutex *mutex;
|
||||||
} fileMagic_t;
|
} fileMagic_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define ERROR_FLAG_MASK (0xFFFF0000)
|
||||||
|
#define FORCE_REAL_FUNC_MAGIC (0x42420000)
|
||||||
|
#define FORCE_REAL_FUNC_WITH_FULL_ERRORS (FORCE_REAL_FUNC_MAGIC | 0x0000FFFF)
|
||||||
|
|
||||||
|
#define HANDLE_INDICATOR_MASK 0xFFFFFF00
|
||||||
#define HANDLE_INDICATOR_MASK 0xFFFFFF00
|
#define HANDLE_INDICATOR_MASK 0xFFFFFF00
|
||||||
#define HANDLE_MASK (0x000000FF)
|
#define HANDLE_MASK (0x000000FF)
|
||||||
#define DIR_HANDLE_MAGIC 0x30000000
|
#define DIR_HANDLE_MAGIC 0x30000000
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
#include <coreinit/filesystem.h>
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
RPXLoader_ReplacementInformation gReplacementInfo __attribute__((section(".data")));
|
RPXLoader_ReplacementInformation gReplacementInfo __attribute__((section(".data")));
|
||||||
|
|
||||||
|
FSClient * gFSClient __attribute__((section(".data"))) = nullptr;
|
||||||
|
FSCmdBlock * gFSCmd __attribute__((section(".data"))) = nullptr;
|
@ -1,5 +1,6 @@
|
|||||||
#include <wums.h>
|
#include <wums.h>
|
||||||
#include <coreinit/mutex.h>
|
#include <coreinit/mutex.h>
|
||||||
|
#include <coreinit/filesystem.h>
|
||||||
|
|
||||||
typedef struct MetaInformation_t {
|
typedef struct MetaInformation_t {
|
||||||
char shortname[64];
|
char shortname[64];
|
||||||
@ -49,3 +50,5 @@ typedef struct RPXLoader_ReplacementInformation_t {
|
|||||||
|
|
||||||
|
|
||||||
extern RPXLoader_ReplacementInformation gReplacementInfo;
|
extern RPXLoader_ReplacementInformation gReplacementInfo;
|
||||||
|
extern FSClient * gFSClient;
|
||||||
|
extern FSCmdBlock * gFSCmd;
|
22
src/main.cpp
22
src/main.cpp
@ -46,6 +46,11 @@ WUMS_APPLICATION_ENDS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
gReplacementInfo.rpxReplacementInfo.isRPXReplaced = false;
|
gReplacementInfo.rpxReplacementInfo.isRPXReplaced = false;
|
||||||
|
if (gFSClient) {
|
||||||
|
FSDelClient(gFSClient, FS_ERROR_FLAG_ALL);
|
||||||
|
free(gFSClient);
|
||||||
|
}
|
||||||
|
free(gFSCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
WUMS_APPLICATION_STARTS() {
|
WUMS_APPLICATION_STARTS() {
|
||||||
@ -59,6 +64,23 @@ WUMS_APPLICATION_STARTS() {
|
|||||||
}
|
}
|
||||||
WHBLogUdpInit();
|
WHBLogUdpInit();
|
||||||
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
if (gReplacementInfo.contentReplacementInfo.mode == CONTENTREDIRECT_FROM_PATH) {
|
||||||
|
auto fsClient = (FSClient *) memalign(0x20, sizeof(FSClient));
|
||||||
|
auto fsCmd = (FSCmdBlock *) memalign(0x20, sizeof(FSCmdBlock));
|
||||||
|
|
||||||
|
if (fsClient == nullptr || fsCmd == nullptr) {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to alloc memory for fsclient or fsCmd");
|
||||||
|
free(fsClient);
|
||||||
|
free(fsCmd);
|
||||||
|
} else {
|
||||||
|
auto rc = FSAddClient(fsClient, FS_ERROR_FLAG_ALL);
|
||||||
|
if (rc < 0) {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to add FSClient");
|
||||||
|
} else {
|
||||||
|
FSInitCmdBlock(fsCmd);
|
||||||
|
gFSClient = fsClient;
|
||||||
|
gFSCmd = fsCmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user