Source code of Windows XP (NT5)
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.

802 lines
21 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  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 <ntverp.h>
  14. #include <fcntl.h>
  15. #include <wmistr.h>
  16. #include <guiddef.h>
  17. #include <evntrace.h>
  18. #define MAXEVENTS 5000
  19. #define MAXSTR 1024
  20. #define MAXTHREADS 128
  21. // sample string data
  22. #define WIDE_DATA_STRING L"Sample Wide String"
  23. #define COUNTED_DATA_STRING L"Sample Counted String"
  24. TRACEHANDLE LoggerHandle;
  25. #define ResourceName _T("MofResource")
  26. TCHAR ImagePath[MAXSTR];
  27. GUID TransactionGuid =
  28. {0xce5b1020, 0x8ea9, 0x11d0, 0xa4, 0xec, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10};
  29. GUID ControlGuid[2] =
  30. {
  31. {0xd58c126f, 0xb309, 0x11d1, 0x96, 0x9e, 0x00, 0x00, 0xf8, 0x75, 0xa5, 0xbc},
  32. {0x7c6a708a, 0xba1e, 0x11d2, 0x8b, 0xbf, 0x00, 0x00, 0xf8, 0x06, 0xef, 0xe0}
  33. };
  34. TRACE_GUID_REGISTRATION TraceGuidReg[] =
  35. {
  36. { (LPGUID)&TransactionGuid,
  37. NULL
  38. }
  39. };
  40. typedef enum {
  41. TYPE_USER_EVENT,
  42. TYPE_INSTANCE_EVENT,
  43. TYPE_MOF_EVENT,
  44. TYPEPTR_GUID
  45. } TypeEventType;
  46. typedef struct _USER_EVENT {
  47. EVENT_TRACE_HEADER Header;
  48. ULONG EventInfo;
  49. } USER_EVENT, *PUSER_EVENT;
  50. typedef struct _USER_INSTANCE_EVENT {
  51. EVENT_INSTANCE_HEADER Header;
  52. ULONG mofData;
  53. } USER_INSTANCE_EVENT, *PUSER_INSTANCE_EVENT;
  54. // customized event to use sample data that follow
  55. typedef struct _USER_MOF_EVENT {
  56. EVENT_TRACE_HEADER Header;
  57. MOF_FIELD mofData;
  58. } USER_MOF_EVENT, *PUSER_MOF_EVENT;
  59. // sample data structure
  60. typedef struct _INTEGER_SAMPLE_EVENT {
  61. CHAR sc;
  62. UCHAR uc;
  63. SHORT sh;
  64. ULONG ul;
  65. } INTEGER_SAMPLE_EVENT, *PINTEGER_SAMPLE_EVENT;
  66. typedef struct _FLOAT_SAMPLE_EVENT {
  67. float fl;
  68. double db;
  69. } FLOAT_SAMPLE_EVENT, *PFLOAT_SAMPLE_EVENT;
  70. typedef struct _ARRAY_SAMPLE_EVENT {
  71. CHAR ca[9];
  72. } ARRAY_SAMPLE_EVENT, *PARRAY_SAMPLE_EVENT;
  73. TypeEventType EventType = TYPE_USER_EVENT;
  74. TRACEHANDLE RegistrationHandle[2];
  75. BOOLEAN TraceOnFlag;
  76. ULONG EnableLevel = 0;
  77. ULONG EnableFlags = 0;
  78. ULONG nSleepTime = 0;
  79. ULONG EventCount = 0;
  80. BOOLEAN bInstanceTrace=0, bUseGuidPtr=0, bUseMofPtr=0;
  81. BOOLEAN bIncorrect = FALSE;
  82. BOOLEAN bUseNullPtr = FALSE;
  83. BOOLEAN bFirstTime = TRUE;
  84. ULONG InitializeTrace(
  85. void
  86. );
  87. ULONG
  88. ControlCallback(
  89. IN WMIDPREQUESTCODE RequestCode,
  90. IN PVOID Context,
  91. IN OUT ULONG *InOutBufferSize,
  92. IN OUT PVOID Buffer
  93. );
  94. LPTSTR
  95. DecodeStatus(
  96. IN ULONG Status
  97. );
  98. void
  99. LogProc();
  100. LPTSTR
  101. GuidToString(
  102. LPTSTR s,
  103. LPGUID piid
  104. );
  105. TCHAR ErrorMsg[MAXSTR];
  106. ULONG MaxEvents = MAXEVENTS;
  107. ULONG gnMultiReg=1;
  108. BOOLEAN RegistrationSuccess;
  109. __inline
  110. __int64
  111. GetCycleCount()
  112. {
  113. #if defined(_X86_)
  114. __asm _emit 0x0F
  115. __asm _emit 0x31 /* rdtsc */
  116. // returns edx:eax
  117. #elif defined(_AMD64_)
  118. return ReadTimeStampCounter();
  119. #elif defined(_IA64_)
  120. return __getReg(CV_IA64_ApITC);
  121. #else
  122. #error "no build target defined"
  123. #endif
  124. }
  125. void StringToGuid(
  126. TCHAR *str,
  127. LPGUID guid
  128. )
  129. /*++
  130. Routine Description:
  131. Converts a String into a GUID.
  132. Arguments:
  133. str - String representing a GUID.
  134. guid - Pointer to a GUID for ourput
  135. Return Value:
  136. None.
  137. --*/
  138. {
  139. TCHAR temp[10];
  140. int i, n;
  141. temp[8]=_T('\0');
  142. _tcsncpy(temp, str, 8);
  143. _stscanf(temp, _T("%x"), &(guid->Data1));
  144. temp[4]=_T('\0');
  145. _tcsncpy(temp, &str[9], 4);
  146. _stscanf(temp, _T("%x"), &(guid->Data2));
  147. _tcsncpy(temp, &str[14], 4);
  148. _stscanf(temp, _T("%x"), &(guid->Data3));
  149. temp[2]='\0';
  150. for(i=0;i<8;i++)
  151. {
  152. temp[0]=str[19+((i<2)?2*i:2*i+1)]; // to accomodate the minus sign after
  153. temp[1]=str[20+((i<2)?2*i:2*i+1)]; // the first two chars
  154. _stscanf(temp, _T("%x"), &n); // if used more than byte alloc
  155. guid->Data4[i]=(unsigned char)n; // causes overrun of memory
  156. }
  157. }
  158. __cdecl main(argc, argv)
  159. int argc;
  160. char **argv;
  161. /*++
  162. Routine Description:
  163. main() routine.
  164. Arguments:
  165. Usage: TraceDp [options] [number of events]
  166. -UseEventTraceHeader this is default.
  167. -UseEventInstanceHeader
  168. -UseMofPtrFlag
  169. -Thread [n] Sets the number of event-generating threads.
  170. -GuidPtr Use GUID pointer instead of GUID itself.
  171. -MofPtr Use MOF pointer for additional data.
  172. -GuidPtrMofPtr User GUID pointer and MOF pointer.
  173. -InCorrectMofPtr Use incorrect MOF pointer (Creates an error case).
  174. -NullMofPtr Use NULL MOF pointer (Creates an error case).
  175. -MultiReg Register multiple event GUIDS.
  176. -Sleep [n] Sets the sleep time before unregistering.
  177. [number of events] default is 5000
  178. Return Value:
  179. Error Code defined in winerror.h : If the function succeeds,
  180. it returns ERROR_SUCCESS (== 0).
  181. --*/
  182. {
  183. ULONG status;
  184. LPGUID Guid = NULL;
  185. DWORD ThreadId;
  186. HANDLE hThreadVector[MAXTHREADS];
  187. ULONG i;
  188. ULONG nThreads = 1;
  189. LPTSTR *targv;
  190. MaxEvents = MAXEVENTS;
  191. TraceOnFlag = FALSE;
  192. #ifdef UNICODE
  193. if ((targv = CommandLineToArgvW(
  194. GetCommandLineW(), // pointer to a command-line string
  195. &argc // receives the argument count
  196. )) == NULL)
  197. {
  198. return(GetLastError());
  199. };
  200. #else
  201. targv = argv;
  202. #endif
  203. // process command line arguments to override defaults
  204. //
  205. while (--argc > 0)
  206. {
  207. targv ++;
  208. if (**targv == '-' || **targv == '/')
  209. {
  210. if(targv[0][0] == '/' ) targv[0][0] = '-';
  211. if (!_tcsicmp(targv[0],_T("-UseEventTraceHeader")))
  212. {
  213. EventType = TYPE_USER_EVENT;
  214. }
  215. else if (!_tcsicmp(targv[0],_T("-UseEventInstanceHeader")))
  216. {
  217. EventType = TYPE_INSTANCE_EVENT;
  218. }
  219. else if (!_tcsicmp(targv[0],_T("-UseMofPtrFlag")))
  220. {
  221. EventType = TYPE_MOF_EVENT;
  222. }
  223. else if (!_tcsicmp(targv[0],_T("-Thread")))
  224. {
  225. if (argc > 1) {
  226. targv++; --argc;
  227. nThreads = _ttoi(targv[0]);
  228. if (nThreads > MAXTHREADS)
  229. nThreads = MAXTHREADS;
  230. }
  231. }
  232. else if (!_tcsicmp(targv[0],_T("-GuidPtr")))
  233. {
  234. bUseGuidPtr = TRUE;
  235. }
  236. else if (!_tcsicmp(targv[0],_T("-MofPtr")))
  237. {
  238. bUseMofPtr = TRUE;
  239. }
  240. else if (!_tcsicmp(targv[0],_T("-GuidPtrMofPtr")))
  241. {
  242. bUseGuidPtr = TRUE;
  243. bUseMofPtr = TRUE;
  244. }
  245. else if (!_tcsicmp(targv[0],_T("-InCorrectMofPtr")))
  246. {
  247. bUseMofPtr = TRUE;
  248. bIncorrect = TRUE;
  249. }
  250. else if (!_tcsicmp(targv[0],_T("-NullMofPtr")))
  251. {
  252. bUseMofPtr = TRUE;
  253. bUseNullPtr = TRUE;
  254. bIncorrect = TRUE;;
  255. }
  256. else if (!_tcsicmp(targv[0],_T("-MultiReg")))
  257. {
  258. gnMultiReg = 2;
  259. }
  260. else if (!_tcsicmp(targv[0], _T("-guid"))) {
  261. if (argc > 1) {
  262. if (targv[1][0] == _T('#')) {
  263. StringToGuid(&targv[1][1], &ControlGuid[0]);
  264. ++targv; --argc;
  265. }
  266. }
  267. }
  268. else if (!_tcsicmp(targv[0],_T("-Sleep")))
  269. {
  270. if (argc > 1) {
  271. targv++; --argc;
  272. nSleepTime = _ttoi(targv[0]);
  273. }
  274. }
  275. else
  276. {
  277. printf("Usage: TraceDp [options] [number of events]\n");
  278. printf("\t-UseEventTraceHeader this is default.\n");
  279. printf("\t-UseEventInstanceHeader\n");
  280. printf("\t-UseMofPtrFlag\n");
  281. printf("\t-Thread [n]\n");
  282. printf("\t-GuidPtr\n");
  283. printf("\t-MofPtr\n");
  284. printf("\t-GuidPtrMofPtr\n");
  285. printf("\t-InCorrectMofPtr\n");
  286. printf("\t-NullMofPtr\n");
  287. printf("\t-MultiReg\n");
  288. printf("\t-Sleep [n]\n");
  289. printf("\t[number of events] default is 5000\n");
  290. return 0;
  291. }
  292. }
  293. else if (** targv >= '0' && ** targv <= '9')
  294. {
  295. MaxEvents = _ttoi(targv[0]);
  296. }
  297. }
  298. status = InitializeTrace();
  299. if (status != ERROR_SUCCESS) {
  300. return 0;
  301. }
  302. while (! TraceOnFlag)
  303. _sleep(1000);
  304. for (i=0; i < nThreads; i++) {
  305. hThreadVector[i] = CreateThread(NULL,
  306. 0,
  307. (LPTHREAD_START_ROUTINE) LogProc,
  308. NULL,
  309. 0,
  310. (LPDWORD)&ThreadId);
  311. }
  312. WaitForMultipleObjects(nThreads, hThreadVector, TRUE, INFINITE);
  313. if (nSleepTime > 0) {
  314. _sleep(nSleepTime * 1000);
  315. }
  316. for (i=0; i<gnMultiReg; i++) {
  317. UnregisterTraceGuids(RegistrationHandle[i]);
  318. }
  319. return status;
  320. }
  321. LPTSTR
  322. DecodeStatus(
  323. IN ULONG Status
  324. )
  325. /*++
  326. Routine Description:
  327. Decodes error status.
  328. Arguments:
  329. Status - Return status of function calls to be decoded.
  330. Return Value:
  331. Pointer to a decoded error message.
  332. --*/
  333. {
  334. memset( ErrorMsg, 0, MAXSTR );
  335. FormatMessage(
  336. FORMAT_MESSAGE_FROM_SYSTEM |
  337. FORMAT_MESSAGE_IGNORE_INSERTS,
  338. NULL,
  339. Status,
  340. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  341. (LPTSTR) ErrorMsg,
  342. MAXSTR,
  343. NULL );
  344. return ErrorMsg;
  345. }
  346. ULONG InitializeTrace(
  347. void
  348. )
  349. /*++
  350. Routine Description:
  351. Register traces.
  352. Arguments:
  353. Return Value:
  354. Error Status. ERROR_SUCCESS if successful.
  355. --*/
  356. {
  357. ULONG Status;
  358. ULONG i, j;
  359. Status = GetModuleFileName(NULL, &ImagePath[0], MAXSTR*sizeof(TCHAR));
  360. if (Status == 0) {
  361. return (ERROR_FILE_NOT_FOUND);
  362. }
  363. for (i=0; i<gnMultiReg; i++) {
  364. Status = RegisterTraceGuids(
  365. (WMIDPREQUEST)ControlCallback, //use same callback function
  366. (PVOID)(INT_PTR)(0x12345678+i), // RequestContext
  367. (LPCGUID)&ControlGuid[i],
  368. 1,
  369. &TraceGuidReg[i],
  370. (LPCTSTR)&ImagePath[0],
  371. (LPCTSTR)ResourceName,
  372. &RegistrationHandle[i]
  373. );
  374. if (Status != ERROR_SUCCESS) {
  375. _tprintf(_T("Trace registration failed\n"));
  376. RegistrationSuccess = FALSE;
  377. if( i > 0) {
  378. for (j=0; j<i; j++) {
  379. UnregisterTraceGuids(RegistrationHandle[i]);
  380. }
  381. }
  382. _tprintf(_T("InitializeTrace failed. i=%d, status=%d, %s\n"), i, Status, DecodeStatus(Status));
  383. return(Status);
  384. }
  385. else {
  386. _tprintf(_T("Trace registered successfully\n"));
  387. RegistrationSuccess = TRUE;
  388. }
  389. }
  390. return(Status);
  391. }
  392. ULONG
  393. ControlCallback(
  394. IN WMIDPREQUESTCODE RequestCode,
  395. IN PVOID Context,
  396. IN OUT ULONG *InOutBufferSize,
  397. IN OUT PVOID Buffer
  398. )
  399. /*++
  400. Routine Description:
  401. Callback function when enabled.
  402. Arguments:
  403. RequestCode - Flag for either enable or disable.
  404. Context - User-defined context.
  405. InOutBufferSize - not used.
  406. Buffer - WNODE_HEADER for the logger session.
  407. Return Value:
  408. Error Status. ERROR_SUCCESS if successful.
  409. --*/
  410. {
  411. ULONG Status;
  412. ULONG RetSize;
  413. Status = ERROR_SUCCESS;
  414. switch (RequestCode)
  415. {
  416. case WMI_ENABLE_EVENTS:
  417. {
  418. RetSize = 0;
  419. LoggerHandle = GetTraceLoggerHandle( Buffer );
  420. EnableLevel = GetTraceEnableLevel(LoggerHandle);
  421. EnableFlags = GetTraceEnableFlags(LoggerHandle);
  422. _tprintf(_T("Logging enabled to 0x%016I64x(%d,%d,%d)\n"),
  423. LoggerHandle, RequestCode, EnableLevel, EnableFlags);
  424. TraceOnFlag = TRUE;
  425. break;
  426. }
  427. case WMI_DISABLE_EVENTS:
  428. {
  429. TraceOnFlag = FALSE;
  430. RetSize = 0;
  431. LoggerHandle = 0;
  432. _tprintf(_T("\nLogging Disabled\n"));
  433. break;
  434. }
  435. default:
  436. {
  437. RetSize = 0;
  438. Status = ERROR_INVALID_PARAMETER;
  439. break;
  440. }
  441. }
  442. *InOutBufferSize = RetSize;
  443. return(Status);
  444. }
  445. void
  446. LogProc()
  447. /*++
  448. Routine Description:
  449. Generates events. It is spawned as separate threads.
  450. Based on the options given by users, it generates different events.
  451. Arguments:
  452. Return Value:
  453. None.
  454. --*/
  455. {
  456. USER_EVENT UserEvent;
  457. USER_INSTANCE_EVENT UserInstanceEvent;
  458. USER_MOF_EVENT UserMofEvent;
  459. EVENT_INSTANCE_INFO InstInfo;
  460. PMOF_FIELD mofField;
  461. ULONG i;
  462. PWNODE_HEADER Wnode;
  463. ULONG status;
  464. LPGUID Guid = NULL;
  465. ULONG nTemp;
  466. USHORT nSize, nStrEventSize;
  467. WCHAR wstrTemp[MAXSTR];
  468. INTEGER_SAMPLE_EVENT ise;
  469. FLOAT_SAMPLE_EVENT fse;
  470. ARRAY_SAMPLE_EVENT ase;
  471. CHAR *sse, *ptr;
  472. __int64 StartTime, EndTime;
  473. // some arbitrary data for MOF structs
  474. ise.sc = 'x';
  475. ise.uc = 'y';
  476. ise.sh = (SHORT)rand();
  477. ise.ul = (ULONG)rand();
  478. nTemp = 0;
  479. while (nTemp == 0) {
  480. nTemp = rand();
  481. }
  482. fse.fl = ((float)rand() / (float)nTemp);
  483. fse.db = ((double)rand() / (double)nTemp);
  484. ase.ca[0] = 'M';
  485. ase.ca[1] = 'i';
  486. ase.ca[2] = 'c';
  487. ase.ca[3] = 'r';
  488. ase.ca[4] = 'o';
  489. ase.ca[5] = 's';
  490. ase.ca[6] = 'o';
  491. ase.ca[7] = 'f';
  492. ase.ca[8] = 't';
  493. nStrEventSize = ((wcslen(WIDE_DATA_STRING) + 1) * sizeof(WCHAR)) + sizeof(SHORT) + (wcslen(COUNTED_DATA_STRING) * sizeof(WCHAR));
  494. sse = (PCHAR) malloc(nStrEventSize);
  495. if (NULL != sse) {
  496. ptr = sse;
  497. wcscpy(wstrTemp, WIDE_DATA_STRING);
  498. wstrTemp[wcslen(WIDE_DATA_STRING)] = L'\0';
  499. memcpy(ptr, wstrTemp, (wcslen(WIDE_DATA_STRING) + 1) * sizeof(WCHAR));
  500. ptr += (wcslen(WIDE_DATA_STRING) + 1) * sizeof(WCHAR);
  501. nSize = (USHORT)(wcslen(COUNTED_DATA_STRING) * sizeof(WCHAR));
  502. memcpy(ptr, &nSize, sizeof(USHORT));
  503. ptr += sizeof(USHORT);
  504. wcscpy(wstrTemp, COUNTED_DATA_STRING);
  505. memcpy(ptr, wstrTemp, wcslen(COUNTED_DATA_STRING) * sizeof(WCHAR));
  506. }
  507. RtlZeroMemory(&UserEvent, sizeof(UserEvent));
  508. Wnode = (PWNODE_HEADER) &UserEvent;
  509. UserEvent.Header.Size = sizeof(USER_EVENT);
  510. UserEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
  511. UserEvent.Header.Guid = TransactionGuid;
  512. RtlZeroMemory(&UserInstanceEvent, sizeof(UserInstanceEvent));
  513. UserInstanceEvent.Header.Size = sizeof(UserInstanceEvent);
  514. UserInstanceEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
  515. RtlZeroMemory(&UserMofEvent, sizeof(UserMofEvent));
  516. Wnode = (PWNODE_HEADER) &UserMofEvent;
  517. UserMofEvent.Header.Size = sizeof(UserMofEvent);
  518. UserMofEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
  519. UserMofEvent.Header.Guid = TransactionGuid;
  520. if (bUseGuidPtr) {
  521. UserEvent.Header.Flags |= WNODE_FLAG_USE_GUID_PTR;
  522. UserEvent.Header.GuidPtr = (ULONGLONG)&TransactionGuid;
  523. UserMofEvent.Header.Flags |= WNODE_FLAG_USE_GUID_PTR;
  524. UserMofEvent.Header.GuidPtr = (ULONGLONG)&TransactionGuid;
  525. }
  526. i = 0;
  527. while (TraceOnFlag) {
  528. if ((i % 4) == 0) {
  529. UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
  530. UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
  531. UserMofEvent.Header.Class.Type = 1;
  532. }
  533. else if ((i % 4) == 1) {
  534. UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
  535. UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
  536. UserMofEvent.Header.Class.Type = 2;
  537. }
  538. else if ((i % 4) == 2) {
  539. UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
  540. UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
  541. UserMofEvent.Header.Class.Type = 3;
  542. }
  543. else {
  544. UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
  545. UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
  546. UserMofEvent.Header.Class.Type = 4;
  547. }
  548. switch (EventType)
  549. {
  550. case TYPE_INSTANCE_EVENT:
  551. if (UserInstanceEvent.Header.Class.Type == EVENT_TRACE_TYPE_START) {
  552. status = CreateTraceInstanceId(
  553. (PVOID) TraceGuidReg[0].RegHandle,
  554. & InstInfo);
  555. if (status != ERROR_SUCCESS) {
  556. fprintf(stderr,
  557. "CreatTraceInstanceId() status=%d, %s\n",
  558. status, DecodeStatus(status)
  559. );
  560. return;
  561. }
  562. }
  563. StartTime = GetCycleCount();
  564. status = TraceEventInstance(
  565. LoggerHandle,
  566. (PEVENT_INSTANCE_HEADER) & UserInstanceEvent,
  567. & InstInfo,
  568. NULL);
  569. EndTime = GetCycleCount();
  570. fprintf(stdout, "# of cycles: %d\n", EndTime - StartTime);
  571. break;
  572. case TYPE_USER_EVENT:
  573. UserEvent.EventInfo = InterlockedIncrement(&EventCount);
  574. StartTime = GetCycleCount();
  575. status = TraceEvent(
  576. LoggerHandle,
  577. (PEVENT_TRACE_HEADER) & UserEvent);
  578. EndTime = GetCycleCount();
  579. fprintf(stdout, "# of cycles: %d\n", EndTime - StartTime);
  580. break;
  581. case TYPE_MOF_EVENT:
  582. UserMofEvent.Header.Flags |= WNODE_FLAG_USE_MOF_PTR;
  583. mofField = (PMOF_FIELD) & UserMofEvent.mofData;
  584. if (UserMofEvent.Header.Class.Type == 2) {
  585. mofField->DataPtr = (ULONGLONG) (&ise);
  586. mofField->Length = sizeof(INTEGER_SAMPLE_EVENT);
  587. }
  588. else if (UserMofEvent.Header.Class.Type == 3) {
  589. mofField->DataPtr = (ULONGLONG) (&fse);
  590. mofField->Length = sizeof(FLOAT_SAMPLE_EVENT);
  591. }
  592. else if (UserMofEvent.Header.Class.Type == 4) {
  593. mofField->DataPtr = (ULONGLONG) (&ase);
  594. mofField->Length = sizeof(ARRAY_SAMPLE_EVENT);
  595. }
  596. else {
  597. mofField->DataPtr = (ULONGLONG) (sse);
  598. mofField->Length = nStrEventSize;
  599. }
  600. if (bUseNullPtr)
  601. mofField->DataPtr = (ULONGLONG) (NULL);
  602. if (bIncorrect)
  603. mofField->Length += 1000;
  604. // measuring
  605. StartTime = GetCycleCount();
  606. status = TraceEvent(
  607. LoggerHandle,
  608. (PEVENT_TRACE_HEADER) & UserMofEvent);
  609. EndTime = GetCycleCount();
  610. if (status != ERROR_SUCCESS) {
  611. fprintf(stderr, "Error(%d) while writing event.\n", status);
  612. }
  613. else {
  614. fprintf(stdout, "# of cycles: %d\n", EndTime - StartTime);
  615. }
  616. break;
  617. default:
  618. status = ERROR_SUCCESS;
  619. break;
  620. }
  621. // logger buffers out of memory should not prevent provider from
  622. // generating events. This will only cause events lost.
  623. //
  624. if (status == ERROR_NOT_ENOUGH_MEMORY) {
  625. status = ERROR_SUCCESS;
  626. }
  627. if (status != ERROR_SUCCESS) {
  628. _ftprintf(stderr, _T("\nError %s while writing event\n"),
  629. DecodeStatus(status));
  630. _ftprintf( stderr, _T("Use GUID to disable Logger\n"));
  631. _ftprintf( stderr, _T("Logging Terminated\n"));
  632. return;
  633. }
  634. i++;
  635. if (i >= MaxEvents)
  636. break;
  637. if (!(i % 100))
  638. _tprintf(_T("."));
  639. _sleep(1);
  640. }
  641. }
  642. LPTSTR
  643. GuidToString(
  644. LPTSTR s,
  645. LPGUID piid
  646. )
  647. /*++
  648. Routine Description:
  649. Converts a GUID into a string.
  650. Arguments:
  651. s - String that will have the converted GUID.
  652. piid - GUID
  653. Return Value:
  654. None.
  655. --*/
  656. {
  657. _stprintf(s, _T("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
  658. piid->Data1,
  659. piid->Data2,
  660. piid->Data3,
  661. piid->Data4[0],
  662. piid->Data4[1],
  663. piid->Data4[2],
  664. piid->Data4[3],
  665. piid->Data4[4],
  666. piid->Data4[5],
  667. piid->Data4[6],
  668. piid->Data4[7]);
  669. return(s);
  670. }