Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

337 lines
9.0 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
memlib.c
Abstract:
Contains memory functions
Contents:
initialize_memory_package
my_malloc
my_calloc
alloc_common
my_free
report_memory_usage
report_allocs
traverse_mem_list
id$
Author:
Richard L Firth (rfirth) 2-Apr-1994
Revision History:
02-Apr-1994 rfirth
Created
--*/
#include "pmsimh.h"
#pragma hdrstop
#define ROUND_UP(n) ((((n) + (sizeof(DWORD) - 1)) / sizeof(DWORD)) * sizeof(DWORD))
typedef struct {
LIST_ENTRY List;
DWORD Size;
DWORD OriginalSize;
DWORD Signature;
DWORD Id;
} MEMORY_HEADER, *PMEMORY_HEADER;
typedef struct {
DWORD Size;
DWORD Signature;
} MEMORY_FOOTER, *PMEMORY_FOOTER;
LONG AllocatedBytesOutstanding = 0;
DWORD TotalBytesAllocated = 0;
DWORD TotalBytesFreed = 0;
DWORD TotalAllocations = 0;
DWORD TotalFrees = 0;
extern int Debugging;
extern int AccessViolate;
extern int NoMemoryUsageReporting;
LONG GrowthRate = 4096;
LONG CurrentMaximum = 0;
LONG MaxAllocated = 0;
DWORD TypeAllocs[NUMBER_OF_ALLOC_IDS];
CRITICAL_SECTION MemListCritSec;
LIST_ENTRY MemList;
void* alloc_common(char, int, DWORD);
char* id$(DWORD);
void dump_ccb(PLLC_CCB);
void initialize_memory_package() {
static BOOL Initialized = FALSE;
if (!Initialized) {
InitializeCriticalSection(&MemListCritSec);
InitializeListHead(&MemList);
Initialized = TRUE;
}
}
void* my_malloc(int size, DWORD Id) {
return alloc_common('M', size, Id);
}
void* my_calloc(int num, int size, DWORD Id) {
return alloc_common('C', num * size, Id);
}
void* alloc_common(char type, int size, DWORD Id) {
void* ptr;
int originalSize = size;
size = ROUND_UP(size) + sizeof(MEMORY_HEADER) + sizeof(MEMORY_FOOTER);
if (type == 'M') {
ptr = malloc(size);
} else {
ptr = calloc(1, size);
}
if (ptr) {
((PMEMORY_HEADER)ptr)->Size = size;
((PMEMORY_HEADER)ptr)->OriginalSize = originalSize;
((PMEMORY_HEADER)ptr)->Signature = 0xcec171a2;
((PMEMORY_HEADER)ptr)->Id = Id;
((PMEMORY_FOOTER)((PBYTE)ptr + size - sizeof(MEMORY_FOOTER)))->Size = size;
((PMEMORY_FOOTER)((PBYTE)ptr + size - sizeof(MEMORY_FOOTER)))->Signature = 0xcec171a2;
AllocatedBytesOutstanding += (LONG)size;
if (AllocatedBytesOutstanding < 0) {
printf("alloc_common(%c): alloc overflow? AllocatedBytesOutstanding=%x\n",
type,
AllocatedBytesOutstanding
);
}
TotalBytesAllocated += (DWORD)size;
++TotalAllocations;
if (AllocatedBytesOutstanding > MaxAllocated) {
MaxAllocated = AllocatedBytesOutstanding;
}
if (Debugging && (MaxAllocated > CurrentMaximum + GrowthRate)) {
report_memory_usage(FALSE);
CurrentMaximum = MaxAllocated;
}
++TypeAllocs[Id];
EnterCriticalSection(&MemListCritSec);
InsertHeadList(&MemList, &((PMEMORY_HEADER)ptr)->List);
LeaveCriticalSection(&MemListCritSec);
return (PMEMORY_HEADER)ptr + 1;
} else {
printf("alloc_common(%c): error: failed to allocate %d bytes memory\n", type, size);
if (Debugging) {
if (AccessViolate) {
*(LPDWORD)0 = 0;
} else {
DebugBreak();
}
}
return NULL;
}
}
void my_free(void* ptr) {
DWORD size;
((PMEMORY_HEADER)ptr) -= 1;
size = ((PMEMORY_HEADER)ptr)->Size;
EnterCriticalSection(&MemListCritSec);
if ((size & 3)
|| (((PMEMORY_HEADER)ptr)->Signature != 0xcec171a2)
|| (((PMEMORY_FOOTER)((PBYTE)ptr + size - sizeof(MEMORY_FOOTER)))->Signature != 0xcec171a2)
|| (((PMEMORY_FOOTER)((PBYTE)ptr + size - sizeof(MEMORY_FOOTER)))->Size != size)
|| IsListEmpty(&MemList)) {
printf("\amy_free: bad block %x?\n", ptr);
report_memory_usage(TRUE);
if (Debugging) {
if (AccessViolate) {
*(LPDWORD)0 = 0;
} else {
DebugBreak();
}
}
LeaveCriticalSection(&MemListCritSec);
} else {
RemoveEntryList(&((PMEMORY_HEADER)ptr)->List);
LeaveCriticalSection(&MemListCritSec);
AllocatedBytesOutstanding -= size;
if (AllocatedBytesOutstanding < 0) {
printf("my_free: free underflow? AllocatedBytesOutstanding=%x\n",
AllocatedBytesOutstanding
);
}
if (((PMEMORY_HEADER)ptr)->Id >= NUMBER_OF_ALLOC_IDS) {
printf("\amy_free: bad alloc id: %d (%s) block @ %x\n",
((LPDWORD)ptr)[3],
id$(((LPDWORD)ptr)[3]),
ptr
);
report_memory_usage(TRUE);
report_allocs();
if (Debugging) {
if (AccessViolate) {
*(LPDWORD)0 = 0;
} else {
DebugBreak();
}
}
}
--TypeAllocs[((PMEMORY_HEADER)ptr)->Id];
memset(ptr, '@', size);
free(ptr);
TotalBytesFreed += (DWORD)size;
++TotalFrees;
}
}
void report_memory_usage(BOOL force) {
if (!force && NoMemoryUsageReporting) {
return;
}
display_elapsed_time();
printf("\n"
"Memory Usage:\n"
);
printf("\tAllocatedBytesOutstanding : %s\n", nice_num(AllocatedBytesOutstanding));
printf("\tTotalBytesAllocated . . . : %s\n", nice_num(TotalBytesAllocated));
printf("\tTotalBytesFreed . . . . . : %s\n", nice_num(TotalBytesFreed));
printf("\tTotalAllocations. . . . . : %s\n", nice_num(TotalAllocations));
printf("\tTotalFrees. . . . . . . . : %s\n", nice_num(TotalFrees));
printf("\tAllocations - Frees . . . : %s\n", nice_num(TotalAllocations - TotalFrees));
putchar('\n');
}
void report_allocs() {
display_elapsed_time();
printf("\n"
"Memory Allocations by type:\n"
);
printf("\tCreate Buffer . . . . . . : %s\n", nice_num(TypeAllocs[0]));
printf("\tClose Adapter CCB . . . . : %s\n", nice_num(TypeAllocs[1]));
printf("\tClose SAP CCB . . . . . . : %s\n", nice_num(TypeAllocs[2]));
printf("\tClose Station CCB . . . . : %s\n", nice_num(TypeAllocs[3]));
printf("\tReset CCB . . . . . . . . : %s\n", nice_num(TypeAllocs[4]));
printf("\tReceive CCB . . . . . . . : %s\n", nice_num(TypeAllocs[5]));
printf("\tReceive Parms . . . . . . : %s\n", nice_num(TypeAllocs[6]));
printf("\tRead CCB. . . . . . . . . : %s\n", nice_num(TypeAllocs[7]));
printf("\tRead Parms. . . . . . . . : %s\n", nice_num(TypeAllocs[8]));
printf("\tTransmit CCB. . . . . . . : %s\n", nice_num(TypeAllocs[9]));
printf("\tTransmit Parms. . . . . . : %s\n", nice_num(TypeAllocs[10]));
printf("\tEcho Packet . . . . . . . : %s\n", nice_num(TypeAllocs[11]));
printf("\tReceiver Object . . . . . : %s\n", nice_num(TypeAllocs[12]));
printf("\tStation Object. . . . . . : %s\n", nice_num(TypeAllocs[13]));
printf("\tJob Object. . . . . . . . : %s\n", nice_num(TypeAllocs[14]));
putchar('\n');
}
void traverse_mem_list(BOOL expand) {
PMEMORY_HEADER header;
display_elapsed_time();
EnterCriticalSection(&MemListCritSec);
if (IsListEmpty(&MemList)) {
printf("traverse_mem_list: list is empty\n");
LeaveCriticalSection(&MemListCritSec);
return;
}
header = (PMEMORY_HEADER)MemList.Flink;
while (header != (PMEMORY_HEADER)&MemList.Flink) {
printf("entry @ %08x Id=%s\n", header, id$(header->Id));
if (expand) {
if (IS_CCB_ID(header->Id)) {
dump_ccb((PLLC_CCB)(header + 1));
} else if (IS_RECEIVER(header->Id)) {
dump_receiver((PRECEIVER)(header + 1));
} else if (IS_STATION(header->Id)) {
dump_station((PSTATION)(header + 1));
} else if (IS_JOB(header->Id)) {
dump_job((PJOB)(header + 1));
}
}
header = (PMEMORY_HEADER)header->List.Flink;
}
LeaveCriticalSection(&MemListCritSec);
putchar('\n');
}
char* id$(DWORD Id) {
switch (Id) {
case ID_CREATE_BUFFER:
return "ID_CREATE_BUFFER";
case ID_CLOSE_ADAPTER:
return "ID_CLOSE_ADAPTER";
case ID_CLOSE_SAP:
return "ID_CLOSE_SAP";
case ID_CLOSE_STATION:
return "ID_CLOSE_STATION";
case ID_RESET:
return "ID_RESET";
case ID_RECEIVE:
return "ID_RECEIVE";
case ID_RECEIVE_PARMS:
return "ID_RECEIVE_PARMS";
case ID_READ:
return "ID_READ";
case ID_READ_PARMS:
return "ID_READ_PARMS";
case ID_TRANSMIT:
return "ID_TRANSMIT";
case ID_TRANSMIT_PARMS:
return "ID_TRANSMIT_PARMS";
case ID_ECHO_PACKET:
return "ID_ECHO_PACKET";
case ID_RECEIVER:
return "ID_RECEIVER";
case ID_STATION:
return "ID_STATION";
case ID_JOB:
return "ID_JOB";
}
return "*** Unknown Id ***";
}