diff --git a/Dockerfile b/Dockerfile index 1fcc684..a0985b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ FROM wiiuenv/devkitppc:20211106 +COPY --from=wiiuenv/libromfs_wiiu:20210924 /artifacts $DEVKITPRO + WORKDIR project \ No newline at end of file diff --git a/Makefile b/Makefile index de69f31..6b1482e 100644 --- a/Makefile +++ b/Makefile @@ -36,13 +36,13 @@ CXXFLAGS := $(CFLAGS) ASFLAGS := -g $(ARCH) -mregnames LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map) -LIBS := -lwut +LIBS := -lwut -lromfs #------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level # containing include and lib #------------------------------------------------------------------------------- -LIBDIRS := $(PORTLIBS) $(WUT_ROOT) +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) $(WUT_ROOT)/usr #------------------------------------------------------------------------------- diff --git a/source/main.cpp b/source/main.cpp index 0e1d637..01efc3a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,9 +1,15 @@ +#include +#include +#include #include #include #include #include #include #include +#include + +#include typedef struct __attribute((packed)) { uint32_t command; @@ -16,7 +22,53 @@ typedef struct __attribute((packed)) { extern "C" void _SYSLaunchTitleWithStdArgsInNoSplash(uint64_t, int); extern "C" void OSRestartGame(); -int main(int argc, char **argv) { +bool StringEndsWith(const std::string &a, const std::string &b) { + if (b.size() > a.size()) + return false; + return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); +} + +int32_t getRPXInfoForPath(const std::string &path, romfs_fileInfo *info) { + if (romfsMount("rcc", path.c_str(), RomfsSource_FileDescriptor_CafeOS) < 0) { + return -1; + } + DIR *dir; + struct dirent *entry; + + if (!(dir = opendir("rcc:/code/"))) { + romfsUnmount("rcc"); + return -2; + } + bool found = false; + int res = -3; + while ((entry = readdir(dir)) != nullptr) { + if (StringEndsWith(entry->d_name, ".rpx")) { + if (romfsGetFileInfoPerPath("rcc", (std::string("code/") + entry->d_name).c_str(), info) >= 0) { + found = true; + res = 0; + } + break; + } + } + + closedir(dir); + + romfsUnmount("rcc"); + + if (!found) { + return -4; + } + return res; +} + +int main(int argc, char **argv) { + std::string bundle_path = "wiiu/apps/PayloadLoaderInstaller.wuhb"; + std::string completePath = std::string("/vol/external01/") + bundle_path; + + if (fopen(completePath.c_str(), "r") == NULL) { + OSFatal("\"sd:/wiiu/apps/PayloadLoaderInstaller.wuhb\" is missing on the sd card");; + } + LOAD_REQUEST request; memset(&request, 0, sizeof(request)); @@ -25,8 +77,17 @@ int main(int argc, char **argv) { request.filesize = 0; // unknown filesize request.fileoffset = 0; // request.path[0] = '\0'; + - strncat(request.path, "/wiiu/apps/payload_loader_installer.rpx", sizeof(request.path) - 1); + romfs_fileInfo info; + int res = getRPXInfoForPath(completePath, &info); + + if (res >= 0) { + request.filesize = ((uint32_t *) &info.length)[1]; + request.fileoffset = ((uint32_t *) &info.offset)[1]; + } + + strncat(request.path, bundle_path.c_str() , sizeof(request.path) - 1); DCFlushRange(&request, sizeof(LOAD_REQUEST)); int mcpFd = IOS_Open("/dev/mcp", (IOSOpenMode) 0);