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.

143 lines
3.0 KiB

  1. /*++
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. HeapDelayLocalFree.cpp
  5. Abstract:
  6. Delay calls to LocalFree.
  7. History:
  8. 09/19/2000 robkenny
  9. 02/12/2002 robkenny Convert InitializeCriticalSection to InitializeCriticalSectionAndSpinCount
  10. and checking return status to verify that critical section was
  11. actually created.
  12. Shim was deallocating memory in SHIM_PROCESS_DETACH, which can
  13. cause the shim to crash when the process is exiting, since there
  14. is not guarantee that the shim will not be called from other
  15. libraries afterwards.
  16. --*/
  17. #include "precomp.h"
  18. #include "CharVector.h"
  19. IMPLEMENT_SHIM_BEGIN(HeapDelayLocalFree)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(LocalFree)
  23. APIHOOK_ENUM_END
  24. CRITICAL_SECTION g_CritSec;
  25. static VectorT<HLOCAL> *g_DelayLocal = NULL;
  26. static DWORD g_DelayBufferSize = 20;
  27. HLOCAL
  28. APIHOOK(LocalFree)(
  29. HLOCAL hMem // handle to local memory object
  30. )
  31. {
  32. if (hMem == NULL)
  33. return NULL;
  34. if (g_DelayLocal)
  35. {
  36. EnterCriticalSection(&g_CritSec);
  37. // If the list is full
  38. if (g_DelayLocal->Size() > 0 &&
  39. g_DelayLocal->Size() >= g_DelayLocal->MaxSize())
  40. {
  41. HLOCAL & hDelayed = g_DelayLocal->Get(0);
  42. #if DBG
  43. DPFN(eDbgLevelInfo, "LocalFree(0x%08x).", hDelayed);
  44. #endif
  45. ORIGINAL_API(LocalFree)(hDelayed);
  46. g_DelayLocal->Remove(0);
  47. }
  48. g_DelayLocal->Append(hMem);
  49. #if DBG
  50. DPFN(eDbgLevelInfo, "Delaying LocalFree(0x%08x).", hMem);
  51. #endif
  52. LeaveCriticalSection(&g_CritSec);
  53. return NULL;
  54. }
  55. HLOCAL returnValue = ORIGINAL_API(LocalFree)(hMem);
  56. return returnValue;
  57. }
  58. BOOL ParseCommandLine(const char * /*commandLine*/)
  59. {
  60. // Preallocate the event, prevents EnterCriticalSection
  61. // from throwing an exception in low-memory situations.
  62. if (!InitializeCriticalSectionAndSpinCount(&g_CritSec, 0x8000000))
  63. {
  64. return FALSE;
  65. }
  66. g_DelayLocal = new VectorT<HLOCAL>;
  67. if (g_DelayLocal)
  68. {
  69. // If we cannot resize the array, stop now
  70. if (!g_DelayLocal->Resize(g_DelayBufferSize))
  71. {
  72. delete g_DelayLocal;
  73. g_DelayLocal = NULL;
  74. // Turn off all hooks:
  75. return FALSE;
  76. }
  77. }
  78. return TRUE;
  79. }
  80. /*++
  81. Register hooked functions
  82. --*/
  83. BOOL
  84. NOTIFY_FUNCTION(
  85. DWORD fdwReason
  86. )
  87. {
  88. if (fdwReason == DLL_PROCESS_ATTACH)
  89. {
  90. return ParseCommandLine(COMMAND_LINE);
  91. }
  92. return TRUE;
  93. }
  94. /*++
  95. Register hooked functions
  96. --*/
  97. HOOK_BEGIN
  98. CALL_NOTIFY_FUNCTION
  99. APIHOOK_ENTRY(KERNEL32.DLL, LocalFree)
  100. HOOK_END
  101. IMPLEMENT_SHIM_END