[Win] Fix GetModulePath to return correct Dawn DLL path
GetHModulePath ignores its 'module' parameter and always returns
the executable path instead of the Dawn path.
CL fixes Dawn's GetHMmodulePath to forward the module parameter to
the OS GetModuleFileName. We use the more convenient __ImageBase
compiler intrinsic to get the current module's HINSTANCE.
Improve DynamicLib::Open error string by including filename of the
library which failed to load.
Change-Id: I7e0bca05b48b139b26ecb4ade6ff76130a61eaa6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/247754
Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/common/DynamicLib.cpp b/src/dawn/common/DynamicLib.cpp
index d700aa0..c1457df 100644
--- a/src/dawn/common/DynamicLib.cpp
+++ b/src/dawn/common/DynamicLib.cpp
@@ -81,7 +81,8 @@
mHandle = LoadLibraryA(filename.c_str());
#endif
if (mHandle == nullptr && error != nullptr) {
- *error = "Windows Error: " + std::to_string(GetLastError());
+ *error =
+ "DynamicLib.Open: " + filename + " Windows Error: " + std::to_string(GetLastError());
}
#elif DAWN_PLATFORM_IS(POSIX)
mHandle = dlopen(filename.c_str(), RTLD_NOW);
diff --git a/src/dawn/common/SystemUtils.cpp b/src/dawn/common/SystemUtils.cpp
index 9e1389d..b27e7b2 100644
--- a/src/dawn/common/SystemUtils.cpp
+++ b/src/dawn/common/SystemUtils.cpp
@@ -105,7 +105,7 @@
#if DAWN_PLATFORM_IS(WINDOWS)
std::optional<std::string> GetHModulePath(HMODULE module) {
std::array<char, MAX_PATH> executableFileBuf;
- DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(),
+ DWORD executablePathLen = GetModuleFileNameA(module, executableFileBuf.data(),
static_cast<DWORD>(executableFileBuf.size()));
if (executablePathLen == 0) {
return {};
@@ -179,20 +179,20 @@
return absolutePath.data();
}
#elif DAWN_PLATFORM_IS(WINDOWS)
+// To get the module path, use the __ImageBase pseudo-variable as described in
+// https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483. __ImageBase
+// must be forward declared here, outside of GetModulePath.
+extern "C" IMAGE_DOS_HEADER __ImageBase;
+
std::optional<std::string> GetModulePath() {
- static int placeholderSymbol = 0;
- HMODULE module = nullptr;
-// GetModuleHandleEx is unavailable on UWP
#if defined(DAWN_IS_WINUWP)
+ // GetModuleHandleEx is unavailable on UWP
return {};
#else
- if (!GetModuleHandleExA(
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- reinterpret_cast<LPCSTR>(&placeholderSymbol), &module)) {
- return {};
- }
-#endif
+ // The HMODULE of the DLL is the same as the module's base address
+ const HMODULE module = reinterpret_cast<HMODULE>(&__ImageBase);
return GetHModulePath(module);
+#endif
}
#elif DAWN_PLATFORM_IS(FUCHSIA)
std::optional<std::string> GetModulePath() {