|
|
/*++
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 );
|