aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSlawomir Cygan <slawomir.cygan@intel.com>2019-10-21 12:36:53 +0200
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2019-12-10 10:08:45 -0700
commit8c4e6525314edbb879c66a710e4e69aa530a47f9 (patch)
tree23d696b0632db2450123fbd3288ed6be2593351d
parent5ceb7be9a3bf86f34ade5a7f72459248d99a4b76 (diff)
downloadusermoji-8c4e6525314edbb879c66a710e4e69aa530a47f9.tar.xz
vulkaninfo: load user32.dll dynamically
Instead of depending on user32.dll, this library is now loaded dynamically. This change is needed to redistribute vulkaninfo.exe as a part of "universal" windows driverm, by making vulkaninfo pass the 'ApiValidator' test. See more here https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/validating-universal-drivers Change-Id: I79a28cbb5d761b33ab673994a2b578c4044f5a90 Author: Kamil Szypryt <kamil.szypryt@intel.com>
-rw-r--r--vulkaninfo/vulkaninfo.cpp21
-rw-r--r--vulkaninfo/vulkaninfo.h105
2 files changed, 108 insertions, 18 deletions
diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp
index fae81475..bab61ee7 100644
--- a/vulkaninfo/vulkaninfo.cpp
+++ b/vulkaninfo/vulkaninfo.cpp
@@ -28,6 +28,19 @@
#include "vulkaninfo.hpp"
+#ifdef _WIN32
+// Initialize User32 pointers
+PFN_AdjustWindowRect User32Handles::pfnAdjustWindowRect = nullptr;
+PFN_CreateWindowExA User32Handles::pfnCreateWindowExA = nullptr;
+PFN_DefWindowProcA User32Handles::pfnDefWindowProcA = nullptr;
+PFN_DestroyWindow User32Handles::pfnDestroyWindow = nullptr;
+PFN_LoadIconA User32Handles::pfnLoadIconA = nullptr;
+PFN_RegisterClassExA User32Handles::pfnRegisterClassExA = nullptr;
+
+HMODULE User32Handles::user32DllHandle = nullptr;
+
+#endif
+
// =========== Dump Functions ========= //
void DumpExtensions(Printer &p, std::string layer_name, std::vector<VkExtensionProperties> extensions) {
@@ -676,6 +689,11 @@ void print_usage(const char *argv0) {
int main(int argc, char **argv) {
#ifdef _WIN32
if (ConsoleIsExclusive()) ConsoleEnlarge();
+ if (!LoadUser32Dll()) {
+ fprintf(stderr, "Failed to load user32.dll library!\n");
+ WAIT_FOR_CONSOLE_DESTROY;
+ exit(1);
+ }
#endif
uint32_t selected_gpu = 0;
@@ -790,6 +808,9 @@ int main(int argc, char **argv) {
#endif
WAIT_FOR_CONSOLE_DESTROY;
+#ifdef _WIN32
+ FreeUser32Dll();
+#endif
return 0;
}
diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h
index 060ef2ce..c0b02825 100644
--- a/vulkaninfo/vulkaninfo.h
+++ b/vulkaninfo/vulkaninfo.h
@@ -104,6 +104,73 @@ static int ConsoleIsExclusive(void) {
exit(-1); \
} while (0)
+#ifdef _WIN32
+
+#define _CALL_PFN(pfn, ...) (pfn)
+#define CALL_PFN(fncName) _CALL_PFN(User32Handles::pfn##fncName)
+
+#define _CHECK_PFN(pfn, fncName) \
+ do { \
+ if (pfn == nullptr) { \
+ fprintf(stderr, "Failed to get %s function address!\n", fncName); \
+ WAIT_FOR_CONSOLE_DESTROY; \
+ exit(1); \
+ } \
+ } while (false)
+
+#define _SET_PFN(dllHandle, pfnType, pfn, fncName) \
+ do { \
+ pfn = reinterpret_cast<pfnType>(GetProcAddress(dllHandle, fncName)); \
+ _CHECK_PFN(pfn, fncName); \
+ } while (false)
+
+#define SET_PFN(dllHandle, fncName) _SET_PFN(User32Handles::dllHandle, PFN_##fncName, User32Handles::pfn##fncName, #fncName)
+
+// User32 function declarations
+typedef WINUSERAPI BOOL(WINAPI *PFN_AdjustWindowRect)(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL);
+typedef WINUSERAPI HWND(WINAPI *PFN_CreateWindowExA)(_In_ DWORD, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ DWORD, _In_ int, _In_ int,
+ _In_ int, _In_ int, _In_opt_ HWND, _In_opt_ HMENU, _In_opt_ HINSTANCE,
+ _In_opt_ LPVOID);
+typedef WINUSERAPI LRESULT(WINAPI *PFN_DefWindowProcA)(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM);
+typedef WINUSERAPI BOOL(WINAPI *PFN_DestroyWindow)(_In_ HWND);
+typedef WINUSERAPI HICON(WINAPI *PFN_LoadIconA)(_In_opt_ HINSTANCE, _In_ LPCSTR);
+typedef WINUSERAPI ATOM(WINAPI *PFN_RegisterClassExA)(_In_ CONST WNDCLASSEXA *);
+
+struct User32Handles {
+ // User32 function pointers
+ static PFN_AdjustWindowRect pfnAdjustWindowRect;
+ static PFN_CreateWindowExA pfnCreateWindowExA;
+ static PFN_DefWindowProcA pfnDefWindowProcA;
+ static PFN_DestroyWindow pfnDestroyWindow;
+ static PFN_LoadIconA pfnLoadIconA;
+ static PFN_RegisterClassExA pfnRegisterClassExA;
+
+ // User32 dll handle
+ static HMODULE user32DllHandle;
+};
+
+bool LoadUser32Dll() {
+ User32Handles::user32DllHandle = LoadLibraryExA("user32.dll", nullptr, 0);
+ if (User32Handles::user32DllHandle != NULL) {
+ SET_PFN(user32DllHandle, AdjustWindowRect);
+ SET_PFN(user32DllHandle, CreateWindowExA);
+ SET_PFN(user32DllHandle, DefWindowProcA);
+ SET_PFN(user32DllHandle, DestroyWindow);
+ SET_PFN(user32DllHandle, LoadIconA);
+ SET_PFN(user32DllHandle, RegisterClassExA);
+ return true;
+ }
+ return false;
+}
+
+void FreeUser32Dll() {
+ if (User32Handles::user32DllHandle != nullptr) {
+ FreeLibrary(User32Handles::user32DllHandle);
+ User32Handles::user32DllHandle = nullptr;
+ }
+}
+#endif // _WIN32
+
static const char *VkResultString(VkResult err);
const char *app_short_name = "vulkaninfo";
@@ -414,7 +481,9 @@ struct AppInstance {
#ifdef VK_USE_PLATFORM_WIN32_KHR
// MS-Windows event handling function:
-LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return (DefWindowProc(hWnd, uMsg, wParam, lParam)); }
+LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ return (CALL_PFN(DefWindowProcA)(hWnd, uMsg, wParam, lParam));
+}
static void AppCreateWin32Window(AppInstance &inst) {
inst.h_instance = GetModuleHandle(nullptr);
@@ -428,34 +497,34 @@ static void AppCreateWin32Window(AppInstance &inst) {
win_class.cbClsExtra = 0;
win_class.cbWndExtra = 0;
win_class.hInstance = inst.h_instance;
- win_class.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
+ win_class.hIcon = CALL_PFN(LoadIconA)(nullptr, IDI_APPLICATION);
win_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
win_class.lpszMenuName = nullptr;
win_class.lpszClassName = app_short_name;
win_class.hInstance = inst.h_instance;
- win_class.hIconSm = LoadIcon(nullptr, IDI_WINLOGO);
+ win_class.hIconSm = CALL_PFN(LoadIconA)(nullptr, IDI_WINLOGO);
// Register window class:
- if (!RegisterClassEx(&win_class)) {
+ if (!CALL_PFN(RegisterClassExA)(&win_class)) {
// It didn't work, so try to give a useful error:
fprintf(stderr, "Failed to register the window class!\n");
exit(1);
}
// Create window with the registered class:
RECT wr = {0, 0, inst.width, inst.height};
- AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
- inst.h_wnd = CreateWindowEx(0,
- app_short_name, // class name
- app_short_name, // app name
- // WS_VISIBLE | WS_SYSMENU |
- WS_OVERLAPPEDWINDOW, // window style
- 100, 100, // x/y coords
- wr.right - wr.left, // width
- wr.bottom - wr.top, // height
- nullptr, // handle to parent
- nullptr, // handle to menu
- inst.h_instance, // hInstance
- nullptr); // no extra parameters
+ CALL_PFN(AdjustWindowRect)(&wr, WS_OVERLAPPEDWINDOW, FALSE);
+ inst.h_wnd = CALL_PFN(CreateWindowExA)(0,
+ app_short_name, // class name
+ app_short_name, // app name
+ // WS_VISIBLE | WS_SYSMENU |
+ WS_OVERLAPPEDWINDOW, // window style
+ 100, 100, // x/y coords
+ wr.right - wr.left, // width
+ wr.bottom - wr.top, // height
+ nullptr, // handle to parent
+ nullptr, // handle to menu
+ inst.h_instance, // hInstance
+ nullptr); // no extra parameters
if (!inst.h_wnd) {
// It didn't work, so try to give a useful error:
fprintf(stderr, "Failed to create a window!\n");
@@ -477,7 +546,7 @@ static VkSurfaceKHR AppCreateWin32Surface(AppInstance &inst) {
return surface;
}
-static void AppDestroyWin32Window(AppInstance &inst) { DestroyWindow(inst.h_wnd); }
+static void AppDestroyWin32Window(AppInstance &inst) { CALL_PFN(DestroyWindow)(inst.h_wnd); }
#endif // VK_USE_PLATFORM_WIN32_KHR
//-----------------------------------------------------------