ReactOS  0.4.15-dev-2704-gd5265b0
fxmemoryobject.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxMemoryObject.cpp
8 
9 Abstract:
10 
11  This module implements a frameworks managed FxMemoryObject
12 
13 Author:
14 
15 Environment:
16 
17  kernel mode only
18 
19 Revision History:
20 
21 --*/
22 
23 #include "coreprivshared.hpp"
24 
25 extern "C" {
26 // #include "FxMemoryObject.tmh"
27 }
28 
30  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
31  __in USHORT ObjectSize,
32  __in size_t BufferSize
33  ) :
34  // intentionally do not pass IFX_TYPE_MEMORY to the base constructor
35  // because we need to pass the interface back when converting from
36  // handle to object and that will require a different this pointer offset
37  // which will be handled by QueryInterface
38  FxObject(FX_TYPE_OBJECT, ObjectSize, FxDriverGlobals),
39  m_BufferSize(BufferSize)
40 {
41  //
42  // Since we are passing the generic object type FX_TYPE_OBJECT to FxObject,
43  // we need to figure out on our own if need to allocate a tag tracker or not.
44  //
45  if (IsDebug()) {
47  }
48 }
49 
53  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
57  __in size_t BufferSize,
59  )
60 {
61  //
62  // If the buffer is
63  // a) a PAGE or larger
64  // b) we are debugging allocations
65  // c) less then a page and pageable
66  //
67  // separate the object from its memory so that we can assure
68  //
69  // 1) the buffer pointer is PAGE aligned
70  // 2) the kernel's buffer overrun/underrun checking can be used
71  // 3) for case c), that the object is non pageable while the memory pointer
72  // it returns to the driver is pageable
73  //
74 
75  //
76  // By placing FxIsPagedPool last in the list, BufferSize < PAGE_SIZE
77  //
78  if (BufferSize >= PAGE_SIZE ||
79  (FxDriverGlobals->FxVerifierOn && FxDriverGlobals->FxPoolTrackingOn) ||
82  FxDriverGlobals,
83  Attributes,
84  PoolType,
85  PoolTag,
86  BufferSize,
87  Object);
88  }
89  else {
90 
91  //
92  // Before the changes for NxPool this code path assumed NonPagedPool
93  //
94  // To maintain compatibility with existing behavior (and add on NxPool
95  // options we pass in PoolType to FxMemoryBuffer::_Create but
96  // normalize NonPagedPool variants to NonPagedPool.
97  //
98  switch(PoolType)
99  {
104  }
105 
107  FxDriverGlobals,
108  Attributes,
109  PoolTag,
110  BufferSize,
111  PoolType,
112  Object);
113  }
114 }
115 
117 NTSTATUS
119  __in_opt PWDFMEMORY_OFFSET DestinationOffsets,
120  __in_bcount(SourceBufferLength) PVOID SourceBuffer,
121  __in size_t SourceBufferLength,
122  __in_opt PWDFMEMORY_OFFSET SourceOffsets
123  )
124 {
126 
128 
129  //
130  // We read from the supplied buffer writing to the current FxMemoryBuffer
131  //
133  //
134  // FxMemoryBuffer is not writeable
135  //
137  "Target WDFMEMORY 0x%p is ReadOnly", GetHandle());
139 
141  }
142 
143  return _CopyPtrToPtr(
144  SourceBuffer,
145  SourceBufferLength,
146  SourceOffsets,
147  GetBuffer(),
148  GetBufferSize(),
149  DestinationOffsets
150  );
151 }
152 
154 NTSTATUS
156  __in_opt PWDFMEMORY_OFFSET SourceOffsets,
157  __out_bcount(DestinationBufferLength)PVOID DestinationBuffer,
158  __in size_t DestinationBufferLength,
159  __in_opt PWDFMEMORY_OFFSET DestinationOffsets
160  )
161 /*++
162 
163 Routine Description:
164 
165  Worker routine for the various copy APIs. Verifies that a copy will not
166  overrun a buffer, or write into a read only memory buffer
167 
168 Arguments:
169 
170  SourceOffsets - Offsets into SourceBuffer from which the copy starts. If
171  NULL, an offset of 0 is used.
172 
173  DestinationBuffer - Memory whose contents we are copying into
174 
175  DestinationBufferLength - Size of DestinationBuffer in bytes
176 
177  DestinationOffsets - Offsets into DestinationMemory from which the copy
178  starts and indicates how many bytes to copy. If length is 0 or
179  parameter is NULL, the entire length of DestinationMemory is used.
180 
181 Return Value:
182  STATUS_BUFFER_TOO_SMALL - SourceMemory is smaller then the requested number
183  of bytes to be copied.
184  STATUS_INVALID_BUFFER_SIZE - DestinationMemory is not large enough to contain
185  the number of bytes requested to be copied
186  NTSTATUS
187 
188  --*/
189 {
190  //
191  // We are reading from the FxMemoryBuffer, so no need to check for ReadOnly
192  //
193  return _CopyPtrToPtr(
194  GetBuffer(),
195  GetBufferSize(),
196  SourceOffsets,
197  DestinationBuffer,
198  DestinationBufferLength,
199  DestinationOffsets
200  );
201 }
202 
204 NTSTATUS
206  __in_bcount(SourceBufferLength)PVOID SourceBuffer,
207  __in size_t SourceBufferLength,
208  __in_opt PWDFMEMORY_OFFSET SourceOffsets,
209  __out_bcount(DestinationBufferLength) PVOID DestinationBuffer,
210  __in size_t DestinationBufferLength,
211  __in_opt PWDFMEMORY_OFFSET DestinationOffsets
212  )
213 /*++
214 
215 Routine Description:
216  Worker routine for the various copy APIs. Verifies that a copy will not
217  overrun a buffer.
218 
219 Arguments:
220  SourceBuffer - Memory whose contents we are copying from.
221 
222  SourceBufferLength - Size of SourceBuffer in bytes
223 
224  SourceOffsets - Offsets into SourceBuffer from which the copy starts. If
225  NULL, an offset of 0 is used.
226 
227  DestinationBuffer - Memory whose contents we are copying into
228 
229  DestinationBufferLength - Size of DestinationBuffer in bytes
230 
231  DestinationOffsets - Offsets into DestinationMemory from which the copy
232  starts and indicates how many bytes to copy. If length is 0 or
233  parameter is NULL, the entire length of DestinationMemory is used.
234 
235 Return Value:
236  STATUS_BUFFER_TOO_SMALL - SourceMemory is smaller then the requested number
237  of bytes to be copied.
238  STATUS_INVALID_BUFFER_SIZE - DestinationMemory is not large enough to contain
239  the number of bytes requested to be copied
240  NTSTATUS
241 
242  --*/
243 {
244  size_t srcSize, copyLength;
245  PUCHAR pSrcBuf, pDstBuf;
246 
247  if (SourceBuffer == NULL) {
249  }
250 
251  pSrcBuf = (PUCHAR) SourceBuffer;
252  srcSize = SourceBufferLength;
253 
254  pDstBuf = (PUCHAR) DestinationBuffer;
255  copyLength = DestinationBufferLength;
256 
257  if (SourceOffsets != NULL) {
258  if (SourceOffsets->BufferOffset != 0) {
259  if (SourceOffsets->BufferOffset >= srcSize) {
260  //
261  // Offset is beyond end of buffer
262  //
264  }
265 
266  //
267  // Adjust the start and source size to reflect the offset info the
268  // source
269  //
270  pSrcBuf += SourceOffsets->BufferOffset;
271  srcSize -= SourceOffsets->BufferOffset;
272  }
273  }
274 
275  if (DestinationOffsets != NULL) {
276  if (DestinationOffsets->BufferOffset != 0) {
277  if (DestinationOffsets->BufferOffset >= copyLength) {
278  //
279  // Offset is beyond end of buffer
280  //
282  }
283 
284  //
285  // Adjust the start and copy length to reflect the offset info the
286  // destination
287  //
288  pDstBuf += DestinationOffsets->BufferOffset;
289  copyLength -= DestinationOffsets->BufferOffset;
290  }
291 
292  //
293  // Non zero buffer length overrides previously calculated copy length
294  //
295  if (DestinationOffsets->BufferLength != 0) {
296  //
297  // Is the desired buffer length greater than the amount of buffer
298  // available?
299  //
300  if (DestinationOffsets->BufferLength > copyLength) {
302  }
303 
304  copyLength = DestinationOffsets->BufferLength;
305  }
306  }
307 
308  //
309  // Compare the final computed copy length against the length of the source
310  // buffer.
311  //
312  if (copyLength > srcSize) {
314  }
315 
316  RtlCopyMemory(pDstBuf, pSrcBuf, copyLength);
317 
318  return STATUS_SUCCESS;
319 }
BOOLEAN FxIsPagedPoolType(__in POOL_TYPE Type)
Definition: wdfpool.cpp:43
#define __in_bcount(x)
Definition: dbghelp.h:41
static _Must_inspect_result_ NTSTATUS _CopyPtrToPtr(__in_bcount(SourceBufferLength) PVOID SourceBuffer, __in size_t SourceBufferLength, __in_opt PWDFMEMORY_OFFSET SourceOffsets, __out_bcount(DestinationBufferLength) PVOID DestinationBuffer, __in size_t DestinationBufferLength, __in_opt PWDFMEMORY_OFFSET DestinationOffsets)
VOID AllocateTagTracker(__in WDFTYPE Type)
Definition: fxobject.cpp:273
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define __out_bcount(x)
Definition: dbghelp.h:68
#define __in_opt
Definition: dbghelp.h:38
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
virtual PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)=0
LONG NTSTATUS
Definition: precomp.h:26
virtual WDFMEMORY GetHandle(VOID)=0
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in POOL_TYPE PoolType, __in ULONG PoolTag, __in size_t BufferSize, __out FxMemoryObject **Buffer)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define __out
Definition: dbghelp.h:62
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define TRACINGDEVICE
Definition: dbgtrace.h:58
PFX_DRIVER_GLOBALS pFxDriverGlobals
INT POOL_TYPE
Definition: typedefs.h:78
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:159
FxMemoryObject(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in size_t BufferSize)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ NTSTATUS CopyFromPtr(__in_opt PWDFMEMORY_OFFSET DestinationOffsets, __in_bcount(SourceBufferLength) PVOID SourceBuffer, __in size_t SourceBufferLength, __in_opt PWDFMEMORY_OFFSET SourceOffsets)
virtual USHORT GetFlags(VOID)=0
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
unsigned short USHORT
Definition: pedump.c:61
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
_Must_inspect_result_ NTSTATUS CopyToPtr(__in_opt PWDFMEMORY_OFFSET SourceOffsets, __out_bcount(DestinationBufferLength) PVOID DestinationBuffer, __in size_t DestinationBufferLength, __in_opt PWDFMEMORY_OFFSET DestinationOffsets)
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS DriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG PoolTag, __in size_t BufferSize, __in POOL_TYPE PoolType, __out FxMemoryObject **Object)
BOOLEAN IsDebug(VOID)
Definition: fxobject.hpp:409
#define STATUS_SUCCESS
Definition: shellext.h:65
#define __in
Definition: dbghelp.h:35
virtual size_t GetBufferSize(VOID)=0
FxVerifierDbgBreakPoint(pFxDriverGlobals)
virtual PVOID GetBuffer(VOID)=0
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS DriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in POOL_TYPE PoolType, __in ULONG PoolTag, __in size_t BufferSize, __out FxMemoryObject **Object)