1 /*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_USB_NEW_DELETE_H__
18 #define ANDROID_USB_NEW_DELETE_H__
19 /** \file
20 This file consists implementations of our 'new' and 'delete' operators
21 */
22
23 #include "android_usb_pool_tags.h"
24
25 /** \brief Checks if given pool type is one of NonPaged pool kinds.
26
27 All numeric values for all NonPaged pool types are even numbers while all
28 numeric values for all PagedPool types are odd numbers (see definition of
29 POOL_TYPE enum). So this routine utilizes this to see whether given pool
30 type is one of NonPaged pool kinds. This routine can be called at any IRQL.
31 @param pool_type[in] Pool type
32 @return True if pool type is one of NonPaged pool types, false otherwise
33 */
IsPoolNonPaged(POOL_TYPE pool_type)34 __forceinline bool IsPoolNonPaged(POOL_TYPE pool_type) {
35 return (0 == (pool_type & 0x1));
36 }
37
38 /** @name Operators new and delete
39
40 In Kernel Mode development each memory allocation must specify type of the
41 pool from which memory should be allocated, usualy PagedPool or NonPagedPool.
42 Because of that "traditional" operator 'new' that takes only one parameter
43 (memory size) is not good so we modify that operator by adding two more
44 parameters: pool type and memory tag (last one is optional but highly
45 encouraged). To prevent from mistakes, traditional operator 'new' is also
46 defined. It will allocate requested number of bytes from NonPagedPool with
47 default memory tag but it will always assert on checked (debug) builds.
48 Since there is no infrastructure for C++ exceptions in Kernel Mode we are
49 not using them to report memory allocation error. So, on failure operators
50 'new' are returning NULL instead of throwing an exception.
51 */
52 ///@{
53
54 /** \brief Main operator new
55
56 This is the main operator new that allocates specified number of bytes from
57 the specified pool and assigns a custom tag to the allocated memory.
58 Inherits IRQL restrictions for ExAllocatePoolWithTag (see the DDK doc).
59 @param size[in] Number of bytes to allocate.
60 @param pool_type[in] Type of the pool to allocate from.
61 @param pool_tag[in] A tag to attach to the allocated memory. Since utilities
62 that display tags use their ASCII representations it's advisable to
63 use tag values that are ASCII symbols, f.i. 'ATag'. Note that due to
64 inversion of bytes in stored ULONG value, to read 'ATag' in the tag
65 displaying utility, the actual value passed to operator 'new' must be
66 'gaTA'
67 @return Pointer to allocated memory on success, NULL on error.
68 */
new(size_t size,POOL_TYPE pool_type,ULONG pool_tag)69 __forceinline void* __cdecl operator new(size_t size,
70 POOL_TYPE pool_type,
71 ULONG pool_tag) {
72 ASSERT((pool_type < MaxPoolType) && (0 != size));
73 // Enforce IRQL restriction check.
74 ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
75 return size ? ExAllocatePoolWithTag(pool_type,
76 static_cast<ULONG>(size),
77 pool_tag) :
78 NULL;
79 }
80
81 /** \brief
82 Short operator new that attaches a default tag to the allocated memory.
83
84 This version of operator new allocates specified number of bytes from the
85 specified pool and assigns a default tag (GANDR_POOL_TAG_DEFAULT) to the
86 allocated memory. Inherits IRQL restrictions for ExAllocatePoolWithTag.
87 @param size[in] Number of bytes to allocate.
88 @param pool_type[in] Type of the pool to allocate from.
89 @return Pointer to allocated memory on success, NULL on error.
90 */
new(size_t size,POOL_TYPE pool_type)91 __forceinline void* __cdecl operator new(size_t size, POOL_TYPE pool_type) {
92 ASSERT((pool_type < MaxPoolType) && (0 != size));
93 // Enforce IRQL restriction check.
94 ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
95 return size ? ExAllocatePoolWithTag(pool_type,
96 static_cast<ULONG>(size),
97 GANDR_POOL_TAG_DEFAULT) :
98 NULL;
99 }
100
101 /** \brief Traditional operator new that should never be used.
102
103 Using of this version of operator 'new' is prohibited in Kernel Mode
104 development. For the sake of safety it is implemented though to allocate
105 requested number of bytes from the NonPagedPool and attach default tag
106 to the allocated memory. It will assert on checked (debug) builds.
107 Inherits IRQL restrictions for ExAllocatePoolWithTag.
108 @param size[in] Number of bytes to allocate.
109 @return Pointer to memory allocated from NonPagedPool on success or NULL on
110 error.
111 */
new(size_t size)112 __forceinline void* __cdecl operator new(size_t size) {
113 ASSERTMSG("\n!!! Using of operator new(size_t size) is detected!\n"
114 "This is illegal in our driver C++ development environment to use "
115 "this version of operator 'new'. Please switch to\n"
116 "new(size_t size, POOL_TYPE pool_type) or "
117 "new(size_t size, POOL_TYPE pool_type, ULONG pool_tag) ASAP!!!\n",
118 false);
119 ASSERT(0 != size);
120 return size ? ExAllocatePoolWithTag(NonPagedPool,
121 static_cast<ULONG>(size),
122 GANDR_POOL_TAG_DEFAULT) :
123 NULL;
124 }
125
126 /** \brief Operator delete.
127
128 Frees memory allocated by 'new' operator.
129 @param pointer[in] Memory to free. If this parameter is NULL operator does
130 nothing but asserts on checked build. Inherits IRQL restrictions
131 for ExFreePool.
132 */
delete(void * pointer)133 __forceinline void __cdecl operator delete(void* pointer) {
134 ASSERT(NULL != pointer);
135 if (NULL != pointer)
136 ExFreePool(pointer);
137 }
138
139 /** \brief Operator delete for arrays.
140
141 Frees memory allocated by 'new' operator.
142 @param pointer[in] Memory to free. If this parameter is NULL operator does
143 nothing but asserts on checked build. Inherits IRQL restrictions
144 for ExFreePool.
145 */
146 __forceinline void __cdecl operator delete[](void* pointer) {
147 ASSERT(NULL != pointer);
148 if (NULL != pointer)
149 ExFreePool(pointer);
150 }
151
152 ///@}
153
154 #endif // ANDROID_USB_NEW_DELETE_H__
155