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.
521 lines
12 KiB
521 lines
12 KiB
/*-----------------------------------------------------------------------------
|
|
* Copyright (C) Microsoft Corporation, 1995 - 1996.
|
|
* All rights reserved.
|
|
*
|
|
* Snipped from SChannel sources
|
|
*
|
|
* 1/23/96
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <debug.h>
|
|
|
|
DWORD g_dwEventLogging=0;
|
|
typedef LONG HRESULT;
|
|
|
|
#include "pstdef.h"
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* NOTE: This file not compiled for retail builds */
|
|
/*----------------------------------------------------------------------------*/
|
|
#if DBG
|
|
|
|
|
|
|
|
#ifdef HEAPDUMP
|
|
#include <winbasep.h>
|
|
#endif
|
|
|
|
#define WINDEBUG
|
|
|
|
#ifndef min
|
|
#define min(x,y) ((x)<(y)?(x):(y))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DWORD g_dwInfoLevel = SS_LOG_WARNING | SS_LOG_ERROR;
|
|
DWORD SSTraceIndent = 0;
|
|
|
|
|
|
|
|
#define MAX_DEBUG_BUFFER 2048
|
|
|
|
|
|
// This function simply outputs information to the debugging log file handle.
|
|
|
|
void
|
|
SSDebugOutput(char *szOutString)
|
|
{
|
|
OutputDebugStringA(szOutString);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
DbgDumpHexString(const unsigned char *String, DWORD cbString)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < cbString; i++)
|
|
{
|
|
int j;
|
|
char *pch;
|
|
char ach[9];
|
|
|
|
pch = &ach[wsprintf(ach, "%2.2x", String[i])];
|
|
SS_ASSERT(pch - ach <= sizeof(ach) - 4);
|
|
|
|
|
|
if ((i & 1) == 1)
|
|
{
|
|
*pch++ = ' ';
|
|
}
|
|
if ((i & 7) == 7)
|
|
{
|
|
*pch++ = ' ';
|
|
}
|
|
if ((i & 15) == 15)
|
|
{
|
|
*pch++ = '\n';
|
|
}
|
|
*pch = '\0';
|
|
SSDebugOutput(ach);
|
|
}
|
|
}
|
|
|
|
|
|
char *aszSSDebugLevel[] =
|
|
{
|
|
"Error ",
|
|
"Warning",
|
|
"Trace ",
|
|
"Mem ",
|
|
"Result "
|
|
};
|
|
|
|
|
|
void
|
|
SSDebugLog(long Mask, const char *Format, ...)
|
|
{
|
|
va_list ArgList;
|
|
int Level = 0;
|
|
int PrefixSize = 0;
|
|
int iOut;
|
|
char szOutString[MAX_DEBUG_BUFFER];
|
|
long OriginalMask = Mask;
|
|
|
|
if (Mask & g_dwInfoLevel)
|
|
{
|
|
while (!(Mask & 1))
|
|
{
|
|
Level++;
|
|
Mask >>= 1;
|
|
}
|
|
|
|
if (Level >= sizeof(aszSSDebugLevel) / sizeof(char *))
|
|
{
|
|
Level = sizeof(aszSSDebugLevel) / sizeof(char *) - 1;
|
|
}
|
|
// Make the prefix first: "Process.Thread> GINA-XXX"
|
|
|
|
iOut = wsprintf(
|
|
szOutString,
|
|
"%3d.%3d> %s: ",
|
|
GetCurrentProcessId(),
|
|
GetCurrentThreadId(),
|
|
aszSSDebugLevel[Level]);
|
|
|
|
PrefixSize = min(60, SSTraceIndent * 3);
|
|
FillMemory(szOutString+iOut, PrefixSize, ' ');
|
|
PrefixSize += iOut;
|
|
szOutString[PrefixSize] = '\0';
|
|
|
|
va_start(ArgList, Format);
|
|
|
|
if (wvsprintf(&szOutString[PrefixSize], Format, ArgList) < 0)
|
|
{
|
|
static char szOverFlow[] = "\n<256 byte OVERFLOW!>\n";
|
|
|
|
// Less than zero indicates that the string would not fit into the
|
|
// buffer. Output a special message indicating overflow.
|
|
|
|
lstrcpy(
|
|
&szOutString[sizeof(szOutString) - sizeof(szOverFlow)],
|
|
szOverFlow);
|
|
}
|
|
va_end(ArgList);
|
|
|
|
SSDebugOutput(szOutString);
|
|
}
|
|
}
|
|
|
|
LPSTR SzErrorCase(long err)
|
|
{
|
|
char *szName = "Unknown";
|
|
|
|
switch(err)
|
|
{
|
|
case PST_E_OK: szName = "PST_OK"; break;
|
|
case PST_E_FAIL: szName = "PST_FAIL"; break;
|
|
case PST_E_PROV_DLL_NOT_FOUND: szName = "PST_PROV_DLL_NOT_FOUND"; break;
|
|
case PST_E_INVALID_HANDLE: szName = "PST_INVALID_HANDLE"; break;
|
|
case PST_E_TYPE_EXISTS: szName = "PST_TYPE_EXISTS"; break;
|
|
case PST_E_TYPE_NO_EXISTS: szName = "PST_TYPE_NO_EXISTS"; break;
|
|
case PST_E_INVALID_RULESET: szName = "PST_INVALID_RULESET"; break;
|
|
case PST_E_NO_PERMISSIONS: szName = "PST_NO_PERMISSIONS"; break;
|
|
case PST_E_STORAGE_ERROR: szName = "PST_STORAGE_ERROR"; break;
|
|
case PST_E_CALLER_NOT_VERIFIED: szName = "PST_CALLER_NOT_VERIFIED"; break;
|
|
case PST_E_WRONG_PASSWORD: szName = "PST_WRONG_PASSWORD"; break;
|
|
case PST_E_DISK_IMAGE_MISMATCH: szName = "PST_DISK_IMAGE_MISMATCH"; break;
|
|
case PST_E_MEMORY_IMAGE_MISMATCH: szName = "PST_MEMORY_IMAGE_MISMATCH"; break;
|
|
case PST_E_UNKNOWN_EXCEPTION: szName = "PST_UNKNOWN_EXCEPTION"; break;
|
|
case PST_E_NYI: szName = "PST_NYI"; break;
|
|
}
|
|
|
|
return szName;
|
|
}
|
|
|
|
|
|
long
|
|
SSLogErrorCode(
|
|
long err,
|
|
const char *szFile,
|
|
long lLine)
|
|
{
|
|
LPSTR szName;
|
|
szName = SzErrorCase(err);
|
|
|
|
SSDebugLog(SS_LOG_RES, "Result: %s (0x%lx) - %s, Line %d\n", szName, err, szFile, lLine);
|
|
|
|
return err;
|
|
}
|
|
|
|
#pragma warning(disable:4206) /* Disable the empty translation unit */
|
|
/* warning/error */
|
|
|
|
void
|
|
SSAssert(
|
|
void * FailedAssertion,
|
|
void * FileName,
|
|
unsigned long LineNumber,
|
|
char * Message)
|
|
{
|
|
SSDebugLog(SS_LOG_ERROR,
|
|
"Assertion FAILED, %s, %s : %d\n",
|
|
FailedAssertion,
|
|
FileName,
|
|
LineNumber);
|
|
|
|
DebugBreak();
|
|
}
|
|
|
|
|
|
// NOTE: heap dumping reqs winbasep.h, generated by
|
|
// windows build. Therefore, heap dumping unsupported
|
|
// in this build.
|
|
|
|
// Get winbasep.h and define HEAPDUMP to dump heap.
|
|
|
|
int HeapFlags = 0x0; // no trace
|
|
//int HeapFlags = 0x2; // output window trace
|
|
|
|
VOID
|
|
DumpHeapState(char *pszMsg)
|
|
{
|
|
|
|
#ifdef HEAPDUMP
|
|
|
|
DWORD dwWritten;
|
|
char szOutString[256];
|
|
|
|
if (HeapFlags & 2)
|
|
{
|
|
HANDLE BaseHeap = RtlProcessHeap();
|
|
HEAP_SUMMARY HeapSum;
|
|
|
|
wsprintf(szOutString, "%s: HeapSummary(%p): ", pszMsg, BaseHeap);
|
|
HeapSum.cb = sizeof(HeapSum);
|
|
|
|
if (!HeapSummary(BaseHeap, 0, &HeapSum))
|
|
{
|
|
wsprintf(
|
|
&szOutString[lstrlen(szOutString)],
|
|
"FAILED: %u\n",
|
|
GetLastError());
|
|
}
|
|
else
|
|
{
|
|
wsprintf(
|
|
&szOutString[lstrlen(szOutString)],
|
|
"Allocated=%x Committed=%x\n",
|
|
HeapSum.cbAllocated,
|
|
HeapSum.cbCommitted);
|
|
}
|
|
SSDebugOutput(szOutString);
|
|
}
|
|
|
|
#endif // HEAPDUMP
|
|
|
|
}
|
|
|
|
VOID
|
|
CaptureStackBackTrace(
|
|
EXCEPTION_POINTERS *pep,
|
|
ULONG cSkip,
|
|
ULONG cFrames,
|
|
ULONG *aeip)
|
|
{
|
|
FillMemory(aeip, cFrames * sizeof(aeip[0]), 0);
|
|
|
|
#if i386 == 1
|
|
{
|
|
ULONG ieip, *pebp;
|
|
ULONG *pebpMax;
|
|
ULONG *pebpMin;
|
|
|
|
if (pep == NULL)
|
|
{
|
|
ieip = 0;
|
|
cSkip++; // always skip current frame
|
|
pebp = ((ULONG *) &pep) - 2;
|
|
}
|
|
else
|
|
{
|
|
ieip = 1;
|
|
SS_ASSERT(cSkip == 0);
|
|
aeip[0] = pep->ContextRecord->Eip;
|
|
pebp = (ULONG *) pep->ContextRecord->Ebp;
|
|
}
|
|
|
|
pebpMin = (ULONG *) &pep - 3; // start below current frame
|
|
pebpMax = pebpMin + 16*1024/sizeof(ULONG);
|
|
if (pebp >= pebpMin && pebp < pebpMax)
|
|
{
|
|
// __try
|
|
{
|
|
for ( ; ieip < cSkip + cFrames; ieip++)
|
|
{
|
|
ULONG *pebpNext;
|
|
|
|
if (ieip >= cSkip)
|
|
{
|
|
aeip[ieip - cSkip] = *(pebp + 1); // save an eip
|
|
}
|
|
|
|
pebpNext = (ULONG *) *pebp;
|
|
if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1)
|
|
{
|
|
break;
|
|
}
|
|
pebp = pebpNext;
|
|
}
|
|
}
|
|
// __except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
#endif // i386 == 1
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
// debug mem routines
|
|
|
|
|
|
#define CMEMMAX 500
|
|
#define CEIP 6
|
|
|
|
int cMemAlloc;
|
|
int cMemAlloc2;
|
|
ULONG cbMemTotal;
|
|
ULONG cbMemTotal2;
|
|
|
|
typedef struct _MEM {
|
|
VOID *pv;
|
|
ULONG cb;
|
|
ULONG aeip[CEIP];
|
|
} MEM;
|
|
|
|
MEM amem[CMEMMAX];
|
|
|
|
|
|
VOID *
|
|
SSAlloc(DWORD cb)
|
|
{
|
|
VOID *pv;
|
|
|
|
int i;
|
|
char szOutString[256];
|
|
int iRecorded = -1;
|
|
MEM mem;
|
|
|
|
DumpHeapState("Before Alloc");
|
|
|
|
if (HeapFlags & 2)
|
|
{
|
|
CaptureStackBackTrace(NULL, 1, CEIP, mem.aeip);
|
|
wsprintf(szOutString, "AllocMem(%x bytes): ", cb);
|
|
cMemAlloc2++;
|
|
cbMemTotal2 += cb;
|
|
mem.cb = cb;
|
|
}
|
|
|
|
pv = LocalAlloc(LMEM_FIXED, cb);
|
|
|
|
if (HeapFlags & 2)
|
|
{
|
|
mem.pv = pv;
|
|
if (pv != NULL)
|
|
{
|
|
for (i = 0; i < CMEMMAX; i++)
|
|
{
|
|
if (amem[i].pv == pv)
|
|
{
|
|
char szOutString2[256];
|
|
|
|
wsprintf(
|
|
szOutString2,
|
|
"FreeDup(%p) (%x bytes) from %x %x %x %x %x %x (%d)\n",
|
|
pv,
|
|
amem[i].cb,
|
|
amem[i].aeip[0],
|
|
amem[i].aeip[1],
|
|
amem[i].aeip[2],
|
|
amem[i].aeip[3],
|
|
amem[i].aeip[4],
|
|
amem[i].aeip[5],
|
|
i);
|
|
SSDebugOutput(szOutString2);
|
|
cMemAlloc--;
|
|
cbMemTotal -= amem[i].cb;
|
|
amem[i].pv = NULL;
|
|
}
|
|
|
|
if (amem[i].pv == NULL && iRecorded == -1)
|
|
{
|
|
amem[i] = mem;
|
|
cMemAlloc++;
|
|
cbMemTotal += cb;
|
|
iRecorded = i;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lstrcat(szOutString, "FAILED: ");
|
|
}
|
|
|
|
wsprintf(
|
|
&szOutString[lstrlen(szOutString)],
|
|
"0x%p from %x %x %x %x %x %x (%d)\n",
|
|
mem.pv,
|
|
mem.aeip[0],
|
|
mem.aeip[1],
|
|
mem.aeip[2],
|
|
mem.aeip[3],
|
|
mem.aeip[4],
|
|
mem.aeip[5],
|
|
iRecorded);
|
|
|
|
SSDebugOutput(szOutString);
|
|
}
|
|
DumpHeapState("After Alloc");
|
|
|
|
return(pv);
|
|
}
|
|
|
|
|
|
VOID *
|
|
SSReAlloc(VOID *pv, DWORD cb)
|
|
{
|
|
void* pTemp;
|
|
|
|
pTemp = LocalReAlloc(pv, cb, LMEM_MOVEABLE); // allow realloc to move this memory
|
|
|
|
if (pTemp == NULL)
|
|
{
|
|
CHAR sz[50];
|
|
wsprintf(sz, "ReAlloc Failed! error %d\n", GetLastError());
|
|
SSDebugOutput(sz);
|
|
}
|
|
else
|
|
{
|
|
if (pv != pTemp)
|
|
SSDebugOutput("Performance: ReAlloc forced to move memory!\n");
|
|
}
|
|
|
|
return pTemp;
|
|
}
|
|
|
|
|
|
VOID
|
|
SSFree(VOID *pv)
|
|
{
|
|
int i;
|
|
char szOutString[256];
|
|
|
|
DumpHeapState("Before Free");
|
|
if (HeapFlags & 2)
|
|
{
|
|
cMemAlloc2--;
|
|
wsprintf(szOutString, "FreeMem(%p)", pv);
|
|
for (i = 0; i < CMEMMAX; i++)
|
|
{
|
|
if (pv == amem[i].pv)
|
|
{
|
|
cMemAlloc--;
|
|
cbMemTotal -= amem[i].cb;
|
|
amem[i].pv = NULL;
|
|
wsprintf(
|
|
&szOutString[lstrlen(szOutString)],
|
|
" (%x bytes) from %x %x %x %x %x %x (%d)",
|
|
amem[i].cb,
|
|
amem[i].aeip[0],
|
|
amem[i].aeip[1],
|
|
amem[i].aeip[2],
|
|
amem[i].aeip[3],
|
|
amem[i].aeip[4],
|
|
amem[i].aeip[5],
|
|
i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
LocalFree(pv);
|
|
|
|
if (HeapFlags & 2)
|
|
{
|
|
lstrcat(szOutString, "\n");
|
|
SSDebugOutput(szOutString);
|
|
}
|
|
DumpHeapState("After Free");
|
|
|
|
}
|
|
|
|
SIZE_T
|
|
SSSize(HLOCAL hMem)
|
|
{
|
|
return LocalSize( hMem );
|
|
}
|
|
|
|
|
|
|
|
#endif /* DBG */
|
|
/*----------------------------------------------------------------------------*/
|
|
/* NOTE: This file not compiled for retail builds */
|
|
/*----------------------------------------------------------------------------*/
|
|
|