@@ -352,8 +352,8 @@ void CALLBACK EventRecordCallback(EVENT_RECORD* pEventRecord)
352352 #pragma warning(disable: 4984) // c++17 extension
353353
354354 if constexpr (SAVE_FIRST_TIMESTAMP) {
355- if (session->mStartQpc .QuadPart == 0 ) {
356- session->mStartQpc = hdr.TimeStamp ;
355+ if (session->mStartTimestamp .QuadPart == 0 ) {
356+ session->mStartTimestamp = hdr.TimeStamp ;
357357 }
358358 }
359359
@@ -481,18 +481,19 @@ ULONG TraceSession::Start(
481481 PMTraceConsumer* pmConsumer,
482482 MRTraceConsumer* mrConsumer,
483483 wchar_t const * etlPath,
484- wchar_t const * sessionName)
484+ wchar_t const * sessionName,
485+ TimestampType timestampType)
485486{
486487 assert (mSessionHandle == 0 );
487488 assert (mTraceHandle == INVALID_PROCESSTRACE_HANDLE);
488- mStartQpc .QuadPart = 0 ;
489+ mStartTimestamp .QuadPart = 0 ;
489490 mPMConsumer = pmConsumer;
490491 mMRConsumer = mrConsumer;
491492 mContinueProcessingBuffers = TRUE ;
492493
493494 // -------------------------------------------------------------------------
494495 // Configure trace properties
495- EVENT_TRACE_LOGFILE traceProps = {};
496+ EVENT_TRACE_LOGFILEW traceProps = {};
496497 traceProps.LogFileName = (wchar_t *) etlPath;
497498 traceProps.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP;
498499 traceProps.Context = this ;
@@ -528,7 +529,7 @@ ULONG TraceSession::Start(
528529
529530 TraceProperties sessionProps = {};
530531 sessionProps.Wnode .BufferSize = (ULONG) sizeof (TraceProperties);
531- sessionProps.Wnode .ClientContext = 1 ; // Clock resolution to use when logging the timestamp for each event; 1 == query performance counter
532+ sessionProps.Wnode .ClientContext = timestampType ; // Clock resolution to use when logging the timestamp for each event
532533 sessionProps.LogFileMode = EVENT_TRACE_REAL_TIME_MODE; // We have a realtime consumer, not writing to a log file
533534 sessionProps.LogFileNameOffset = 0 ; // 0 means no output log file
534535 sessionProps.LoggerNameOffset = offsetof (TraceProperties, mSessionName ); // Location of session name; will be written by StartTrace()
@@ -556,7 +557,7 @@ ULONG TraceSession::Start(
556557 sessionProps.LoggerThreadId // tracing session identifier
557558 */
558559
559- auto status = StartTrace (&mSessionHandle , sessionName, &sessionProps);
560+ auto status = StartTraceW (&mSessionHandle , sessionName, &sessionProps);
560561 if (status != ERROR_SUCCESS) {
561562 mSessionHandle = 0 ;
562563 return status;
@@ -571,7 +572,7 @@ ULONG TraceSession::Start(
571572
572573 // -------------------------------------------------------------------------
573574 // Open the trace
574- mTraceHandle = OpenTrace (&traceProps);
575+ mTraceHandle = OpenTraceW (&traceProps);
575576 if (mTraceHandle == INVALID_PROCESSTRACE_HANDLE) {
576577 auto lastError = GetLastError ();
577578 Stop ();
@@ -584,14 +585,15 @@ ULONG TraceSession::Start(
584585 // captures are based off the timestamp here.
585586
586587 switch (traceProps.LogfileHeader .ReservedFlags ) {
587- case 2 : // System time
588- mQpcFrequency .QuadPart = 10000000ull ;
588+ case TIMESTAMP_TYPE_SYSTEM_TIME:
589+ mTimestampFrequency .QuadPart = 10000000ull ;
589590 break ;
590- case 3 : // CPU cycle counter
591- mQpcFrequency .QuadPart = 1000000ull * traceProps.LogfileHeader .CpuSpeedInMHz ;
591+ case TIMESTAMP_TYPE_CPU_CYCLE_COUNTER:
592+ mTimestampFrequency .QuadPart = 1000000ull * traceProps.LogfileHeader .CpuSpeedInMHz ;
592593 break ;
593- default : // 1 == QPC
594- mQpcFrequency = traceProps.LogfileHeader .PerfFreq ;
594+ case TIMESTAMP_TYPE_QPC:
595+ default :
596+ mTimestampFrequency = traceProps.LogfileHeader .PerfFreq ;
595597 break ;
596598 }
597599
@@ -602,17 +604,20 @@ ULONG TraceSession::Start(
602604 QueryPerformanceCounter (&qpc1);
603605 GetSystemTimeAsFileTime (&ft);
604606 QueryPerformanceCounter (&qpc2);
605- FileTimeToLocalFileTime (&ft, & mStartTime );
606- mStartQpc .QuadPart = qpc1.QuadPart + ( qpc2. QuadPart - qpc1 .QuadPart ) / 2 ;
607+ FileTimeToLocalFileTime (&ft, (FILETIME*) & mStartFileTime );
608+ mStartTimestamp .QuadPart = ( qpc1.QuadPart + qpc2.QuadPart ) / 2 ;
607609 } else {
608- SYSTEMTIME ust = {};
609- SYSTEMTIME lst = {};
610+ // Convert start FILETIME to local start FILETIME
611+ SYSTEMTIME ust{};
612+ SYSTEMTIME lst{};
610613 FileTimeToSystemTime ((FILETIME const *) &traceProps.LogfileHeader .StartTime , &ust);
611614 SystemTimeToTzSpecificLocalTime (&traceProps.LogfileHeader .TimeZone , &ust, &lst);
612- SystemTimeToFileTime (&lst, &mStartTime );
615+ SystemTimeToFileTime (&lst, (FILETIME*) &mStartFileTime );
616+ // The above conversion stops at milliseconds, so copy the rest over too
617+ mStartFileTime += traceProps.LogfileHeader .StartTime .QuadPart % 10000 ;
613618 }
614619
615- InitializeTimestampInfo (&mStartQpc , mQpcFrequency );
620+ InitializeTimestampInfo (&mStartTimestamp , mTimestampFrequency );
616621
617622 return ERROR_SUCCESS;
618623}
0 commit comments