155 lines
6.4 KiB
C
155 lines
6.4 KiB
C
/*
|
|
* Copyright (C) 2006 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_USB_NEW_DELETE_H__
|
|
#define ANDROID_USB_NEW_DELETE_H__
|
|
/** \file
|
|
This file consists implementations of our 'new' and 'delete' operators
|
|
*/
|
|
|
|
#include "android_usb_pool_tags.h"
|
|
|
|
/** \brief Checks if given pool type is one of NonPaged pool kinds.
|
|
|
|
All numeric values for all NonPaged pool types are even numbers while all
|
|
numeric values for all PagedPool types are odd numbers (see definition of
|
|
POOL_TYPE enum). So this routine utilizes this to see whether given pool
|
|
type is one of NonPaged pool kinds. This routine can be called at any IRQL.
|
|
@param pool_type[in] Pool type
|
|
@return True if pool type is one of NonPaged pool types, false otherwise
|
|
*/
|
|
__forceinline bool IsPoolNonPaged(POOL_TYPE pool_type) {
|
|
return (0 == (pool_type & 0x1));
|
|
}
|
|
|
|
/** @name Operators new and delete
|
|
|
|
In Kernel Mode development each memory allocation must specify type of the
|
|
pool from which memory should be allocated, usualy PagedPool or NonPagedPool.
|
|
Because of that "traditional" operator 'new' that takes only one parameter
|
|
(memory size) is not good so we modify that operator by adding two more
|
|
parameters: pool type and memory tag (last one is optional but highly
|
|
encouraged). To prevent from mistakes, traditional operator 'new' is also
|
|
defined. It will allocate requested number of bytes from NonPagedPool with
|
|
default memory tag but it will always assert on checked (debug) builds.
|
|
Since there is no infrastructure for C++ exceptions in Kernel Mode we are
|
|
not using them to report memory allocation error. So, on failure operators
|
|
'new' are returning NULL instead of throwing an exception.
|
|
*/
|
|
///@{
|
|
|
|
/** \brief Main operator new
|
|
|
|
This is the main operator new that allocates specified number of bytes from
|
|
the specified pool and assigns a custom tag to the allocated memory.
|
|
Inherits IRQL restrictions for ExAllocatePoolWithTag (see the DDK doc).
|
|
@param size[in] Number of bytes to allocate.
|
|
@param pool_type[in] Type of the pool to allocate from.
|
|
@param pool_tag[in] A tag to attach to the allocated memory. Since utilities
|
|
that display tags use their ASCII representations it's advisable to
|
|
use tag values that are ASCII symbols, f.i. 'ATag'. Note that due to
|
|
inversion of bytes in stored ULONG value, to read 'ATag' in the tag
|
|
displaying utility, the actual value passed to operator 'new' must be
|
|
'gaTA'
|
|
@return Pointer to allocated memory on success, NULL on error.
|
|
*/
|
|
__forceinline void* __cdecl operator new(size_t size,
|
|
POOL_TYPE pool_type,
|
|
ULONG pool_tag) {
|
|
ASSERT((pool_type < MaxPoolType) && (0 != size));
|
|
// Enforce IRQL restriction check.
|
|
ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
|
|
return size ? ExAllocatePoolWithTag(pool_type,
|
|
static_cast<ULONG>(size),
|
|
pool_tag) :
|
|
NULL;
|
|
}
|
|
|
|
/** \brief
|
|
Short operator new that attaches a default tag to the allocated memory.
|
|
|
|
This version of operator new allocates specified number of bytes from the
|
|
specified pool and assigns a default tag (GANDR_POOL_TAG_DEFAULT) to the
|
|
allocated memory. Inherits IRQL restrictions for ExAllocatePoolWithTag.
|
|
@param size[in] Number of bytes to allocate.
|
|
@param pool_type[in] Type of the pool to allocate from.
|
|
@return Pointer to allocated memory on success, NULL on error.
|
|
*/
|
|
__forceinline void* __cdecl operator new(size_t size, POOL_TYPE pool_type) {
|
|
ASSERT((pool_type < MaxPoolType) && (0 != size));
|
|
// Enforce IRQL restriction check.
|
|
ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
|
|
return size ? ExAllocatePoolWithTag(pool_type,
|
|
static_cast<ULONG>(size),
|
|
GANDR_POOL_TAG_DEFAULT) :
|
|
NULL;
|
|
}
|
|
|
|
/** \brief Traditional operator new that should never be used.
|
|
|
|
Using of this version of operator 'new' is prohibited in Kernel Mode
|
|
development. For the sake of safety it is implemented though to allocate
|
|
requested number of bytes from the NonPagedPool and attach default tag
|
|
to the allocated memory. It will assert on checked (debug) builds.
|
|
Inherits IRQL restrictions for ExAllocatePoolWithTag.
|
|
@param size[in] Number of bytes to allocate.
|
|
@return Pointer to memory allocated from NonPagedPool on success or NULL on
|
|
error.
|
|
*/
|
|
__forceinline void* __cdecl operator new(size_t size) {
|
|
ASSERTMSG("\n!!! Using of operator new(size_t size) is detected!\n"
|
|
"This is illegal in our driver C++ development environment to use "
|
|
"this version of operator 'new'. Please switch to\n"
|
|
"new(size_t size, POOL_TYPE pool_type) or "
|
|
"new(size_t size, POOL_TYPE pool_type, ULONG pool_tag) ASAP!!!\n",
|
|
false);
|
|
ASSERT(0 != size);
|
|
return size ? ExAllocatePoolWithTag(NonPagedPool,
|
|
static_cast<ULONG>(size),
|
|
GANDR_POOL_TAG_DEFAULT) :
|
|
NULL;
|
|
}
|
|
|
|
/** \brief Operator delete.
|
|
|
|
Frees memory allocated by 'new' operator.
|
|
@param pointer[in] Memory to free. If this parameter is NULL operator does
|
|
nothing but asserts on checked build. Inherits IRQL restrictions
|
|
for ExFreePool.
|
|
*/
|
|
__forceinline void __cdecl operator delete(void* pointer) {
|
|
ASSERT(NULL != pointer);
|
|
if (NULL != pointer)
|
|
ExFreePool(pointer);
|
|
}
|
|
|
|
/** \brief Operator delete for arrays.
|
|
|
|
Frees memory allocated by 'new' operator.
|
|
@param pointer[in] Memory to free. If this parameter is NULL operator does
|
|
nothing but asserts on checked build. Inherits IRQL restrictions
|
|
for ExFreePool.
|
|
*/
|
|
__forceinline void __cdecl operator delete[](void* pointer) {
|
|
ASSERT(NULL != pointer);
|
|
if (NULL != pointer)
|
|
ExFreePool(pointer);
|
|
}
|
|
|
|
///@}
|
|
|
|
#endif // ANDROID_USB_NEW_DELETE_H__
|