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.
625 lines
15 KiB
625 lines
15 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
tracep.h
|
|
|
|
Abstract:
|
|
|
|
Trace Consumer header file
|
|
|
|
|
|
Author:
|
|
|
|
07-May-2002 Melur Raghuraman
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#define INITGUID
|
|
#include "wmiump.h"
|
|
#include "traceump.h"
|
|
#include "evntrace.h"
|
|
#include "ntperf.h"
|
|
|
|
#define DEFAULT_LOG_BUFFER_SIZE 1024
|
|
#define DEFAULT_REALTIME_BUFFER_SIZE 32768
|
|
|
|
#define MAXBUFFERS 1024
|
|
|
|
#define MAX_TRACE_BUFFER_CACHE_SIZE 29
|
|
|
|
extern ULONG WmipTraceDebugLevel;
|
|
|
|
#define ETW_LEVEL_MIN 0
|
|
#define ETW_LEVEL_API 1
|
|
#define ETW_LEVEL_BUFFER 2
|
|
#define ETW_LEVEL_EVENT 3
|
|
#define ETW_LEVEL_MAX 4
|
|
|
|
#define ETW_LOG_ERROR() (WmipTraceDebugLevel >> ETW_LEVEL_MIN)
|
|
#define ETW_LOG_API() (WmipTraceDebugLevel >> ETW_LEVEL_API)
|
|
#define ETW_LOG_BUFFER() (WmipTraceDebugLevel >> ETW_LEVEL_BUFFER)
|
|
#define ETW_LOG_EVENT() (WmipTraceDebugLevel >> ETW_LEVEL_EVENT)
|
|
#define ETW_LOG_MAX() (WmipTraceDebugLevel >> ETW_LEVEL_MAX)
|
|
|
|
|
|
//
|
|
// Kernel Events are logged with SYSTEM_TRACE_HEADER or PERFINFO_TRACE_HEADER.
|
|
// These headers have a GroupType and not a Guid in the header. In post-processing
|
|
// we map the Grouptype to Guid transparently to the consumer.
|
|
// The mapping between GroupType and Guid is maintained by this structure.
|
|
//
|
|
|
|
typedef struct _TRACE_GUID_MAP { // used to map GroupType to Guid
|
|
ULONG GroupType; // Group & Type
|
|
GUID Guid; // Guid
|
|
} TRACE_GUID_MAP, *PTRACE_GUID_MAP;
|
|
|
|
//
|
|
// In W2K and WinXP, TraceEventInstance API replaced the Guids in the header
|
|
// with GuidHandle values. In postprocessing we need to replace the GuidHandle
|
|
// back to Guid transparently to the consumer. The mapping between GuidHandle
|
|
// and Guid is maintained by EVENT_GUID_MAP structure. This is obsolete in
|
|
// .NET and above.
|
|
//
|
|
|
|
typedef struct _EVENT_GUID_MAP {
|
|
LIST_ENTRY Entry;
|
|
ULONGLONG GuidHandle;
|
|
GUID Guid;
|
|
} EVENT_GUID_MAP, *PEVENT_GUID_MAP;
|
|
|
|
//
|
|
// Callback routines wired through SetTraceCallback API is maintained by
|
|
// the EVENT_TRACE_CALLBACK structure. This is global for the process at the
|
|
// moment mainly due to the way the API is designed.
|
|
//
|
|
|
|
typedef struct _EVENT_TRACE_CALLBACK {
|
|
LIST_ENTRY Entry;
|
|
GUID Guid;
|
|
PEVENT_CALLBACK CallbackRoutine;
|
|
} EVENT_TRACE_CALLBACK, *PEVENT_TRACE_CALLBACK;
|
|
|
|
|
|
|
|
//
|
|
// If the tracelog instance is a realtime data feed instead of from a
|
|
// tracefile, TRACELOG_REALTIME_CONTEXT is used to maintain the real time
|
|
// buffers in a buffer pool.
|
|
//
|
|
|
|
typedef struct _TRACE_BUFFER_SPACE {
|
|
ULONG Reserved; // amount of memory reserved
|
|
ULONG Committed;
|
|
PVOID Space;
|
|
LIST_ENTRY FreeListHead;
|
|
} TRACE_BUFFER_SPACE, *PTRACE_BUFFER_SPACE;
|
|
|
|
typedef struct _TRACELOG_REALTIME_CONTEXT {
|
|
ULONG BuffersProduced; // Number of Buffers to read
|
|
ULONG BufferOverflow; // Number of Buffers missed by the consumer
|
|
GUID InstanceGuid; // Logger Instance Guid
|
|
HANDLE MoreDataEvent; // Event to signal there is more data in this stream
|
|
PTRACE_BUFFER_SPACE EtwpTraceBufferSpace;
|
|
PWNODE_HEADER RealTimeBufferPool[MAXBUFFERS];
|
|
} TRACELOG_REALTIME_CONTEXT, *PTRACELOG_REALTIME_CONTEXT;
|
|
|
|
|
|
//
|
|
// RealTime Free Buffer Pool is chained up as TRACE_BUFFER_HEADER
|
|
//
|
|
|
|
typedef struct _TRACE_BUFFER_HEADER {
|
|
WNODE_HEADER Wnode;
|
|
LIST_ENTRY Entry;
|
|
} TRACE_BUFFER_HEADER, *PTRACE_BUFFER_HEADER;
|
|
|
|
typedef struct _TRACERT_BUFFER_LIST_ENTRY {
|
|
ULONG Size;
|
|
LIST_ENTRY Entry;
|
|
LIST_ENTRY BufferListHead;
|
|
} TRACERT_BUFFER_LIST_ENTRY, *PTRACERT_BUFFER_LIST_ENTRY;
|
|
|
|
|
|
typedef struct _TRACE_BUFFER_CACHE_ENTRY {
|
|
LONG Index;
|
|
PVOID Buffer;
|
|
} TRACE_BUFFER_CACHE_ENTRY, *PTRACE_BUFFER_CACHE_ENTRY;
|
|
|
|
|
|
struct _TRACE_BUFFER_LIST_ENTRY;
|
|
|
|
typedef struct _TRACE_BUFFER_LIST_ENTRY {
|
|
struct _TRACE_BUFFER_LIST_ENTRY *Next;
|
|
LONG FileOffset; // Offset in File of this Buffer
|
|
ULONG BufferOffset; // Offset in Buffer for the current event
|
|
ULONG Flags; // Flags on status of this buffer
|
|
ULONG EventSize;
|
|
ULONG ClientContext; // Alignment, ProcessorNumber
|
|
ULONG TraceType; // Current Event Type
|
|
EVENT_TRACE Event; // CurrentEvent of this Buffer
|
|
} TRACE_BUFFER_LIST_ENTRY, *PTRACE_BUFFER_LIST_ENTRY;
|
|
|
|
|
|
typedef struct _TRACELOG_CONTEXT {
|
|
LIST_ENTRY Entry; // Keeps track of storage allocations.
|
|
|
|
//
|
|
// This implements a caching scheme for Sequential files with repeated
|
|
// call to ProcessTrace.
|
|
//
|
|
ULONGLONG OldMaxReadPosition; // Maximum Read Position for the file.
|
|
// Only valid for Sequential, used for
|
|
// Read Behind.
|
|
// Upon Exit From ProcessTrace, this
|
|
// value can be cached to avoid rescanning.
|
|
|
|
LONGLONG LastTimeStamp;
|
|
|
|
// Fields from HandleListEntry
|
|
EVENT_TRACE_LOGFILEW Logfile;
|
|
|
|
TRACEHANDLE TraceHandle;
|
|
ULONG ConversionFlags; // Indicates event processing options
|
|
LONG BufferBeingRead;
|
|
OVERLAPPED AsynchRead;
|
|
|
|
//
|
|
// Fields Below this will be reset upon ProcessTrace exit.
|
|
//
|
|
|
|
BOOLEAN fProcessed;
|
|
USHORT LoggerId; // Logger Id of this DataFeed.
|
|
UCHAR IsRealTime; // Flag to tell if this feed is RT.
|
|
UCHAR fGuidMapRead;
|
|
|
|
LIST_ENTRY GuidMapListHead; // This is LogFile specific property
|
|
|
|
//
|
|
// For using PerfClock, we need to save startTime, Freq
|
|
//
|
|
|
|
ULONG UsePerfClock;
|
|
ULONG CpuSpeedInMHz;
|
|
LARGE_INTEGER PerfFreq; // Frequency from the LogFile
|
|
LARGE_INTEGER StartTime; // Start Wall clock time
|
|
LARGE_INTEGER StartPerfClock; // Start PerfClock value
|
|
|
|
union
|
|
{
|
|
HANDLE Handle; // NT handle to logfile
|
|
PTRACELOG_REALTIME_CONTEXT RealTimeCxt; // Ptr to Real Time Context
|
|
};
|
|
|
|
ULONG EndOfFile; // Flag to show whether this stream is still active.
|
|
|
|
ULONG BufferSize;
|
|
ULONG BufferCount;
|
|
ULONG StartBuffer; // Start of the Circular Buffers
|
|
ULONG FirstBuffer; // Jump off point to start reading
|
|
ULONG LastBuffer; // last of the buffers in the boundary
|
|
|
|
PTRACE_BUFFER_LIST_ENTRY Root;
|
|
PTRACE_BUFFER_LIST_ENTRY BufferList;
|
|
PVOID BufferCacheSpace;
|
|
TRACE_BUFFER_CACHE_ENTRY BufferCache[MAX_TRACE_BUFFER_CACHE_SIZE];
|
|
|
|
LIST_ENTRY StreamListHead; // Used to free the Stream datastructures
|
|
ULONGLONG MaxReadPosition;
|
|
PERFINFO_GROUPMASK PerfGroupMask;
|
|
ULONG CbCount;
|
|
|
|
} TRACELOG_CONTEXT, *PTRACELOG_CONTEXT;
|
|
|
|
//
|
|
// Each LogFile supplied to ProcessTrace consists of a number
|
|
// of streams. Each Stream has the following structure.
|
|
//
|
|
|
|
typedef struct _TRACE_STREAM_CONTEXT {
|
|
LIST_ENTRY Entry; // SortList Entry
|
|
LIST_ENTRY AllocEntry;// Used to free storage
|
|
|
|
EVENT_TRACE CurrentEvent;
|
|
ULONG EventCount; // Number of Events detected in current buffer
|
|
ULONG CbCount;
|
|
ULONG ScanDone; // For circular logfiles
|
|
BOOLEAN bActive; // Is this Stream still active?
|
|
USHORT Type; // StreamType
|
|
ULONG ProcessorNumber; // Processor Number for this stream
|
|
ULONG CurrentOffset; // Offset into the buffer
|
|
ULONGLONG ReadPosition; // BufferCount starts with 0 for first buffer
|
|
PTRACELOG_CONTEXT pContext; // back pointer to the LogFileContext
|
|
// Need this only for GetNextBuffer?
|
|
PVOID StreamBuffer; // CurrentBuffer for this stream
|
|
|
|
} TRACE_STREAM_CONTEXT, *PTRACE_STREAM_CONTEXT;
|
|
|
|
|
|
|
|
//
|
|
// this structure is used only by EtwpGetBuffersWrittenFromQuery() and
|
|
// EtwpCheckForRealTimeLoggers()
|
|
//
|
|
typedef struct _ETW_QUERY_PROPERTIES {
|
|
EVENT_TRACE_PROPERTIES TraceProp;
|
|
WCHAR LoggerName[MAXSTR];
|
|
WCHAR LogFileName[MAXSTR];
|
|
} ETW_QUERY_PROPERTIES, *PETW_QUERY_PROPERTIES;
|
|
|
|
|
|
|
|
|
|
|
|
extern ETW_QUERY_PROPERTIES QueryProperties;
|
|
extern PLIST_ENTRY EventCallbackListHead;
|
|
extern ULONG WmiTraceAlignment;
|
|
|
|
//
|
|
// This TraceHandleListHeadPtr should be the only real global
|
|
// for ProcessTrace to be multithreaded
|
|
//
|
|
|
|
extern PLIST_ENTRY TraceHandleListHeadPtr;
|
|
extern PTRACE_GUID_MAP EventMapList; // Array mapping the Grouptype to Guids
|
|
|
|
#define EtwpNtStatusToDosError(Status) ((ULONG)((Status == STATUS_SUCCESS)?ERROR_SUCCESS:RtlNtStatusToDosError(Status)))
|
|
|
|
extern
|
|
ULONG
|
|
WMIAPI
|
|
EtwNotificationRegistrationW(
|
|
IN LPGUID Guid,
|
|
IN BOOLEAN Enable,
|
|
IN PVOID DeliveryInfo,
|
|
IN ULONG_PTR DeliveryContext,
|
|
IN ULONG Flags
|
|
);
|
|
|
|
extern
|
|
ULONG
|
|
WMIAPI
|
|
EtwControlTraceA(
|
|
IN TRACEHANDLE LoggerHandle,
|
|
IN LPCSTR LoggerName,
|
|
IN OUT PEVENT_TRACE_PROPERTIES Properties,
|
|
IN ULONG Control
|
|
);
|
|
|
|
extern
|
|
ULONG
|
|
WMIAPI
|
|
EtwControlTraceW(
|
|
IN TRACEHANDLE LoggerHandle,
|
|
IN LPCWSTR LoggerName,
|
|
IN OUT PEVENT_TRACE_PROPERTIES Properties,
|
|
IN ULONG Control
|
|
);
|
|
|
|
__inline __int64 EtwpGetSystemTime()
|
|
{
|
|
LARGE_INTEGER SystemTime;
|
|
|
|
//
|
|
// Read system time from shared region.
|
|
//
|
|
|
|
do {
|
|
SystemTime.HighPart = USER_SHARED_DATA->SystemTime.High1Time;
|
|
SystemTime.LowPart = USER_SHARED_DATA->SystemTime.LowPart;
|
|
} while (SystemTime.HighPart != USER_SHARED_DATA->SystemTime.High2Time);
|
|
|
|
return SystemTime.QuadPart;
|
|
}
|
|
|
|
|
|
extern
|
|
BOOL
|
|
EtwpSynchReadFile(
|
|
HANDLE LogFile,
|
|
LPVOID Buffer,
|
|
DWORD NumberOfBytesToRead,
|
|
LPDWORD NumberOfBytesRead,
|
|
LPOVERLAPPED Overlapped
|
|
);
|
|
|
|
extern
|
|
__inline
|
|
ULONG
|
|
EtwpSetDosError(
|
|
IN ULONG DosError
|
|
);
|
|
|
|
extern
|
|
PVOID
|
|
EtwpMemCommit(
|
|
IN PVOID Buffer,
|
|
IN SIZE_T Size
|
|
);
|
|
|
|
extern
|
|
ULONG
|
|
EtwpMemFree(
|
|
IN PVOID Buffer
|
|
);
|
|
|
|
extern
|
|
PVOID
|
|
EtwpMemReserve(
|
|
IN SIZE_T Size
|
|
);
|
|
|
|
__inline Move64(
|
|
IN PLARGE_INTEGER pSrc,
|
|
OUT PLARGE_INTEGER pDest
|
|
)
|
|
{
|
|
pDest->LowPart = pSrc->LowPart;
|
|
pDest->HighPart = pSrc->HighPart;
|
|
}
|
|
|
|
#ifdef DBG
|
|
void
|
|
EtwpDumpEvent(
|
|
PEVENT_TRACE pEvent
|
|
);
|
|
void
|
|
EtwpDumpGuid(
|
|
LPGUID
|
|
);
|
|
|
|
void
|
|
EtwpDumpCallbacks();
|
|
#endif
|
|
|
|
|
|
ULONG
|
|
EtwpConvertEnumToTraceType(
|
|
WMI_HEADER_TYPE eTraceType
|
|
);
|
|
|
|
WMI_HEADER_TYPE
|
|
EtwpConvertTraceTypeToEnum(
|
|
ULONG TraceType
|
|
);
|
|
|
|
ULONG
|
|
EtwpCheckForRealTimeLoggers(
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
ULONG Unicode
|
|
);
|
|
|
|
ULONG
|
|
EtwpLookforRealTimeBuffers(
|
|
PEVENT_TRACE_LOGFILEW logfile
|
|
);
|
|
ULONG
|
|
EtwpRealTimeCallback(
|
|
IN PWNODE_HEADER Wnode,
|
|
IN ULONG_PTR Context
|
|
);
|
|
void
|
|
EtwpFreeRealTimeContext(
|
|
PTRACELOG_REALTIME_CONTEXT RTCxt
|
|
);
|
|
|
|
ULONG
|
|
EtwpSetupRealTimeContext(
|
|
PTRACEHANDLE HandleArray,
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount
|
|
);
|
|
|
|
PVOID
|
|
EtwpAllocTraceBuffer(
|
|
PTRACELOG_REALTIME_CONTEXT RTCxt,
|
|
ULONG BufferSize
|
|
);
|
|
|
|
VOID
|
|
EtwpFreeTraceBuffer(
|
|
PTRACELOG_REALTIME_CONTEXT RTCxt,
|
|
PVOID Buffer
|
|
);
|
|
|
|
ULONG
|
|
EtwpProcessRealTimeTraces(
|
|
PTRACEHANDLE HandleArray,
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
LONGLONG StartTime,
|
|
LONGLONG EndTime,
|
|
ULONG Unicode
|
|
);
|
|
|
|
//
|
|
// Routines used in this file only
|
|
//
|
|
|
|
ULONG
|
|
EtwpDoEventCallbacks(
|
|
PEVENT_TRACE_LOGFILEW logfile,
|
|
PEVENT_TRACE pEvent
|
|
);
|
|
|
|
ULONG
|
|
EtwpCreateGuidMapping(void);
|
|
|
|
LPGUID
|
|
EtwpGuidMapHandleToGuid(
|
|
PLIST_ENTRY GuidMapListHeadPtr,
|
|
ULONGLONG GuidHandle
|
|
);
|
|
|
|
void
|
|
EtwpCleanupGuidMapList(
|
|
PLIST_ENTRY GuidMapListHeadPtr
|
|
);
|
|
|
|
PTRACELOG_CONTEXT
|
|
EtwpLookupTraceHandle(
|
|
TRACEHANDLE TraceHandle
|
|
);
|
|
|
|
|
|
void
|
|
EtwpCleanupTraceLog(
|
|
PTRACELOG_CONTEXT pEntry,
|
|
BOOLEAN bSaveLastOffset
|
|
);
|
|
|
|
VOID
|
|
EtwpGuidMapCallback(
|
|
PLIST_ENTRY GuidMapListHeadPtr,
|
|
PEVENT_TRACE pEvent
|
|
);
|
|
|
|
ULONG
|
|
EtwpProcessGuidMaps(
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
ULONG Unicode
|
|
);
|
|
|
|
PEVENT_TRACE_CALLBACK
|
|
EtwpGetCallbackRoutine(
|
|
LPGUID pGuid
|
|
);
|
|
|
|
VOID
|
|
EtwpFreeCallbackList();
|
|
|
|
|
|
ULONG
|
|
EtwpProcessLogHeader(
|
|
PTRACEHANDLE HandleArray,
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
ULONG Unicode,
|
|
ULONG bFree
|
|
);
|
|
|
|
ULONG
|
|
EtwpProcessTraceLog(
|
|
PTRACEHANDLE HandleArray,
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
LONGLONG StartTime,
|
|
LONGLONG EndTime,
|
|
ULONG Unicode
|
|
);
|
|
|
|
ULONG
|
|
EtwpProcessTraceLogEx(
|
|
PTRACEHANDLE HandleArray,
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
LONGLONG StartTime,
|
|
LONGLONG EndTime,
|
|
ULONG Unicode
|
|
);
|
|
|
|
ULONG
|
|
EtwpParseTraceEvent(
|
|
IN PTRACELOG_CONTEXT pContext,
|
|
IN PVOID LogBuffer,
|
|
IN ULONG Offset,
|
|
IN WMI_HEADER_TYPE HeaderType,
|
|
IN OUT PVOID EventInfo,
|
|
IN ULONG EventInfoSize
|
|
);
|
|
|
|
ULONG
|
|
EtwpGetBuffersWrittenFromQuery(
|
|
LPWSTR LoggerName
|
|
);
|
|
|
|
VOID
|
|
EtwpCopyLogHeader (
|
|
IN PTRACE_LOGFILE_HEADER pLogFileHeader,
|
|
IN PVOID MofData,
|
|
IN ULONG MofLength,
|
|
IN PWCHAR *LoggerName,
|
|
IN PWCHAR *LogFileName,
|
|
IN ULONG Unicode
|
|
);
|
|
|
|
ULONG
|
|
EtwpSetupLogFileStreams(
|
|
PLIST_ENTRY pStreamListHead,
|
|
PTRACEHANDLE HandleArray,
|
|
PEVENT_TRACE_LOGFILEW *Logfiles,
|
|
ULONG LogfileCount,
|
|
LONGLONG StartTime,
|
|
LONGLONG EndTime,
|
|
ULONG Unicode
|
|
);
|
|
|
|
ULONG
|
|
EtwpGetLastBufferWithMarker(
|
|
PTRACELOG_CONTEXT pContext
|
|
);
|
|
|
|
ULONG
|
|
EtwpAddTraceStream(
|
|
PLIST_ENTRY pStreamListHead,
|
|
PTRACELOG_CONTEXT pContext,
|
|
USHORT StreamType,
|
|
LONGLONG StartTime,
|
|
LONGLONG EndTime,
|
|
ULONG ProcessorNumber
|
|
);
|
|
|
|
ULONG
|
|
EtwpGetNextBuffer(
|
|
PTRACE_STREAM_CONTEXT pStream
|
|
);
|
|
|
|
ULONG
|
|
EtwpAdvanceToNewEventEx(
|
|
PLIST_ENTRY pStreamListHead,
|
|
PTRACE_STREAM_CONTEXT pStream
|
|
);
|
|
|
|
ULONG
|
|
EtwpGetNextEventOffsetType(
|
|
PUCHAR pBuffer,
|
|
ULONG Offset,
|
|
PULONG RetSize
|
|
);
|
|
|
|
ULONG
|
|
EtwpCopyCurrentEvent(
|
|
PTRACELOG_CONTEXT pContext,
|
|
PVOID pHeader,
|
|
PEVENT_TRACE pEvent,
|
|
ULONG TraceType,
|
|
PWMI_BUFFER_HEADER LogBuffer
|
|
);
|
|
|
|
LPGUID
|
|
EtwpGroupTypeToGuid(
|
|
ULONG GroupType
|
|
);
|
|
|
|
VOID
|
|
EtwpCalculateCurrentTime (
|
|
OUT PLARGE_INTEGER DestTime,
|
|
IN PLARGE_INTEGER TimeValue,
|
|
IN PTRACELOG_CONTEXT pContext
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|