windows-nt/Source/XPSP1/NT/com/ole32/log/log.cxx

106 lines
2.9 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
extern "C" {
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
}
#include "log.hxx"
#ifdef DBG
/*
* Debuggers should not use this value (which is why it's in the source, not
* the header. Don't get confused! Look for g_OleLogLen instead!
*/
#define OLE32_LOG_MAX (4096)
// The actual log. Allocated on first access to the log function
DebugEvent *gOleLog = NULL;
/*
* The size of the log. While technically I could just use the define,
* changing the value would then break debugger extensions that read this
* stuff, and that would then destroy the whole point of this, now wouldn't
* it?
*/
DWORD gOleLogLen = OLE32_LOG_MAX;
/*
* This is where the next event is going to go.
* To read the log, start with the entry g_OleLog[g_OleLogNext], and work your
* way around to g_OleLog[g_OleLogNext-1]. Ignore every reference to the
* subject SU_NOTHING.... those are entries that haven't been used yet.
*
* Don't you DARE try to log an event that has SU_NOTHING as the subject.
*/
long gOleLogNext = 0;
unsigned char gIgnoreSubject[256] = {0};
unsigned char gIgnoreVerb[256] = {0};
BOOL gfDisableLog = 0;
/*
* Currently there are a couple issues that this does not attempt to solve.
* For example, this does nothing in the case of contention of threads for
* a particular entry in the log. This only happens when the log wraps
* WAY over. The solution requires locking, and I think it's more important
* to be fast in the majority of cases than correct in the extreme minority.
*/
void __Ole32Log (unsigned char Subject, unsigned char Verb,
void *SubjectPtr, void *ObjectPtr, ULONG_PTR UserData,
BOOL fGrabStack, int FramesToSkip)
{
DebugEvent *log;
DWORD myIndex;
if (gIgnoreSubject[Subject] || gIgnoreVerb[Verb] || gfDisableLog)
return;
// Allocate the log...
if (gOleLog == NULL)
{
log = (DebugEvent *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
gOleLogLen * sizeof(DebugEvent));
if (log == NULL)
return;
if (InterlockedCompareExchangePointer((void **)&gOleLog, (void *)log,
NULL) != NULL)
HeapFree(GetProcessHeap(), 0, log);
}
myIndex = InterlockedIncrement(&gOleLogNext) % gOleLogLen;
gOleLog[myIndex].Time = GetTickCount();
gOleLog[myIndex].ThreadID = GetCurrentThreadId();
gOleLog[myIndex].Subject = Subject;
gOleLog[myIndex].Verb = Verb;
gOleLog[myIndex].SubjectPtr= SubjectPtr;
gOleLog[myIndex].ObjectPtr = ObjectPtr;
gOleLog[myIndex].UserData = UserData;
if (fGrabStack)
{
ULONG ignore;
RtlCaptureStackBackTrace( 1 + FramesToSkip, STACKTRACE_DEPTH,
gOleLog[myIndex].Stack, &ignore );
} else {
gOleLog[myIndex].Stack[0] = NULL;
}
}
#endif // DBG