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.

385 lines
12 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. ntrtlbuffer3.c
  5. Abstract:
  6. Author:
  7. Jay Krell (JayKrell) January 2002
  8. Environment:
  9. Revision History:
  10. --*/
  11. #include "ntrtlbuffer3.h"
  12. typedef struct _REVEAL_RTL_BYTE_BUFFER3 {
  13. PREVEAL_RTL_BYTE_BUFFER3 Self; // for heap allocated "mini dynamic"
  14. PVOID Buffer;
  15. SIZE_T RequestedSize;
  16. SIZE_T AllocatedSize;
  17. PVOID StaticBuffer;
  18. SIZE_T StaticBufferSize;
  19. PCRTL_BUFFER3_ALLOCATOR Traits;
  20. PVOID TraitsContext;
  21. } REVEAL_RTL_BYTE_BUFFER3, *PREVEAL_RTL_BYTE_BUFFER3;
  22. typedef const REVEAL_RTL_BYTE_BUFFER3 * PCREVEAL_RTL_BYTE_BUFFER3;
  23. PREVEAL_RTL_BYTE_BUFFER3
  24. RtlpRevealByteBuffer3(
  25. PRTL_BYTE_BUFFER3 OpaqueBuffer
  26. )
  27. {
  28. return ((PREVEAL_RTL_BYTE_BUFFER3)OpaqueBuffer)->Self;
  29. }
  30. RTL_BUFFER3_RETURN
  31. FASTCALL
  32. RtlInitByteBuffer3(
  33. ULONG Flags,
  34. SIZE_T SizeofBuffer,
  35. PRTL_BYTE_BUFFER3 Buffer,
  36. SIZE_T SizeofStaticBuffer,
  37. PBYTE StaticBuffer,
  38. SIZE_T SizeofTraits,
  39. PCRTL_BUFFER3_ALLOCATOR Traits,
  40. PVOID TraitsContext
  41. )
  42. {
  43. RTL_BUFFER3_RETURN Ret;
  44. PREVEAL_RTL_BYTE_BUFFER3 Revealed;
  45. BOOL NewStaticWithMiniDynamic;
  46. if (SizeofBuffer < sizeof(*Buffer))
  47. {
  48. if (SizeofBuffer < (sizeof(ULONG_PTR)))
  49. {
  50. goto InvalidParameter;
  51. }
  52. if (Traits == NULL)
  53. {
  54. goto InvalidParameter;
  55. }
  56. if (!RTL_CONTAINS_FIELD(Traits, SizeofTraits, CanAllocate))
  57. {
  58. goto InvalidParameter;
  59. }
  60. if (!RTL_CONTAINS_FIELD(Traits, SizeofTraits, Allocate))
  61. {
  62. goto InvalidParameter;
  63. }
  64. if (!Traits->CanAllocate(TraitsContext))
  65. {
  66. goto InvalidParameter;
  67. }
  68. NewStaticWithMiniDynamic = (StaticBuffer == NULL && SizeofStaticBuffer != 0);
  69. RevealedSize = sizeof(*Revealed;
  70. if (NewStaticWithMiniDynamic)
  71. {
  72. RevealedSize += SizeofStaticBuffer;
  73. }
  74. Revealed = (PREVEAL_RTL_BYTE_BUFFER3)Traits->Allocate(TraitsContext, RevealedSize);
  75. if (Revealed == NULL)
  76. {
  77. if (NewStaticWithMiniDynamic)
  78. {
  79. NewStaticWithMiniDynamic = FALSE;
  80. Revealed = (PREVEAL_RTL_BYTE_BUFFER3)Traits->Allocate(TraitsContext, sizeof(*Revealed));
  81. }
  82. if (Revealed == NULL)
  83. {
  84. goto CallbackError;
  85. }
  86. }
  87. if (NewStaticWithMiniDynamic)
  88. {
  89. StaticBuffer = (PBYTE)(Revealed + 1);
  90. }
  91. }
  92. else
  93. {
  94. Revealed = (PREVEAL_RTL_BYTE_BUFFER3)Buffer;
  95. }
  96. ((PREVEAL_RTL_BYTE_BUFFER3)OpaqueBuffer)->Self = Revealed;
  97. Revealed->StaticBuffer = StaticBuffer;
  98. Revealed->StaticBufferSize = SizeofStaticBuffer;
  99. Revealed->RequestedSize = 0;
  100. Revealed->AllocatedSize = SizeofStaticBuffer;
  101. Revealed->Buffer = StaticBuffer;
  102. Revealed->Traits = Traits;
  103. Revealed->TraitsContext = TraitsContext;
  104. Ret = RTL_BUFFER3_SUCCESS;
  105. Exit:
  106. return Ret;
  107. InvalidParameter:
  108. Ret = RTL_BUFFER3_INVALID_PARAMETER;
  109. goto Exit;
  110. CallbackError:
  111. Ret = RTL_BUFFER3_CALLBACK_ERROR;
  112. goto Exit;
  113. }
  114. BOOL FASTCALL RtlBuffer3Allocator_CanAllocate_False(PVOID VoidContext) { return FALSE; }
  115. BOOL FASTCALL RtlBuffer3Allocator_CanAllocate_True(PVOID VoidContext) { return TRUE; }
  116. BOOL FASTCALL RtlBuffer3Allocator_CanReallocate_False(PVOID VoidContext) { return FALSE; }
  117. BOOL FASTCALL RtlBuffer3Allocator_CanReallocate_True(PVOID VoidContext) { return TRUE; }
  118. #if defined(_WINBASE_)
  119. #define RtlpBuffer3Allocator_Win32HeapGetHeap(c) \
  120. (((c) != NULL && (c)->UsePrivateHeap) ? (c)->PrivateHeap : GetProcessHeap())
  121. #define RtlpBuffer3Allocator_Win32HeapGetError(c) \
  122. (((c) != NULL && (c)->UsePrivateError) ? (c)->PrivateOutOfMemoryError : ERROR_NO_MEMORY)
  123. #define RtlpBuffer3Allocator_Win32HeapGetFlags(c) \
  124. (((c) != NULL) ? (c)->HeapFlags : 0)
  125. #define RtlpBuffer3Allocator_Win32HeapSetLastError(c) \
  126. (((c) == NULL || (c)->DoNotSetLastError) ? ((void)0) : SetLastError(RtlpBuffer3Allocator_Win32HeapGetError(c)))
  127. PVOID FASTCALL RtlBuffer3Allocator_Win32HeapAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
  128. {
  129. PVOID p;
  130. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  131. p = HeapAlloc(RtlpBuffer3Allocator_Win32HeapGetHeap(Context), RtlpBuffer3Allocator_Win32HeapGetFlags(Context), NumberOfBytes);
  132. if (p == NULL)
  133. RtlpBuffer3Allocator_Win32HeapSetLastError(Context);
  134. return p;
  135. }
  136. VOID FASTCALL RtlBuffer3Allocator_Win32HeapFree(PVOID VoidContext, PVOID Pointer);
  137. {
  138. PVOID p;
  139. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  140. HeapFree(RtlpBuffer3Allocator_Win32HeapGetHeap(Context), RtlpBuffer3Allocator_Win32HeapGetFlags(Context), Pointer);
  141. }
  142. PVOID FASTCALL RtlBuffer3Allocator_Win32HeapReallocate(PVOID VoidContext, PVOID OldPointer, SIZE_T NewSize)
  143. {
  144. PVOID p;
  145. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  146. p = HeapReAlloc(RtlpBuffer3Allocator_Win32HeapGetHeap(Context), RtlpBuffer3Allocator_Win32HeapGetFlags(Context), OldPointer, NewSize);
  147. if (p == NULL)
  148. RtlpBuffer3Allocator_Win32HeapSetLastError(Context);
  149. return p;
  150. }
  151. #endif
  152. #if defined(_NTRTL_) || defined(_NTURTL_)
  153. #if RTLBUFFER3_KERNELMODE
  154. #define RtlpBuffer3Allocator_NtHeapGetHeap(c) \
  155. (ASSERT((c) != NULL), ASSERT((c)->UsePrivateHeap), ASSERT((c)->PrivateHeap != NULL), (c)->PrivateHeap)
  156. #define RtlpBuffer3Allocator_NtHeapGetFlags(c) \
  157. (ASSERT((c) != NULL), (c)->HeapFlags)
  158. #else
  159. #define RtlpBuffer3Allocator_NtHeapGetHeap(c) \
  160. (((c) != NULL && (c)->UsePrivateHeap) ? (c)->PrivateHeap : RtlProcessHeap())
  161. #define RtlpBuffer3Allocator_NtHeapGetFlags(c) \
  162. (((c) != NULL) ? (c)->HeapFlags : 0)
  163. #endif
  164. PVOID FASTCALL RtlBuffer3Allocator_NtHeapAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
  165. {
  166. PVOID p;
  167. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  168. p = RtlAllocateHeap(RtlpBuffer3Allocator_NtHeapGetHeap(Context), RtlpBuffer3Allocator_NtHeapGetFlags(Context), NumberOfBytes);
  169. return p;
  170. }
  171. VOID FASTCALL RtlBuffer3Allocator_NtHeapFree(PVOID VoidContext, PVOID Pointer);
  172. {
  173. PVOID p;
  174. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  175. RtlFreeHeap(RtlpBuffer3Allocator_NtHeapGetHeap(Context), RtlpBuffer3Allocator_NtHeapGetFlags(Context), Pointer);
  176. }
  177. PVOID FASTCALL RtlBuffer3Allocator_NtHeapReallocate(PVOID VoidContext, PVOID OldPointer, SIZE_T NewSize)
  178. {
  179. #if RTLBUFFER3_KERNELMODE || !defined(_NTURTL_)
  180. return NULL;
  181. #else
  182. PVOID p;
  183. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  184. p = RtlReAllocateHeap(RtlpBuffer3Allocator_NtHeapGetHeap(Context), RtlpBuffer3Allocator_NtHeapGetFlags(Context), OldPointer, NewSize);
  185. return p;
  186. #endif
  187. }
  188. #endif
  189. SIZE_T FASTCALL * RtlBuffer3Allocator_FixedAllocationSize(PVOID VoidContext, SIZE_T CurrentAllocatedSize, SIZE_T RequiredSize)
  190. {
  191. return CurrentAllocatedSize;
  192. }
  193. SIZE_T FASTCALL * RtlBuffer3Allocator_DoublingAllocationSize(PVOID VoidContext, SIZE_T CurrentAllocatedSize, SIZE_T RequiredSize)
  194. {
  195. CurrentAllocatedSize += CurrentAllocatedSize;
  196. return (RequiredSize >= CurrentAllocatedSize) ? RequiredSize : CurrentAllocatedSize;
  197. }
  198. SIZE_T FASTCALL * RtlBuffer3Allocator_MinimumAlocationSize(PVOID VoidContext, SIZE_T CurrentAllocatedSize, SIZE_T RequiredSize)
  199. {
  200. return RequiredSize;
  201. }
  202. //
  203. // RtlAllocateStringRoutine is not exported outside of ntoskrnl.exe and ntdll.dll.
  204. // RtlFreeStringRoutine is exported directly enough via RtlFreeUnicodeString.
  205. //
  206. // see base\ntdll\ldrinit.c and base\ntos\ex\pool.c for the definitions
  207. // of RtlAllocateStringRoutine and RtlFreeStringRoutine.
  208. //
  209. VOID FASTCALL RtlBuffer3Allocator_NtStringFree(PVOID VoidContext, PVOID Pointer)
  210. {
  211. UNICODE_STRING UnicodeString;
  212. UnicodeString.Buffer = (PWSTR)Pointer;
  213. RtlFreeUnicodeString(&UnicodeString);
  214. }
  215. #if RTLBUFFER3_NTKERNEL || RTLBUFFER3_NTDLL
  216. PVOID FASTCALL RtlBuffer3Allocator_NtStringAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
  217. {
  218. return (*RtlAllocateStringRoutine)(NumberOfBytes);
  219. }
  220. #elif RTLBUFFER3_USERMODE
  221. PVOID FASTCALL RtlBuffer3Allocator_NtStringAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
  222. {
  223. return RtlAllocateHeap(RtlProcessHeap(), 0, NumberOfBytes);
  224. }
  225. #elif RTLBUFFER3_KERNELMODE
  226. PVOID FASTCALL RtlBuffer3Allocator_NtStringAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
  227. {
  228. #undef ExAllocatePoolWithTag
  229. return ExAllocatePoolWithTag(PagedPool,NumberOfBytes,'grtS');
  230. }
  231. #endif
  232. #if RTLBUFFER3_KERNELMODE && (defined(_EX_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTOSP_) || defined(_WDM_) || defined(_NTHAL_))
  233. #define RtlpBuffer3Allocator_NtkernelPool_GetWhichFunction(c) \
  234. (((c) != NULL) ? (c)->WhichFunction : RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL)
  235. #define RtlpBuffer3Allocator_NtkernelPool_GetTag(c) \
  236. (((c) != NULL) ? (c)->Tag : 0)
  237. #define RtlpBuffer3Allocator_NtkernelPool_GetType(c) \
  238. (((c) != NULL) ? (c)->Type : NonPagedPool)
  239. #define RtlpBuffer3Allocator_NtkernelPool_GetPriority(c) \
  240. (((c) != NULL) ? (c)->Priority : NormalPoolPriority)
  241. #undef ExAllocatePoolWithTag
  242. #undef ExAllocatePool
  243. #undef ExAllocatePoolWithQuota
  244. #undef ExAllocatePoolWithQuotaTag
  245. #undef ExFreePool
  246. #undef ExFreePoolWithTag
  247. PVOID FASTCALL RtlBuffer3Allocator_NtkernelPoolAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
  248. {
  249. PVOID p;
  250. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  251. switch (RtlpBuffer3Allocator_NtkernelPool_GetWhichFunction(Context))
  252. {
  253. default:
  254. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL:
  255. p = ExAllocatePool(
  256. RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
  257. NumberOfBytes
  258. );
  259. break;
  260. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG:
  261. p = ExAllocatePoolWithTag(
  262. RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
  263. NumberOfBytes,
  264. RtlpBuffer3Allocator_NtkernelPool_GetTag(Context)
  265. );
  266. break;
  267. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA:
  268. p = ExAllocatePoolWithQuota(
  269. RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
  270. NumberOfBytes
  271. );
  272. break;
  273. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA_TAG:
  274. p = ExAllocatePoolWithQuotaTag(
  275. RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
  276. NumberOfBytes,
  277. RtlpBuffer3Allocator_NtkernelPool_GetTag(Context)
  278. );
  279. break;
  280. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG_PRIORITY:
  281. p = ExAllocatePoolWithTagPriority(
  282. RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
  283. NumberOfBytes,
  284. RtlpBuffer3Allocator_NtkernelPool_GetTag(Context),
  285. RtlpBuffer3Allocator_NtkernelPool_GetPriority(Context)
  286. );
  287. break;
  288. }
  289. return p;
  290. }
  291. VOID FASTCALL RtlBuffer3Allocator_NtKernelPoolFree(PVOID VoidContext, PVOID Pointer)
  292. {
  293. PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context;
  294. //
  295. // ExFreePool/ExAllocatePoolWithTag, pretty unique among allocators, does not accept NULL.
  296. //
  297. if (Pointer == NULL)
  298. return;
  299. Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
  300. switch (RtlpBuffer3Allocator_NtkernelPool_GetWhichFunction(Context))
  301. {
  302. default:
  303. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL:
  304. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA:
  305. ExFreePool(Pointer);
  306. break;
  307. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG:
  308. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA_TAG:
  309. case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG_PRIORITY:
  310. ExAllocatePoolWithTag(Pointer);
  311. break;
  312. }
  313. }
  314. #endif