#ifndef CDEBUG #ifndef WIN32 #define WIN32 #endif #endif /*++ Copyright (c) 1991-92 Microsoft Corporation Module Name: MemAlloc.c Abstract: Memory allocation routines for per-process use. Note that the semantics of these routines are intended to be 100% compatible with the ANSI C routines malloc(), free(), and realloc(). (That way, an implementation which can actually use the ANSI routines would just #define NetpMemoryAllocate as malloc.) Author: John Rogers (JohnRo) 15-Mar-1991 Environment: Only runs under NT, although the interface is portable (Win/32). Requires ANSI C extensions: slash-slash comments, long external names. Revision History: 15-Mar-91 JohnRo Created. 16-Apr-1991 JohnRo Include for . Got rid of tabs in source file. 13-Oct-1991 JohnRo Fix memory realloc problems. 18-Nov-1991 JohnRo Make sure output areas are aligned for worst case use. 12-Jan-1992 JohnRo Workaround a LocalReAlloc() bug where 2nd realloc messes up. (See WIN32_WORKAROUND code below.) Added NETLIB_LOCAL_ALLOCATION_FLAGS to make clearer what we're doing. 10-May-1992 JohnRo Add some debug output. --*/ // These must be included first: #include // Rtl routines, etc. (Must be first.) #include #ifdef WIN32 #include // Needed for nturtl/winbase.h #include // Needed for winbase.h???? #include // LocalAlloc(), LMEM_ flags, etc. #endif #include // NET_API_STATUS. // These may be included in any order: #include // ROUND_UP_POINTER(), ALIGN_WORST. #include // IF_DEBUG(). #include // NetpAssert(), NetpKdPrint(()), FORMAT_ equates. #include // My prototypes, NetpMoveMemory(). #include // PREFIX_ equates. #ifdef CDEBUG #include // free(), malloc(), realloc(). #endif // def CDEBUG // Define memory alloc/realloc flags. We are NOT using movable or zeroed // on allocation here. #define NETLIB_LOCAL_ALLOCATION_FLAGS LMEM_FIXED LPVOID NetpMemoryAllocate( IN DWORD Size ) /*++ Routine Description: NetpMemoryAllocate will allocate memory, or return NULL if not available. Arguments: Size - Supplies number of bytes of memory to allocate. Return Value: LPVOID - pointer to allocated memory. NULL - no memory is available. --*/ { LPVOID NewAddress; if (Size == 0) { return (NULL); } #ifdef WIN32 { HANDLE hMem; hMem = LocalAlloc( NETLIB_LOCAL_ALLOCATION_FLAGS, Size); // size in bytes NewAddress = (LPVOID) hMem; } #else // ndef WIN32 #ifndef CDEBUG NewAddress = RtlAllocateHeap( RtlProcessHeap( ), 0, // heap handle Size )); // bytes wanted #else // def CDEBUG NetpAssert( Size == (DWORD) (size_t) Size ); NewAddress = malloc( (size_t) Size )); #endif // def CDEBUG #endif // ndef WIN32 NetpAssert( ROUND_UP_POINTER( NewAddress, ALIGN_WORST) == NewAddress); return (NewAddress); } // NetpMemoryAllocate VOID NetpMemoryFree( IN LPVOID Address OPTIONAL ) /*++ Routine Description: Free memory at Address (must have been gotten from NetpMemoryAllocate or NetpMemoryReallocate). (Address may be NULL.) Arguments: Address - points to an area allocated by NetpMemoryAllocate (or NetpMemoryReallocate). Return Value: None. --*/ { NetpAssert( ROUND_UP_POINTER( Address, ALIGN_WORST) == Address); #ifdef WIN32 if (Address == NULL) { return; } if (LocalFree(Address) != NULL) { NetpAssert(FALSE); } #else // ndef WIN32 #ifndef CDEBUG if (Address == NULL) { return; } RtlFreeHeap( RtlProcessHeap( ), 0, // heap handle Address); // addr of alloc'ed space. #else // def CDEBUG free( Address ); #endif // def CDEBUG #endif // ndef WIN32 } // NetpMemoryFree LPVOID NetpMemoryReallocate( IN LPVOID OldAddress OPTIONAL, IN DWORD NewSize ) /*++ Routine Description: NetpMemoryReallocate reallocates a block of memory to a different size. Contents of the block are copied if necessary. Returns NULL if unable to allocate additional storage. Arguments: OldAddress - Optionally gives address of a block which was allocated by NetpMemoryAllocate or NetpMemoryReallocate. NewSize - Gives the new size in bytes. Return Value: LPVOID - Pointer to new (possibly moved) block of memory. (Pointer may be NULL, in which case the old block is still allocated.) --*/ { LPVOID NewAddress; // may be NULL. NetpAssert( ROUND_UP_POINTER( OldAddress, ALIGN_WORST) == OldAddress); IF_DEBUG( MEMALLOC ) { NetpKdPrint(( PREFIX_NETLIB "NetpMemoryReallocate: called with ptr " FORMAT_LPVOID " and size " FORMAT_DWORD ".\n", (LPVOID) OldAddress, NewSize )); } // Special cases: something into nothing, or nothing into something. if (OldAddress == NULL) { NewAddress = NetpMemoryAllocate(NewSize); } else if (NewSize == 0) { NetpMemoryFree(OldAddress); NewAddress = NULL; } else { // must be realloc of something to something else. #if defined(WIN32) HANDLE hNewMem; // handle for new (may = old handle) HANDLE hOldMem; #ifdef notdef // LocalHandle returns 0 for LMEM_FIXED block hOldMem = LocalHandle( (LPSTR) OldAddress); #else hOldMem = (HANDLE) OldAddress; #endif // notdef NetpAssert(hOldMem != NULL); hNewMem = LocalReAlloc( hOldMem, // old handle NewSize, // new size in bytes LMEM_MOVEABLE); // OK if new block is in new location if (hNewMem == NULL) { return (NULL); } NewAddress = (LPVOID) hNewMem; #elif !defined(CDEBUG) // not WIN32 or CDEBUG, must be NT DWORD OldSize; // Need size of old area to continue... OldSize = RtlSizeHeap( RtlProcessHeap( ), 0, // heap handle OldAddress); // "base" address if (OldSize == NewSize) { NewAddress = OldAddress; // Another special case. } else { // Normal case (something into something else). Alloc new area. NewAddress = NetpMemoryAllocate(NewSize); if (NewAddress != NULL) { // Copy lesser of old and new sizes. NetpMoveMemory( NewAddress, // dest OldAddress, // src (NewSize < OldSize) ? NewSize : OldSize); // len NetpMemoryFree(OldAddress); } } #else // must be CDEBUG NetpAssert(NewSize == (DWORD)(size_t)NewSize); NewAddress = realloc( OldAddress, NewSize ); #endif // CDEBUG } // must be realloc of something to something else IF_DEBUG( MEMALLOC ) { NetpKdPrint(( PREFIX_NETLIB "NetpMemoryReallocate: new address is " FORMAT_LPVOID ".\n", (LPVOID) OldAddress )); } NetpAssert( ROUND_UP_POINTER( NewAddress, ALIGN_WORST) == NewAddress); return (NewAddress); } // NetpMemoryReallocate