Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

420 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. ForceDXSetupSuccess.cpp
  5. Abstract:
  6. This DLL APIHooks LoadLibrary calls and checks to see if dsetup.dll or
  7. dsetup32.dll are being loaded. If dsetup.dll or dsetup32.dll are being
  8. loaded return this module, so that subsequent calls to that dll can be
  9. intercepted and stubbed out. If not dsetup.dll or dsetup32.dll then just
  10. do what is expected.
  11. Notes:
  12. This is a general purpose shim.
  13. History:
  14. 11/10/1999 v-johnwh Created
  15. 03/29/2000 a-michni Added DirectXSetupGetVersion hook to return
  16. a command line specified version number for
  17. apps which look for a specific version.
  18. example :
  19. <DLL NAME="ForceDXSetupSuccess.dll" COMMAND_LINE="0x00040005;0x0000009B"/>
  20. 04/2000 a-batjar check for null in input params for directxsetupgetversion
  21. 06/30/2000 a-brienw I added a check for dsetup32.dll to APIHook_LoadLibraryA
  22. and APIHook_LoadLibraryW. Previously the routines were
  23. only looking for dsetup.dll. This was added to fix a
  24. problem in the install for Earthworm Jim 3D.
  25. 02/27/2001 robkenny Converted to use CString
  26. --*/
  27. #include "precomp.h"
  28. #include <stdio.h>
  29. IMPLEMENT_SHIM_BEGIN(ForceDXSetupSuccess)
  30. #include "ShimHookMacro.h"
  31. APIHOOK_ENUM_BEGIN
  32. APIHOOK_ENUM_ENTRY(LoadLibraryA)
  33. APIHOOK_ENUM_ENTRY(LoadLibraryW)
  34. APIHOOK_ENUM_ENTRY(LoadLibraryExA)
  35. APIHOOK_ENUM_ENTRY(LoadLibraryExW)
  36. APIHOOK_ENUM_ENTRY(GetProcAddress)
  37. APIHOOK_ENUM_ENTRY(FreeLibrary)
  38. APIHOOK_ENUM_END
  39. /*++
  40. This function simply returns 0, success, when called upon.
  41. --*/
  42. int
  43. DirectXSetup(
  44. HWND /*hWnd*/,
  45. LPSTR /*lpszRootPath*/,
  46. DWORD /*dwFlags*/
  47. )
  48. {
  49. LOGN(
  50. eDbgLevelError,
  51. "[DirectXSetup] Returning SUCCESS.");
  52. return 0; // SUCCESS
  53. }
  54. int
  55. DirectXSetupA(
  56. HWND /*hWnd*/,
  57. LPSTR /*lpszRootPath*/,
  58. DWORD /*dwFlags*/
  59. )
  60. {
  61. LOGN(
  62. eDbgLevelError,
  63. "[DirectXSetupA] Returning SUCCESS.");
  64. return 0; // SUCCESS
  65. }
  66. int
  67. DirectXSetupW(
  68. HWND hWnd,
  69. LPWSTR lpszRootPath,
  70. DWORD dwFlags
  71. )
  72. {
  73. LOGN(
  74. eDbgLevelError,
  75. "[DirectXSetupW] Returning SUCCESS.");
  76. return 0; // SUCCESS
  77. }
  78. /*++
  79. This Function returns either a COMMAND_LINE parsed value for the version and
  80. rev or, if no command line is present, it returns version 7 rev 1792
  81. --*/
  82. int
  83. DirectXSetupGetVersion(
  84. DWORD* pdwVersion,
  85. DWORD* pdwRevision
  86. )
  87. {
  88. DWORD dwVersion = 0x00040007;
  89. DWORD dwRevision = 0x00000700;
  90. //
  91. // If no seperator is present or there is nothing after
  92. // seperator then return a default value of ver 7 rev 1792
  93. // Otherwise parse the command line, it should contain a
  94. // 10 char hex version and a 10 char hex revision
  95. //
  96. CSTRING_TRY
  97. {
  98. CStringToken csTokenizer(COMMAND_LINE, ";");
  99. CString csVersion;
  100. CString csRevision;
  101. if (csTokenizer.GetToken(csVersion) && csTokenizer.GetToken(csRevision))
  102. {
  103. sscanf(csVersion.GetAnsi(), "%x", &dwVersion);
  104. sscanf(csRevision.GetAnsi(), "%x", &dwRevision);
  105. }
  106. }
  107. CSTRING_CATCH
  108. {
  109. // Do nothing
  110. }
  111. if (pdwVersion)
  112. {
  113. *pdwVersion = dwVersion;
  114. }
  115. if (pdwRevision)
  116. {
  117. *pdwRevision = dwRevision;
  118. }
  119. return 1;
  120. }
  121. /*++
  122. These stub functions break into LoadLibraryA and check to see if lpLibFileName
  123. equals dsetup.dll. If so return FAKE_MODULE. If lpLibFileName does not
  124. contain dsetup.dll return the original value of lpLibFileName.
  125. --*/
  126. HINSTANCE
  127. APIHOOK(LoadLibraryA)(
  128. LPCSTR lpLibFileName
  129. )
  130. {
  131. HINSTANCE hInstance = NULL;
  132. CSTRING_TRY
  133. {
  134. CString csName(lpLibFileName);
  135. CString csFilePart;
  136. csName.GetLastPathComponent(csFilePart);
  137. if (
  138. csFilePart.CompareNoCase(L"dsetup.dll") == 0 ||
  139. csFilePart.CompareNoCase(L"dsetup") == 0 ||
  140. csFilePart.CompareNoCase(L"dsetup32.dll") == 0 ||
  141. csFilePart.CompareNoCase(L"dsetup32") == 0
  142. )
  143. {
  144. LOGN(
  145. eDbgLevelError,
  146. "[LoadLibraryA] Caught %s attempt - returning %08lx", lpLibFileName, g_hinstDll);
  147. return g_hinstDll;
  148. }
  149. }
  150. CSTRING_CATCH
  151. {
  152. // Do nothing
  153. }
  154. hInstance = ORIGINAL_API(LoadLibraryA)(lpLibFileName);
  155. return hInstance;
  156. }
  157. HINSTANCE
  158. APIHOOK(LoadLibraryW)(
  159. LPCWSTR lpLibFileName
  160. )
  161. {
  162. HINSTANCE hInstance = NULL;
  163. CSTRING_TRY
  164. {
  165. CString csName(lpLibFileName);
  166. CString csFilePart;
  167. csName.GetLastPathComponent(csFilePart);
  168. if (
  169. csFilePart.CompareNoCase(L"dsetup.dll") == 0 ||
  170. csFilePart.CompareNoCase(L"dsetup") == 0 ||
  171. csFilePart.CompareNoCase(L"dsetup32.dll") == 0 ||
  172. csFilePart.CompareNoCase(L"dsetup32") == 0
  173. )
  174. {
  175. LOGN(
  176. eDbgLevelError,
  177. "[LoadLibraryW] Caught %S attempt - returning %08lx", lpLibFileName, g_hinstDll);
  178. return g_hinstDll;
  179. }
  180. }
  181. CSTRING_CATCH
  182. {
  183. // Do nothing
  184. }
  185. hInstance = ORIGINAL_API(LoadLibraryW)(lpLibFileName);
  186. return hInstance;
  187. }
  188. HINSTANCE
  189. APIHOOK(LoadLibraryExA)(
  190. LPCSTR lpLibFileName,
  191. HANDLE hFile,
  192. DWORD dwFlags
  193. )
  194. {
  195. HINSTANCE hInstance = NULL;
  196. CSTRING_TRY
  197. {
  198. CString csName(lpLibFileName);
  199. CString csFilePart;
  200. csName.GetLastPathComponent(csFilePart);
  201. if (
  202. csFilePart.CompareNoCase(L"dsetup.dll") == 0 ||
  203. csFilePart.CompareNoCase(L"dsetup") == 0 ||
  204. csFilePart.CompareNoCase(L"dsetup32.dll") == 0 ||
  205. csFilePart.CompareNoCase(L"dsetup32") == 0
  206. )
  207. {
  208. LOGN(
  209. eDbgLevelError,
  210. "[LoadLibraryExA] Caught %s attempt - returning %08lx", lpLibFileName, g_hinstDll);
  211. return g_hinstDll;
  212. }
  213. }
  214. CSTRING_CATCH
  215. {
  216. // Do nothing
  217. }
  218. hInstance = ORIGINAL_API(LoadLibraryExA)(lpLibFileName, hFile, dwFlags);
  219. return hInstance;
  220. }
  221. HINSTANCE
  222. APIHOOK(LoadLibraryExW)(
  223. LPCWSTR lpLibFileName,
  224. HANDLE hFile,
  225. DWORD dwFlags
  226. )
  227. {
  228. HINSTANCE hInstance = NULL;
  229. CSTRING_TRY
  230. {
  231. CString csName(lpLibFileName);
  232. CString csFilePart;
  233. csName.GetLastPathComponent(csFilePart);
  234. if (
  235. csFilePart.CompareNoCase(L"dsetup.dll") == 0 ||
  236. csFilePart.CompareNoCase(L"dsetup") == 0 ||
  237. csFilePart.CompareNoCase(L"dsetup32.dll") == 0 ||
  238. csFilePart.CompareNoCase(L"dsetup32") == 0
  239. )
  240. {
  241. LOGN(
  242. eDbgLevelError,
  243. "[LoadLibraryExW] Caught %S attempt - returning %08lx", lpLibFileName, g_hinstDll);
  244. return g_hinstDll;
  245. }
  246. }
  247. CSTRING_CATCH
  248. {
  249. // Do nothing
  250. }
  251. hInstance = ORIGINAL_API(LoadLibraryExW)(lpLibFileName, hFile, dwFlags);
  252. return hInstance;
  253. }
  254. /*++
  255. Just a simple routine to make GetProcAddress look cleaner.
  256. ++*/
  257. BOOL CheckProc(const CString & csProcName, const WCHAR * lpszCheckName)
  258. {
  259. if (csProcName.Compare(lpszCheckName) == 0)
  260. {
  261. DPFN(
  262. eDbgLevelInfo,
  263. "[GetProcAddress] Caught %S query. Returning stubbed function at 0x%08X",
  264. lpszCheckName, DirectXSetup);
  265. return TRUE;
  266. }
  267. return FALSE;
  268. }
  269. /*++
  270. This stub function breaks into GetProcAddress and checks to see if hModule is
  271. equal to FAKE_MODULE. If so, and pResult contains the string "DirectXSetupA"
  272. set pRet to the return value of DirectXSetup.
  273. --*/
  274. FARPROC
  275. APIHOOK(GetProcAddress)(
  276. HMODULE hModule,
  277. LPCSTR lpProcName
  278. )
  279. {
  280. if (hModule == g_hinstDll)
  281. {
  282. CSTRING_TRY
  283. {
  284. CString csProcName(lpProcName);
  285. csProcName.MakeLower();
  286. if (CheckProc(csProcName, L"directxsetup"))
  287. {
  288. return (FARPROC) DirectXSetup;
  289. }
  290. else if (CheckProc(csProcName, L"directxsetupa"))
  291. {
  292. return (FARPROC) DirectXSetupA;
  293. }
  294. else if (CheckProc(csProcName, L"directxsetupw"))
  295. {
  296. return (FARPROC) DirectXSetupW;
  297. }
  298. else if (CheckProc(csProcName, L"directxsetupgetversion"))
  299. {
  300. return (FARPROC) DirectXSetupGetVersion;
  301. }
  302. }
  303. CSTRING_CATCH
  304. {
  305. // Do nothing
  306. }
  307. }
  308. return ORIGINAL_API(GetProcAddress)(hModule, lpProcName);
  309. }
  310. /*++
  311. This stub function breaks into FreeLibrary and checks to see if hLibModule
  312. equals FAKE_MODULE. If so return TRUE. If hLibModule does not contain
  313. FAKE_MODULE return the original argument.
  314. --*/
  315. BOOL
  316. APIHOOK(FreeLibrary)(
  317. HMODULE hLibModule
  318. )
  319. {
  320. BOOL bRet;
  321. if (hLibModule == g_hinstDll)
  322. {
  323. DPFN(
  324. eDbgLevelInfo,
  325. "[FreeLibrary] Caught DSETUP.DLL/DSETUP32.DLL free attempt. Returning TRUE");
  326. bRet = TRUE;
  327. }
  328. else
  329. {
  330. bRet = ORIGINAL_API(FreeLibrary)(hLibModule);
  331. }
  332. return bRet;
  333. }
  334. /*++
  335. Register hooked functions
  336. --*/
  337. HOOK_BEGIN
  338. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryA)
  339. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryW)
  340. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryExA)
  341. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryExW)
  342. APIHOOK_ENTRY(KERNEL32.DLL, GetProcAddress)
  343. APIHOOK_ENTRY(KERNEL32.DLL, FreeLibrary)
  344. HOOK_END
  345. IMPLEMENT_SHIM_END