Author: mjansen
Date: Sat Dec 3 21:24:47 2016
New Revision: 73421
URL:
http://svn.reactos.org/svn/reactos?rev=73421&view=rev
Log:
[APPSHIM_APITEST] Add tests for display mode shims. CORE-11927
Added:
trunk/rostests/apitests/appshim/dispmode.c (with props)
Modified:
trunk/rostests/apitests/appshim/CMakeLists.txt
trunk/rostests/apitests/appshim/testlist.c
trunk/rostests/apitests/appshim/versionlie.c
Modified: trunk/rostests/apitests/appshim/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/appshim/CMakeLis…
==============================================================================
--- trunk/rostests/apitests/appshim/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/appshim/CMakeLists.txt [iso-8859-1] Sat Dec 3 21:24:47 2016
@@ -2,6 +2,7 @@
add_definitions(-D__ROS_LONG64__)
list(APPEND SOURCE
+ dispmode.c
versionlie.c
testlist.c)
Added: trunk/rostests/apitests/appshim/dispmode.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/appshim/dispmode…
==============================================================================
--- trunk/rostests/apitests/appshim/dispmode.c (added)
+++ trunk/rostests/apitests/appshim/dispmode.c [iso-8859-1] Sat Dec 3 21:24:47 2016
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2016 Mark Jansen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <windows.h>
+#ifdef __REACTOS__
+#include <ntndk.h>
+#else
+#include <winternl.h>
+#endif
+#include <stdio.h>
+#include <strsafe.h>
+#include "wine/test.h"
+
+extern DWORD get_host_winver(void);
+static DWORD g_WinVersion;
+#define WINVER_ANY 0
+#define WINVER_VISTA 0x0600
+
+
+/* apphelp.dll */
+static BOOL(WINAPI* pSdbGetAppPatchDir)(PVOID, LPWSTR, DWORD);
+
+/* aclayers.dll */
+static PVOID(WINAPI* pGetHookAPIs)(LPCSTR, LPCWSTR, PDWORD);
+static BOOL(WINAPI* pNotifyShims)(DWORD fdwReason, PVOID ptr);
+
+
+static LONG g_Count;
+static DEVMODEA g_LastDevmode;
+static DWORD g_LastFlags;
+
+LONG (WINAPI *pChangeDisplaySettingsA)(_In_opt_ PDEVMODEA lpDevMode, _In_ DWORD
dwflags);
+LONG WINAPI mChangeDisplaySettingsA(_In_opt_ PDEVMODEA lpDevMode, _In_ DWORD dwflags)
+{
+ g_Count++;
+ g_LastDevmode = *lpDevMode;
+ g_LastFlags = dwflags;
+
+ return DISP_CHANGE_FAILED;
+}
+
+
+static void pre_8bit()
+{
+ g_Count = 0;
+ memset(&g_LastDevmode, 0, sizeof(g_LastDevmode));
+ g_LastFlags = 0xffffffff;
+}
+
+static void post_8bit()
+{
+ ok_int(g_Count, 1);
+ ok_hex(g_LastDevmode.dmFields & DM_BITSPERPEL, DM_BITSPERPEL);
+ ok_int(g_LastDevmode.dmBitsPerPel, 8);
+ ok_hex(g_LastFlags, CDS_FULLSCREEN);
+}
+
+static void pre_640()
+{
+ g_Count = 0;
+ memset(&g_LastDevmode, 0, sizeof(g_LastDevmode));
+ g_LastFlags = 0xffffffff;
+}
+
+static void post_640()
+{
+ ok_int(g_Count, 1);
+ ok_hex(g_LastDevmode.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT), (DM_PELSWIDTH |
DM_PELSHEIGHT));
+ ok_int(g_LastDevmode.dmPelsWidth, 640);
+ ok_int(g_LastDevmode.dmPelsHeight, 480);
+ ok_hex(g_LastFlags, CDS_FULLSCREEN);
+}
+
+
+
+
+static PIMAGE_IMPORT_DESCRIPTOR FindImportDescriptor(PBYTE DllBase, PCSTR DllName)
+{
+ ULONG Size;
+ PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor =
RtlImageDirectoryEntryToData((HMODULE)DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT,
&Size);
+ while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk)
+ {
+ PCHAR Name = (PCHAR)(DllBase + ImportDescriptor->Name);
+ if (!lstrcmpiA(Name, DllName))
+ {
+ return ImportDescriptor;
+ }
+ ImportDescriptor++;
+ }
+ return NULL;
+}
+
+static BOOL RedirectIat(HMODULE TargetDll, PCSTR DllName, PCSTR FunctionName, ULONG_PTR
NewFunction, ULONG_PTR* OriginalFunction)
+{
+ PBYTE DllBase = (PBYTE)TargetDll;
+ PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = FindImportDescriptor(DllBase, DllName);
+ if (ImportDescriptor)
+ {
+ // On loaded images, OriginalFirstThunk points to the name / ordinal of the
function
+ PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(DllBase +
ImportDescriptor->OriginalFirstThunk);
+ // FirstThunk points to the resolved address.
+ PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)(DllBase +
ImportDescriptor->FirstThunk);
+ while (OriginalThunk->u1.AddressOfData && FirstThunk->u1.Function)
+ {
+ if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk->u1.AddressOfData))
+ {
+ PIMAGE_IMPORT_BY_NAME ImportName = (PIMAGE_IMPORT_BY_NAME)(DllBase +
OriginalThunk->u1.AddressOfData);
+ if (!lstrcmpiA((PCSTR)ImportName->Name, FunctionName))
+ {
+ DWORD dwOld;
+ VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR),
PAGE_EXECUTE_READWRITE, &dwOld);
+ *OriginalFunction = FirstThunk->u1.Function;
+ FirstThunk->u1.Function = NewFunction;
+ VirtualProtect(&FirstThunk->u1.Function, sizeof(ULONG_PTR),
dwOld, &dwOld);
+ return TRUE;
+ }
+ }
+ OriginalThunk++;
+ FirstThunk++;
+ }
+ skip("Unable to find the Import %s!%s\n", DllName, FunctionName);
+ }
+ else
+ {
+ skip("Unable to find the ImportDescriptor for %s\n", DllName);
+ }
+ return FALSE;
+}
+
+
+
+static void test_one(LPCSTR shim, DWORD dwReason, void(*pre)(), void(*post)())
+{
+ DWORD num_shims = 0;
+ WCHAR wide_shim[50] = { 0 };
+ PVOID hook;
+ BOOL ret;
+ MultiByteToWideChar(CP_ACP, 0, shim, -1, wide_shim, 50);
+
+ if (pre)
+ pre();
+
+ hook = pGetHookAPIs("", wide_shim, &num_shims);
+ if (hook == NULL)
+ {
+ skip("Skipping tests for layers (%s) not present in this os (0x%x)\n",
shim, g_WinVersion);
+ return;
+ }
+ ok(hook != NULL, "Expected hook to be a valid pointer for %s\n", shim);
+ ok(num_shims == 0, "Expected not to find any apihooks, got: %u for %s\n",
num_shims, shim);
+
+ ret = pNotifyShims(dwReason, NULL);
+
+ /* Win7 and Win10 return 1, w2k3 returns a pointer */
+ ok(ret != 0, "Expected pNotifyShims to succeed (%i)\n", ret);
+
+ if (post)
+ post();
+}
+
+static struct test_info
+{
+ const char* name;
+ DWORD winver;
+ DWORD reason;
+ void(*pre)();
+ void(*post)();
+} tests[] =
+{
+ { "Force8BitColor", WINVER_ANY, 1, pre_8bit, post_8bit },
+ { "Force8BitColor", WINVER_VISTA, 100, pre_8bit, post_8bit },
+ { "Force640x480", WINVER_ANY, 1, pre_640, post_640 },
+ { "Force640x480", WINVER_VISTA, 100, pre_640, post_640 },
+ /* { "DisableThemes" }, AcGenral.dll */
+};
+
+
+static void run_test(size_t n, WCHAR* buf, BOOL unload)
+{
+ BOOL ret;
+ HMODULE dll;
+
+ trace("Running %d (%s)\n", n, tests[n].name);
+
+ dll = LoadLibraryW(buf);
+ pGetHookAPIs = (void*)GetProcAddress(dll, "GetHookAPIs");
+ 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);
+ return;
+ }
+
+ ret = RedirectIat(dll, "user32.dll", "ChangeDisplaySettingsA",
(ULONG_PTR)mChangeDisplaySettingsA, (ULONG_PTR*)&pChangeDisplaySettingsA);
+ if (ret)
+ {
+ test_one(tests[n].name, tests[n].reason, tests[n].pre, tests[n].post);
+ }
+ else
+ {
+ ok(0, "Unable to redirect ChangeDisplaySettingsA!\n");
+ }
+ FreeLibrary(dll);
+ if (unload)
+ {
+ dll = GetModuleHandleW(buf);
+ ok(dll == NULL, "Unable to unload %s\n", wine_dbgstr_w(buf));
+ }
+}
+
+
+START_TEST(dispmode)
+{
+ HMODULE dll = LoadLibraryA("apphelp.dll");
+ WCHAR buf[MAX_PATH];
+ WCHAR aclayers[] = L"\\aclayers.dll";
+ size_t n;
+ int argc;
+ char **argv;
+
+ pSdbGetAppPatchDir = (void*)GetProcAddress(dll, "SdbGetAppPatchDir");
+ if (!pSdbGetAppPatchDir)
+ {
+ skip("apphelp.dll not loaded, or does not export
SdbGetAppPatchDir\n");
+ return;
+ }
+
+ g_WinVersion = get_host_winver();
+
+ pSdbGetAppPatchDir(NULL, buf, MAX_PATH);
+ StringCchCatW(buf, _countof(buf), aclayers);
+
+ argc = winetest_get_mainargs(&argv);
+ if (argc < 3)
+ {
+ WCHAR path[MAX_PATH];
+ GetModuleFileNameW(NULL, path, _countof(path));
+ dll = GetModuleHandleW(buf);
+ if (dll != NULL)
+ trace("Loaded under a shim, running each test in it's own
process\n");
+
+ for (n = 0; n < _countof(tests); ++n)
+ {
+ if (g_WinVersion < tests[n].winver)
+ continue;
+
+ if (dll == NULL)
+ {
+ run_test(n, buf, TRUE);
+ }
+ else
+ {
+ WCHAR buf[MAX_PATH+40];
+ STARTUPINFOW si = { sizeof(si) };
+ PROCESS_INFORMATION pi;
+ BOOL created;
+
+ StringCchPrintfW(buf, _countof(buf), L"\"%ls\" dispmode
%u", path, n);
+ created = CreateProcessW(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL,
&si, &pi);
+ ok(created, "Expected CreateProcess to succeed\n");
+ if (created)
+ {
+ winetest_wait_child_process(pi.hProcess);
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ }
+ }
+ }
+ }
+ else
+ {
+ n = (size_t)atoi(argv[2]);
+ if (n >= 0 && n < _countof(tests))
+ {
+ run_test(n, buf, FALSE);
+ }
+ else
+ {
+ ok(0, "Test out of range: %u\n", n);
+ }
+ }
+}
Propchange: trunk/rostests/apitests/appshim/dispmode.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/appshim/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/appshim/testlist…
==============================================================================
--- trunk/rostests/apitests/appshim/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/appshim/testlist.c [iso-8859-1] Sat Dec 3 21:24:47 2016
@@ -3,10 +3,12 @@
#define STANDALONE
#include <wine/test.h>
+extern void func_dispmode(void);
extern void func_versionlie(void);
const struct test winetest_testlist[] =
{
+ { "dispmode", func_dispmode },
{ "versionlie", func_versionlie },
{ 0, 0 }
};
Modified: trunk/rostests/apitests/appshim/versionlie.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/appshim/versionl…
==============================================================================
--- trunk/rostests/apitests/appshim/versionlie.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/appshim/versionlie.c [iso-8859-1] Sat Dec 3 21:24:47 2016
@@ -279,21 +279,6 @@
}
}
-static void hookless_shim(LPCSTR shim)
-{
- DWORD num_shims = 0;
- WCHAR wide_shim[50] = { 0 };
- PHOOKAPI hook;
- MultiByteToWideChar(CP_ACP, 0, shim, -1, wide_shim, 50);
- hook = pGetHookAPIs("", wide_shim, &num_shims);
- if (hook == NULL)
- {
- skip("Skipping tests for layers (%s) not present in this os (0x%x)\n",
shim, g_WinVersion);
- return;
- }
- ok(hook != NULL, "Expected hook to be a valid pointer for %s\n", shim);
- ok(num_shims == 0, "Expected not to find any apihooks, got: %u for %s\n",
num_shims, shim);
-}
VersionLieInfo g_Win95 = { 0xC3B60004, 4, 0, 950, VER_PLATFORM_WIN32_WINDOWS, 0, 0 };
VersionLieInfo g_WinNT4SP5 = { 0x05650004, 4, 0, 1381, VER_PLATFORM_WIN32_NT, 5, 0 };
@@ -370,8 +355,4 @@
run_test("VistaSP1VersionLie", &g_WinVistaSP1);
run_test("VistaSP2VersionLie", &g_WinVistaSP2);
run_test("Win7RTMVersionLie", &g_Win7RTM);
-
- hookless_shim("Force8BitColor");
- hookless_shim("Force640x480");
- hookless_shim("DisableThemes");
-}
+}