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); | ||
|  | } | ||
|  | 
 | ||
|  | 
 |