From 7d08a2bdca5c660f76d29a1e77211fcde1878ba1 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 23 Jan 2023 15:22:50 -0500 Subject: [PATCH] Various fixes for mwcc/mwld (#32) * Override GetFileAttributesA for MWCC license.dat * Add WIN_FUNC to FileTimeToLocalFileTime * Use callee_pop_aggregate_return(0) * Lexically normalize paths --- common.h | 2 +- dll/kernel32.cpp | 9 ++++++++- files.cpp | 4 ++-- files.h | 5 +++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/common.h b/common.h index 5c2cda5..b150afe 100644 --- a/common.h +++ b/common.h @@ -8,7 +8,7 @@ // On Windows, the incoming stack is aligned to a 4 byte boundary. // force_align_arg_pointer will realign the stack to match GCC's 16 byte alignment. -#define WIN_ENTRY __attribute__((force_align_arg_pointer)) +#define WIN_ENTRY __attribute__((force_align_arg_pointer, callee_pop_aggregate_return(0))) #define WIN_FUNC WIN_ENTRY __attribute__((stdcall)) #define DEBUG_LOG(...) wibo::debug_log(__VA_ARGS__) diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index 658644c..01a736d 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -565,6 +565,13 @@ namespace kernel32 { unsigned int WIN_FUNC GetFileAttributesA(const char *lpFileName) { auto path = files::pathFromWindows(lpFileName); DEBUG_LOG("GetFileAttributesA(%s)... (%s)\n", lpFileName, path.c_str()); + + // See ole32::CoCreateInstance + if (endsWith(path, "/license.dat")) { + DEBUG_LOG("MWCC license override\n"); + return 0x80; // FILE_ATTRIBUTE_NORMAL + } + auto status = std::filesystem::status(path); wibo::lastError = 0; @@ -868,7 +875,7 @@ namespace kernel32 { return 1; } - int FileTimeToLocalFileTime(const FILETIME *lpFileTime, FILETIME *lpLocalFileTime) { + int WIN_FUNC FileTimeToLocalFileTime(const FILETIME *lpFileTime, FILETIME *lpLocalFileTime) { DEBUG_LOG("FileTimeToLocalFileTime\n"); // we live on Iceland *lpLocalFileTime = *lpFileTime; diff --git a/files.cpp b/files.cpp index b395e75..fbb0d88 100644 --- a/files.cpp +++ b/files.cpp @@ -22,7 +22,7 @@ namespace files { // Return as-is if it exists, else traverse the filesystem looking for // a path that matches case insensitively - std::filesystem::path path = std::filesystem::path(str); + std::filesystem::path path = std::filesystem::path(str).lexically_normal(); if (std::filesystem::exists(path)) { return path; } @@ -58,7 +58,7 @@ namespace files { } std::string pathToWindows(const std::filesystem::path &path) { - std::string str = path; + std::string str = path.lexically_normal(); if (path.is_absolute()) { str.insert(0, "Z:"); diff --git a/files.h b/files.h index 158f32e..1023b84 100644 --- a/files.h +++ b/files.h @@ -1,4 +1,5 @@ #include +#include namespace files { std::filesystem::path pathFromWindows(const char *inStr); @@ -9,3 +10,7 @@ namespace files { unsigned int setStdHandle(uint32_t nStdHandle, void *hHandle); void init(); } + +static bool endsWith(const std::string &str, const std::string &suffix) { + return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; +}