1 /* 2 * PROJECT: appshim_apitest 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Test to document the hooks used by various shims in AcLayers 5 * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include <ntstatus.h> 9 #define WIN32_NO_STATUS 10 #include <windows.h> 11 #include <ndk/rtlfuncs.h> 12 #include <strsafe.h> 13 #include "wine/test.h" 14 15 #include "appshim_apitest.h" 16 17 static DWORD g_WinVersion; 18 19 20 typedef struct expect_shim_hook 21 { 22 const char* Library; 23 const char* Function; 24 } expect_shim_hook; 25 26 typedef struct expect_shim_data 27 { 28 const WCHAR* ShimName; 29 DWORD MinVersion; 30 expect_shim_hook hooks[6]; 31 } expect_shim_data; 32 33 34 static expect_shim_data data[] = 35 { 36 { 37 L"ForceDXSetupSuccess", 38 0, 39 { 40 { "KERNEL32.DLL", "LoadLibraryA" }, 41 { "KERNEL32.DLL", "LoadLibraryW" }, 42 { "KERNEL32.DLL", "LoadLibraryExA" }, 43 { "KERNEL32.DLL", "LoadLibraryExW" }, 44 { "KERNEL32.DLL", "GetProcAddress" }, 45 { "KERNEL32.DLL", "FreeLibrary" }, 46 } 47 }, 48 { 49 L"VerifyVersionInfoLite", 50 _WIN32_WINNT_VISTA, 51 { 52 { "KERNEL32.DLL", "VerifyVersionInfoA" }, 53 { "KERNEL32.DLL", "VerifyVersionInfoW" }, 54 } 55 }, 56 /* Show that it is not case sensitive */ 57 { 58 L"VeRiFyVeRsIoNInFoLiTe", 59 _WIN32_WINNT_VISTA, 60 { 61 { "KERNEL32.DLL", "VerifyVersionInfoA" }, 62 { "KERNEL32.DLL", "VerifyVersionInfoW" }, 63 } 64 }, 65 }; 66 67 static DWORD count_shims(expect_shim_data* data) 68 { 69 DWORD num; 70 for (num = 0; num < _countof(data->hooks) && data->hooks[num].Library;) 71 { 72 ++num; 73 } 74 return num; 75 } 76 77 static const char* safe_str(const char* ptr) 78 { 79 static char buffer[2][30]; 80 static int index = 0; 81 if (HIWORD(ptr)) 82 return ptr; 83 84 index ^= 1; 85 StringCchPrintfA(buffer[index], _countof(buffer[index]), "#%Id", (intptr_t)ptr); 86 return buffer[index]; 87 } 88 89 START_TEST(layer_hooks) 90 { 91 RTL_OSVERSIONINFOEXW rtlinfo = {0}; 92 size_t n, h; 93 94 tGETHOOKAPIS pGetHookAPIs = LoadShimDLL2(L"AcLayers.dll"); 95 if (!pGetHookAPIs) 96 return; 97 98 rtlinfo.dwOSVersionInfoSize = sizeof(rtlinfo); 99 RtlGetVersion((PRTL_OSVERSIONINFOW)&rtlinfo); 100 g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; 101 102 103 104 for (n = 0; n < _countof(data); ++n) 105 { 106 expect_shim_data* current = data + n; 107 DWORD num_shims = 0, expected_shims = count_shims(current); 108 109 PHOOKAPI hook = pGetHookAPIs("", current->ShimName, &num_shims); 110 111 if (current->MinVersion > g_WinVersion && !hook) 112 { 113 skip("Shim %s not present\n", wine_dbgstr_w(current->ShimName)); 114 continue; 115 } 116 117 ok(!!hook, "Expected a valid pointer, got nothing for %s\n", wine_dbgstr_w(current->ShimName)); 118 ok(num_shims == expected_shims, "Expected %u shims, got %u for %s\n", 119 expected_shims, num_shims, wine_dbgstr_w(current->ShimName)); 120 for (h = 0; h < min(num_shims, expected_shims); ++h) 121 { 122 expect_shim_hook* expect_hk = current->hooks + h; 123 PHOOKAPI got_hk = hook+h; 124 int lib = lstrcmpA(expect_hk->Library, got_hk->LibraryName); 125 int fn = lstrcmpA(safe_str(expect_hk->Function), safe_str(got_hk->FunctionName)); 126 ok(lib == 0, "Expected LibraryName to be %s, was: %s for %s\n", 127 expect_hk->Library, got_hk->LibraryName, wine_dbgstr_w(current->ShimName)); 128 ok(fn == 0, "Expected FunctionName to be %s, was: %s for %s\n", 129 safe_str(expect_hk->Function), safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName)); 130 } 131 if (num_shims > expected_shims) 132 { 133 for (h = expected_shims; h < num_shims; ++h) 134 { 135 PHOOKAPI got_hk = hook+h; 136 137 ok(0, "Extra shim: %s!%s for %s\n", 138 got_hk->LibraryName, safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName)); 139 } 140 } 141 else 142 { 143 for (h = num_shims; h < expected_shims; ++h) 144 { 145 expect_shim_hook* expect_hk = current->hooks + h; 146 147 ok(0, "Missing shim: %s!%s for %s\n", 148 expect_hk->Library, safe_str(expect_hk->Function), wine_dbgstr_w(current->ShimName)); 149 } 150 } 151 } 152 } 153