Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM ghcr.io/wiiu-env/devkitppc:20240505
FROM ghcr.io/wiiu-env/devkitppc:20241128

COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20240424 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libcontentredirection:20240428 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libcontentredirection:1.2-dev-20250207-b11c3c8 /artifacts $DEVKITPRO

WORKDIR project
8 changes: 6 additions & 2 deletions src/DirInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
#include <coreinit/filesystem.h>
#include <sys/dirent.h>

struct DirInfo {
virtual ~DirInfo() = default;
struct DirInfoBase {
virtual ~DirInfoBase() = default;
FSDirectoryHandle handle{};
};

struct DirInfo : DirInfoBase {
~DirInfo() override = default;
DIR *dir{};
char path[0x280]{};
};
16 changes: 11 additions & 5 deletions src/DirInfoEx.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
#include <coreinit/filesystem_fsa.h>

typedef struct FSDirectoryEntryEx {
FSADirectoryEntry realEntry{};
bool isMarkedAsDeleted = false;
FSADirectoryEntry realEntry = {};
bool isMarkedAsDeleted = false;
} FSDirectoryEntryEx;

struct DirInfoEx : public DirInfo {
public:
struct DirInfoEx final : DirInfo {
FSDirectoryEntryEx *readResult = nullptr;
int readResultCapacity = 0;
int readResultNumberOfEntries = 0;
FSDirectoryHandle realDirHandle = 0;
};
};

struct DirInfoExSingleFile final : DirInfoBase {
FSADirectoryEntry directoryEntry = {};
bool entryRead = false;
bool entryReadSuccess = false;
FSDirectoryHandle realDirHandle = 0;
};
98 changes: 56 additions & 42 deletions src/FSWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
#include "utils/StringTools.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include <algorithm>

#include <coreinit/cache.h>
#include <coreinit/debug.h>
#include <coreinit/filesystem_fsa.h>
#include <cstdio>

#include <algorithm>
#include <filesystem>

#include <cstdio>
#include <sys/dirent.h>
#include <sys/fcntl.h>
#include <sys/unistd.h>
Expand All @@ -28,7 +30,7 @@ FSError FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle)

FSError result = FS_ERROR_OK;

auto dirHandle = getNewDirHandle();
const auto dirHandle = getNewDirInfoHandle();
if (dirHandle) {
DIR *dir;
auto newPath = GetNewPath(path);
Expand All @@ -40,11 +42,7 @@ FSError FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle)

dirHandle->path[0] = '\0';
strncat(dirHandle->path, newPath.c_str(), sizeof(dirHandle->path) - 1);
{
std::lock_guard<std::mutex> lock(openDirsMutex);
openDirs.push_back(dirHandle);
OSMemoryBarrier();
}
addDirHandle(dirHandle);
} else {
auto err = errno;
if (err == ENOENT) {
Expand All @@ -68,11 +66,11 @@ FSError FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle)
return result;
}

FSError FSWrapper::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry *entry) {
FSError FSWrapper::FSReadDirWrapper(const FSDirectoryHandle handle, FSDirectoryEntry *entry) {
if (!isValidDirHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
auto dirHandle = getDirFromHandle(handle);
const auto dirHandle = getDirInfoFromHandle(handle);

DIR *dir = dirHandle->dir;

Expand Down Expand Up @@ -139,11 +137,11 @@ FSError FSWrapper::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry *
return result;
}

FSError FSWrapper::FSCloseDirWrapper(FSDirectoryHandle handle) {
FSError FSWrapper::FSCloseDirWrapper(const FSDirectoryHandle handle) {
if (!isValidDirHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
auto dirHandle = getDirFromHandle(handle);
const auto dirHandle = getDirInfoFromHandle(handle);

DIR *dir = dirHandle->dir;

Expand All @@ -158,11 +156,11 @@ FSError FSWrapper::FSCloseDirWrapper(FSDirectoryHandle handle) {
return result;
}

FSError FSWrapper::FSRewindDirWrapper(FSDirectoryHandle handle) {
FSError FSWrapper::FSRewindDirWrapper(const FSDirectoryHandle handle) {
if (!isValidDirHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
auto dirHandle = getDirFromHandle(handle);
const auto dirHandle = getDirInfoFromHandle(handle);

DIR *dir = dirHandle->dir;

Expand Down Expand Up @@ -295,7 +293,7 @@ FSError FSWrapper::FSOpenFileWrapper(const char *path, const char *mode, FSFileH
return result;
}

FSError FSWrapper::FSCloseFileWrapper(FSFileHandle handle) {
FSError FSWrapper::FSCloseFileWrapper(const FSFileHandle handle) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand Down Expand Up @@ -360,7 +358,7 @@ FSError FSWrapper::FSGetStatWrapper(const char *path, FSStat *stats) {
return result;
}

FSError FSWrapper::FSGetStatFileWrapper(FSFileHandle handle, FSStat *stats) {
FSError FSWrapper::FSGetStatFileWrapper(const FSFileHandle handle, FSStat *stats) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand All @@ -382,7 +380,7 @@ FSError FSWrapper::FSGetStatFileWrapper(FSFileHandle handle, FSStat *stats) {
return result;
}

FSError FSWrapper::FSReadFileWrapper(void *buffer, uint32_t size, uint32_t count, FSFileHandle handle, [[maybe_unused]] uint32_t unk1) {
FSError FSWrapper::FSReadFileWrapper(void *buffer, const uint32_t size, const uint32_t count, const FSFileHandle handle, [[maybe_unused]] uint32_t unk1) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand Down Expand Up @@ -417,7 +415,7 @@ FSError FSWrapper::FSReadFileWrapper(void *buffer, uint32_t size, uint32_t count
return result;
}

FSError FSWrapper::FSReadFileWithPosWrapper(void *buffer, uint32_t size, uint32_t count, uint32_t pos, FSFileHandle handle, int32_t unk1) {
FSError FSWrapper::FSReadFileWithPosWrapper(void *buffer, const uint32_t size, const uint32_t count, const uint32_t pos, const FSFileHandle handle, const int32_t unk1) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand All @@ -432,7 +430,7 @@ FSError FSWrapper::FSReadFileWithPosWrapper(void *buffer, uint32_t size, uint32_
return result;
}

FSError FSWrapper::FSSetPosFileWrapper(FSFileHandle handle, uint32_t pos) {
FSError FSWrapper::FSSetPosFileWrapper(const FSFileHandle handle, const uint32_t pos) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand All @@ -457,7 +455,7 @@ FSError FSWrapper::FSSetPosFileWrapper(FSFileHandle handle, uint32_t pos) {
return result;
}

FSError FSWrapper::FSGetPosFileWrapper(FSFileHandle handle, uint32_t *pos) {
FSError FSWrapper::FSGetPosFileWrapper(const FSFileHandle handle, uint32_t *pos) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand All @@ -478,7 +476,7 @@ FSError FSWrapper::FSGetPosFileWrapper(FSFileHandle handle, uint32_t *pos) {
return result;
}

FSError FSWrapper::FSIsEofWrapper(FSFileHandle handle) {
FSError FSWrapper::FSIsEofWrapper(const FSFileHandle handle) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand Down Expand Up @@ -509,7 +507,7 @@ FSError FSWrapper::FSIsEofWrapper(FSFileHandle handle) {
return result;
}

FSError FSWrapper::FSTruncateFileWrapper(FSFileHandle handle) {
FSError FSWrapper::FSTruncateFileWrapper(const FSFileHandle handle) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand Down Expand Up @@ -542,7 +540,7 @@ FSError FSWrapper::FSTruncateFileWrapper(FSFileHandle handle) {
return result;
}

FSError FSWrapper::FSWriteFileWrapper(const uint8_t *buffer, uint32_t size, uint32_t count, FSFileHandle handle, [[maybe_unused]] uint32_t unk1) {
FSError FSWrapper::FSWriteFileWrapper(const uint8_t *buffer, const uint32_t size, const uint32_t count, const FSFileHandle handle, [[maybe_unused]] uint32_t unk1) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand All @@ -569,7 +567,7 @@ FSError FSWrapper::FSWriteFileWrapper(const uint8_t *buffer, uint32_t size, uint
result = FS_ERROR_MEDIA_ERROR;
}
} else {
result = static_cast<FSError>(((uint32_t) writeRes) / size);
result = static_cast<FSError>(static_cast<uint32_t>(writeRes) / size);
}

return result;
Expand Down Expand Up @@ -630,7 +628,7 @@ FSError FSWrapper::FSRenameWrapper(const char *oldPath, const char *newPath) {
return FS_ERROR_OK;
}

FSError FSWrapper::FSFlushFileWrapper(FSFileHandle handle) {
FSError FSWrapper::FSFlushFileWrapper(const FSFileHandle handle) {
if (!isValidFileHandle(handle)) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
Expand All @@ -639,8 +637,8 @@ FSError FSWrapper::FSFlushFileWrapper(FSFileHandle handle) {
return FS_ERROR_ACCESS_ERROR;
}

auto fileHandle = getFileFromHandle(handle);
int real_fd = fileHandle->fd;
const auto fileHandle = getFileFromHandle(handle);
const int real_fd = fileHandle->fd;

DEBUG_FUNCTION_LINE_VERBOSE("[%s] fsync fd %08X (FSFileHandle %08X)", real_fd, handle);
FSError result = FS_ERROR_OK;
Expand Down Expand Up @@ -673,16 +671,15 @@ bool FSWrapper::IsFileModeAllowed(const char *mode) {
return false;
}


bool FSWrapper::IsPathToReplace(const std::string_view &path) {
return starts_with_case_insensitive(path, pPathToReplace);
}

std::string FSWrapper::GetNewPath(const std::string_view &path) {
auto subStr = path.substr(this->pPathToReplace.length());
auto res = string_format("%s%.*s", this->pReplacePathWith.c_str(), int(subStr.length()), subStr.data());
std::string FSWrapper::GetNewPath(const std::string_view &path) const {
auto res = std::string(path);
SafeReplaceInString(res, this->pPathToReplace, this->pReplacePathWith);

std::replace(res.begin(), res.end(), '\\', '/');
std::ranges::replace(res, '\\', '/');

uint32_t length = res.size();

Expand All @@ -700,25 +697,26 @@ std::string FSWrapper::GetNewPath(const std::string_view &path) {
}

bool FSWrapper::isValidFileHandle(FSFileHandle handle) {
std::lock_guard<std::mutex> lock(openFilesMutex);
std::lock_guard lock(openFilesMutex);
return std::ranges::any_of(openFiles, [handle](auto &cur) { return cur->handle == handle; });
}

bool FSWrapper::isValidDirHandle(FSDirectoryHandle handle) {
std::lock_guard<std::mutex> lock(openDirsMutex);
std::lock_guard lock(openDirsMutex);
return std::ranges::any_of(openDirs, [handle](auto &cur) { return cur->handle == handle; });
}


std::shared_ptr<FileInfo> FSWrapper::getNewFileHandle() {
return make_shared_nothrow<FileInfo>();
}

std::shared_ptr<DirInfo> FSWrapper::getNewDirHandle() {
std::shared_ptr<DirInfo> FSWrapper::getNewDirInfoHandle() {
return make_shared_nothrow<DirInfo>();
}

std::shared_ptr<FileInfo> FSWrapper::getFileFromHandle(FSFileHandle handle) {
std::lock_guard<std::mutex> lock(openFilesMutex);
std::shared_ptr<FileInfo> FSWrapper::getFileFromHandle(const FSFileHandle handle) {
std::lock_guard lock(openFilesMutex);
for (auto &file : openFiles) {
if (file->handle == handle) {
return file;
Expand All @@ -729,8 +727,8 @@ std::shared_ptr<FileInfo> FSWrapper::getFileFromHandle(FSFileHandle handle) {
return nullptr;
}

std::shared_ptr<DirInfo> FSWrapper::getDirFromHandle(FSDirectoryHandle handle) {
std::lock_guard<std::mutex> lock(openDirsMutex);
std::shared_ptr<DirInfoBase> FSWrapper::getDirFromHandle(const FSDirectoryHandle handle) {
std::lock_guard lock(openDirsMutex);
for (auto &dir : openDirs) {
if (dir->handle == handle) {
return dir;
Expand All @@ -741,18 +739,34 @@ std::shared_ptr<DirInfo> FSWrapper::getDirFromHandle(FSDirectoryHandle handle) {
return nullptr;
}

void FSWrapper::addDirHandle(const std::shared_ptr<DirInfoBase> &dirHandle) {
std::lock_guard lock(openDirsMutex);
openDirs.push_back(dirHandle);
OSMemoryBarrier();
}

void FSWrapper::deleteDirHandle(FSDirectoryHandle handle) {
if (!remove_locked_first_if(openDirsMutex, openDirs, [handle](auto &cur) { return (FSFileHandle) cur->handle == handle; })) {
if (!remove_locked_first_if(openDirsMutex, openDirs, [handle](auto &cur) { return static_cast<FSDirectoryHandle>(cur->handle) == handle; })) {
DEBUG_FUNCTION_LINE_ERR("[%s] Delete failed because the handle %08X was not found", getName().c_str(), handle);
}
}

void FSWrapper::deleteFileHandle(FSFileHandle handle) {
if (!remove_locked_first_if(openFilesMutex, openFiles, [handle](auto &cur) { return (FSFileHandle) cur->handle == handle; })) {
if (!remove_locked_first_if(openFilesMutex, openFiles, [handle](auto &cur) { return static_cast<FSFileHandle>(cur->handle) == handle; })) {
DEBUG_FUNCTION_LINE_ERR("[%s] Delete failed because the handle %08X was not found", getName().c_str(), handle);
}
}

bool FSWrapper::SkipDeletedFilesInReadDir() {
return true;
}

std::shared_ptr<DirInfo> FSWrapper::getDirInfoFromHandle(const FSDirectoryHandle handle) {
auto dir = std::dynamic_pointer_cast<DirInfo>(getDirFromHandle(handle));

if (!dir) {
DEBUG_FUNCTION_LINE_ERR("[%s] dynamic_pointer_cast<DirInfoEx *>(%08X) failed", getName().c_str(), handle);
OSFatal("ContentRedirectionModule: dynamic_pointer_cast<DirInfoEx *> failed");
}
return dir;
}
Loading