perflog.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. //------------------------------------------------------------------------------
  2. // File: perflog.cpp
  3. //
  4. // Desc: Macros for DirectShow performance logging.
  5. //
  6. // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
  7. //------------------------------------------------------------------------------
  8. #pragma warning (disable:4201)
  9. #include <streams.h>
  10. #include <windows.h>
  11. #include <tchar.h>
  12. #include <winperf.h>
  13. #include <wmistr.h>
  14. #include <evntrace.h>
  15. #include <strsafe.h>
  16. #include "perflog.h"
  17. //
  18. // Local function prototypes.
  19. //
  20. ULONG
  21. WINAPI
  22. PerflogCallback (
  23. WMIDPREQUESTCODE RequestCode,
  24. __in PVOID Context,
  25. __out ULONG* BufferSize,
  26. __in PVOID Buffer
  27. );
  28. //
  29. // Event tracing function pointers.
  30. // We have to do this to run on down-level platforms.
  31. //
  32. #ifdef UNICODE
  33. ULONG
  34. (__stdcall * _RegisterTraceGuids) (
  35. __in IN WMIDPREQUEST RequestAddress,
  36. __in IN PVOID RequestContext,
  37. IN LPCGUID ControlGuid,
  38. IN ULONG GuidCount,
  39. __in IN PTRACE_GUID_REGISTRATION TraceGuidReg,
  40. IN LPCWSTR MofImagePath,
  41. IN LPCWSTR MofResourceName,
  42. OUT PTRACEHANDLE RegistrationHandle
  43. );
  44. #define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsW"
  45. #else
  46. ULONG
  47. (__stdcall * _RegisterTraceGuids) (
  48. __in IN WMIDPREQUEST RequestAddress,
  49. __in IN PVOID RequestContext,
  50. IN LPCGUID ControlGuid,
  51. IN ULONG GuidCount,
  52. __in IN PTRACE_GUID_REGISTRATION TraceGuidReg,
  53. IN LPCSTR MofImagePath,
  54. IN LPCSTR MofResourceName,
  55. __out OUT PTRACEHANDLE RegistrationHandle
  56. );
  57. #define REGISTERTRACEGUIDS_NAME "RegisterTraceGuidsA"
  58. #endif
  59. ULONG
  60. (__stdcall * _UnregisterTraceGuids) (
  61. TRACEHANDLE RegistrationHandle
  62. );
  63. TRACEHANDLE
  64. (__stdcall * _GetTraceLoggerHandle) (
  65. __in PVOID Buffer
  66. );
  67. UCHAR
  68. (__stdcall * _GetTraceEnableLevel) (
  69. TRACEHANDLE TraceHandle
  70. );
  71. ULONG
  72. (__stdcall * _GetTraceEnableFlags) (
  73. TRACEHANDLE TraceHandle
  74. );
  75. ULONG
  76. (__stdcall * _TraceEvent) (
  77. TRACEHANDLE TraceHandle,
  78. __in PEVENT_TRACE_HEADER EventTrace
  79. );
  80. HINSTANCE _Advapi32;
  81. //
  82. // Global variables.
  83. //
  84. BOOL EventTracingAvailable=FALSE;
  85. ULONG PerflogEnableFlags;
  86. UCHAR PerflogEnableLevel;
  87. ULONG PerflogModuleLevel = 0;
  88. void (*OnStateChanged)(void);
  89. TRACEHANDLE PerflogTraceHandle=NULL;
  90. TRACEHANDLE PerflogRegHandle;
  91. // The Win32 wsprintf() function writes a maximum of 1024 characters to it's output buffer.
  92. // See the documentation for wsprintf()'s lpOut parameter for more information.
  93. const INT iDEBUGINFO = 1024; // Used to format strings
  94. //
  95. // This routine initializes performance logging.
  96. // It should be called from DllMain().
  97. //
  98. VOID
  99. PerflogReadModuleLevel(
  100. HINSTANCE hInstance
  101. )
  102. {
  103. LONG lReturn; // Create key return value
  104. TCHAR szInfo[iDEBUGINFO]; // Constructs key names
  105. TCHAR szFullName[iDEBUGINFO]; // Load the full path and module name
  106. HKEY hModuleKey; // Module key handle
  107. LPTSTR pName; // Searches from the end for a backslash
  108. DWORD dwKeySize, dwKeyType, dwKeyValue;
  109. DWORD dwSize = GetModuleFileName(
  110. (hInstance ? hInstance : GetModuleHandle( NULL )),
  111. szFullName,
  112. iDEBUGINFO );
  113. if (0 == dwSize || iDEBUGINFO == dwSize) {
  114. return;
  115. }
  116. pName = _tcsrchr(szFullName,'\\');
  117. if (pName == NULL) {
  118. pName = szFullName;
  119. } else {
  120. pName++;
  121. }
  122. /* Construct the base key name */
  123. (void)StringCchPrintf(szInfo,NUMELMS(szInfo),TEXT("SOFTWARE\\Debug\\%s"),pName);
  124. /* Open the key for this module */
  125. lReturn =
  126. RegOpenKeyEx(
  127. HKEY_LOCAL_MACHINE, // Handle of an open key
  128. szInfo, // Address of subkey name
  129. (DWORD) 0, // Reserved value
  130. KEY_QUERY_VALUE, // Desired security access
  131. &hModuleKey ); // Opened handle buffer
  132. if (lReturn != ERROR_SUCCESS) {
  133. return;
  134. }
  135. dwKeySize = sizeof(DWORD);
  136. lReturn = RegQueryValueEx(
  137. hModuleKey, // Handle to an open key
  138. TEXT("PERFLOG"),
  139. NULL, // Reserved field
  140. &dwKeyType, // Returns the field type
  141. (LPBYTE) &dwKeyValue, // Returns the field's value
  142. &dwKeySize ); // Number of bytes transferred
  143. if ((lReturn == ERROR_SUCCESS) && (dwKeyType == REG_DWORD))
  144. {
  145. PerflogModuleLevel = dwKeyValue;
  146. }
  147. RegCloseKey(hModuleKey);
  148. }
  149. BOOL PerflogInitIfEnabled(
  150. IN HINSTANCE hInstance,
  151. __in IN PPERFLOG_LOGGING_PARAMS LogParams
  152. )
  153. {
  154. PerflogReadModuleLevel( hInstance );
  155. if (PerflogModuleLevel)
  156. {
  157. return PerflogInitialize( LogParams );
  158. }
  159. else
  160. {
  161. return FALSE;
  162. }
  163. }
  164. BOOL
  165. PerflogInitialize (
  166. __in IN PPERFLOG_LOGGING_PARAMS LogParams
  167. )
  168. {
  169. ULONG status;
  170. //
  171. // If we're running on a recent-enough platform, this will get
  172. // pointers to the event tracing routines.
  173. //
  174. _Advapi32 = GetModuleHandle (_T("ADVAPI32.DLL"));
  175. if (_Advapi32 == NULL) {
  176. return FALSE;
  177. }
  178. *((FARPROC*) &_RegisterTraceGuids) = GetProcAddress (_Advapi32, REGISTERTRACEGUIDS_NAME);
  179. *((FARPROC*) &_UnregisterTraceGuids) = GetProcAddress (_Advapi32, "UnregisterTraceGuids");
  180. *((FARPROC*) &_GetTraceLoggerHandle) = GetProcAddress (_Advapi32, "GetTraceLoggerHandle");
  181. *((FARPROC*) &_GetTraceEnableLevel) = GetProcAddress (_Advapi32, "GetTraceEnableLevel");
  182. *((FARPROC*) &_GetTraceEnableFlags) = GetProcAddress (_Advapi32, "GetTraceEnableFlags");
  183. *((FARPROC*) &_TraceEvent) = GetProcAddress (_Advapi32, "TraceEvent");
  184. if (_RegisterTraceGuids == NULL ||
  185. _UnregisterTraceGuids == NULL ||
  186. _GetTraceEnableLevel == NULL ||
  187. _GetTraceEnableFlags == NULL ||
  188. _TraceEvent == NULL) {
  189. return FALSE;
  190. }
  191. EventTracingAvailable = TRUE;
  192. OnStateChanged = LogParams->OnStateChanged;
  193. //
  194. // Register our GUIDs.
  195. //
  196. status = _RegisterTraceGuids (PerflogCallback,
  197. LogParams,
  198. &LogParams->ControlGuid,
  199. LogParams->NumberOfTraceGuids,
  200. LogParams->TraceGuids,
  201. NULL,
  202. NULL,
  203. &PerflogRegHandle);
  204. return (status == ERROR_SUCCESS);
  205. }
  206. //
  207. // This routine shuts down performance logging.
  208. //
  209. VOID
  210. PerflogShutdown (
  211. VOID
  212. )
  213. {
  214. if (!EventTracingAvailable) {
  215. return;
  216. }
  217. _UnregisterTraceGuids (PerflogRegHandle);
  218. PerflogRegHandle = NULL;
  219. PerflogTraceHandle = NULL;
  220. }
  221. //
  222. // Event tracing callback routine.
  223. // It's called when controllers call event tracing control functions.
  224. //
  225. ULONG
  226. WINAPI
  227. PerflogCallback (
  228. WMIDPREQUESTCODE RequestCode,
  229. __in PVOID Context,
  230. __out ULONG* BufferSize,
  231. __in PVOID Buffer
  232. )
  233. {
  234. ULONG status;
  235. UNREFERENCED_PARAMETER (Context);
  236. ASSERT (EventTracingAvailable);
  237. status = ERROR_SUCCESS;
  238. switch (RequestCode) {
  239. case WMI_ENABLE_EVENTS:
  240. PerflogTraceHandle = _GetTraceLoggerHandle (Buffer);
  241. PerflogEnableFlags = _GetTraceEnableFlags (PerflogTraceHandle);
  242. PerflogEnableLevel = _GetTraceEnableLevel (PerflogTraceHandle);
  243. break;
  244. case WMI_DISABLE_EVENTS:
  245. PerflogTraceHandle = NULL;
  246. PerflogEnableFlags = 0;
  247. PerflogEnableLevel = 0;
  248. break;
  249. default:
  250. status = ERROR_INVALID_PARAMETER;
  251. }
  252. if (OnStateChanged != NULL) {
  253. OnStateChanged();
  254. }
  255. *BufferSize = 0;
  256. return status;
  257. }
  258. //
  259. // Logging routine.
  260. //
  261. VOID
  262. PerflogTraceEvent (
  263. __in PEVENT_TRACE_HEADER Event
  264. )
  265. {
  266. if (!EventTracingAvailable) {
  267. return;
  268. }
  269. _TraceEvent (PerflogTraceHandle, Event);
  270. }
  271. VOID
  272. PerflogTraceEventLevel(
  273. ULONG Level,
  274. __in PEVENT_TRACE_HEADER Event
  275. )
  276. {
  277. if ((!EventTracingAvailable) || (Level <= PerflogModuleLevel)) {
  278. return;
  279. }
  280. _TraceEvent (PerflogTraceHandle, Event);
  281. }