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