[SHIMENG] Find shims case-insensitive
[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 static BOOL IsDxSetupW(PCUNICODE_STRING LibraryPath)
57 {
58 static const UNICODE_STRING DxSetupDlls[] = {
59 RTL_CONSTANT_STRING(L"dsetup.dll"),
60 RTL_CONSTANT_STRING(L"dsetup32.dll"),
61 RTL_CONSTANT_STRING(L"dsetup"),
62 RTL_CONSTANT_STRING(L"dsetup32"),
63 };
64 static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/");
65 UNICODE_STRING LibraryName;
66 USHORT PathDivider;
67 DWORD n;
68
69 if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, LibraryPath, &PathDividerFind, &PathDivider)))
70 PathDivider = 0;
71
72 if (PathDivider)
73 PathDivider += sizeof(WCHAR);
74
75 LibraryName.Buffer = LibraryPath->Buffer + PathDivider / sizeof(WCHAR);
76 LibraryName.Length = LibraryPath->Length - PathDivider;
77 LibraryName.MaximumLength = LibraryPath->MaximumLength - PathDivider;
78
79 for (n = 0; n < ARRAYSIZE(DxSetupDlls); ++n)
80 {
81 if (RtlEqualUnicodeString(&LibraryName, DxSetupDlls + n, TRUE))
82 {
83 SHIM_MSG("Found %wZ\n", DxSetupDlls + n);
84 return TRUE;
85 }
86 }
87 return FALSE;
88 }
89
90 static BOOL IsDxSetupA(PCANSI_STRING LibraryPath)
91 {
92 BOOL bIsDxSetup;
93 UNICODE_STRING LibraryPathW;
94
95 if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&LibraryPathW, LibraryPath, TRUE)))
96 {
97 bIsDxSetup = IsDxSetupW(&LibraryPathW);
98 RtlFreeUnicodeString(&LibraryPathW);
99 return bIsDxSetup;
100 }
101 return FALSE;
102 }
103
104 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryA)(LPCSTR lpLibFileName)
105 {
106 ANSI_STRING Library;
107
108 RtlInitAnsiString(&Library, lpLibFileName);
109 if (IsDxSetupA(&Library))
110 return ShimLib_Instance();
111
112 return CALL_SHIM(0, LOADLIBRARYAPROC)(lpLibFileName);
113 }
114
115 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryW)(LPCWSTR lpLibFileName)
116 {
117 UNICODE_STRING Library;
118
119 RtlInitUnicodeString(&Library, lpLibFileName);
120 if (IsDxSetupW(&Library))
121 return ShimLib_Instance();
122
123 return CALL_SHIM(1, LOADLIBRARYWPROC)(lpLibFileName);
124 }
125
126 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryExA)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
127 {
128 ANSI_STRING Library;
129
130 RtlInitAnsiString(&Library, lpLibFileName);
131 if (IsDxSetupA(&Library))
132 return ShimLib_Instance();
133
134 return CALL_SHIM(2, LOADLIBRARYEXAPROC)(lpLibFileName, hFile, dwFlags);
135 }
136
137 HMODULE WINAPI SHIM_OBJ_NAME(APIHook_LoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
138 {
139 UNICODE_STRING Library;
140
141 RtlInitUnicodeString(&Library, lpLibFileName);
142 if (IsDxSetupW(&Library))
143 return ShimLib_Instance();
144
145 return CALL_SHIM(3, LOADLIBRARYEXWPROC)(lpLibFileName, hFile, dwFlags);
146 }
147
148 FARPROC WINAPI SHIM_OBJ_NAME(APIHook_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName)
149 {
150 static const STRING DxSetupFunctions[] = {
151 RTL_CONSTANT_STRING("DirectXSetup"),
152 RTL_CONSTANT_STRING("DirectXSetupA"),
153 RTL_CONSTANT_STRING("DirectXSetupW"),
154 RTL_CONSTANT_STRING("DirectXSetupGetVersion"),
155 };
156 static const FARPROC DxSetupRedirections[] = {
157 DirectXSetup,
158 DirectXSetupA,
159 DirectXSetupW,
160 DirectXSetupGetVersion,
161 };
162 DWORD n;
163
164 if (hModule == ShimLib_Instance() && ((ULONG_PTR)lpProcName > MAXUSHORT))
165 {
166 STRING ProcName;
167 RtlInitAnsiString(&ProcName, lpProcName);
168 for (n = 0; n < ARRAYSIZE(DxSetupFunctions); ++n)
169 {
170 if (RtlEqualString(&ProcName, DxSetupFunctions + n, TRUE))
171 {
172 SHIM_MSG("Intercepted %Z\n", DxSetupFunctions + n);
173 return DxSetupRedirections[n];
174 }
175 }
176 }
177 return CALL_SHIM(4, GETPROCADDRESSPROC)(hModule, lpProcName);
178 }
179
180 BOOL WINAPI SHIM_OBJ_NAME(APIHook_FreeLibrary)(HINSTANCE hLibModule)
181 {
182 if (hLibModule == ShimLib_Instance())
183 {
184 SHIM_MSG("Intercepted\n");
185 return TRUE;
186 }
187
188 return CALL_SHIM(5, FREELIBRARYPROC)(hLibModule);
189 }
190
191
192 #define SHIM_NUM_HOOKS 6
193 #define SHIM_SETUP_HOOKS \
194 SHIM_HOOK(0, "KERNEL32.DLL", "LoadLibraryA", SHIM_OBJ_NAME(APIHook_LoadLibraryA)) \
195 SHIM_HOOK(1, "KERNEL32.DLL", "LoadLibraryW", SHIM_OBJ_NAME(APIHook_LoadLibraryW)) \
196 SHIM_HOOK(2, "KERNEL32.DLL", "LoadLibraryExA", SHIM_OBJ_NAME(APIHook_LoadLibraryExA)) \
197 SHIM_HOOK(3, "KERNEL32.DLL", "LoadLibraryExW", SHIM_OBJ_NAME(APIHook_LoadLibraryExW)) \
198 SHIM_HOOK(4, "KERNEL32.DLL", "GetProcAddress", SHIM_OBJ_NAME(APIHook_GetProcAddress)) \
199 SHIM_HOOK(5, "KERNEL32.DLL", "FreeLibrary", SHIM_OBJ_NAME(APIHook_FreeLibrary))
200
201 #include <implement_shim.inl>