Leaked source code of windows server 2003
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.

298 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. IgnoreLoadLibrary.cpp
  5. Abstract:
  6. This shim allows the user to specified a list of libraries it tries to ignore and
  7. optionally the return values of the LoadLibrary call. Some apps try to load libraries
  8. they don't use but expect the LoadLibrary call to succeed.
  9. Use ; as the delimeter of the item and optionally use : to specify the return value.
  10. If you don't specify a return value we'll make the return value NULL.
  11. Eg:
  12. video_3dfx.dll;video_3dfx
  13. helper32.dll:1234;helper.dll
  14. Notes:
  15. This is a general purpose shim.
  16. History:
  17. 04/13/2000 a-jamd Created
  18. 10/11/2000 maonis Added support for specifying return values and renamed it from
  19. FailLoadLibrary to IgnoreLoadLibrary.
  20. 11/16/2000 linstev Added SetErrorMode emulation
  21. --*/
  22. #include "precomp.h"
  23. IMPLEMENT_SHIM_BEGIN(IgnoreLoadLibrary)
  24. #include "ShimHookMacro.h"
  25. // Globals are zero initialized by default. see c++ spec 3.6.2.
  26. CString * g_csIgnoreLib;
  27. int g_csIgnoreLibCount;
  28. DWORD * g_rgReturnValues;
  29. APIHOOK_ENUM_BEGIN
  30. APIHOOK_ENUM_ENTRY(LoadLibraryA)
  31. APIHOOK_ENUM_ENTRY(LoadLibraryExA)
  32. APIHOOK_ENUM_ENTRY(LoadLibraryW)
  33. APIHOOK_ENUM_ENTRY(LoadLibraryExW)
  34. APIHOOK_ENUM_END
  35. /*++
  36. This function parses the COMMAND_LINE for the libraries you wish to ignore.
  37. --*/
  38. BOOL ParseCommandLine(LPCSTR lpszCommandLine)
  39. {
  40. CSTRING_TRY
  41. {
  42. DPF(g_szModuleName, eDbgLevelInfo, "[ParseCommandLine] CommandLine(%s)\n", lpszCommandLine);
  43. CString csCl(lpszCommandLine);
  44. CStringParser csParser(csCl, L" ;");
  45. g_csIgnoreLibCount = csParser.GetCount();
  46. g_csIgnoreLib = csParser.ReleaseArgv();
  47. g_rgReturnValues = (DWORD *)malloc(sizeof(*g_rgReturnValues) * g_csIgnoreLibCount);
  48. if (g_csIgnoreLibCount && !g_rgReturnValues)
  49. {
  50. return FALSE;
  51. }
  52. // Iterate over all strings looking for a return value
  53. for (int i = 0; i < g_csIgnoreLibCount; ++i)
  54. {
  55. CStringToken csIgnore(g_csIgnoreLib[i], L":");
  56. CString csLib;
  57. CString csValue;
  58. csIgnore.GetToken(csLib);
  59. csIgnore.GetToken(csValue);
  60. if (!csValue.IsEmpty())
  61. {
  62. WCHAR *unused;
  63. g_csIgnoreLib[i] = csLib;
  64. g_rgReturnValues[i] = wcstol(csValue, &unused, 10);
  65. }
  66. else
  67. {
  68. // g_csIgnoreLib[i] is already initialized
  69. g_rgReturnValues[i] = 0;
  70. }
  71. DPF(g_szModuleName, eDbgLevelInfo, "[ParseCommandLine] library (%S) return value(%d)\n", g_csIgnoreLib[i].Get(), g_rgReturnValues[i]);
  72. }
  73. return TRUE;
  74. }
  75. CSTRING_CATCH
  76. {
  77. // Do nothing.
  78. }
  79. return FALSE;
  80. }
  81. /*++
  82. These stub functions break into LoadLibrary and check to see if lpLibFileName equals
  83. one of the specified dll's. If so return the specified return value. If not call LoadLibrary on it.
  84. --*/
  85. HINSTANCE
  86. APIHOOK(LoadLibraryA)(LPCSTR lpLibFileName)
  87. {
  88. CSTRING_TRY
  89. {
  90. CString csFilePath(lpLibFileName);
  91. CString csFileName;
  92. csFilePath.GetLastPathComponent(csFileName);
  93. for (int i = 0; i < g_csIgnoreLibCount; i++)
  94. {
  95. if (g_csIgnoreLib[i].CompareNoCase(csFileName) == 0)
  96. {
  97. LOG(g_szModuleName,eDbgLevelError, "[LoadLibraryA] Caught attempt loading %s, return %d\n", g_csIgnoreLib[i].Get(), g_rgReturnValues[i]);
  98. return (HINSTANCE) g_rgReturnValues[i];
  99. }
  100. }
  101. }
  102. CSTRING_CATCH
  103. {
  104. // Do Nothing
  105. }
  106. DPF(g_szModuleName, eDbgLevelSpew, "LoadLibraryA Allow(%s)", lpLibFileName);
  107. UINT uLastMode;
  108. HINSTANCE hRet;
  109. uLastMode = SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  110. hRet = ORIGINAL_API(LoadLibraryA)(lpLibFileName);
  111. SetErrorMode(uLastMode);
  112. return hRet;
  113. }
  114. HINSTANCE
  115. APIHOOK(LoadLibraryExA)(
  116. LPCSTR lpLibFileName,
  117. HANDLE hFile,
  118. DWORD dwFlags
  119. )
  120. {
  121. CSTRING_TRY
  122. {
  123. CString csFilePath(lpLibFileName);
  124. CString csFileName;
  125. csFilePath.GetLastPathComponent(csFileName);
  126. for (int i = 0; i < g_csIgnoreLibCount; i++)
  127. {
  128. if (g_csIgnoreLib[i].CompareNoCase(csFileName) == 0)
  129. {
  130. LOG(g_szModuleName,eDbgLevelError, "[LoadLibraryExA] Caught attempt loading %s, return %d\n", g_csIgnoreLib[i].Get(), g_rgReturnValues[i]);
  131. return (HINSTANCE) g_rgReturnValues[i];
  132. }
  133. }
  134. }
  135. CSTRING_CATCH
  136. {
  137. // Do Nothing
  138. }
  139. DPF(g_szModuleName, eDbgLevelSpew, "LoadLibraryExA Allow(%s)", lpLibFileName);
  140. UINT uLastMode;
  141. HINSTANCE hRet;
  142. uLastMode = SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  143. hRet = ORIGINAL_API(LoadLibraryExA)(lpLibFileName, hFile, dwFlags);
  144. SetErrorMode(uLastMode);
  145. return hRet;
  146. }
  147. HINSTANCE
  148. APIHOOK(LoadLibraryW)(LPCWSTR lpLibFileName)
  149. {
  150. CSTRING_TRY
  151. {
  152. CString csFilePath(lpLibFileName);
  153. CString csFileName;
  154. csFilePath.GetLastPathComponent(csFileName);
  155. for (int i = 0; i < g_csIgnoreLibCount; i++)
  156. {
  157. if (g_csIgnoreLib[i].CompareNoCase(csFileName) == 0)
  158. {
  159. LOG(g_szModuleName,eDbgLevelError, "[LoadLibraryW] Caught attempt loading %s, return %d\n", g_csIgnoreLib[i].Get(), g_rgReturnValues[i]);
  160. return (HINSTANCE) g_rgReturnValues[i];
  161. }
  162. }
  163. }
  164. CSTRING_CATCH
  165. {
  166. // Do Nothing
  167. }
  168. DPF(g_szModuleName, eDbgLevelSpew,"LoadLibraryW Allow(%S)", lpLibFileName);
  169. UINT uLastMode;
  170. HINSTANCE hRet;
  171. uLastMode = SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  172. hRet = ORIGINAL_API(LoadLibraryW)(lpLibFileName);
  173. SetErrorMode(uLastMode);
  174. return hRet;
  175. }
  176. HINSTANCE
  177. APIHOOK(LoadLibraryExW)(
  178. LPCWSTR lpLibFileName,
  179. HANDLE hFile,
  180. DWORD dwFlags
  181. )
  182. {
  183. CSTRING_TRY
  184. {
  185. CString csFilePath(lpLibFileName);
  186. CString csFileName;
  187. csFilePath.GetLastPathComponent(csFileName);
  188. for (int i = 0; i < g_csIgnoreLibCount; i++)
  189. {
  190. if (g_csIgnoreLib[i].CompareNoCase(csFileName) == 0)
  191. {
  192. LOG(g_szModuleName,eDbgLevelError, "[LoadLibraryExW] Caught attempt loading %s, return %d\n", g_csIgnoreLib[i].Get(), g_rgReturnValues[i]);
  193. return (HINSTANCE) g_rgReturnValues[i];
  194. }
  195. }
  196. }
  197. CSTRING_CATCH
  198. {
  199. // Do Nothing
  200. }
  201. DPF(g_szModuleName, eDbgLevelSpew,"APIHook_LoadLibraryExW Allow(%S)", lpLibFileName);
  202. UINT uLastMode;
  203. HINSTANCE hRet;
  204. uLastMode = SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  205. hRet = ORIGINAL_API(LoadLibraryExW)(lpLibFileName, hFile, dwFlags);
  206. SetErrorMode(uLastMode);
  207. return hRet;
  208. }
  209. /*++
  210. Register hooked functions
  211. --*/
  212. BOOL
  213. NOTIFY_FUNCTION(
  214. DWORD fdwReason)
  215. {
  216. if (fdwReason == DLL_PROCESS_ATTACH)
  217. {
  218. ParseCommandLine(COMMAND_LINE);
  219. }
  220. return TRUE;
  221. }
  222. HOOK_BEGIN
  223. CALL_NOTIFY_FUNCTION
  224. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryA)
  225. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryExA)
  226. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryW)
  227. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryExW)
  228. HOOK_END
  229. IMPLEMENT_SHIM_END