1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxLookasideList.cpp
8
9 Abstract:
10
11 This module implements a frameworks managed FxLookasideList
12
13 Author:
14
15
16 Environment:
17
18 kernel mode only
19
20 Revision History:
21
22 --*/
23
24 #include "coreprivshared.hpp"
25 #include "fxlookasidelist.hpp"
26
FxLookasideList(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in USHORT ObjectSize,__in ULONG PoolTag)27 FxLookasideList::FxLookasideList(
28 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
29 __in USHORT ObjectSize,
30 __in ULONG PoolTag
31 ) :
32 FxObject(FX_TYPE_LOOKASIDE, ObjectSize, FxDriverGlobals),
33 m_BufferSize(0), m_PoolTag(PoolTag), m_MemoryObjectSize(0)
34 /*++
35
36 Routine Description:
37 Constructor for FxLookasideList
38
39 Arguments:
40 ObjectSize - Size of the derived object.
41
42 PoolTag - Tag to use when allocating memory.
43
44 Return Value:
45 None
46
47 --*/
48 {
49 }
50
~FxLookasideList()51 FxLookasideList::~FxLookasideList()
52 /*++
53
54 Routine Description:
55 Destructor for FxLookasideList. Default implementation does nothing.
56 Derived classes will call the appropriate NTOS export to remove itself from
57 the list of lookaside lists.
58
59 Arguments:
60 None
61
62 Return Value:
63 None
64
65 --*/
66 {
67 }
68
69 _Must_inspect_result_
70 NTSTATUS
InitializeLookaside(__in USHORT BufferSize,__in USHORT MemoryObjectSize,__in PWDF_OBJECT_ATTRIBUTES MemoryAttributes)71 FxLookasideList::InitializeLookaside(
72 __in USHORT BufferSize,
73 __in USHORT MemoryObjectSize,
74 __in PWDF_OBJECT_ATTRIBUTES MemoryAttributes
75 )
76 /*++
77
78 Routine Description:
79 Computes the memory object size to be used by the derived class. This
80 function handles the overflow in computing the size and returns an error
81 if that occurs.
82
83 Arguments:
84 BufferSize - the length of the buffer being allocated alongside the object
85
86 MemoryObjectSize - the raw size of the FxObject derived object, ie
87 sizeof(FxMemoryBufferFromLookaside)
88
89 MemoryAttributes - attributes to be associated for each memory object created
90
91 Return Value:
92 None
93
94 --*/
95 {
96 size_t size;
97 NTSTATUS status;
98
99 if (MemoryAttributes != NULL) {
100 RtlCopyMemory(&m_MemoryAttributes,
101 MemoryAttributes,
102 sizeof(m_MemoryAttributes));
103 }
104 else {
105 RtlZeroMemory(&m_MemoryAttributes, sizeof(m_MemoryAttributes));
106 }
107
108 status = FxCalculateObjectTotalSize(GetDriverGlobals(),
109 MemoryObjectSize,
110 BufferSize,
111 &m_MemoryAttributes,
112 &size);
113
114 if (!NT_SUCCESS(status)) {
115 //
116 // FxCalculateObjectTotalSize logs an error to the IFR
117 //
118 return status;
119 }
120
121 status = FxPoolAddHeaderSize(GetDriverGlobals(), size, &size);
122 if (!NT_SUCCESS(status)) {
123 //
124 // FxPoolAddHeaderSize logs to the IFR on error
125 //
126 return status;
127 }
128
129 //
130 // It is *required* to set these values only once we know we are returning
131 // success b/c the derived classes use == 0 as an indication that Initialization
132 // failed and that any associated lookaside lists were not initialized.
133 //
134 m_MemoryObjectSize = size;
135 m_BufferSize = BufferSize;
136
137 return status;
138 }
139
140 #pragma prefast(push)
141
142
143
144 //This routine intentionally accesses the header of the allocated memory.
145 #pragma prefast(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY)
146 PVOID
147 FxLookasideList::InitObjectAlloc(
148 __out_bcount(this->m_MemoryObjectSize) PVOID Alloc
149 )
150 /*++
151
152 Routine Description:
153 Initializes the object allocation so that it can be tracked and inserted
154 in this drivers POOL.
155
156 Arguments:
157 Alloc - the raw allocation
158
159 Return Value:
160 the start of where the object memory should be, not necessarily == Alloc
161
162 --*/
163 {
164 PFX_DRIVER_GLOBALS pFxDriverGlobals;
165 PFX_POOL_HEADER pHeader;
166 PFX_POOL_TRACKER tracker;
167
168 pFxDriverGlobals = GetDriverGlobals();
169
170 RtlZeroMemory(Alloc, m_MemoryObjectSize);
171
172 if (pFxDriverGlobals->IsPoolTrackingOn()) {
173 //
174 // PoolTracking is active, so format and insert
175 // a tracker in the NonPagedHeader list of the pool.
176 //
177 tracker = (PFX_POOL_TRACKER) Alloc;
178 pHeader = WDF_PTR_ADD_OFFSET_TYPE(Alloc,
179 sizeof(FX_POOL_TRACKER),
180 PFX_POOL_HEADER);
181
182 pHeader->Base = Alloc;
183 pHeader->FxDriverGlobals = pFxDriverGlobals;
184
185 FxPoolInsertNonPagedAllocateTracker(
186 &pFxDriverGlobals->FxPoolFrameworks,
187 tracker,
188 m_BufferSize,
189 m_PoolTag,
190 _ReturnAddress());
191 }
192 else {
193 //
194 // PoolTracking is inactive, only format FX_POOL_HEADER area.
195 //
196 pHeader = (PFX_POOL_HEADER) Alloc;
197 pHeader->Base = Alloc;
198 pHeader->FxDriverGlobals = pFxDriverGlobals;
199 }
200
201 return &pHeader->AllocationStart[0];
202 }
203 #pragma prefast(pop)
204
205 VOID
_Reclaim(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__inout PNPAGED_LOOKASIDE_LIST List,__in FxMemoryBufferFromLookaside * Memory)206 FxLookasideList::_Reclaim(
207 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
208 __inout PNPAGED_LOOKASIDE_LIST List,
209 __in FxMemoryBufferFromLookaside* Memory
210 )
211 {
212 PFX_POOL_HEADER pHeader;
213
214 pHeader = FxObject::_CleanupPointer(FxDriverGlobals, (FxObject*) Memory);
215
216 FxFreeToNPagedLookasideList(List, pHeader->Base);
217 }
218