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.

306 lines
7.5 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. tracedp.c
  5. Abstract:
  6. Sample trace provider program.
  7. --*/
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <windows.h>
  11. #include <shellapi.h>
  12. #include <tchar.h>
  13. #include <wmistr.h>
  14. #include <guiddef.h>
  15. #include <evntrace.h>
  16. #define DEFAULT_EVENTS 5000
  17. #define MAXSTR 1024
  18. TRACEHANDLE LoggerHandle;
  19. // Control GUID for this provider.
  20. GUID ControlGuid =
  21. {0xd58c126f, 0xb309, 0x11d1, 0x96, 0x9e, 0x00, 0x00, 0xf8, 0x75, 0xa5, 0xbc};
  22. // Only one transaction GUID will be registered for this provider.
  23. GUID TransactionGuid =
  24. {0xce5b1020, 0x8ea9, 0x11d0, 0xa4, 0xec, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10};
  25. // Array for transaction GUID registration.
  26. TRACE_GUID_REGISTRATION TraceGuidReg[] =
  27. {
  28. { (LPGUID)&TransactionGuid,
  29. NULL
  30. }
  31. };
  32. // User event layout: one ULONG.
  33. typedef struct _USER_EVENT {
  34. EVENT_TRACE_HEADER Header;
  35. ULONG EventInfo;
  36. } USER_EVENT, *PUSER_EVENT;
  37. // Registration handle.
  38. TRACEHANDLE RegistrationHandle;
  39. // Trace on/off switch, level, and flag.
  40. BOOLEAN TraceOnFlag;
  41. ULONG EnableLevel = 0;
  42. ULONG EnableFlags = 0;
  43. // Number of events to be logged. The actual number can be less if disabled early.
  44. ULONG MaxEvents = DEFAULT_EVENTS;
  45. // To keep track of events logged.
  46. ULONG EventCount = 0;
  47. // ControlCallback function for enable/disable.
  48. ULONG
  49. ControlCallback(
  50. IN WMIDPREQUESTCODE RequestCode,
  51. IN PVOID Context,
  52. IN OUT ULONG *InOutBufferSize,
  53. IN OUT PVOID Buffer
  54. );
  55. // Main work to be traced is done here.
  56. void
  57. DoWork();
  58. __cdecl main(argc, argv)
  59. int argc;
  60. char **argv;
  61. /*++
  62. Routine Description:
  63. main() routine.
  64. Arguments:
  65. Usage: TraceDp [number of events]
  66. [number of events] default is 5000
  67. Return Value:
  68. Error Code defined in winerror.h : If the function succeeds,
  69. it returns ERROR_SUCCESS (== 0).
  70. --*/
  71. {
  72. ULONG Status, i;
  73. LPTSTR *targv, *utargv = NULL;
  74. TraceOnFlag = FALSE;
  75. #ifdef UNICODE
  76. if ((targv = CommandLineToArgvW(
  77. GetCommandLineW(), // pointer to a command-line string
  78. &argc // receives the argument count
  79. )) == NULL)
  80. {
  81. return (GetLastError());
  82. };
  83. utargv = targv;
  84. #else
  85. targv = argv;
  86. #endif
  87. // process command line arguments to override defaults
  88. if (argc == 2) {
  89. targv ++;
  90. if (**targv >= _T('0') && **targv <= _T('9')) {
  91. MaxEvents = _ttoi(targv[0]);
  92. }
  93. else if (!_tcsicmp(targv[0], _T("/?")) || !_tcsicmp(targv[0], _T("-?"))) {
  94. printf("Usage: TraceDp [number of events]\n");
  95. printf("\t[number of events] default is 5000\n");
  96. return ERROR_SUCCESS;
  97. }
  98. }
  99. // Free temporary argument buffer.
  100. if (utargv != NULL) {
  101. GlobalFree(utargv);
  102. }
  103. // Event provider registration.
  104. Status = RegisterTraceGuids(
  105. (WMIDPREQUEST)ControlCallback, // callback function
  106. 0,
  107. &ControlGuid,
  108. 1,
  109. TraceGuidReg,
  110. NULL,
  111. NULL,
  112. &RegistrationHandle
  113. );
  114. if (Status != ERROR_SUCCESS) {
  115. _tprintf(_T("Trace registration failed. Status=%d\n"), Status);
  116. return(Status);
  117. }
  118. else {
  119. _tprintf(_T("Trace registered successfully\n"));
  120. }
  121. _tprintf(_T("Testing Logger with %d events\n"),
  122. MaxEvents);
  123. // Sleep until enabled by a trace controller. In this sample, we wait to be
  124. // enabled for tracing. However, normal applications should continue and log
  125. // events when enabled later on.
  126. while (!TraceOnFlag) {
  127. _sleep(1000);
  128. }
  129. // Do the work while logging events. We trace two events (START and END) for
  130. // each call to DoWork.
  131. for (i = 0; i < MaxEvents / 2; i++) {
  132. DoWork();
  133. }
  134. // Unregister.
  135. UnregisterTraceGuids(RegistrationHandle);
  136. return ERROR_SUCCESS;
  137. }
  138. ULONG
  139. ControlCallback(
  140. IN WMIDPREQUESTCODE RequestCode,
  141. IN PVOID Context,
  142. IN OUT ULONG *InOutBufferSize,
  143. IN OUT PVOID Buffer
  144. )
  145. /*++
  146. Routine Description:
  147. Callback function when enabled.
  148. Arguments:
  149. RequestCode - Flag for either enable or disable.
  150. Context - User-defined context.
  151. InOutBufferSize - not used.
  152. Buffer - WNODE_HEADER for the logger session.
  153. Return Value:
  154. Error Status. ERROR_SUCCESS if successful.
  155. --*/
  156. {
  157. ULONG Status;
  158. ULONG RetSize;
  159. Status = ERROR_SUCCESS;
  160. switch (RequestCode)
  161. {
  162. case WMI_ENABLE_EVENTS:
  163. {
  164. RetSize = 0;
  165. LoggerHandle = GetTraceLoggerHandle( Buffer );
  166. EnableLevel = GetTraceEnableLevel(LoggerHandle);
  167. EnableFlags = GetTraceEnableFlags(LoggerHandle);
  168. _tprintf(_T("Logging enabled to 0x%016I64x(%d,%d,%d)\n"),
  169. LoggerHandle, RequestCode, EnableLevel, EnableFlags);
  170. TraceOnFlag = TRUE;
  171. break;
  172. }
  173. case WMI_DISABLE_EVENTS:
  174. {
  175. TraceOnFlag = FALSE;
  176. RetSize = 0;
  177. LoggerHandle = 0;
  178. _tprintf(_T("\nLogging Disabled\n"));
  179. break;
  180. }
  181. default:
  182. {
  183. RetSize = 0;
  184. Status = ERROR_INVALID_PARAMETER;
  185. break;
  186. }
  187. }
  188. *InOutBufferSize = RetSize;
  189. return(Status);
  190. }
  191. void
  192. DoWork()
  193. /*++
  194. Routine Description:
  195. Logs events.
  196. Arguments:
  197. Return Value:
  198. None.
  199. --*/
  200. {
  201. USER_EVENT UserEvent;
  202. ULONG Status;
  203. RtlZeroMemory(&UserEvent, sizeof(UserEvent));
  204. UserEvent.Header.Size = sizeof(USER_EVENT);
  205. UserEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
  206. UserEvent.Header.Guid = TransactionGuid;
  207. // Log START event to indicate a start of a routine or activity.
  208. // We log EventCount as data.
  209. if (TraceOnFlag) {
  210. UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
  211. UserEvent.EventInfo = ++EventCount;
  212. Status = TraceEvent(
  213. LoggerHandle,
  214. (PEVENT_TRACE_HEADER) & UserEvent);
  215. if (Status != ERROR_SUCCESS) {
  216. // TraceEvent() failed. This could happen when the logger
  217. // cannot keep up with too many events logged rapidly.
  218. // In such cases, the return valid is
  219. // ERROR_NOT_ENOUGH_MEMORY.
  220. _tprintf(_T("TraceEvent failed. Status=%d\n"), Status);
  221. }
  222. }
  223. //
  224. // Main body of the work in this routine comes here.
  225. //
  226. _sleep(1);
  227. // Log END event to indicate an end of a routine or activity.
  228. // We log EventCount as data.
  229. if (TraceOnFlag) {
  230. UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
  231. UserEvent.EventInfo = ++EventCount;
  232. Status = TraceEvent(
  233. LoggerHandle,
  234. (PEVENT_TRACE_HEADER) & UserEvent);
  235. if (Status != ERROR_SUCCESS) {
  236. // TraceEvent() failed. This could happen when the logger
  237. // cannot keep up with too many events logged rapidly.
  238. // In such cases, the return valid is
  239. // ERROR_NOT_ENOUGH_MEMORY.
  240. _tprintf(_T("TraceEvent failed. Status=%d\n"), Status);
  241. }
  242. }
  243. }