From fc503b7c083751d43c07b317f70729be438e0f45 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Wed, 14 Jun 2017 18:38:41 +0200 Subject: [PATCH] [APPSHIM_APITEST] Add test for shims in AcGenral --- .../rostests/apitests/appshim/CMakeLists.txt | 4 +- .../apitests/appshim/appshim_apitest.h | 35 +++++ modules/rostests/apitests/appshim/dispmode.c | 62 +++----- .../rostests/apitests/appshim/genral_hooks.c | 138 ++++++++++++++++++ modules/rostests/apitests/appshim/testlist.c | 2 + .../rostests/apitests/appshim/versionlie.c | 100 +++++++++---- 6 files changed, 270 insertions(+), 71 deletions(-) create mode 100644 modules/rostests/apitests/appshim/appshim_apitest.h create mode 100644 modules/rostests/apitests/appshim/genral_hooks.c diff --git a/modules/rostests/apitests/appshim/CMakeLists.txt b/modules/rostests/apitests/appshim/CMakeLists.txt index 48a4db166cf..fa7a76527b6 100644 --- a/modules/rostests/apitests/appshim/CMakeLists.txt +++ b/modules/rostests/apitests/appshim/CMakeLists.txt @@ -3,8 +3,10 @@ add_definitions(-D__ROS_LONG64__) list(APPEND SOURCE dispmode.c + genral_hooks.c versionlie.c - testlist.c) + testlist.c + appshim_apitest.h) add_executable(appshim_apitest ${SOURCE}) set_module_type(appshim_apitest win32cui) diff --git a/modules/rostests/apitests/appshim/appshim_apitest.h b/modules/rostests/apitests/appshim/appshim_apitest.h new file mode 100644 index 00000000000..1f3a0f6bb23 --- /dev/null +++ b/modules/rostests/apitests/appshim/appshim_apitest.h @@ -0,0 +1,35 @@ +#ifndef APPSHIM_APITEST_H +#define APPSHIM_APITEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct tagHOOKAPI { + PCSTR LibraryName; + PCSTR FunctionName; + PVOID ReplacementFunction; + PVOID OriginalFunction; + PVOID Unk1; + PVOID Unk2; +} HOOKAPI, *PHOOKAPI; + +typedef BOOL (WINAPI* tSDBGETAPPPATCHDIR)(PVOID hsdb, LPWSTR path, DWORD size); +typedef PHOOKAPI (WINAPI* tGETHOOKAPIS)(LPCSTR szCommandLine, LPCWSTR wszShimName, PDWORD pdwHookCount); + + +/* versionlie.c */ +void expect_shim_imp(PHOOKAPI hook, PCSTR library, PCSTR function, PCSTR shim, int* same); +#define expect_shim (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_shim_imp + + +BOOL LoadShimDLL(PCWSTR ShimDll, HMODULE* module, tGETHOOKAPIS* ppGetHookAPIs); +tGETHOOKAPIS LoadShimDLL2(PCWSTR ShimDll); + + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // APPHELP_APITEST_H diff --git a/modules/rostests/apitests/appshim/dispmode.c b/modules/rostests/apitests/appshim/dispmode.c index 0f8b3aaaeaf..68c3b2f190a 100644 --- a/modules/rostests/apitests/appshim/dispmode.c +++ b/modules/rostests/apitests/appshim/dispmode.c @@ -2,7 +2,7 @@ * PROJECT: appshim_apitest * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: Tests for display mode shims - * COPYRIGHT: Copyright 2016 Mark Jansen (mark.jansen@reactos.org) + * COPYRIGHT: Copyright 2016-2018 Mark Jansen (mark.jansen@reactos.org) */ #include @@ -17,18 +17,16 @@ #include #include "wine/test.h" #include "apitest_iathook.h" +#include "appshim_apitest.h" static DWORD g_Version; #define WINVER_ANY 0 - -/* apphelp.dll */ -static BOOL(WINAPI* pSdbGetAppPatchDir)(PVOID, LPWSTR, DWORD); - /* aclayers.dll / acgenral.dll */ -static PVOID(WINAPI* pGetHookAPIs)(LPCSTR, LPCWSTR, PDWORD); +static tGETHOOKAPIS pGetHookAPIs; static BOOL(WINAPI* pNotifyShims)(DWORD fdwReason, PVOID ptr); + DWORD get_module_version(HMODULE mod) { DWORD dwVersion = 0; @@ -123,14 +121,6 @@ void WINAPI mSetThemeAppProperties(DWORD dwFlags) } -static const WCHAR* shim_dll(const WCHAR* name) -{ - static WCHAR buf[MAX_PATH]; - pSdbGetAppPatchDir(NULL, buf, MAX_PATH); - StringCchCatW(buf, _countof(buf), name); - return buf; -} - static void pre_8bit(void) { g_ChangeCount = 0; @@ -379,18 +369,18 @@ static struct test_info } tests[] = { /* Success */ - { "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit, post_8bit, post_8bit_no }, - { "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp,pre_8bit, post_8bit, post_8bit_no }, - { "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, - { "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, - { "DisableThemes", L"\\acgenral.dll", WINVER_ANY, 1, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, - { "DisableThemes", L"\\acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, + { "Force8BitColor", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit, post_8bit, post_8bit_no }, + { "Force8BitColor", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp,pre_8bit, post_8bit, post_8bit_no }, + { "Force640x480", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, + { "Force640x480", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, + { "DisableThemes", L"acgenral.dll", WINVER_ANY, 1, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, + { "DisableThemes", L"acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, /* No need to change anything */ - { "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, - { "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, - { "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, - { "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, + { "Force8BitColor", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, + { "Force8BitColor", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, + { "Force640x480", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, + { "Force640x480", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, }; @@ -398,16 +388,15 @@ static void run_test(size_t n, BOOL unload) { BOOL ret; HMODULE dll; - const WCHAR* buf = shim_dll(tests[n].dll); - dll = LoadLibraryW(shim_dll(tests[n].dll)); - pGetHookAPIs = (void*)GetProcAddress(dll, "GetHookAPIs"); + if (!LoadShimDLL(tests[n].dll, &dll, &pGetHookAPIs)) + pGetHookAPIs = NULL; pNotifyShims = (void*)GetProcAddress(dll, "NotifyShims"); if (!pGetHookAPIs || !pNotifyShims) { - skip("aclayers.dll not loaded, or does not export GetHookAPIs or pNotifyShims (%s, %p, %p)\n", - tests[n].name, pGetHookAPIs, pNotifyShims); + skip("%s not loaded, or does not export GetHookAPIs or pNotifyShims (%s, %p, %p)\n", + wine_dbgstr_w(tests[n].dll), tests[n].name, pGetHookAPIs, pNotifyShims); return; } @@ -435,8 +424,8 @@ static void run_test(size_t n, BOOL unload) FreeLibrary(dll); if (unload) { - dll = GetModuleHandleW(buf); - ok(dll == NULL, "Unable to unload %s\n", wine_dbgstr_w(buf)); + dll = GetModuleHandleW(tests[n].dll); + ok(dll == NULL, "Unable to unload %s\n", wine_dbgstr_w(tests[n].dll)); } } @@ -448,21 +437,14 @@ START_TEST(dispmode) int argc; char **argv; - pSdbGetAppPatchDir = (void*)GetProcAddress(dll, "SdbGetAppPatchDir"); - if (!pSdbGetAppPatchDir) - { - skip("apphelp.dll not loaded, or does not export SdbGetAppPatchDir\n"); - return; - } - argc = winetest_get_mainargs(&argv); if (argc < 3) { WCHAR path[MAX_PATH]; GetModuleFileNameW(NULL, path, _countof(path)); - dll = GetModuleHandleW(shim_dll(L"\\aclayers.dll")); + dll = GetModuleHandleW(L"aclayers.dll"); if (!dll) - dll = GetModuleHandleW(shim_dll(L"\\acgenral.dll")); + dll = GetModuleHandleW(L"acgenral.dll"); if (dll != NULL) trace("Loaded under a shim, running each test in it's own process\n"); diff --git a/modules/rostests/apitests/appshim/genral_hooks.c b/modules/rostests/apitests/appshim/genral_hooks.c new file mode 100644 index 00000000000..72680c75a88 --- /dev/null +++ b/modules/rostests/apitests/appshim/genral_hooks.c @@ -0,0 +1,138 @@ +/* + * PROJECT: appshim_apitest + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test to document the hooks used by various shims in AcGenral + * COPYRIGHT: Copyright 2017-2018 Mark Jansen (mark.jansen@reactos.org) + */ + +#include +#define WIN32_NO_STATUS +#include +#include +#include +#include "wine/test.h" + +#include "appshim_apitest.h" + +static DWORD g_WinVersion; +#define WINVER_WIN8 0x0602 + + +typedef struct expect_shim_hook +{ + const char* Library; + const char* Function; +} expect_shim_hook; + +typedef struct expect_shim_data +{ + const WCHAR* ShimName; + DWORD MinVersion; + expect_shim_hook hooks[4]; +} expect_shim_data; + + +static expect_shim_data data[] = +{ + { + L"IgnoreChromeSandbox", + WINVER_WIN8, + { + { "KERNEL32.DLL", "CreateProcessW" }, + } + }, + { + L"AddProcessParametersFlags", + 0, + /* No hooks */ + }, + { + L"DisableThemes", + 0, + /* No hooks */ + }, +}; + +static DWORD count_shims(expect_shim_data* data) +{ + DWORD num; + for (num = 0; num < _countof(data->hooks) && data->hooks[num].Library;) + { + ++num; + } + return num; +} + +static const char* safe_str(const char* ptr) +{ + static char buffer[2][30]; + static int index = 0; + if (HIWORD(ptr)) + return ptr; + + index ^= 1; + StringCchPrintfA(buffer[index], _countof(buffer[index]), "#%d", (int)ptr); + return buffer[index]; +} + +START_TEST(genral_hooks) +{ + RTL_OSVERSIONINFOEXW rtlinfo = {0}; + size_t n, h; + + tGETHOOKAPIS pGetHookAPIs = LoadShimDLL2(L"AcGenral.dll"); + if (!pGetHookAPIs) + return; + + rtlinfo.dwOSVersionInfoSize = sizeof(rtlinfo); + RtlGetVersion((PRTL_OSVERSIONINFOW)&rtlinfo); + g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; + + + + for (n = 0; n < _countof(data); ++n) + { + expect_shim_data* current = data + n; + DWORD num_shims = 0, expected_shims = count_shims(current); + + PHOOKAPI hook = pGetHookAPIs("", current->ShimName, &num_shims); + + if (current->MinVersion > g_WinVersion && !hook) + continue; + + ok(!!hook, "Expected a valid pointer, got nothing for %s\n", wine_dbgstr_w(current->ShimName)); + ok(num_shims == expected_shims, "Expected %u shims, got %u for %s\n", + expected_shims, num_shims, wine_dbgstr_w(current->ShimName)); + for (h = 0; h < min(num_shims, expected_shims); ++h) + { + expect_shim_hook* expect_hk = current->hooks + h; + PHOOKAPI got_hk = hook+h; + int lib = lstrcmpA(expect_hk->Library, got_hk->LibraryName); + int fn = lstrcmpA(safe_str(expect_hk->Function), safe_str(got_hk->FunctionName)); + ok(lib == 0, "Expected LibraryName to be %s, was: %s for %s\n", + expect_hk->Library, got_hk->LibraryName, wine_dbgstr_w(current->ShimName)); + ok(fn == 0, "Expected FunctionName to be %s, was: %s for %s\n", + safe_str(expect_hk->Function), safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName)); + } + if (num_shims > expected_shims) + { + for (h = expected_shims; h < num_shims; ++h) + { + PHOOKAPI got_hk = hook+h; + + ok(0, "Extra shim: %s!%s for %s\n", + got_hk->LibraryName, safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName)); + } + } + else + { + for (h = num_shims; h < expected_shims; ++h) + { + expect_shim_hook* expect_hk = current->hooks + h; + + ok(0, "Missing shim: %s!%s for %s\n", + expect_hk->Library, safe_str(expect_hk->Function), wine_dbgstr_w(current->ShimName)); + } + } + } +} diff --git a/modules/rostests/apitests/appshim/testlist.c b/modules/rostests/apitests/appshim/testlist.c index b3b8a216dbf..2b2e692a3db 100644 --- a/modules/rostests/apitests/appshim/testlist.c +++ b/modules/rostests/apitests/appshim/testlist.c @@ -4,11 +4,13 @@ #include extern void func_dispmode(void); +extern void func_genral_hooks(void); extern void func_versionlie(void); const struct test winetest_testlist[] = { { "dispmode", func_dispmode }, + { "genral_hooks", func_genral_hooks }, { "versionlie", func_versionlie }, { 0, 0 } }; diff --git a/modules/rostests/apitests/appshim/versionlie.c b/modules/rostests/apitests/appshim/versionlie.c index ad38731796c..5322b8a03e3 100644 --- a/modules/rostests/apitests/appshim/versionlie.c +++ b/modules/rostests/apitests/appshim/versionlie.c @@ -2,7 +2,7 @@ * PROJECT: appshim_apitest * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: Tests for versionlie shims - * COPYRIGHT: Copyright 2015 Mark Jansen (mark.jansen@reactos.org) + * COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org) */ #include @@ -13,20 +13,12 @@ #else #include #endif -#include #include "wine/test.h" +#include -typedef struct tagHOOKAPI { - PCSTR LibraryName; - PCSTR FunctionName; - PVOID ReplacementFunction; - PVOID OriginalFunction; - PVOID Unk1; - PVOID Unk2; -} HOOKAPI, *PHOOKAPI; +#include "appshim_apitest.h" -static BOOL (WINAPI* pSdbGetAppPatchDir)(PVOID,LPWSTR,DWORD); -static PHOOKAPI (WINAPI* pGetHookAPIs)(LPCSTR,LPCWSTR,PDWORD); +static tGETHOOKAPIS pGetHookAPIs; static DWORD g_WinVersion; @@ -48,7 +40,7 @@ typedef BOOL(WINAPI* GETVERSIONEXAPROC)(LPOSVERSIONINFOEXA); typedef BOOL(WINAPI* GETVERSIONEXWPROC)(LPOSVERSIONINFOEXW); typedef DWORD(WINAPI* GETVERSIONPROC)(void); -static void expect_shim_imp(PHOOKAPI hook, PCSTR library, PCSTR function, PCSTR shim, int* same) +void expect_shim_imp(PHOOKAPI hook, PCSTR library, PCSTR function, PCSTR shim, int* same) { int lib = lstrcmpA(library, hook->LibraryName); int fn = lstrcmpA(function, hook->FunctionName); @@ -86,7 +78,7 @@ static void verify_shima_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR sh winetest_ok(info->dwPlatformId == v2.dwPlatformId, "Expected dwPlatformId to be equal, was: %u, %u for %s\n", info->dwPlatformId, v2.dwPlatformId, shim); if (info->wServicePackMajor) - sprintf(szCSDVersion, "Service Pack %u", info->wServicePackMajor); + StringCchPrintfA(szCSDVersion, _countof(szCSDVersion), "Service Pack %u", info->wServicePackMajor); winetest_ok(lstrcmpA(szCSDVersion, v2.szCSDVersion) == 0, "Expected szCSDVersion to be equal, was: %s, %s for %s\n", szCSDVersion, v2.szCSDVersion, shim); if (v1.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)) @@ -150,7 +142,6 @@ static void verify_shimw_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR sh } if (ok1 && ok2) { - static const WCHAR szCSDFMT[] = {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','%','u',0}; WCHAR szCSDVersion[128] = { 0 }; winetest_ok(v1.dwOSVersionInfoSize == v2.dwOSVersionInfoSize, "Expected dwOSVersionInfoSize to be equal, was: %u, %u for %s\n", v1.dwOSVersionInfoSize, v2.dwOSVersionInfoSize, shim); winetest_ok(info->dwMajorVersion == v2.dwMajorVersion, "Expected dwMajorVersion to be equal, was: %u, %u for %s\n", info->dwMajorVersion, v2.dwMajorVersion, shim); @@ -159,7 +150,7 @@ static void verify_shimw_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR sh winetest_ok(info->dwPlatformId == v2.dwPlatformId, "Expected dwPlatformId to be equal, was: %u, %u for %s\n", info->dwPlatformId, v2.dwPlatformId, shim); if (info->wServicePackMajor) - swprintf(szCSDVersion, szCSDFMT, info->wServicePackMajor); + StringCchPrintfW(szCSDVersion, _countof(szCSDVersion), L"Service Pack %u", info->wServicePackMajor); winetest_ok(lstrcmpW(szCSDVersion, v2.szCSDVersion) == 0, "Expected szCSDVersion to be equal, was: %s, %s for %s\n", wine_dbgstr_w(szCSDVersion), wine_dbgstr_w(v2.szCSDVersion), shim); if (v1.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW)) @@ -209,7 +200,6 @@ static void verify_shim_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR shi } -#define expect_shim (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_shim_imp #define verify_shima (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_shima_imp #define verify_shimw (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_shimw_imp #define verify_shim (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_shim_imp @@ -303,28 +293,78 @@ DWORD get_host_winver(void) return (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; } -START_TEST(versionlie) +BOOL LoadShimDLL(PCWSTR ShimDll, HMODULE* module, tGETHOOKAPIS* ppGetHookAPIs) { - HMODULE dll = LoadLibraryA("apphelp.dll"); - WCHAR buf[MAX_PATH]; - WCHAR aclayers[] = {'\\','a','c','l','a','y','e','r','s','.','d','l','l',0}; - pSdbGetAppPatchDir = (void*)GetProcAddress(dll, "SdbGetAppPatchDir"); + static tSDBGETAPPPATCHDIR pSdbGetAppPatchDir = NULL; + HMODULE dll; + WCHAR buf[MAX_PATH] = {0}; if (!pSdbGetAppPatchDir) { - skip("apphelp.dll not loaded, or does not export SdbGetAppPatchDir\n"); - return; + dll = LoadLibraryA("apphelp.dll"); + pSdbGetAppPatchDir = (tSDBGETAPPPATCHDIR)GetProcAddress(dll, "SdbGetAppPatchDir"); + + if (!pSdbGetAppPatchDir) + { + skip("Unable to retrieve SdbGetAppPatchDir (%p, %p)\n", dll, pSdbGetAppPatchDir); + } + } + + if (!pSdbGetAppPatchDir || !pSdbGetAppPatchDir(NULL, buf, MAX_PATH)) + { + skip("Unable to retrieve AppPatch dir, building manually\n"); + if (!GetSystemWindowsDirectoryW(buf, MAX_PATH)) + { + skip("Unable to build AppPatch name(1)\n"); + return FALSE; + } + if (!SUCCEEDED(StringCchCatW(buf, _countof(buf), L"\\AppPatch"))) + { + skip("Unable to build AppPatch name(2)\n"); + return FALSE; + } + } + if (!SUCCEEDED(StringCchCatW(buf, _countof(buf), L"\\")) || + !SUCCEEDED(StringCchCatW(buf, _countof(buf), ShimDll))) + { + skip("Unable to append dll name\n"); + return FALSE; } - pSdbGetAppPatchDir(NULL, buf, MAX_PATH); - lstrcatW(buf, aclayers); dll = LoadLibraryW(buf); - pGetHookAPIs = (void*)GetProcAddress(dll, "GetHookAPIs"); + if (!dll) + { + skip("Unable to load shim dll\n"); + return FALSE; + } + *module = dll; + *ppGetHookAPIs = (tGETHOOKAPIS)GetProcAddress(dll, "GetHookAPIs"); - if (!pGetHookAPIs) + return *ppGetHookAPIs != NULL; +} + + +tGETHOOKAPIS LoadShimDLL2(PCWSTR ShimDll) +{ + HMODULE module; + tGETHOOKAPIS pGetHookAPIs; + + if (LoadShimDLL(ShimDll, &module, &pGetHookAPIs)) { - skip("aclayers.dll not loaded, or does not export GetHookAPIs\n"); - return; + if (!pGetHookAPIs) + skip("No GetHookAPIs found\n"); + return pGetHookAPIs; } + return NULL; +} + + +START_TEST(versionlie) +{ + pGetHookAPIs = LoadShimDLL2(L"aclayers.dll"); + + if (!pGetHookAPIs) + return; + g_WinVersion = get_host_winver(); run_test("Win95VersionLie", &g_Win95); -- 2.17.1