| 590 | } |
| 591 | |
| 592 | void PMTraceSession::Stop() |
| 593 | { |
| 594 | ULONG status = 0; |
| 595 | |
| 596 | // Stop the session |
| 597 | if (mSessionHandle != 0) { |
| 598 | DisableProviders(mSessionHandle); |
| 599 | |
| 600 | TraceProperties sessionProps = {}; |
| 601 | sessionProps.Wnode.BufferSize = (ULONG) sizeof(TraceProperties); |
| 602 | sessionProps.LoggerNameOffset = offsetof(TraceProperties, mSessionName); |
| 603 | |
| 604 | status = ControlTraceW(mSessionHandle, nullptr, &sessionProps, EVENT_TRACE_CONTROL_QUERY); |
| 605 | mNumEventsLost = sessionProps.EventsLost; |
| 606 | mNumBuffersLost = sessionProps.LogBuffersLost + sessionProps.RealTimeBuffersLost; |
| 607 | |
| 608 | status = ControlTraceW(mSessionHandle, nullptr, &sessionProps, EVENT_TRACE_CONTROL_STOP); |
| 609 | |
| 610 | mSessionHandle = 0; // mSessionHandle is no longer valid after EVENT_TRACE_CONTROL_STOP |
| 611 | } |
| 612 | |
| 613 | // Stop the trace (remains open until ProcessTrace() finishes) |
| 614 | if (mTraceHandle != INVALID_PROCESSTRACE_HANDLE) { |
| 615 | status = CloseTrace(mTraceHandle); |
| 616 | mTraceHandle = INVALID_PROCESSTRACE_HANDLE; |
| 617 | } |
| 618 | |
| 619 | // If collecting realtime events, CloseTrace() will cause ProcessTrace() to |
| 620 | // stop filling buffers and it will return after it finishes processing |
| 621 | // events already in it's buffers. |
| 622 | // |
| 623 | // If collecting from a log file, ProcessTrace() normally continues to |
| 624 | // process the entire file so we cancel processing from the BufferCallback |
| 625 | // in this case. |
| 626 | if (!mIsRealtimeSession) { |
| 627 | mContinueProcessingBuffers = FALSE; |
| 628 | } |
| 629 | } |
| 630 | |
| 631 | ULONG StopNamedTraceSession(wchar_t const* sessionName) |
| 632 | { |
no test coverage detected