f86339e07852b78389985009e7152c776a2db030
[reactos.git] / dll / appcompat / shims / layer / forcedxsetupsuccess.c
1 /*
2 * PROJECT: ReactOS 'Layers' Shim library
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: ForceDxSetupSuccess shim
5 * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8 #define WIN32_NO_STATUS
9 #include <windef.h>
10 #include <winbase.h>
11 #include <shimlib.h>
12 #include "ntndk.h"
13
14 typedef HMODULE(WINAPI* LOADLIBRARYAPROC)(LPCSTR lpLibFileName);
15 typedef HMODULE(WINAPI* LOADLIBRARYWPROC)(LPCWSTR lpLibFileName);
16 typedef HMODULE(WINAPI* LOADLIBRARYEXAPROC)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
17 typedef HMODULE(WINAPI* LOADLIBRARYEXWPROC)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
18 typedef FARPROC(WINAPI* GETPROCADDRESSPROC)(HMODULE hModule, LPCSTR lpProcName);
19 typedef BOOL (WINAPI* FREELIBRARYPROC)(HINSTANCE hLibModule);
20
21
22 #define SHIM_NS ForceDxSetupSuccess
23 #include <setup_shim.inl>
24
25
26 #define DSETUPERR_SUCCESS 0
27
28 INT WINAPI DirectXSetup(HWND hWnd, LPSTR lpszRootPath, DWORD dwFlags)
29 {
30 SHIM_MSG("Returning DSETUPERR_SUCCESS\n");
31 return DSETUPERR_SUCCESS;
32 }
33
34 INT WINAPI DirectXSetupA(HWND hWnd, LPSTR lpszRootPath, DWORD dwFlags)
35 {
36 SHIM_MSG("Returning DSETUPERR_SUCCESS\n");
37 return DSETUPERR_SUCCESS;
38 }
39
40 INT WINAPI DirectXSetupW(HWND hWnd, LPWSTR lpszRootPath, DWORD dwFlags)
41 {
42 SHIM_MSG("Returning DSETUPERR_SUCCESS\n");
43 return DSETUPERR_SUCCESS;
44 }
45
46 INT WINAPI DirectXSetupGetVersion(DWORD *lpdwVersion, DWORD *lpdwMinorVersion)
47 {
48 if (lpdwVersion)
49 *lpdwVersion = MAKELONG(7, 4); // DirectX 7.0
50 if (lpdwMinorVersion)
51 *lpdwMinorVersion = MAKELONG(1792, 0);
52
53 return TRUE;
54 }
55
56
57 static
58 BOOLEAN
59 IsCharInAnsiString(
60 IN CHAR Char,
61 IN const STRING* MatchString)
62 {
63 USHORT i;
64
65 for (i = 0; i < MatchString->Length; i++)
66 {
67 if (Char == MatchString->Buffer[i])
68 return TRUE;
69 }
70
71 return FALSE;
72 }
73
74
75 NTSTATUS
76 NTAPI
77 FindCharInAnsiString(
78 IN const STRING* SearchString,
79 IN const STRING* MatchString,
80 OUT PUSHORT Position)
81 {
82 BOOLEAN Found;
83 ULONG i, Length;
84
85 *Position = 0;
86
87 /* Search */
88 Length = SearchString->Length;
89 for (i = Length - 1; (LONG)i >= 0; i--)
90 {
91 Found = IsCharInAnsiString(SearchString->Buffer[i], MatchString);
92 if (Found)
93 {
94 *Position = i;
95 return STATUS_SUCCESS;
96 }
97 }
98
99 return STATUS_NOT_FOUND;
100 }
101
102
103 static BOOL IsDxSetupA(const PSTRING LibraryPath)
104 {
105 static const STRING DxSetupDlls[] = {
106 RTL_CONSTANT_STRING("dsetup.dll"),
107 RTL_CONSTANT_STRING("dsetup32.dll"),
108 RTL_CONSTANT_STRING("dsetup"),
109 RTL_CONSTANT_STRING("dsetup32"),
110 };
111 static const STRING PathDividerFind = RTL_CONSTANT_STRING("\\/");
112 STRING LibraryName;
113 USHORT PathDivider;
114 DWORD n;
115
116 if (!NT_SUCCESS(FindCharInAnsiString(LibraryPath, &PathDividerFind, &PathDivider)))
117 PathDivider = 0;
118
119 if (PathDivider)
120 PathDivider += sizeof(CHAR);
121
122 LibraryName.Buffer = LibraryPath->Buffer + PathDivider;
123 LibraryName.Length = LibraryPath->Length - PathDivider;
124 LibraryName.MaximumLength = LibraryPath->MaximumLength - PathDivider;
125
126 for (n = 0; n < ARRAYSIZE(DxSetupDlls); ++n)
127 {
128 if (RtlEqualString(&LibraryName, DxSetupDlls + n, TRUE))
129 {
130 SHIM_MSG("Found %Z\n", DxSetupDlls + n);
131 return TRUE;
132 }
133 }
134 return FALSE;
135 }
136
137 static BOOL IsDxSetupW(PCUNICODE_STRING LibraryPath)
138 {
139 static const UNICODE_STRING DxSetupDlls[] = {
140 RTL_CONSTANT_STRING(L"dsetup.dll"),
141 RTL_CONSTANT_STRING(L"dsetup32.dll"),
142 RTL_CONSTANT_STRING(L"dsetup"),
143 RTL_CONSTANT_STRING(L"dsetup32"),
144 };
145 static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/");
146 UNICODE_STRING LibraryName;
147 USHORT PathDivider;
148 DWORD n;
149
150 if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, LibraryPath, &PathDividerFind, &PathDivider)))
151 PathDivider = 0;
152
153 if (PathDivider)
154 PathDivider += sizeof(WCHAR);
155
156 LibraryName.Buffer = LibraryPath->Buffer + PathDivider / sizeof(WCHAR);
157 LibraryName.Length = LibraryPath->Length - PathDivider;
158 LibraryName.MaximumLength = LibraryPath->MaximumLength - PathDivider;
159
160 for (n = 0; n < ARRAYSIZE(DxSetupDlls); ++n)
161 {
162 if (RtlEqualUnicodeString(&LibraryName, DxSetupDlls + n, TRUE))
163 {
164 SHIM_MSG("Found %wZ\n", DxSetupDlls + n);
165 return TRUE;
166 }
167 }
168 return FALSE;
169 }
170
171 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryA)(LPCSTR lpLibFileName)
172 {
173 STRING Library;
174
175 RtlInitAnsiString(&Library, lpLibFileName);
176 if (IsDxSetupA(&Library))
177 return ShimLib_Instance();
178
179 return CALL_SHIM(0, LOADLIBRARYAPROC)(lpLibFileName);
180 }
181
182 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryW)(LPCWSTR lpLibFileName)
183 {
184 UNICODE_STRING Library;
185
186 RtlInitUnicodeString(&Library, lpLibFileName);
187 if (IsDxSetupW(&Library))
188 return ShimLib_Instance();
189
190 return CALL_SHIM(1, LOADLIBRARYWPROC)(lpLibFileName);
191 }
192
193 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryExA)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
194 {
195 STRING Library;
196
197 RtlInitAnsiString(&Library, lpLibFileName);
198 if (IsDxSetupA(&Library))
199 return ShimLib_Instance();
200
201 return CALL_SHIM(2, LOADLIBRARYEXAPROC)(lpLibFileName, hFile, dwFlags);
202 }
203
204 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
205 {
206 UNICODE_STRING Library;
207
208 RtlInitUnicodeString(&Library, lpLibFileName);
209 if (IsDxSetupW(&Library))
210 return ShimLib_Instance();
211
212 return CALL_SHIM(3, LOADLIBRARYEXWPROC)(lpLibFileName, hFile, dwFlags);
213 }
214
215 FARPROC WINAPI SHIM_OBJ_NAME(APIHook_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName)
216 {
217 static const STRING DxSetupFunctions[] = {
218 RTL_CONSTANT_STRING("DirectXSetup"),
219 RTL_CONSTANT_STRING("DirectXSetupA"),
220 RTL_CONSTANT_STRING("DirectXSetupW"),
221 RTL_CONSTANT_STRING("DirectXSetupGetVersion"),
222 };
223 static const FARPROC DxSetupRedirections[] = {
224 DirectXSetup,
225 DirectXSetupA,
226 DirectXSetupW,
227 DirectXSetupGetVersion,
228 };
229 DWORD n;
230
231 if (hModule == ShimLib_Instance() && ((ULONG_PTR)lpProcName > MAXUSHORT))
232 {
233 STRING ProcName;
234 RtlInitAnsiString(&ProcName, lpProcName);
235 for (n = 0; n < ARRAYSIZE(DxSetupFunctions); ++n)
236 {
237 if (RtlEqualString(&ProcName, DxSetupFunctions + n, TRUE))
238 {
239 SHIM_MSG("Intercepted %Z\n", DxSetupFunctions + n);
240 return DxSetupRedirections[n];
241 }
242 }
243 }
244 return CALL_SHIM(4, GETPROCADDRESSPROC)(hModule, lpProcName);
245 }
246
247 BOOL WINAPI SHIM_OBJ_NAME(APIHook_FreeLibrary)(HINSTANCE hLibModule)
248 {
249 if (hLibModule == ShimLib_Instance())
250 {
251 SHIM_MSG("Intercepted\n");
252 return TRUE;
253 }
254
255 return CALL_SHIM(5, FREELIBRARYPROC)(hLibModule);
256 }
257
258
259 #define SHIM_NUM_HOOKS 6
260 #define SHIM_SETUP_HOOKS \
261 SHIM_HOOK(0, "KERNEL32.DLL", "LoadLibraryA", SHIM_OBJ_NAME(APIHook_LoadLibraryA)) \
262 SHIM_HOOK(1, "KERNEL32.DLL", "LoadLibraryW", SHIM_OBJ_NAME(APIHook_LoadLibraryW)) \
263 SHIM_HOOK(2, "KERNEL32.DLL", "LoadLibraryExA", SHIM_OBJ_NAME(APIHook_LoadLibraryExA)) \
264 SHIM_HOOK(3, "KERNEL32.DLL", "LoadLibraryExW", SHIM_OBJ_NAME(APIHook_LoadLibraryExW)) \
265 SHIM_HOOK(4, "KERNEL32.DLL", "GetProcAddress", SHIM_OBJ_NAME(APIHook_GetProcAddress)) \
266 SHIM_HOOK(5, "KERNEL32.DLL", "FreeLibrary", SHIM_OBJ_NAME(APIHook_FreeLibrary))
267
268 #include <implement_shim.inl>