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.

143 lines
2.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. IgnoreFreeLibrary.cpp
  5. Abstract:
  6. Some applications free DLLs before they're actually ready to. When this occurs,
  7. if the offending application attempts to make a call to an exported function,
  8. the call fails. This results in an access violation.
  9. This shim takes a command line of ; delimited DLL names. For each DLL on the command
  10. line, a call to FreeLibrary for the specified DLL will be ignored.
  11. Example:
  12. xanim.dll
  13. video_3dfx.dll;glide.dll
  14. Notes:
  15. This is a general purpose shim.
  16. History:
  17. 10/31/2000 rparsons Created
  18. --*/
  19. #include "precomp.h"
  20. IMPLEMENT_SHIM_BEGIN(IgnoreFreeLibrary)
  21. #include "ShimHookMacro.h"
  22. APIHOOK_ENUM_BEGIN
  23. APIHOOK_ENUM_ENTRY(FreeLibrary)
  24. APIHOOK_ENUM_END
  25. #define MAX_FILES 64
  26. int g_nLibraryCountFreeLibrary = 0;
  27. CString * g_rgLibrariesToIgnoreFreeLibrary = NULL;
  28. /*++
  29. Hook the call to FreeLibrary. Determine if the file name that corresponds to this
  30. module should be ignored.
  31. --*/
  32. BOOL
  33. APIHOOK(FreeLibrary)(
  34. HMODULE hModule
  35. )
  36. {
  37. CSTRING_TRY
  38. {
  39. CString csModule;
  40. csModule.GetModuleFileNameW(hModule);
  41. CString csFileName;
  42. csModule.GetLastPathComponent(csFileName);
  43. for (int i = 0; i < g_nLibraryCountFreeLibrary; ++i)
  44. {
  45. if (csFileName.CompareNoCase(g_rgLibrariesToIgnoreFreeLibrary[i]) == 0)
  46. {
  47. DPFN( eDbgLevelInfo, "Caught attempt freeing %S\n", csModule.Get());
  48. return TRUE;
  49. }
  50. }
  51. }
  52. CSTRING_CATCH
  53. {
  54. // Do Nothing
  55. }
  56. return ORIGINAL_API(FreeLibrary)(hModule);
  57. }
  58. /*++
  59. This function parses the COMMAND_LINE for the libraries that should
  60. have their FreeLibrary call ignored.
  61. --*/
  62. BOOL ParseCommandLine()
  63. {
  64. CSTRING_TRY
  65. {
  66. CString csCl(COMMAND_LINE);
  67. CStringParser csParser(csCl, L";");
  68. g_nLibraryCountFreeLibrary = csParser.GetCount();
  69. g_rgLibrariesToIgnoreFreeLibrary = csParser.ReleaseArgv();
  70. }
  71. CSTRING_CATCH
  72. {
  73. return FALSE;
  74. }
  75. for (int i = 0; i < g_nLibraryCountFreeLibrary; ++i) {
  76. DPFN( eDbgLevelInfo, "Library %d: name: --%S--\n", i, g_rgLibrariesToIgnoreFreeLibrary[i].Get());
  77. }
  78. return TRUE;
  79. }
  80. BOOL
  81. NOTIFY_FUNCTION(
  82. DWORD fdwReason
  83. )
  84. {
  85. if (fdwReason == DLL_PROCESS_ATTACH) {
  86. return ParseCommandLine();
  87. }
  88. return TRUE;
  89. }
  90. /*++
  91. Register hooked functions
  92. --*/
  93. HOOK_BEGIN
  94. CALL_NOTIFY_FUNCTION
  95. APIHOOK_ENTRY(KERNEL32.DLL, FreeLibrary)
  96. HOOK_END
  97. IMPLEMENT_SHIM_END