Files
dolphin/Tools/PerformanceTrace/PrivateETW.h
T
Yaya48 c230971f07 IOS LLE: checkpoint NAND conformance and diagnostic tooling
Preserve formatted NAND boot and Wii Remote pairing, add DMA/SRAM conformance tests and a Wii comparison probe. Keep P1 profiling tools and native update A/B evidence; reject the unhelpful targeted SRAM shortcut.
2026-09-23 13:30:17 +02:00

88 lines
3.3 KiB
C++

// Copyright 2026 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// A local, user-mode-only trace for validating the provider without WPR rights.
#pragma once
#include <cstddef>
#include <cstring>
#include <filesystem>
#include <stdexcept>
#include <string>
#include <vector>
#include <windows.h>
#include <evntrace.h>
#include "Common/PerformanceTrace.h"
class PrivateETW
{
public:
explicit PrivateETW(const char* output)
{
if (!output)
return;
const auto path = std::filesystem::absolute(output);
if (std::filesystem::exists(path))
throw std::runtime_error("Private ETL target already exists");
if (!Common::PerformanceTrace::Requested())
throw std::runtime_error("Set DOLPHIN_PERF_TRACE=1 for a private trace");
Common::PerformanceTrace::Enabled(); // Register before starting the session.
constexpr wchar_t name[] = L"DolphinP1LocalProbe";
const std::wstring filename = path.wstring();
const size_t name_size = sizeof(name);
const size_t filename_size = (filename.size() + 1) * sizeof(wchar_t);
m_storage.resize(sizeof(EVENT_TRACE_PROPERTIES) + name_size + filename_size);
m_properties = reinterpret_cast<EVENT_TRACE_PROPERTIES*>(m_storage.data());
std::memset(m_properties, 0, m_storage.size());
m_properties->Wnode.BufferSize = static_cast<ULONG>(m_storage.size());
m_properties->Wnode.Guid = PERF_PROVIDER;
m_properties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
m_properties->Wnode.ClientContext = 1; // QPC
m_properties->BufferSize = 64;
m_properties->MinimumBuffers = 2;
m_properties->MaximumBuffers = 16;
m_properties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_PRIVATE_LOGGER_MODE |
EVENT_TRACE_PRIVATE_IN_PROC;
m_properties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
m_properties->LogFileNameOffset =
static_cast<ULONG>(sizeof(EVENT_TRACE_PROPERTIES) + name_size);
std::memcpy(m_storage.data() + m_properties->LoggerNameOffset, name, name_size);
std::memcpy(m_storage.data() + m_properties->LogFileNameOffset, filename.c_str(),
filename_size);
const ULONG started = StartTraceW(&m_handle, name, m_properties);
if (started != ERROR_SUCCESS)
throw std::runtime_error("Private ETW StartTrace error " + std::to_string(started));
m_started = true;
const ULONG enabled =
EnableTraceEx2(m_handle, &PERF_PROVIDER, EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_VERBOSE, 0, 0, 0, nullptr);
if (enabled != ERROR_SUCCESS || !Common::PerformanceTrace::Enabled())
{
Close();
throw std::runtime_error("Private ETW enable error " + std::to_string(enabled));
}
}
~PrivateETW() { Close(); }
PrivateETW(const PrivateETW&) = delete;
PrivateETW& operator=(const PrivateETW&) = delete;
bool Close()
{
if (!m_started)
return true;
m_started = false;
return ControlTraceW(m_handle, L"DolphinP1LocalProbe", m_properties,
EVENT_TRACE_CONTROL_STOP) == ERROR_SUCCESS;
}
private:
static constexpr GUID PERF_PROVIDER = {
0x54ee9231, 0x28be, 0x4ab0, {0x98, 0x1e, 0xb2, 0x6f, 0x97, 0x9c, 0x56, 0xa4}};
TRACEHANDLE m_handle = 0;
bool m_started = false;
EVENT_TRACE_PROPERTIES* m_properties = nullptr;
std::vector<u8> m_storage;
};