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 AcGenral
5  * COPYRIGHT:   Copyright 2017-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[4];
31 } expect_shim_data;
32 
33 
34 static expect_shim_data data[] =
35 {
36     {
37         L"IgnoreChromeSandbox",
38         _WIN32_WINNT_WIN8,
39         {
40             { "KERNEL32.DLL", "CreateProcessW" },
41         }
42     },
43     {
44         L"AddProcessParametersFlags",
45         0,
46         /* No hooks */
47     },
48     {
49         L"DisableThemes",
50         0,
51         /* No hooks */
52     },
53 };
54 
55 static DWORD count_shims(expect_shim_data* data)
56 {
57     DWORD num;
58     for (num = 0; num < _countof(data->hooks) && data->hooks[num].Library;)
59     {
60         ++num;
61     }
62     return num;
63 }
64 
65 static const char* safe_str(const char* ptr)
66 {
67     static char buffer[2][30];
68     static int index = 0;
69     if (HIWORD(ptr))
70         return ptr;
71 
72     index ^= 1;
73     StringCchPrintfA(buffer[index], _countof(buffer[index]), "#%Id", (intptr_t)ptr);
74     return buffer[index];
75 }
76 
77 START_TEST(genral_hooks)
78 {
79     RTL_OSVERSIONINFOEXW rtlinfo = {0};
80     size_t n, h;
81 
82     tGETHOOKAPIS pGetHookAPIs = LoadShimDLL2(L"AcGenral.dll");
83     if (!pGetHookAPIs)
84         return;
85 
86     rtlinfo.dwOSVersionInfoSize = sizeof(rtlinfo);
87     RtlGetVersion((PRTL_OSVERSIONINFOW)&rtlinfo);
88     g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
89 
90 
91 
92     for (n = 0; n < _countof(data); ++n)
93     {
94         expect_shim_data* current = data + n;
95         DWORD num_shims = 0, expected_shims = count_shims(current);
96 
97         PHOOKAPI hook = pGetHookAPIs("", current->ShimName, &num_shims);
98 
99         if (current->MinVersion > g_WinVersion && !hook)
100         {
101             skip("Shim %s not present\n", wine_dbgstr_w(current->ShimName));
102             continue;
103         }
104 
105         ok(!!hook, "Expected a valid pointer, got nothing for %s\n", wine_dbgstr_w(current->ShimName));
106         ok(num_shims == expected_shims, "Expected %u shims, got %u for %s\n",
107            expected_shims, num_shims, wine_dbgstr_w(current->ShimName));
108         for (h = 0; h < min(num_shims, expected_shims); ++h)
109         {
110             expect_shim_hook* expect_hk = current->hooks + h;
111             PHOOKAPI got_hk = hook+h;
112             int lib = lstrcmpA(expect_hk->Library, got_hk->LibraryName);
113             int fn = lstrcmpA(safe_str(expect_hk->Function), safe_str(got_hk->FunctionName));
114             ok(lib == 0, "Expected LibraryName to be %s, was: %s for %s\n",
115                expect_hk->Library, got_hk->LibraryName, wine_dbgstr_w(current->ShimName));
116             ok(fn == 0, "Expected FunctionName to be %s, was: %s for %s\n",
117                safe_str(expect_hk->Function), safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName));
118         }
119         if (num_shims > expected_shims)
120         {
121             for (h = expected_shims; h < num_shims; ++h)
122             {
123                 PHOOKAPI got_hk = hook+h;
124 
125                 ok(0, "Extra shim: %s!%s for %s\n",
126                    got_hk->LibraryName, safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName));
127             }
128         }
129         else
130         {
131             for (h = num_shims; h < expected_shims; ++h)
132             {
133                 expect_shim_hook* expect_hk = current->hooks + h;
134 
135                 ok(0, "Missing shim: %s!%s for %s\n",
136                    expect_hk->Library, safe_str(expect_hk->Function), wine_dbgstr_w(current->ShimName));
137             }
138         }
139     }
140 }
141