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.

188 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. alloca.h
  5. Abstract:
  6. This module implements a safe stack-based allocator with fallback to the heap.
  7. Author:
  8. Jonathan Schwartz (JSchwart) 16-Mar-2001
  9. Revision History:
  10. --*/
  11. #ifndef _SAFEALLOCA_H_
  12. #define _SAFEALLOCA_H_
  13. #ifdef __cplusplus
  14. extern "C"
  15. {
  16. #endif // __cplusplus
  17. #include <align.h> // ALIGN_WORST
  18. //
  19. // Type definitions
  20. //
  21. typedef ULONG SAFEALLOCA_HEADER;
  22. typedef PVOID (APIENTRY *SAFEALLOC_ALLOC_PROC)(
  23. SIZE_T Size
  24. );
  25. typedef VOID (APIENTRY *SAFEALLOC_FREE_PROC)(
  26. PVOID BaseAddress
  27. );
  28. //
  29. // Constant definitions
  30. //
  31. #ifndef SAFEALLOCA_ASSERT
  32. #define SAFEALLOCA_ASSERT ASSERT
  33. #endif
  34. #define SAFEALLOCA_STACK_HEADER ((SAFEALLOCA_HEADER) 0x6b637453) /* "Stck" */
  35. #define SAFEALLOCA_HEAP_HEADER ((SAFEALLOCA_HEADER) 0x70616548) /* "Heap" */
  36. #define SAFEALLOCA_USE_DEFAULT 0xdeadbeef
  37. //
  38. // We'll be adding ALIGN_WORST bytes to the allocation size to add room for
  39. // the SAFEALLOCA_HEADER -- make sure we'll always have enough space.
  40. //
  41. C_ASSERT(sizeof(SAFEALLOCA_HEADER) <= ALIGN_WORST);
  42. //
  43. // Per-DLL SafeAlloca globals
  44. //
  45. extern SIZE_T g_ulMaxStackAllocSize;
  46. extern SIZE_T g_ulAdditionalProbeSize;
  47. extern SAFEALLOC_ALLOC_PROC g_pfnAllocate;
  48. extern SAFEALLOC_FREE_PROC g_pfnFree;
  49. //
  50. // Functions defined in alloca.lib
  51. //
  52. VOID
  53. SafeAllocaInitialize(
  54. IN SIZE_T ulMaxStackAllocSize,
  55. IN SIZE_T ulAdditionalProbeSize,
  56. IN OPTIONAL SAFEALLOC_ALLOC_PROC pfnAllocate,
  57. IN OPTIONAL SAFEALLOC_FREE_PROC pfnFree
  58. );
  59. BOOL
  60. VerifyStackAvailable(
  61. SIZE_T Size
  62. );
  63. //
  64. // Usage:
  65. //
  66. // VOID
  67. // SafeAllocaAllocate(
  68. // PVOID PtrVar,
  69. // SIZE_T BlockSize
  70. // );
  71. //
  72. // (PtrVar == NULL) on failure
  73. //
  74. #define SafeAllocaAllocate(PtrVar, BlockSize) \
  75. \
  76. { \
  77. PVOID *ppvAvoidCast = (PVOID *) &(PtrVar); \
  78. \
  79. (PtrVar) = NULL; \
  80. \
  81. /* Make sure block is below the threshhold and that the probe won't overflow */ \
  82. \
  83. if ((BlockSize) <= g_ulMaxStackAllocSize \
  84. && \
  85. ((BlockSize) + g_ulAdditionalProbeSize + ALIGN_WORST >= (BlockSize))) \
  86. { \
  87. if (VerifyStackAvailable((BlockSize) \
  88. + g_ulAdditionalProbeSize \
  89. + ALIGN_WORST)) \
  90. { \
  91. /* \
  92. * Don't need to wrap with try-except since we just probed \
  93. */ \
  94. \
  95. *ppvAvoidCast = _alloca((BlockSize) + ALIGN_WORST); \
  96. } \
  97. \
  98. if ((PtrVar) != NULL) \
  99. { \
  100. *((SAFEALLOCA_HEADER *) (PtrVar)) = SAFEALLOCA_STACK_HEADER; \
  101. *ppvAvoidCast = ((LPBYTE) (PtrVar) + ALIGN_WORST); \
  102. } \
  103. } \
  104. \
  105. /* \
  106. * Stack allocation failed -- try the heap \
  107. */ \
  108. \
  109. if ((PtrVar) == NULL) \
  110. { \
  111. *ppvAvoidCast = g_pfnAllocate((BlockSize) + ALIGN_WORST); \
  112. \
  113. if ((PtrVar) != NULL) \
  114. { \
  115. *((SAFEALLOCA_HEADER *) (PtrVar)) = SAFEALLOCA_HEAP_HEADER; \
  116. *ppvAvoidCast = ((LPBYTE) (PtrVar) + ALIGN_WORST); \
  117. } \
  118. } \
  119. }
  120. //
  121. // Usage:
  122. //
  123. // VOID
  124. // SafeAllocaFree(
  125. // PVOID PtrVar,
  126. // );
  127. //
  128. #define SafeAllocaFree(PtrVar) \
  129. \
  130. if (PtrVar != NULL) \
  131. { \
  132. SAFEALLOCA_HEADER *Tag = (SAFEALLOCA_HEADER *) ((LPBYTE) (PtrVar) \
  133. - ALIGN_WORST); \
  134. \
  135. if (*(SAFEALLOCA_HEADER *) (Tag) == SAFEALLOCA_HEAP_HEADER) \
  136. { \
  137. g_pfnFree(Tag); \
  138. } \
  139. else \
  140. { \
  141. SAFEALLOCA_ASSERT(*(SAFEALLOCA_HEADER *) (Tag) == SAFEALLOCA_STACK_HEADER);\
  142. } \
  143. }
  144. #ifdef __cplusplus
  145. }
  146. #endif // __cplusplus
  147. #endif // _SAFEALLOCA_H_