Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
8.1 KiB

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