//============================================================================= // Microsoft (R) Bloodhound (tm). Copyright (C) 1991-1992. // // MODULE: mem.c // // Modification History // // raypa 01/28/93 Created // stevehi 07/21/93 Added memory checking functionality // raypa 07/21/93 Changed to use LPTR rather than LocalLock. // Tom Laird-McConnell 08/16/93 Changed to fix no size info in functions // arth 06/16/94 Added extra debug tracing code //============================================================================= #include "switches.h" #include #include "mem.h" #include #include #include "debug.h" #include "strings.h" #include #include "utils.h" #ifdef DEBUG_MEM BOOL _rtlpheapvalidateoncall = TRUE; typedef struct _MEM_BUFFER { struct _MEM_BUFFER *Next; struct _MEM_BUFFER *Prev; ULONG Size; } MEM_BUFFER; MEM_BUFFER *MemList = NULL; ULONG AllocCount = 0; #endif //============================================================================= // Define Tags used by the following routines to stick into memory // and compare later. //============================================================================= #define AllocTagTakeStart 0x3e4b4154 //... TAK> #define AllocTagTakeStop 0x4b41543c //... #define AllocTagReAllocStop 0x4145523c //... #define AllocTagFreeStop 0x4552463c //... Size; lpByte = (LPBYTE) lpMem; lpByte -= sizeof(DWORD); dprintf(TEXT("%lu %lX) Alloc Size: %lu\n"), i++, lpMem, lpMem->Size); if ( *(LPDWORD)(lpByte) != AllocTagTakeStart ) { dprintf(TEXT("AllocTagStart Corrupt\n")); dprintf(TEXT("Total Alloc Mem: %lu\n"), TotSize); DebugBreak; } lpByte += sizeof(DWORD) + sizeof(MEM_BUFFER) + lpMem->Size; if ( *(LPDWORD)(lpByte) != AllocTagTakeStop ) { dprintf(TEXT("AllocTagStop Corrupt\n")); dprintf(TEXT("Total Alloc Mem: %lu\n"), TotSize); DebugBreak; } lpMem = lpMem->Next; } dprintf(TEXT("\nTotal Alloc Mem: %lu\n"), TotSize); } // DBG_MemEnum #endif //============================================================================= // FUNCTION: AllocMemory() // // Modification History // // raypa 01/28/93 Created. // stevehi 07/21/93 Added memory checking functionality // raypa 07/21/93 Changed to use LPTR rather than LocalLock. // raypa 07/21/93 Return NULL if size is zero. //============================================================================= LPVOID WINAPI AllocMemory(DWORD size) { register LPBYTE lpByte; int ret; #ifndef DEBUG_MEM do { ret = IDOK; lpByte = LocalAlloc(LPTR, size); if ((lpByte == NULL) && (size != 0)) { MessageBeep(MB_ICONHAND); ret = MessageBox(NULL, Lids(IDS_S_7), Lids(IDS_S_8), MB_ICONHAND | MB_SYSTEMMODAL | MB_RETRYCANCEL); if (ret == IDCANCEL) exit(1); } } while (ret == IDRETRY); return (LPVOID) lpByte; #else DWORD ActualSize; MEM_BUFFER *lpMem; if ( size != 0 ) { do { ret = IDOK; // take into account 2 tags and buffer header lpByte = LocalAlloc(LPTR, size + (2 * sizeof(DWORD)) + sizeof(MEM_BUFFER)); if (lpByte == NULL) { MessageBeep(MB_ICONHAND); DBG_MemEnum(); ret = MessageBox(NULL, TEXT("Out of Memory"), TEXT("NwConv - Error"), MB_ICONHAND | MB_SYSTEMMODAL | MB_RETRYCANCEL); if (ret == IDCANCEL) exit(1); } } while (ret == IDRETRY); AllocCount++; ActualSize = LocalSize(lpByte) - (2 * sizeof(DWORD)) - sizeof(MEM_BUFFER); *((LPDWORD)(lpByte)) = AllocTagTakeStart; lpMem = (MEM_BUFFER *) &lpByte[sizeof(DWORD)]; lpMem->Next = MemList; lpMem->Prev = NULL; if (MemList != NULL) MemList->Prev = lpMem; lpMem->Size = ActualSize; MemList = lpMem; *((LPDWORD)(lpByte + ActualSize + sizeof(DWORD) + sizeof(MEM_BUFFER))) = AllocTagTakeStop; return (LPVOID) &lpByte[sizeof(DWORD) + sizeof(MEM_BUFFER)]; } return NULL; #endif } // AllocMemory //============================================================================= // FUNCTION: ReallocMemory() // // Modification History // // raypa 01/28/93 Created. // stevehi 07/21/93 Added memory checking functionality // raypa 07/21/93 Changed to use LPTR rather than LocalLock. // raypa 10/22/93 If the ptr is NULL then use AllocMemory. //============================================================================= LPVOID WINAPI ReallocMemory(LPVOID ptr, DWORD NewSize) { #ifdef DEBUG_MEM DWORD GSize; MEM_BUFFER *lpMem; MEM_BUFFER *OldMem; #endif //========================================================================= // If the ptr is NULL then use AllocMemory. //========================================================================= if ( ptr == NULL ) { return AllocMemory(NewSize); } #ifndef DEBUG_MEM return LocalReAlloc(ptr, NewSize, LHND); #else // we are reallocing... might as well check the tags here... (LPBYTE)ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER)); GSize = LocalSize (ptr); if ( *(LPDWORD)(ptr) != AllocTagTakeStart ) DebugBreak; // get the size and check the end tag if (GSize && ( *(LPDWORD)((LPBYTE)ptr + GSize - sizeof(DWORD))) != AllocTagTakeStop ) { DebugBreak; } // just for grins, mark the realloc part. *(LPDWORD)(ptr) = AllocTagReAllocStart; if ( GSize ) *(LPDWORD)((LPBYTE)ptr + GSize - sizeof(DWORD) ) = AllocTagReAllocStop; OldMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD)); ptr = LocalReAlloc(ptr, NewSize + sizeof(MEM_BUFFER) + (2 * sizeof(DWORD)), LHND); if (ptr == NULL ) { dprintf(TEXT("NWConv - Local Realloc failed with %ld.\r\n"), GetLastError() ); DebugBreak; return NULL; } lpMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD)); if (MemList == OldMem) MemList = lpMem; if (lpMem->Prev != NULL) lpMem->Prev->Next = lpMem; if (lpMem->Next != NULL) lpMem->Next->Prev = lpMem; lpMem->Size = NewSize; *((LPDWORD)ptr) = AllocTagTakeStart; *((LPDWORD)((LPBYTE)ptr + NewSize + sizeof(MEM_BUFFER) + sizeof(DWORD))) = AllocTagTakeStop; return (LPVOID)((LPBYTE)ptr + sizeof(DWORD) + sizeof(MEM_BUFFER)); #endif } // ReAllocMemory //============================================================================= // FUNCTION: FreeMemory() // // Modification History // // raypa 01/28/93 Created. // stevehi 07/21/93 Added memory checking functionality // raypa 07/21/93 Changed to use LPTR rather than LocalLock. // raypa 07/21/93 Fixed GP-fault on NULL ptr. // raypa 11/21/93 Allow freeing of NULL pointer. //============================================================================= VOID WINAPI FreeMemory(LPBYTE ptr) { //========================================================================= // If the pointer is NULL, exit. //========================================================================= if ( ptr != NULL ) { #ifdef DEBUG_MEM register DWORD Size; register LPDWORD DwordPtr; MEM_BUFFER *lpMem; ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER)); lpMem = (MEM_BUFFER *) ((LPBYTE)ptr + sizeof(DWORD)); Size = LocalSize(ptr); //... Check start tag DwordPtr = (LPDWORD) &ptr[0]; if ( *DwordPtr != AllocTagTakeStart ) { dprintf(TEXT("NWConv - FreeMemory: Invalid start signature: ptr = %X\r\n"), ptr); DebugBreak(); } else { *DwordPtr = AllocTagFreeStart; } //... get the size and check the end tag DwordPtr = (LPDWORD) &ptr[Size - sizeof(DWORD)]; if ( *DwordPtr != AllocTagTakeStop ) { dprintf(TEXT("NWConv - FreeMemory: Invalid end signature: ptr = %X\r\n"), ptr); DebugBreak(); } else { *DwordPtr = AllocTagFreeStop; } AllocCount--; if (MemList == lpMem) MemList = lpMem->Next; if (lpMem->Prev != NULL) lpMem->Prev->Next = lpMem->Next; if (lpMem->Next != NULL) lpMem->Next->Prev = lpMem->Prev; #endif LocalFree(ptr); } } // FreeMemory //============================================================================= // FUNCTION: MemorySize() // // Modification History // // Tom Laird-McConnell 08/02/93 Created. // Tom Laird-McConnell 08/02/93 Changed to use local var for size... //============================================================================= DWORD WINAPI MemorySize(LPBYTE ptr) { #ifdef DEBUG_MEM register DWORD Size; if ( ptr != NULL ) { register LPDWORD DwordPtr; ptr -= (sizeof(DWORD) + sizeof(MEM_BUFFER)); Size = LocalSize(ptr); DwordPtr = (LPDWORD) &ptr[0]; // Check start tag if ( *DwordPtr != AllocTagTakeStart ) { dprintf(TEXT("NWConv - MemorySize: Invalid start signature!\r\n")); DebugBreak; } // get the size and check the end tag DwordPtr = (LPDWORD) &ptr[Size - sizeof(DWORD)]; if ( *DwordPtr != AllocTagTakeStop ) { dprintf(TEXT("NWConv - MemorySize: Invalid end signature!\r\n")); DebugBreak; } return (Size - (2 * sizeof(DWORD)) - sizeof(MEM_BUFFER)); } #endif return LocalSize(ptr); } // MemorySize