Sync to trunk (r44371)
[reactos.git] / reactos / ntoskrnl / mm / dbgpool.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/mm/dbgpool.c
5 * PURPOSE: Debug version of a pool allocator
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9 /* INCLUDES ***************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS **************************************************************/
16
17 typedef struct _EI_WHOLE_PAGE_HEADER {
18 PVOID ActualAddress;
19 ULONG Size;
20 ULONG Tag;
21 } EI_WHOLE_PAGE_HEADER, *PEI_WHOLE_PAGE_HEADER;
22
23 BOOLEAN
24 NTAPI
25 ExpIsPoolTagDebuggable(ULONG Tag)
26 {
27 #if 0
28 if (Tag == 'llaC') return FALSE;
29 if (Tag == 'virD') return FALSE;
30 if (Tag == 'iveD') return FALSE;
31 if (Tag == 'padA') return FALSE;
32
33 if (Tag == 'dSeS') return FALSE;
34 if (Tag == 'iDbO') return FALSE;
35 if (Tag == 'mNbO') return FALSE;
36 if (Tag == 'DNbO') return FALSE;
37 if (Tag == 'btbO') return FALSE;
38 if (Tag == 'cSbO') return FALSE;
39 //if (Tag == 'iSeS') return FALSE;
40 //if (Tag == 'cAeS') return FALSE;
41 #endif
42
43 return TRUE;
44 }
45
46
47 PVOID
48 NTAPI
49 ExpAllocateDebugPool(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Caller, BOOLEAN EndOfPage)
50 {
51 ULONG UserSize, TotalSize, AlignedSize;
52 ULONG_PTR UserData, GuardArea;
53 PEI_WHOLE_PAGE_HEADER Header;
54 ULONG_PTR Buffer;
55
56 /* Calculate sizes */
57 AlignedSize = ROUND_UP(Size, MM_POOL_ALIGNMENT);
58 UserSize = AlignedSize + sizeof(EI_WHOLE_PAGE_HEADER);
59 TotalSize = UserSize + 2*PAGE_SIZE;
60
61 /* Right now we support only end-of-page allocations */
62 ASSERT(EndOfPage);
63
64 /* Allocate space using default routine */
65 if (Type & PAGED_POOL_MASK)
66 {
67 Buffer = (ULONG_PTR)
68 ExAllocatePagedPoolWithTag(Type, TotalSize, Tag);
69 }
70 else
71 {
72 ASSERT(FALSE);
73 return NULL;
74 }
75
76
77 /* If allocation failed - fail too */
78 if (!Buffer)
79 {
80 DPRINT1("A big problem! Pool allocation failed!\n");
81 return NULL;
82 }
83
84 /* Calculate guard area as placed on a page boundary
85 * at the end of allocated area */
86 GuardArea = PAGE_ROUND_DOWN(Buffer + TotalSize - PAGE_SIZE + 1);
87
88 /* Calculate user data and header pointers */
89 UserData = GuardArea - AlignedSize;
90 Header = (PEI_WHOLE_PAGE_HEADER)(UserData - sizeof(EI_WHOLE_PAGE_HEADER));
91
92 /* Fill out the header */
93 Header->ActualAddress = (PVOID)Buffer;
94 Header->Tag = Tag;
95 Header->Size = AlignedSize;
96
97 /* Protect the guard page */
98 MmSetPageProtect(NULL, (PVOID)GuardArea, PAGE_NOACCESS);
99
100 DPRINT("Allocating whole page block Tag %c%c%c%c, Buffer %p, Header %p, UserData %p, GuardArea %p, Size %d\n",
101 Tag & 0xFF, (Tag >> 8) & 0xFF,
102 (Tag >> 16) & 0xFF, (Tag >> 24) & 0xFF,
103 Buffer, Header, UserData, GuardArea, Size);
104
105 return (PVOID)UserData;
106 }
107
108 VOID
109 NTAPI
110 ExpFreeDebugPool(PVOID Block, BOOLEAN PagedPool)
111 {
112 PEI_WHOLE_PAGE_HEADER Header;
113 PVOID ProtectedPage;
114
115 /* Get pointer to our special header */
116 Header = (PEI_WHOLE_PAGE_HEADER)
117 (((PCHAR)Block) - sizeof(EI_WHOLE_PAGE_HEADER));
118
119 DPRINT("Freeing whole page block at %08x (Tag %c%c%c%c, %x Header %x)\n", Block,
120 Header->Tag & 0xFF, (Header->Tag >> 8) & 0xFF,
121 (Header->Tag >> 16) & 0xFF, (Header->Tag >> 24) & 0xFF, Header->Tag, Header);
122
123 /* Calculate protected page adresss */
124 ProtectedPage = ((PCHAR)Block) + Header->Size;
125
126 /* Unprotect it */
127 MmSetPageProtect(NULL, ProtectedPage, PAGE_READWRITE);
128
129 /* Free storage */
130 ASSERT(PagedPool);
131 ExFreePagedPool(Header->ActualAddress);
132 }
133
134 /* EOF */