mirror of https://github.com/lianthony/NT4.0
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.
381 lines
12 KiB
381 lines
12 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1994 - 1995.
|
|
//
|
|
// File: heapaloc.h
|
|
//
|
|
// Contents: Macros which wrap the standard memory API calls, redirecting
|
|
// them to HeapAlloc.
|
|
//
|
|
// Functions: __inline HLOCAL HeapLocalAlloc (fuFlags, cbBytes)
|
|
// __inline HGLOBAL HeapGlobalAlloc (fuFlags, cbBytes)
|
|
// __inline HGLOBAL HeapGlobalReAlloc(hMem, cbBytes, fuFlags)
|
|
// __inline HLOCAL HeapLocalReAlloc (hMem, cbBytes, fuFlags)
|
|
// __inline DWORD HeapGlobalSize (HGLOBAL hMem)
|
|
// __inline DWORD HeapLocalSize (HLOCAL hMem)
|
|
// __inline HLOCAL HeapLocalFree (HLOCAL hMem)
|
|
// __inline HGLOBAL HeapGlobalFree (HLOCAL hMem)
|
|
// __inline void InvalidMemoryCall()
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// If we are using the debug allocator from ntdll.dll, we set a flag that
|
|
// will give us byte-granularity on allocations (ie: you ask for 3 bytes,
|
|
// you get it, not 8, 16, etc)
|
|
|
|
#if ((defined(WINNT) && defined(DEBUG)) || defined(FORCE_DEBUG_ALLOCATOR))
|
|
#define DEF_ALLOC_FLAGS (0x00000800)
|
|
#else
|
|
#define DEF_ALLOC_FLAGS (0x00000000)
|
|
#endif
|
|
|
|
// Redefine the standard memory APIs to thunk over to our Heap-based funcs
|
|
|
|
#define LocalAlloc(fuFlags, cbBytes) HeapLocalAlloc(fuFlags, cbBytes)
|
|
#define LocalReAlloc(hMem, cbBytes, fuFlags) HeapLocalReAlloc(hMem, cbBytes, fuFlags)
|
|
#define LocalSize(hMem) HeapLocalSize(hMem)
|
|
#define LocalFree(hMem) HeapLocalFree(hMem)
|
|
|
|
//
|
|
// These are functions normally in comctl32, but there's no good reason to call
|
|
// that dll, so handle them here. Since Chicago may still want to use these
|
|
// shared memory routines, only "forward" them under NT.
|
|
//
|
|
|
|
#ifdef WINNT
|
|
#define Alloc(cb) HeapLocalAlloc(LMEM_ZEROINIT | LMEM_FIXED, cb)
|
|
#define ReAlloc(pb, cb) HeapLocalReAlloc(pb, cb, LMEM_ZEROINIT | LMEM_FIXED)
|
|
//
|
|
// Free() in comctl32 is just HeapFree(), so the return code reversing
|
|
// in HeapLocalFree is the opposite of what we want. Reverse it
|
|
// again here for now, and consider redefining Free() as just
|
|
// HeapFree(g_hProcessHeap) if the compiler isn't smart enough
|
|
// to generate the same code already. (BUGBUG investigate)
|
|
//
|
|
#define Free(pb) (!HeapLocalFree(pb))
|
|
#define GetSize(pb) HeapLocalSize(pb)
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
|
|
// GlobalAllocs cannot be trivially replaced since they are used for DDE, OLE,
|
|
// and GDI operations. However, on a case-by-case version we can switch them
|
|
// over to HeapGlobalAlloc as we identify instances that don't _really_ require
|
|
// GlobalAllocs.
|
|
|
|
#define GlobalAlloc(fuFlags, cbBytes) HeapGlobalAlloc(fuFlags, cbBytes)
|
|
#define GlobalReAlloc(hMem, cbBytes, fuFlags) HeapGlobalReAlloc(hMem, cbBytes, fuFlags)
|
|
#define GlobalSize(hMem) HeapGlobalSize(hMem)
|
|
#define GlobalFree(hMem) HeapGlobalFree(hMem)
|
|
#define GlobalCompact InvalidMemoryCall
|
|
#define GlobalDiscard InvalidMemoryCall
|
|
#define GlobalFlags InvalidMemoryCall
|
|
#define GlobalHandle InvalidMemoryCall
|
|
#define GlobalLock InvalidMemoryCall
|
|
#define GlobalUnlock InvalidMemoryCall
|
|
|
|
#endif
|
|
|
|
//
|
|
// Make sure we're not using any unsupported operations on our "handles"
|
|
//
|
|
|
|
#define LocalCompact InvalidMemoryCall
|
|
#ifdef LocalDiscard
|
|
#undef LocalDiscard
|
|
#endif
|
|
#define LocalDiscard InvalidMemoryCall
|
|
#define LocalFlags InvalidMemoryCall
|
|
#define LocalHandle InvalidMemoryCall
|
|
#define LocalLock InvalidMemoryCall
|
|
#define LocalUnlock InvalidMemoryCall
|
|
|
|
|
|
//
|
|
// Pointer to process heap, initialized in LibMain of shell32.dll
|
|
//
|
|
|
|
extern HANDLE g_hProcessHeap;
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HeapLocalAlloc (inline function)
|
|
//
|
|
// Synopsis: Replaces standard LocalAlloc call with a call to HeapAlloc
|
|
//
|
|
// Arguments: [fuFlags] -- LocalAlloc flags to be mapped
|
|
// [cbBytes] -- Number of bytes to allocate
|
|
//
|
|
// Returns: Memory pointer cast to HLOCAL type, NULL on failure
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
// Notes: Only really handles the LMEM_ZEROINIT flag. If your compiler
|
|
// doesn't fold most of this out, buy a new compiler.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline HLOCAL HeapLocalAlloc(IN UINT fuFlags, IN UINT cbBytes)
|
|
{
|
|
void * pv;
|
|
DWORD dwFlags;
|
|
|
|
// Assert our assumptions
|
|
|
|
Assert(g_hProcessHeap);
|
|
|
|
// Map LocalAlloc flags to appropriate HeapAlloc flags
|
|
|
|
dwFlags = (fuFlags & LMEM_ZEROINIT ? HEAP_ZERO_MEMORY : 0);
|
|
dwFlags |= DEF_ALLOC_FLAGS;
|
|
|
|
// Call heap alloc, then assert that we got a good allocation
|
|
|
|
pv = HeapAlloc(g_hProcessHeap, dwFlags, cbBytes);
|
|
|
|
Assert(pv);
|
|
|
|
return (HLOCAL) pv;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HeapLocalFree
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
// Notes: Since HeapFree return a BOOL, we massage it appropriately
|
|
// to emulate LocalFree()
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline HLOCAL HeapLocalFree(HLOCAL hMem)
|
|
{
|
|
BOOL fSuccess = HeapFree(g_hProcessHeap, 0, hMem);
|
|
Assert(fSuccess);
|
|
|
|
return fSuccess ? NULL : (HGLOBAL) -1;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HeapGlobalFree
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
// Notes: Since HeapFree return a BOOL, we massage it appropriately
|
|
// to emulate GlobalFree()
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline HLOCAL HeapGlobalFree(HLOCAL hMem)
|
|
{
|
|
BOOL fSuccess = HeapFree(g_hProcessHeap, 0, hMem);
|
|
Assert(fSuccess);
|
|
|
|
return fSuccess ? NULL : (HGLOBAL) -1;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HeapGlobalAlloc (inline function)
|
|
//
|
|
// Synopsis: Replaces standard GlobalAlloc call with a call to HeapAlloc
|
|
//
|
|
// Arguments: [fuFlags] -- GlobalAlloc flags to be mapped
|
|
// [cbBytes] -- Number of bytes to allocate
|
|
//
|
|
// Returns: Memory pointer cast to HGLOBAL type, NULL on failure
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
// Notes: Only really handles the GMEM_ZEROINIT flag.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline HLOCAL HeapGlobalAlloc(IN UINT fuFlags, IN UINT cbBytes)
|
|
{
|
|
void * pv;
|
|
DWORD dwFlags;
|
|
|
|
// Assert our assumptions
|
|
|
|
Assert(g_hProcessHeap);
|
|
Assert(0 == (fuFlags & GMEM_NOCOMPACT));
|
|
Assert(0 == (fuFlags & GMEM_NODISCARD));
|
|
Assert(0 == (fuFlags & GMEM_DDESHARE));
|
|
Assert(0 == (fuFlags & GMEM_SHARE));
|
|
|
|
// Map GlobalAlloc flags to appropriate HeapAlloc flags
|
|
|
|
dwFlags = (fuFlags & GMEM_ZEROINIT ? HEAP_ZERO_MEMORY : 0);
|
|
dwFlags |= DEF_ALLOC_FLAGS;
|
|
|
|
// Call heap alloc, then assert that we got a good allocation
|
|
|
|
pv = HeapAlloc(g_hProcessHeap, dwFlags, cbBytes);
|
|
|
|
Assert(pv);
|
|
|
|
return (HGLOBAL) pv;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GlobalReAlloc (inline function)
|
|
//
|
|
// Synopsis: Replaces standard GlobalReAlloc call by a call to HeapReAlloc
|
|
//
|
|
// Arguments: [hMem] -- Original pointer that is to be realloc'd
|
|
// [fuFlags] -- GlobalReAlloc flags to be mapped
|
|
// [cbBytes] -- Number of bytes to allocate
|
|
//
|
|
// Returns: Memory pointer cast to HGLOBAL type, NULL on failure
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
// Notes: Only really handles the GMEM_ZEROINIT flag.
|
|
// Did you remember to save your original pointer? I hope so...
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline HLOCAL HeapGlobalReAlloc(IN HGLOBAL hMem,
|
|
IN UINT cbBytes,
|
|
IN UINT fuFlags)
|
|
{
|
|
void * pv;
|
|
DWORD dwFlags;
|
|
|
|
if (NULL == hMem)
|
|
{
|
|
return HeapGlobalAlloc(fuFlags, cbBytes);
|
|
}
|
|
|
|
// Assert our assumptions
|
|
|
|
Assert(g_hProcessHeap);
|
|
Assert(0 == (fuFlags & GMEM_NOCOMPACT));
|
|
Assert(0 == (fuFlags & GMEM_NODISCARD));
|
|
Assert(0 == (fuFlags & GMEM_DDESHARE));
|
|
Assert(0 == (fuFlags & GMEM_SHARE));
|
|
|
|
// Map GlobalReAlloc flags to appropriate HeapAlloc flags
|
|
|
|
dwFlags = (fuFlags & GMEM_ZEROINIT ? HEAP_ZERO_MEMORY : 0);
|
|
dwFlags |= DEF_ALLOC_FLAGS;
|
|
|
|
// Call heap alloc, then assert that we got a good allocation
|
|
|
|
pv = HeapReAlloc(g_hProcessHeap, dwFlags, (void *) hMem, cbBytes);
|
|
|
|
Assert(pv);
|
|
|
|
return (HGLOBAL) pv;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: LocalReAlloc (Macro definition)
|
|
//
|
|
// Synopsis: Replaces standard LocalReAlloc call by a call to HeapReAlloc
|
|
//
|
|
// Arguments: [hMem] -- Original pointer that is to be realloc'd
|
|
// [fuFlags] -- GlobalAlloc flags to be mapped
|
|
// [cbBytes] -- Number of bytes to allocate
|
|
//
|
|
// Returns: Memory pointer cast to HLOCAL type, NULL on failure
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
// Notes: Only really handles the LMEM_ZEROINIT flag.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
__inline HLOCAL HeapLocalReAlloc(IN HGLOBAL hMem,
|
|
IN UINT cbBytes,
|
|
IN UINT fuFlags)
|
|
{
|
|
void * pv;
|
|
DWORD dwFlags;
|
|
|
|
// BUGBUG (DavePl) Why can we realloc on a null ptr?
|
|
|
|
if (NULL == hMem)
|
|
{
|
|
return HeapLocalAlloc(fuFlags, cbBytes);
|
|
}
|
|
|
|
// Assert our assumptions
|
|
|
|
Assert(g_hProcessHeap);
|
|
Assert(0 == (fuFlags & LMEM_NOCOMPACT));
|
|
Assert(0 == (fuFlags & LMEM_NODISCARD));
|
|
|
|
// Map LocalAlloc flags to appropriate HeapAlloc flags
|
|
|
|
dwFlags = (fuFlags & LMEM_ZEROINIT ? HEAP_ZERO_MEMORY : 0);
|
|
dwFlags |= DEF_ALLOC_FLAGS;
|
|
|
|
// Call heap alloc, then assert that we got a good allocation
|
|
|
|
pv = HeapReAlloc(g_hProcessHeap, dwFlags, (void *) hMem, cbBytes);
|
|
|
|
Assert(pv);
|
|
|
|
return (HGLOBAL) pv;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HeapGlobalSize (inline function)
|
|
//
|
|
// Synopsis: Passes GlobalSize call through to HeapGlobalSize
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline DWORD HeapGlobalSize(HGLOBAL hMem)
|
|
{
|
|
Assert(g_hProcessHeap);
|
|
|
|
return HeapSize(g_hProcessHeap, 0, (void *) hMem);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: HeapLocalSize
|
|
//
|
|
// Synopsis: Passes HeapLocalSize call through to HeapGlobalSize
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline DWORD HeapLocalSize(HLOCAL hMem)
|
|
{
|
|
Assert(g_hProcessHeap);
|
|
|
|
return HeapSize(g_hProcessHeap, 0, (void *) hMem);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: InvalidMemoryCall
|
|
//
|
|
// Synopsis: Dead-end stub for unsupported memory API calls
|
|
//
|
|
// History: 2-01-95 davepl Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
__inline void InvalidMemoryCall()
|
|
{
|
|
Assert(0 && "Invalid memory API was called");
|
|
}
|
|
|