Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

268 lines
6.1 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: N C M E M . C P P
//
// Contents: Common memory management routines.
//
// Notes:
//
// Author: shaunco 24 Mar 1997
// deonb 2 Jan 2002
//
//
// Our memory allocations rules are:
// * Most of our memory allocators do NOT throw exceptions but instead return NULL.
// This includes MemAlloc, operator new, operator new[], calloc & malloc.
// * Anything explicitly allocated using: p = new(throwonfail) CClass(), will raise a bad_alloc on failure.
// * STL:
// #ifdef (USE_CUSTOM_STL_ALLOCATOR)
// The STL memory allocator will raise a bad_alloc C++ exception on low memory.
// (Note, not an SEH exception!).
// #else
// STL will raise an access violation exception after out-of-memory occurred and
// it tries to use the memory.
// #endif
// * Currently USE_CUSTOM_STL_ALLOCATOR is defined in our makefile.inc
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "ncdebug.h"
#include "ncmem.h"
// Debug limit for single memory allocation (16 MB)
#define MAX_DEBUG_ALLOC 16 * 1048576
// This global heap handle will be set to the process heap when the
// first request to allocate memory through MemAlloc is made.
//
HANDLE g_hHeap = NULL;
//+---------------------------------------------------------------------------
//
// Function: MemAlloc
//
// Purpose: NetConfig's memory allocator
//
// Arguments:
// cb [in] Count of bytes to allocate.
//
// Returns: Pointer to allocated memory, or NULL if failed.
//
// Author: deonb 2 Jan 2002
//
// Notes: Free the returned buffer with MemFree.
// Will ASSERT in debug if attempt to allocate more than MAX_DEBUG_ALLOC (Currently 16 MB)
//
// We COULD extend this to include a primitive buffer overrun check, but it would require us
// to put the size of the allocated block in the beginning of the buffer, and would make things like
// allocating with MemAlloc but freeing it with HeapFree fail.
// PageHeap / AVRF is better suited for this purpose since it works directly with the RTL allocator.
//
VOID*
MemAlloc (
size_t cb) throw()
{
AssertSz(cb < MAX_DEBUG_ALLOC, "Suspicious request for a lot of memory");
if (!g_hHeap)
{
// Don't trace in this part of the function. It will likely recurse.
g_hHeap = GetProcessHeap();
if (!g_hHeap)
{
AssertSz(FALSE, "MemAlloc could not get the process heap.");
return NULL;
}
}
LPVOID lpAlloc = HeapAlloc (g_hHeap, 0, cb);
if (!lpAlloc)
{
TraceTag(ttidError, "MemAlloc failed request for %d bytes from:", cb);
TraceStack(ttidError);
}
return lpAlloc;
}
//+---------------------------------------------------------------------------
//
// Function: MemFree
//
// Purpose: NetConfig's memory de-allocator
//
// Arguments:
// pv [in] Pointer to previously allocated memory
//
// Returns: none
//
// Author: deonb 2 Jan 2002
//
// Notes: Free the returned buffer from MemAlloc.
// Don't trace in this function. It will recurse.
VOID
MemFree (
VOID* pv) throw()
{
if (pv)
{
if (!g_hHeap)
{
AssertSz(FALSE, "Suspicious call to MemFree before MemAlloc");
g_hHeap = GetProcessHeap();
if (!g_hHeap)
{
return;
}
}
HeapFree (g_hHeap, 0, pv);
}
}
//+---------------------------------------------------------------------------
//
// Function: HrMalloc
//
// Purpose: HRESULT returning version of malloc.
//
// Arguments:
// cb [in] Count of bytes to allocate.
// ppv [out] Address of returned allocation.
//
// Returns: S_OK or E_OUTOFMEMORY;
//
// Author: shaunco 31 Mar 1998
//
// Notes: Free the returned buffer with free.
//
HRESULT
HrMalloc (
size_t cb,
PVOID* ppv) throw()
{
Assert (ppv);
HRESULT hr = S_OK;
*ppv = MemAlloc (cb);
if (!*ppv)
{
hr = E_OUTOFMEMORY;
TraceHr (ttidError, FAL, hr, FALSE, "HrMalloc failed request for %d bytes from:", cb);
TraceStack(ttidError);
}
return hr;
}
namespace std
{
// report a length_error
void __cdecl _Xlen()
{
_THROW(length_error, "string too long");
}
// report an out_of_range error
void __cdecl _Xran()
{
_THROW(out_of_range, "invalid string position");
}
}
//+---------------------------------------------------------------------------
// CRT memory function overloads
//
const throwonfail_t throwonfail;
VOID*
__cdecl
operator new (
size_t cb,
const throwonfail_t&
) throw (std::bad_alloc)
{
LPVOID pv = MemAlloc (cb);
if (!pv)
{
throw std::bad_alloc();
}
return pv;
}
VOID
__cdecl
operator delete (
void* pv,
const throwonfail_t&) throw ()
{
MemFree (pv);
}
const extrabytes_t extrabytes;
VOID*
__cdecl
operator new (
size_t cb,
const extrabytes_t&,
size_t cbExtra) throw()
{
return MemAlloc (cb + cbExtra);
}
VOID
__cdecl
operator delete(
void* pv,
const extrabytes_t&,
size_t cbExtra) throw()
{
MemFree (pv);
}
VOID*
__cdecl
operator new (
size_t cb) throw()
{
return MemAlloc (cb);
}
VOID*
__cdecl
operator new (
size_t cb,
std::nothrow_t const &) throw()
{
return MemAlloc (cb);
}
VOID*
__cdecl
operator new[] (
size_t cb) throw()
{
return MemAlloc (cb);
}
VOID
__cdecl
operator delete (
VOID* pv) throw()
{
MemFree (pv);
}
VOID
__cdecl
operator delete[] (
VOID* pv) throw()
{
MemFree (pv);
}