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.

152 lines
3.5 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. SpecOps2.cpp
  5. Abstract:
  6. App does too much within a DLLMain and hangs because dinput is waiting on
  7. a thread it just created.
  8. The fix is to prevent the DllMain from running during the loader lock. The
  9. only way to do this seems to be to hook an API that's called really early
  10. during the DllMain and jump back to the loader.
  11. The catch is that we still need to call the DllMain after the LoadLibrary
  12. has completed.
  13. Notes:
  14. This is an app specific shim.
  15. History:
  16. 05/01/2001 linstev Created
  17. --*/
  18. #include "precomp.h"
  19. IMPLEMENT_SHIM_BEGIN(SpecOps2)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(GetVersion)
  23. APIHOOK_ENUM_ENTRY(LoadLibraryA)
  24. APIHOOK_ENUM_END
  25. // Global state used to determine what to do for a particular call
  26. BOOL g_bState = FALSE;
  27. // The thread handle for matching synchronization logic
  28. HANDLE g_hThread = NULL;
  29. /*++
  30. This is the first API that the DllMain calls, so we're going to back out
  31. jump straight out of it, back into loader code as if it completed normally.
  32. --*/
  33. __declspec(naked)
  34. DWORD
  35. APIHOOK(GetVersion)(
  36. void
  37. )
  38. {
  39. __asm {
  40. //
  41. // Make sure we're on the right thread so we don't have to synchronize
  42. //
  43. call dword ptr [GetCurrentThread]
  44. cmp eax, g_hThread
  45. jne Exit
  46. // test for the right dll
  47. cmp g_bState, 1
  48. jne Exit
  49. // we're done
  50. mov g_bState, 0
  51. // leave the stack and registers as they were before
  52. add esp, 20
  53. pop edi
  54. pop esi
  55. pop ebx
  56. pop ebp
  57. ret 12
  58. Exit:
  59. // original api
  60. call dword ptr [GetVersion]
  61. ret
  62. }
  63. }
  64. /*++
  65. When "SO Menu.dll" is loaded, we start the sequence which prevents the DllMain
  66. from crashing, but it means we have to run the entry point after the load.
  67. --*/
  68. HINSTANCE
  69. APIHOOK(LoadLibraryA)(
  70. LPCSTR lpLibFileName
  71. )
  72. {
  73. BOOL bCheck = FALSE;
  74. if (_stricmp(lpLibFileName, "menu\\SO Menu.dll") == 0) {
  75. //
  76. // We assume *only* the main thread tries to load this library, so
  77. // we don't synchronize multiple threads trying to load this same dll
  78. //
  79. g_hThread = GetCurrentThread();
  80. bCheck = TRUE;
  81. g_bState = TRUE;
  82. }
  83. //
  84. // Load the library, if it's "SO Menu", we'll catch the GetVersion called
  85. // by its DllMain
  86. //
  87. HMODULE hMod = ORIGINAL_API(LoadLibraryA)(lpLibFileName);
  88. if (hMod && bCheck) {
  89. //
  90. // Run the DllMain
  91. //
  92. typedef BOOL (WINAPI *_pfn_DllMain)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
  93. PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER) hMod;
  94. PIMAGE_NT_HEADERS pINTH = (PIMAGE_NT_HEADERS)((LPBYTE)hMod + pIDH->e_lfanew);
  95. _pfn_DllMain pfnMain = (_pfn_DllMain)((LPBYTE)hMod + pINTH->OptionalHeader.AddressOfEntryPoint);
  96. // Call the startup routine
  97. (*pfnMain)(hMod, DLL_PROCESS_ATTACH, NULL);
  98. }
  99. return hMod;
  100. }
  101. /*++
  102. Register hooked functions
  103. --*/
  104. HOOK_BEGIN
  105. APIHOOK_ENTRY(KERNEL32.DLL, GetVersion)
  106. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryA)
  107. HOOK_END
  108. IMPLEMENT_SHIM_END