forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			348 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			348 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//------------------------------------------------------------------------------
 | 
						|
// File: perflog.cpp
 | 
						|
//
 | 
						|
// Desc: Macros for DirectShow performance logging.
 | 
						|
//
 | 
						|
// 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 <strsafe.h>
 | 
						|
#include "perflog.h"
 | 
						|
 | 
						|
//
 | 
						|
// Local function prototypes.
 | 
						|
//
 | 
						|
 | 
						|
ULONG
 | 
						|
WINAPI
 | 
						|
PerflogCallback (
 | 
						|
    WMIDPREQUESTCODE RequestCode,
 | 
						|
    __in PVOID Context,
 | 
						|
    __out ULONG* BufferSize,
 | 
						|
    __in PVOID Buffer
 | 
						|
    );
 | 
						|
 | 
						|
//
 | 
						|
// Event tracing function pointers.
 | 
						|
// We have to do this to run on down-level platforms.
 | 
						|
//
 | 
						|
 | 
						|
#ifdef UNICODE
 | 
						|
 | 
						|
ULONG
 | 
						|
(__stdcall * _RegisterTraceGuids) (
 | 
						|
    __in IN WMIDPREQUEST RequestAddress,
 | 
						|
    __in IN PVOID RequestContext,
 | 
						|
    IN LPCGUID ControlGuid,
 | 
						|
    IN ULONG GuidCount,
 | 
						|
    __in IN PTRACE_GUID_REGISTRATION TraceGuidReg,
 | 
						|
    IN LPCWSTR MofImagePath,
 | 
						|
    IN LPCWSTR MofResourceName,
 | 
						|
    OUT PTRACEHANDLE RegistrationHandle
 | 
						|
    );
 | 
						|
 | 
						|
#define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsW"
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
ULONG
 | 
						|
(__stdcall * _RegisterTraceGuids) (
 | 
						|
    __in IN WMIDPREQUEST RequestAddress,
 | 
						|
    __in IN PVOID RequestContext,
 | 
						|
    IN LPCGUID ControlGuid,
 | 
						|
    IN ULONG GuidCount,
 | 
						|
    __in IN PTRACE_GUID_REGISTRATION TraceGuidReg,
 | 
						|
    IN LPCSTR MofImagePath,
 | 
						|
    IN LPCSTR MofResourceName,
 | 
						|
    __out OUT PTRACEHANDLE RegistrationHandle
 | 
						|
    );
 | 
						|
 | 
						|
#define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsA"
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
ULONG
 | 
						|
(__stdcall * _UnregisterTraceGuids) (
 | 
						|
    TRACEHANDLE RegistrationHandle
 | 
						|
    );
 | 
						|
 | 
						|
TRACEHANDLE
 | 
						|
(__stdcall * _GetTraceLoggerHandle) (
 | 
						|
    __in PVOID Buffer
 | 
						|
    );
 | 
						|
 | 
						|
UCHAR
 | 
						|
(__stdcall * _GetTraceEnableLevel) (
 | 
						|
    TRACEHANDLE TraceHandle
 | 
						|
    );
 | 
						|
 | 
						|
ULONG
 | 
						|
(__stdcall * _GetTraceEnableFlags) (
 | 
						|
    TRACEHANDLE TraceHandle
 | 
						|
    );
 | 
						|
 | 
						|
ULONG
 | 
						|
(__stdcall * _TraceEvent) (
 | 
						|
    TRACEHANDLE TraceHandle,
 | 
						|
    __in 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
 | 
						|
    LPTSTR pName;                   // Searches from the end for a backslash
 | 
						|
    DWORD dwKeySize, dwKeyType, dwKeyValue;
 | 
						|
 | 
						|
    DWORD dwSize = GetModuleFileName(
 | 
						|
        (hInstance ? hInstance : GetModuleHandle( NULL )),
 | 
						|
        szFullName,
 | 
						|
        iDEBUGINFO );
 | 
						|
 | 
						|
    if (0 == dwSize || iDEBUGINFO == dwSize) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    pName = _tcsrchr(szFullName,'\\');
 | 
						|
    if (pName == NULL) {
 | 
						|
        pName = szFullName;
 | 
						|
    } else {
 | 
						|
        pName++;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Construct the base key name */
 | 
						|
    (void)StringCchPrintf(szInfo,NUMELMS(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 IN PPERFLOG_LOGGING_PARAMS LogParams
 | 
						|
    )
 | 
						|
{
 | 
						|
    PerflogReadModuleLevel( hInstance );
 | 
						|
    if (PerflogModuleLevel)
 | 
						|
    {
 | 
						|
        return PerflogInitialize( LogParams );
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
BOOL
 | 
						|
PerflogInitialize (
 | 
						|
    __in 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,
 | 
						|
    __in PVOID Context,
 | 
						|
    __out ULONG* BufferSize,
 | 
						|
    __in 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 (
 | 
						|
    __in PEVENT_TRACE_HEADER Event
 | 
						|
    )
 | 
						|
{
 | 
						|
    if (!EventTracingAvailable) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    _TraceEvent (PerflogTraceHandle, Event);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
PerflogTraceEventLevel(
 | 
						|
    ULONG Level,
 | 
						|
    __in PEVENT_TRACE_HEADER Event
 | 
						|
    )
 | 
						|
{
 | 
						|
    if ((!EventTracingAvailable) || (Level <= PerflogModuleLevel)) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    _TraceEvent (PerflogTraceHandle, Event);
 | 
						|
}
 | 
						|
 | 
						|
 |