|
|
//------------------------------------------------------------------------------
// File: perflog.cpp
//
// Desc: Macros for DirectShow performance logging.
//
//@@BEGIN_MSINTERNAL
//
// 10-Oct-2000 ArthurZ Created.
//
//@@END_MSINTERNAL
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#pragma warning (disable:4201)
#include <streams.h>
#include <windows.h>
#include <tchar.h>
#include <winperf.h>
#include <wmistr.h>
#include <evntrace.h>
#include "perflog.h"
//
// Local function prototypes.
//
ULONG WINAPI PerflogCallback ( WMIDPREQUESTCODE RequestCode, PVOID Context, ULONG* BufferSize, PVOID Buffer );
//
// Event tracing function pointers.
// We have to do this to run on down-level platforms.
//
#ifdef UNICODE
ULONG (__stdcall * _RegisterTraceGuids) ( IN WMIDPREQUEST RequestAddress, IN PVOID RequestContext, IN LPCGUID ControlGuid, IN ULONG GuidCount, IN PTRACE_GUID_REGISTRATION TraceGuidReg, IN LPCWSTR MofImagePath, IN LPCWSTR MofResourceName, OUT PTRACEHANDLE RegistrationHandle );
#define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsW"
#else
ULONG (__stdcall * _RegisterTraceGuids) ( IN WMIDPREQUEST RequestAddress, IN PVOID RequestContext, IN LPCGUID ControlGuid, IN ULONG GuidCount, IN PTRACE_GUID_REGISTRATION TraceGuidReg, IN LPCSTR MofImagePath, IN LPCSTR MofResourceName, OUT PTRACEHANDLE RegistrationHandle );
#define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsA"
#endif
ULONG (__stdcall * _UnregisterTraceGuids) ( TRACEHANDLE RegistrationHandle );
TRACEHANDLE (__stdcall * _GetTraceLoggerHandle) ( PVOID Buffer );
UCHAR (__stdcall * _GetTraceEnableLevel) ( TRACEHANDLE TraceHandle );
ULONG (__stdcall * _GetTraceEnableFlags) ( TRACEHANDLE TraceHandle );
ULONG (__stdcall * _TraceEvent) ( TRACEHANDLE TraceHandle, PEVENT_TRACE_HEADER EventTrace );
HINSTANCE _Advapi32;
//
// Global variables.
//
BOOL EventTracingAvailable=FALSE; ULONG PerflogEnableFlags; UCHAR PerflogEnableLevel; ULONG PerflogModuleLevel = 0; void (*OnStateChanged)(void); TRACEHANDLE PerflogTraceHandle=NULL; TRACEHANDLE PerflogRegHandle;
// The Win32 wsprintf() function writes a maximum of 1024 characters to it's output buffer.
// See the documentation for wsprintf()'s lpOut parameter for more information.
const INT iDEBUGINFO = 1024; // Used to format strings
//
// This routine initializes performance logging.
// It should be called from DllMain().
//
VOID PerflogReadModuleLevel( HINSTANCE hInstance ) { LONG lReturn; // Create key return value
TCHAR szInfo[iDEBUGINFO]; // Constructs key names
TCHAR szFullName[iDEBUGINFO]; // Load the full path and module name
HKEY hModuleKey; // Module key handle
TCHAR *pName; // Searches from the end for a backslash
DWORD dwKeySize, dwKeyType, dwKeyValue;
GetModuleFileName( (hInstance ? hInstance : GetModuleHandle( NULL )), szFullName, iDEBUGINFO ); pName = _tcsrchr(szFullName,'\\'); if (pName == NULL) { pName = szFullName; } else { pName++; }
/* Construct the base key name */ wsprintf(szInfo,TEXT("SOFTWARE\\Debug\\%s"),pName);
/* Open the key for this module */ lReturn = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // Handle of an open key
szInfo, // Address of subkey name
(DWORD) 0, // Reserved value
KEY_QUERY_VALUE, // Desired security access
&hModuleKey ); // Opened handle buffer
if (lReturn != ERROR_SUCCESS) { return; }
dwKeySize = sizeof(DWORD); lReturn = RegQueryValueEx( hModuleKey, // Handle to an open key
TEXT("PERFLOG"), NULL, // Reserved field
&dwKeyType, // Returns the field type
(LPBYTE) &dwKeyValue, // Returns the field's value
&dwKeySize ); // Number of bytes transferred
if ((lReturn == ERROR_SUCCESS) && (dwKeyType == REG_DWORD)) { PerflogModuleLevel = dwKeyValue; }
RegCloseKey(hModuleKey); }
BOOL PerflogInitIfEnabled( IN HINSTANCE hInstance, IN PPERFLOG_LOGGING_PARAMS LogParams ) { PerflogReadModuleLevel( hInstance ); if (PerflogModuleLevel) { return PerflogInitialize( LogParams ); } else { return FALSE; } }
BOOL PerflogInitialize ( IN PPERFLOG_LOGGING_PARAMS LogParams ) { ULONG status;
//
// If we're running on a recent-enough platform, this will get
// pointers to the event tracing routines.
//
_Advapi32 = GetModuleHandle (_T("ADVAPI32.DLL")); if (_Advapi32 == NULL) { return FALSE; }
*((FARPROC*) &_RegisterTraceGuids) = GetProcAddress (_Advapi32, REGISTERTRACEGUIDS_NAME); *((FARPROC*) &_UnregisterTraceGuids) = GetProcAddress (_Advapi32, "UnregisterTraceGuids"); *((FARPROC*) &_GetTraceLoggerHandle) = GetProcAddress (_Advapi32, "GetTraceLoggerHandle"); *((FARPROC*) &_GetTraceEnableLevel) = GetProcAddress (_Advapi32, "GetTraceEnableLevel"); *((FARPROC*) &_GetTraceEnableFlags) = GetProcAddress (_Advapi32, "GetTraceEnableFlags"); *((FARPROC*) &_TraceEvent) = GetProcAddress (_Advapi32, "TraceEvent");
if (_RegisterTraceGuids == NULL || _UnregisterTraceGuids == NULL || _GetTraceEnableLevel == NULL || _GetTraceEnableFlags == NULL || _TraceEvent == NULL) {
return FALSE; }
EventTracingAvailable = TRUE;
OnStateChanged = LogParams->OnStateChanged;
//
// Register our GUIDs.
//
status = _RegisterTraceGuids (PerflogCallback, LogParams, &LogParams->ControlGuid, LogParams->NumberOfTraceGuids, LogParams->TraceGuids, NULL, NULL, &PerflogRegHandle);
return (status == ERROR_SUCCESS); }
//
// This routine shuts down performance logging.
//
VOID PerflogShutdown ( VOID ) { if (!EventTracingAvailable) { return; }
_UnregisterTraceGuids (PerflogRegHandle); PerflogRegHandle = NULL; PerflogTraceHandle = NULL; }
//
// Event tracing callback routine.
// It's called when controllers call event tracing control functions.
//
ULONG WINAPI PerflogCallback ( WMIDPREQUESTCODE RequestCode, PVOID Context, ULONG* BufferSize, PVOID Buffer ) { ULONG status;
UNREFERENCED_PARAMETER (Context);
ASSERT (EventTracingAvailable);
status = ERROR_SUCCESS;
switch (RequestCode) {
case WMI_ENABLE_EVENTS: PerflogTraceHandle = _GetTraceLoggerHandle (Buffer); PerflogEnableFlags = _GetTraceEnableFlags (PerflogTraceHandle); PerflogEnableLevel = _GetTraceEnableLevel (PerflogTraceHandle); break;
case WMI_DISABLE_EVENTS: PerflogTraceHandle = NULL; PerflogEnableFlags = 0; PerflogEnableLevel = 0; break;
default: status = ERROR_INVALID_PARAMETER; }
if (OnStateChanged != NULL) { OnStateChanged(); }
*BufferSize = 0; return status; }
//
// Logging routine.
//
VOID PerflogTraceEvent ( PEVENT_TRACE_HEADER Event ) { if (!EventTracingAvailable) { return; }
_TraceEvent (PerflogTraceHandle, Event); }
VOID PerflogTraceEventLevel( ULONG Level, PEVENT_TRACE_HEADER Event ) { if ((!EventTracingAvailable) || (Level <= PerflogModuleLevel)) { return; }
_TraceEvent (PerflogTraceHandle, Event); }
|