//+------------------------------------------------------------------------- // // 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"); }