summaryrefslogtreecommitdiff
path: root/third_party/BaseClasses/perflog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/BaseClasses/perflog.cpp')
-rw-r--r--third_party/BaseClasses/perflog.cpp347
1 files changed, 347 insertions, 0 deletions
diff --git a/third_party/BaseClasses/perflog.cpp b/third_party/BaseClasses/perflog.cpp
new file mode 100644
index 00000000..e6425387
--- /dev/null
+++ b/third_party/BaseClasses/perflog.cpp
@@ -0,0 +1,347 @@
+//------------------------------------------------------------------------------
+// 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);
+}
+
+