Skip to content
This repository has been archived by the owner on Aug 4, 2024. It is now read-only.

Commit

Permalink
workaround: mingw: make passing native path to magiskboot work when c…
Browse files Browse the repository at this point in the history
…ompiled using MSYS2 (#27)

- closes #27

Signed-off-by: Ookiineko <[email protected]>
  • Loading branch information
Ookiineko committed Apr 9, 2024
1 parent de80176 commit aeff0c5
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.stub.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ if (WIN32)
src/libc-compat/winsup/file.c
src/libc-compat/winsup/io.c
src/libc-compat/winsup/link.c
src/libc-compat/winsup/main_hack.c
src/libc-compat/winsup/mkdir.c
src/libc-compat/winsup/mknod_stub.c
src/libc-compat/winsup/open.c
Expand All @@ -90,6 +91,9 @@ if (WIN32)

target_include_directories(android_libbase PRIVATE src/libc-compat/include)

# HACK: fix passing native path in argv when using MSYS2's MinGW runtime
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap=main")

# libc-compat overrides
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap=mkdir -Wl,--wrap=creat -Wl,--wrap=open -Wl,--wrap=fopen")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap=fdopen -Wl,--wrap=fstat -Wl,--wrap=CreateFileW")
Expand Down
73 changes: 73 additions & 0 deletions src/libc-compat/winsup/main_hack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// HACK:
// native paths like \\?\C:\windows doesn't get passed correctly
// to main() when compiled with MSYS2's compiler and MinGW-runtime.
//
// so until the root cause is discovered, this hack will be used.

#include <assert.h>
#include <stdlib.h>
#include <wchar.h>

#include <windows.h>

#include "internal/assert.h"

#define LOG_TAG "main_hack"

// defined in:
// src/Magisk/native/src/boot/main.cpp

int __real_main(int argc, char **argv);

int __wrap_main(int argc, char **argv) {
int argc_new, i, len, res;
wchar_t **argv_w;
char **argv_new;

// get wide argv

argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_new);
if (!argv_w) {
LOG_ERR("CommandLineToArgvW failed: %s", win_strerror(GetLastError()));

abort();
}

// convert it to system code page

argv_new = calloc(argc_new + 1, sizeof(char *));
assert(argv_new);

for (i = 0; i < argc_new; i++) {
len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS,
argv_w[i], -1, NULL, 0, NULL, NULL);
if (!len) {
wcstombs_failed:
LOG_ERR("WideCharToMultiByte failed: %s", win_strerror(GetLastError()));

abort();
}

argv_new[i] = malloc(len);
assert(argv_new[i]);

if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, argv_w[i],
-1, argv_new[i], len, NULL, NULL))
goto wcstombs_failed;
}

// the last arg is always a NULL entry,
// which indicates the end of our argv
argv_new[argc_new] = NULL;

LocalFree(argv_w);

res = __real_main(argc_new, argv_new);

for (i = 0; i < argc_new; i++)
free(argv_new[i]);

free(argv_new);

return res;
}

0 comments on commit aeff0c5

Please sign in to comment.