724 lines
21 KiB
C++
724 lines
21 KiB
C++
|
/*++
|
|||
|
|
|||
|
<EFBFBD> 1998 Seagate Software, Inc. All rights reserved
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
wsbtrak.cpp
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Utility functions to keep track of run-time information.
|
|||
|
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ron White [ronw] 5-Dec-1997
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "stdafx.h"
|
|||
|
#include "wsbguid.h"
|
|||
|
|
|||
|
#if defined(WSB_TRACK_MEMORY)
|
|||
|
|
|||
|
#define OBJECT_TABLE_SIZE 100
|
|||
|
#define POINTER_DATA_CURRENT 0
|
|||
|
#define POINTER_DATA_CUMULATIVE 2
|
|||
|
#define POINTER_DATA_MAX 1
|
|||
|
#define POINTER_DATA_SIZE 3
|
|||
|
#define POINTER_LIST_SIZE 1000
|
|||
|
|
|||
|
typedef struct {
|
|||
|
GUID guid;
|
|||
|
LONG count;
|
|||
|
LONG total_count;
|
|||
|
LONG max_count;
|
|||
|
} OBJECT_TABLE_ENTRY;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
OLECHAR * guid_string;
|
|||
|
OLECHAR * name;
|
|||
|
GUID * pGuid;
|
|||
|
} OBJECT_NAME_ENTRY;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
LONG count;
|
|||
|
LONGLONG size;
|
|||
|
} POINTER_DATA_ENTRY;
|
|||
|
|
|||
|
typedef struct {
|
|||
|
const void * addr;
|
|||
|
LONG order;
|
|||
|
ULONG size;
|
|||
|
int index; // Index into object table
|
|||
|
const char * filename;
|
|||
|
int linenum;
|
|||
|
} POINTER_LIST_ENTRY;
|
|||
|
|
|||
|
// Module data
|
|||
|
#if defined(CRT_DEBUG_MEMORY)
|
|||
|
static _CrtMemState CrtMemState;
|
|||
|
#endif
|
|||
|
|
|||
|
static OBJECT_TABLE_ENTRY object_table[OBJECT_TABLE_SIZE];
|
|||
|
static int object_table_count = 0;
|
|||
|
static POINTER_DATA_ENTRY pointer_data[POINTER_DATA_SIZE];
|
|||
|
static BOOL pointer_data_initialized = FALSE;
|
|||
|
static POINTER_LIST_ENTRY pointer_list[POINTER_LIST_SIZE];
|
|||
|
static int pointer_list_count = 0;
|
|||
|
|
|||
|
static OBJECT_NAME_ENTRY object_name_table[] = {
|
|||
|
{ L"{C03D4861-70D7-11d1-994F-0060976A546D}", L"CWsbStringPtr", NULL },
|
|||
|
{ L"{C03D4862-70D7-11d1-994F-0060976A546D}", L"CWsbBstrPtr", NULL },
|
|||
|
{ L"{A0FF1F42-237A-11D0-81BA-00A0C91180F2}", L"CWsbGuid", NULL },
|
|||
|
{ L"{9C7D6F13-1562-11D0-81AC-00A0C91180F2}", L"CWsbOrderedCollection", NULL },
|
|||
|
{ L"{46CE9EDE-447C-11D0-98FC-00A0C9058BF6}", L"CWsbDbKey", NULL },
|
|||
|
|
|||
|
{ L"{E707D9B2-4F89-11D0-81CC-00A0C91180F2}", L"CFsaServerNTFS", NULL },
|
|||
|
{ L"{FCDC8671-7329-11d0-81DF-00A0C91180F2}", L"CFsaFilterNTFS", NULL },
|
|||
|
{ L"{112981B3-1BA5-11D0-81B2-00A0C91180F2}", L"CFsaResourceNTFS", NULL },
|
|||
|
{ L"{0B8B6F12-8B3A-11D0-990C-00A0C9058BF6}", L"CFsaPremigratedDb", NULL },
|
|||
|
{ L"{14005FF1-8B4F-11d0-81E6-00A0C91180F2}", L"CFsaTruncatorNTFS", NULL },
|
|||
|
{ L"{CECCB131-286D-11d1-993E-0060976A546D}", L"CFsaRecoveryRec", NULL },
|
|||
|
{ L"{7CA819F2-8AAB-11D0-990C-00A0C9058BF6}", L"CFsaPremigratedRec", NULL },
|
|||
|
{ L"{B2AD2931-84FD-11d0-81E4-00A0C91180F2}", L"CFsaFilterClientNTFS", NULL },
|
|||
|
{ L"{F7860350-AA27-11d0-B16D-00A0C916F120}", L"CFsaPostIt", NULL },
|
|||
|
{ L"{B2AD2932-84FD-11d0-81E4-00A0C91180F2}", L"CFsaFilterRecallNTFS", NULL },
|
|||
|
{ L"{112981B2-1BA5-11D0-81B2-00A0C91180F2}", L"CFsaScanItemNTFS", NULL },
|
|||
|
|
|||
|
{ L"{7B22FF29-1AD6-11D0-81B1-00A0C91180F2}", L"CHsmActionManage", NULL },
|
|||
|
{ L"{D9E04211-14D7-11d1-9938-0060976A546D}", L"CHsmActionOnResourcePostValidate", NULL },
|
|||
|
{ L"{D9E04212-14D7-11d1-9938-0060976A546D}", L"CHsmActionOnResourcePreValidate", NULL },
|
|||
|
{ L"{7B22FF24-1AD6-11D0-81B1-00A0C91180F2}", L"CHsmActionTruncate", NULL },
|
|||
|
{ L"{D3AF5DB1-1DF8-11D0-81B6-00A0C91180F2}", L"CHsmActionUnmanage", NULL },
|
|||
|
{ L"{7B22FF26-1AD6-11D0-81B1-00A0C91180F2}", L"CHsmActionValidate", NULL },
|
|||
|
{ L"{AD40235F-00FC-11D0-819C-00A0C91180F2}", L"CHsmCritAlways", NULL },
|
|||
|
{ L"{CFB04622-1C9F-11D0-81B4-00A0C91180F2}", L"CHsmCritManageable", NULL },
|
|||
|
{ L"{7B22FF2C-1AD6-11D0-81B1-00A0C91180F2}", L"CHsmCritMigrated", NULL },
|
|||
|
{ L"{7B22FF2D-1AD6-11D0-81B1-00A0C91180F2}", L"CHsmCritPremigrated", NULL },
|
|||
|
{ L"{AD402346-00FC-11D0-819C-00A0C91180F2}", L"CHsmJob", NULL },
|
|||
|
{ L"{AD402364-00FC-11D0-819C-00a0C91180F2}", L"CHsmJobContext", NULL },
|
|||
|
{ L"{AD40234B-00FC-11D0-819C-00a0C91180F2}", L"CHsmJobDef", NULL },
|
|||
|
{ L"{B8E1CD21-81D3-11d0-81E4-00A0C91180F2}", L"CHsmJobWorkItem", NULL },
|
|||
|
{ L"{AB939AD0-6D67-11d0-9E2E-00A0C916F120}", L"CHsmManagedResource", NULL },
|
|||
|
{ L"{8448dd80-7614-11d0-9e33-00a0c916f120}", L"CHsmManagedResourceCollection", NULL },
|
|||
|
{ L"{BEA60F8A-7EBA-11d0-81E4-00A0C91180F2}", L"CHsmPhase", NULL },
|
|||
|
{ L"{AD402350-00FC-11D0-819C-00A0C91180F2}", L"CHsmPolicy", NULL },
|
|||
|
{ L"{AD40235A-00FC-11D0-819C-00A0C91180F2}", L"CHsmRule", NULL },
|
|||
|
{ L"{C2E29801-B1BA-11d0-81E9-00A0C91180F2}", L"CHsmRuleStack", NULL },
|
|||
|
{ L"{2D1E3156-25DE-11D0-8073-00A0C905F098}", L"CHsmServer", NULL },
|
|||
|
{ L"{BEA60F80-7EBA-11d0-81E4-00A0C91180F2}", L"CHsmSession", NULL },
|
|||
|
{ L"{FF67BB34-8430-11d0-81E4-00A0C91180F2}", L"CHsmSessionTotals", NULL },
|
|||
|
{ L"{61F0B790-82D9-11d0-9E35-00A0C916F120}", L"CHsmStoragePool", NULL },
|
|||
|
{ L"{23E45B60-C598-11d0-B16F-00A0C916F120}", L"CHsmWorkItem", NULL },
|
|||
|
{ L"{247DF540-C558-11d0-B16F-00A0C916F120}", L"CHsmWorkQueue", NULL },
|
|||
|
|
|||
|
{ L"{450024A3-47D0-11D0-9E1E-00A0C916F120}", L"CBagHole", NULL },
|
|||
|
{ L"{B13FA473-4E1B-11D0-9E22-00A0C916F120}", L"CBagInfo", NULL },
|
|||
|
{ L"{F0D7AFE0-9026-11d0-9E3B-00A0C916F120}", L"CMediaInfo", NULL },
|
|||
|
{ L"{768AD5A4-40C8-11D0-9E17-00A0C916F120}", L"CSegDB", NULL },
|
|||
|
{ L"{37F704E6-3EF9-11D0-9E17-00A0C916F120}", L"CSegRec", NULL },
|
|||
|
|
|||
|
{ L"{BD030C00-000B-11D0-D0DD-00A0C9190459}", L"CMemIo Class", NULL },
|
|||
|
{ L"{BD040C00-000B-11D0-D0DD-00A0C9190459}", L"CNtTapeIo Class", NULL },
|
|||
|
{ L"{BD050C00-000B-11D0-D0DD-00A0C9190459}", L"CNtFileIo Class", NULL },
|
|||
|
|
|||
|
{ L"{FE37FA04-3729-11D0-8CF4-00A0C9190459}", L"RmsCartridge Class", NULL },
|
|||
|
{ L"{FE37FA07-3729-11D0-8CF4-00A0C9190459}", L"RmsMediumChanger Class", NULL },
|
|||
|
{ L"{FE37FA12-3729-11D0-8CF4-00A0C9190459}", L"RmsClient Class", NULL },
|
|||
|
{ L"{FE37FA03-3729-11D0-8CF4-00A0C9190459}", L"RmsDriveClass Class", NULL },
|
|||
|
{ L"{FE37FA05-3729-11D0-8CF4-00A0C9190459}", L"RmsDrive Class", NULL },
|
|||
|
{ L"{FE37FA08-3729-11D0-8CF4-00A0C9190459}", L"RmsIEPort Class", NULL },
|
|||
|
{ L"{FE37FA02-3729-11D0-8CF4-00A0C9190459}", L"RmsLibrary Class", NULL },
|
|||
|
{ L"{FE37FA09-3729-11D0-8CF4-00A0C9190459}", L"RmsMediaSet Class", NULL },
|
|||
|
{ L"{FE37FA13-3729-11D0-8CF4-00A0C9190459}", L"RmsNTMS Class", NULL },
|
|||
|
{ L"{FE37FA11-3729-11D0-8CF4-00A0C9190459}", L"RmsPartition Class", NULL },
|
|||
|
{ L"{FE37FA10-3729-11D0-8CF4-00A0C9190459}", L"RmsRequest Class", NULL },
|
|||
|
{ L"{FE37FA01-3729-11D0-8CF4-00A0C9190459}", L"RmsServer Class", NULL },
|
|||
|
{ L"{FE37FA14-3729-11D0-8CF4-00A0C9190459}", L"RmsSink Class", NULL },
|
|||
|
{ L"{FE37FA06-3729-11D0-8CF4-00A0C9190459}", L"RmsStorageSlot Class", NULL },
|
|||
|
{ L"{FE37FA15-3729-11D0-8CF4-00A0C9190459}", L"RmsTemplate Class", NULL },
|
|||
|
|
|||
|
{ NULL, NULL, NULL }
|
|||
|
};
|
|||
|
|
|||
|
// Local functions
|
|||
|
static BOOL AddPointer(const void* addr, ULONG size, int index, const char * filename,
|
|||
|
int linenum);
|
|||
|
static OLECHAR* GuidToObjectName(const GUID& guid);
|
|||
|
static BOOL SubPointer(const void* addr, int index);
|
|||
|
|
|||
|
|
|||
|
// AddPointer - add a new pointer to the pointer list
|
|||
|
// Return FALSE on failure (list is full or pointer is already in list)
|
|||
|
static BOOL AddPointer(const void* addr, ULONG size, int index,
|
|||
|
const char * filename, int linenum)
|
|||
|
{
|
|||
|
int empty_slot = -1;
|
|||
|
int i;
|
|||
|
BOOL status = TRUE;
|
|||
|
|
|||
|
if (!pointer_data_initialized) {
|
|||
|
pointer_data[POINTER_DATA_CURRENT].count = 0;
|
|||
|
pointer_data[POINTER_DATA_CURRENT].size = 0;
|
|||
|
pointer_data[POINTER_DATA_MAX].count = 0;
|
|||
|
pointer_data[POINTER_DATA_MAX].size = 0;
|
|||
|
pointer_data[POINTER_DATA_CUMULATIVE].count = 0;
|
|||
|
pointer_data[POINTER_DATA_CUMULATIVE].size = 0;
|
|||
|
pointer_data_initialized = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
for (i = 0; i < pointer_list_count; i++) {
|
|||
|
if (NULL == pointer_list[i].addr) {
|
|||
|
empty_slot = i;
|
|||
|
} else if (addr == pointer_list[i].addr) {
|
|||
|
WsbTraceAlways(OLESTR("AddPointer: address already in list: %lx (<%ls>, line: <%ld>\n"),
|
|||
|
(ULONG)addr, (OLECHAR *)filename, index);
|
|||
|
status = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (i == pointer_list_count) {
|
|||
|
// Not in list. Is the list full?
|
|||
|
if (-1 == empty_slot && POINTER_LIST_SIZE == pointer_list_count) {
|
|||
|
WsbTraceAlways(OLESTR("AddPointer: pointer list is full: %lx\n"),
|
|||
|
(ULONG)addr);
|
|||
|
status = FALSE;
|
|||
|
} else if (-1 == empty_slot) {
|
|||
|
pointer_list_count++;
|
|||
|
} else {
|
|||
|
i = empty_slot;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (status) {
|
|||
|
pointer_list[i].addr = addr;
|
|||
|
pointer_list[i].size = size;
|
|||
|
pointer_list[i].index = index;
|
|||
|
pointer_list[i].filename = filename;
|
|||
|
pointer_list[i].linenum = linenum;
|
|||
|
pointer_data[POINTER_DATA_CURRENT].count++;
|
|||
|
pointer_data[POINTER_DATA_CURRENT].size += size;
|
|||
|
if (pointer_data[POINTER_DATA_CURRENT].count > pointer_data[POINTER_DATA_MAX].count) {
|
|||
|
pointer_data[POINTER_DATA_MAX].count = pointer_data[POINTER_DATA_CURRENT].count;
|
|||
|
}
|
|||
|
if (pointer_data[POINTER_DATA_CURRENT].size > pointer_data[POINTER_DATA_MAX].size) {
|
|||
|
pointer_data[POINTER_DATA_MAX].size = pointer_data[POINTER_DATA_CURRENT].size;
|
|||
|
}
|
|||
|
pointer_data[POINTER_DATA_CUMULATIVE].count++;
|
|||
|
pointer_data[POINTER_DATA_CUMULATIVE].size += size;
|
|||
|
pointer_list[i].order = pointer_data[POINTER_DATA_CUMULATIVE].count;
|
|||
|
}
|
|||
|
|
|||
|
return(status);
|
|||
|
}
|
|||
|
|
|||
|
// GuidToObjectName - convert a guid to an object name
|
|||
|
static OLECHAR* GuidToObjectName(const GUID& guid)
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
int i;
|
|||
|
OLECHAR * name = NULL;
|
|||
|
|
|||
|
try {
|
|||
|
// Need to do conversions from string to Guid?
|
|||
|
if (NULL == object_name_table[0].pGuid) {
|
|||
|
i = 0;
|
|||
|
while (object_name_table[i].guid_string) {
|
|||
|
GUID * pg = new GUID;
|
|||
|
|
|||
|
WsbAffirmHr(WsbGuidFromString(object_name_table[i].guid_string,
|
|||
|
pg));
|
|||
|
object_name_table[i].pGuid = pg;
|
|||
|
i++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// See if this Guid is in the name table
|
|||
|
i = 0;
|
|||
|
while (object_name_table[i].guid_string) {
|
|||
|
if (guid == *object_name_table[i].pGuid) {
|
|||
|
name = object_name_table[i].name;
|
|||
|
break;
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
} WsbCatch(hr);
|
|||
|
|
|||
|
return(name);
|
|||
|
}
|
|||
|
|
|||
|
// SubPointer - remove a pointer from the pointer list
|
|||
|
// Return FALSE on failure (pointer is not in list or index doesn't match)
|
|||
|
static BOOL SubPointer(const void* addr, int index)
|
|||
|
{
|
|||
|
int i;
|
|||
|
BOOL status = TRUE;
|
|||
|
|
|||
|
for (i = 0; i < pointer_list_count; i++) {
|
|||
|
if (addr == pointer_list[i].addr) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (i == pointer_list_count) {
|
|||
|
WsbTraceAlways(OLESTR("SubPointer: pointer not found in list: %lx\n"),
|
|||
|
(ULONG)addr);
|
|||
|
status = FALSE;
|
|||
|
} else if (index != pointer_list[i].index) {
|
|||
|
WsbTraceAlways(OLESTR("SubPointer: type index doesn't match for pointer: %lx\n"),
|
|||
|
(ULONG)addr);
|
|||
|
WsbTraceAlways(OLESTR(", original type index = %d, new type index = %d\n"),
|
|||
|
pointer_list[i].index, index);
|
|||
|
status = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (status) {
|
|||
|
pointer_list[i].addr = NULL;
|
|||
|
pointer_data[POINTER_DATA_CURRENT].count--;
|
|||
|
pointer_data[POINTER_DATA_CURRENT].size -= pointer_list[i].size;
|
|||
|
}
|
|||
|
|
|||
|
return(status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESULT WsbObjectAdd(
|
|||
|
const GUID & guid,
|
|||
|
const void * addr
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Add another object to the object table
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
guid - Guid for the object type
|
|||
|
|
|||
|
addr - Memory address of object
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - Success
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
#if defined(CRT_DEBUG_MEMORY)
|
|||
|
// Set CRT debug flag
|
|||
|
static BOOL first = TRUE;
|
|||
|
if (first) {
|
|||
|
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
|||
|
|
|||
|
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
|
|||
|
|
|||
|
// Set the new state for the flag
|
|||
|
_CrtSetDbgFlag( tmpFlag );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
try {
|
|||
|
int i;
|
|||
|
|
|||
|
// Reserve the first entry for non-objects and table overflow
|
|||
|
if (0 == object_table_count) {
|
|||
|
object_table[0].guid = GUID_NULL;
|
|||
|
object_table[0].count = 0;
|
|||
|
object_table[0].total_count = 0;
|
|||
|
object_table[0].max_count = 0;
|
|||
|
object_table_count = 1;
|
|||
|
}
|
|||
|
|
|||
|
// Check in object type is already in table
|
|||
|
for (i = 0; i < object_table_count; i++) {
|
|||
|
if (guid == object_table[i].guid) break;
|
|||
|
}
|
|||
|
|
|||
|
// Add a new entry if not (and there is room)
|
|||
|
if (i == object_table_count && i < OBJECT_TABLE_SIZE) {
|
|||
|
// WsbTraceAlways(OLESTR("WsbObjectAdd: new object, guid = %ls\n"),
|
|||
|
// WsbGuidAsString(guid));
|
|||
|
#if defined(CRT_DEBUG_MEMORY)
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectAdd: _CrtCheckMemory = %ls\n"),
|
|||
|
WsbBoolAsString(_CrtCheckMemory()));
|
|||
|
#endif
|
|||
|
object_table[i].guid = guid;
|
|||
|
object_table[i].count = 0;
|
|||
|
object_table[i].total_count = 0;
|
|||
|
object_table[i].max_count = 0;
|
|||
|
object_table_count++;
|
|||
|
} else if (OBJECT_TABLE_SIZE == i) {
|
|||
|
// Use the first entry for everything else
|
|||
|
i = 0;
|
|||
|
}
|
|||
|
object_table[i].count++;
|
|||
|
object_table[i].total_count++;
|
|||
|
if (object_table[i].count > object_table[i].max_count) {
|
|||
|
object_table[i].max_count = object_table[i].count;
|
|||
|
}
|
|||
|
|
|||
|
// Add to pointer list
|
|||
|
AddPointer(addr, 0, i, NULL, 0);
|
|||
|
|
|||
|
} WsbCatch(hr);
|
|||
|
|
|||
|
return(hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT WsbObjectSub(
|
|||
|
const GUID & guid,
|
|||
|
const void * addr
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Subtract an object from the object table
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
guid - Guid for the object type
|
|||
|
|
|||
|
addr - Memory address of object
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - Success
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
try {
|
|||
|
int i;
|
|||
|
|
|||
|
// Find the object type in table
|
|||
|
for (i = 0; i < object_table_count; i++) {
|
|||
|
if (guid == object_table[i].guid) {
|
|||
|
// Allow count to go negative since this could indicate a problem
|
|||
|
object_table[i].count--;
|
|||
|
|
|||
|
// Remove from pointer list
|
|||
|
SubPointer(addr, i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} WsbCatch(hr);
|
|||
|
|
|||
|
return(hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT WsbObjectTracePointers(
|
|||
|
ULONG flags
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Dump the pointer list information to the trace file.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
flags - WSB_OTP_ flags
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - Success
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
try {
|
|||
|
int i;
|
|||
|
OLECHAR string[300];
|
|||
|
|
|||
|
// Dump the current sequence number
|
|||
|
if (flags & WSB_OTP_SEQUENCE) {
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTracePointers: current sequence number = %ld\n"),
|
|||
|
pointer_data[POINTER_DATA_CUMULATIVE].count);
|
|||
|
}
|
|||
|
|
|||
|
// Dump statistics
|
|||
|
if (flags & WSB_OTP_STATISTICS) {
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTracePointers: count, size\n"));
|
|||
|
WsbTraceAlways(OLESTR(" Current %8ld %12ls\n"),
|
|||
|
pointer_data[POINTER_DATA_CURRENT].count,
|
|||
|
WsbLonglongAsString(pointer_data[POINTER_DATA_CURRENT].size));
|
|||
|
WsbTraceAlways(OLESTR(" Maximum %8ld %12ls\n"),
|
|||
|
pointer_data[POINTER_DATA_MAX].count,
|
|||
|
WsbLonglongAsString(pointer_data[POINTER_DATA_MAX].size));
|
|||
|
WsbTraceAlways(OLESTR(" Cumulative %8ld %12ls\n"),
|
|||
|
pointer_data[POINTER_DATA_CUMULATIVE].count,
|
|||
|
WsbLonglongAsString(pointer_data[POINTER_DATA_CUMULATIVE].size));
|
|||
|
}
|
|||
|
|
|||
|
// Dump non-NULL pointers
|
|||
|
if (flags & WSB_OTP_ALLOCATED) {
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTracePointers: allocated memory list (addr, size, order, name/GUID/file):\n"));
|
|||
|
for (i = 0; i < pointer_list_count; i++) {
|
|||
|
if (pointer_list[i].addr) {
|
|||
|
GUID guid = GUID_NULL;
|
|||
|
int index;
|
|||
|
OLECHAR * name = NULL;
|
|||
|
OLECHAR * pstr = NULL;
|
|||
|
|
|||
|
index = pointer_list[i].index;
|
|||
|
if (index > 0 && index < object_table_count) {
|
|||
|
guid = object_table[index].guid;
|
|||
|
name = GuidToObjectName(guid);
|
|||
|
}
|
|||
|
if (0 == index) {
|
|||
|
wsprintf(string, OLESTR("%hs(%d)"), pointer_list[i].filename,
|
|||
|
pointer_list[i].linenum);
|
|||
|
pstr = string;
|
|||
|
} else if (name) {
|
|||
|
pstr = name;
|
|||
|
} else {
|
|||
|
wcscpy(string, WsbGuidAsString(guid));
|
|||
|
pstr = string;
|
|||
|
}
|
|||
|
WsbTraceAlways(OLESTR(" %8lx %8ld %8ld %ls\n"), pointer_list[i].addr,
|
|||
|
pointer_list[i].size, pointer_list[i].order, pstr);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if defined(CRT_DEBUG_MEMORY)
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTrace: calling _CrtMemCheckpoint\n"));
|
|||
|
_CrtMemCheckpoint(&CrtMemState);
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTrace: MemState.lHighWaterCount = %ld, TotalCount = %ld\n"),
|
|||
|
CrtMemState.lHighWaterCount, CrtMemState.lTotalCount);
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTrace: MemState.blocks count & size\n"));
|
|||
|
WsbTraceAlways(OLESTR(" FREE %4ld %6ld\n"), CrtMemState.lCounts[_FREE_BLOCK],
|
|||
|
CrtMemState.lSizes[_FREE_BLOCK]);
|
|||
|
WsbTraceAlways(OLESTR(" NORMAL %4ld %6ld\n"), CrtMemState.lCounts[_NORMAL_BLOCK],
|
|||
|
CrtMemState.lSizes[_NORMAL_BLOCK]);
|
|||
|
WsbTraceAlways(OLESTR(" CRT %4ld %6ld\n"), CrtMemState.lCounts[_CRT_BLOCK],
|
|||
|
CrtMemState.lSizes[_CRT_BLOCK]);
|
|||
|
WsbTraceAlways(OLESTR(" IGNORE %4ld %6ld\n"), CrtMemState.lCounts[_IGNORE_BLOCK],
|
|||
|
CrtMemState.lSizes[_IGNORE_BLOCK]);
|
|||
|
WsbTraceAlways(OLESTR(" CLIENT %4ld %6ld\n"), CrtMemState.lCounts[_CLIENT_BLOCK],
|
|||
|
CrtMemState.lSizes[_CLIENT_BLOCK]);
|
|||
|
|
|||
|
// WsbTraceAlways(OLESTR("WsbObjectTrace: calling _CrtMemDumpStatistics\n"));
|
|||
|
// _CrtMemDumpStatistics(&CrtMemState);
|
|||
|
// _CrtDumpMemoryLeaks();
|
|||
|
#endif
|
|||
|
|
|||
|
} WsbCatch(hr);
|
|||
|
|
|||
|
return(hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT WsbObjectTraceTypes(
|
|||
|
void
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Dump the object table information to the trace file.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - Success
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
try {
|
|||
|
int i;
|
|||
|
|
|||
|
WsbTraceAlways(OLESTR("WsbObjectTraceTypes: object table (GUID, total count, max count, current count, name):\n"));
|
|||
|
// Find the object type in table
|
|||
|
for (i = 0; i < object_table_count; i++) {
|
|||
|
OLECHAR * name;
|
|||
|
|
|||
|
name = GuidToObjectName(object_table[i].guid);
|
|||
|
WsbTraceAlways(OLESTR(" %ls %6ld %5ld %5ld %ls\n"), WsbGuidAsString(object_table[i].guid),
|
|||
|
object_table[i].total_count, object_table[i].max_count,
|
|||
|
object_table[i].count, (name ? name : OLESTR("")));
|
|||
|
}
|
|||
|
|
|||
|
} WsbCatch(hr);
|
|||
|
|
|||
|
return(hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
LPVOID WsbMemAlloc(ULONG cb, const char * filename, int linenum)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for CoTaskAlloc.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LPVOID p;
|
|||
|
|
|||
|
p = CoTaskMemAlloc(cb);
|
|||
|
if (p) {
|
|||
|
AddPointer(p, cb, 0, filename, linenum);
|
|||
|
}
|
|||
|
return(p);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void WsbMemFree(LPVOID pv, const char *, int)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for CoTaskFree.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (pv) {
|
|||
|
SubPointer(pv, 0);
|
|||
|
}
|
|||
|
CoTaskMemFree(pv);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
LPVOID WsbMemRealloc(LPVOID pv, ULONG cb, const char * filename, int linenum)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for CoTaskRealloc.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LPVOID p;
|
|||
|
|
|||
|
p = CoTaskMemRealloc(pv, cb);
|
|||
|
if (p) {
|
|||
|
if (pv) {
|
|||
|
SubPointer(pv, 0);
|
|||
|
}
|
|||
|
AddPointer(p, cb, 0, filename, linenum);
|
|||
|
}
|
|||
|
return(p);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BSTR WsbSysAllocString(const OLECHAR FAR * sz,
|
|||
|
const char * filename, int linenum)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for SysAllocString
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BSTR b;
|
|||
|
|
|||
|
b = SysAllocString(sz);
|
|||
|
if (b) {
|
|||
|
AddPointer(b, SysStringByteLen(b), 0, filename, linenum);
|
|||
|
}
|
|||
|
return(b);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BSTR WsbSysAllocStringLen(const OLECHAR FAR * sz,
|
|||
|
unsigned int cc, const char * filename, int linenum)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for SysAllocStringLen
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BSTR b;
|
|||
|
|
|||
|
b = SysAllocStringLen(sz, cc);
|
|||
|
if (b) {
|
|||
|
AddPointer(b, SysStringByteLen(b), 0, filename, linenum);
|
|||
|
}
|
|||
|
return(b);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void WsbSysFreeString(BSTR bs, const char *, int)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for SysFreeString
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (bs) {
|
|||
|
SubPointer(bs, 0);
|
|||
|
}
|
|||
|
SysFreeString(bs);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT WsbSysReallocString(BSTR FAR * pb, const OLECHAR FAR * sz,
|
|||
|
const char * filename, int linenum)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for SysReallocString
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
if (*pb) {
|
|||
|
SubPointer(*pb, 0);
|
|||
|
}
|
|||
|
hr = SysReAllocString(pb, sz);
|
|||
|
if (*pb) {
|
|||
|
AddPointer(*pb, SysStringByteLen(*pb), 0, filename, linenum);
|
|||
|
}
|
|||
|
return(hr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
HRESULT WsbSysReallocStringLen(BSTR FAR * pb,
|
|||
|
const OLECHAR FAR * sz, unsigned int cc, const char * filename, int linenum)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Debug tracking replacement for SysStringLen
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
if (*pb) {
|
|||
|
SubPointer(*pb, 0);
|
|||
|
}
|
|||
|
hr = SysReAllocStringLen(pb, sz, cc);
|
|||
|
if (*pb) {
|
|||
|
AddPointer(*pb, SysStringByteLen(*pb), 0, filename, linenum);
|
|||
|
}
|
|||
|
return(hr);
|
|||
|
}
|
|||
|
|
|||
|
#endif // WSB_TRACK_MEMORY
|