Skip to content

Commit

Permalink
Try cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
stefansjfw committed Aug 13, 2024
1 parent ebbce35 commit 726b012
Show file tree
Hide file tree
Showing 10 changed files with 515 additions and 4 deletions.
23 changes: 19 additions & 4 deletions PowerToys.sln
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
src\.editorconfig = src\.editorconfig
.vsconfig = .vsconfig
src\Common.Dotnet.CsWinRT.props = src\Common.Dotnet.CsWinRT.props
src\Common.SelfContained.props = src\Common.SelfContained.props
Cpp.Build.props = Cpp.Build.props
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
Directory.Packages.props = Directory.Packages.props
Solution.props = Solution.props
src\Version.props = src\Version.props
src\Common.SelfContained.props = src\Common.SelfContained.props
src\Common.Dotnet.CsWinRT.props = src\Common.Dotnet.CsWinRT.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Settings.UI.Library", "src\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj", "{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A}"
Expand Down Expand Up @@ -295,8 +295,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Telemetry", "Telemetry", "{
ProjectSection(SolutionItems) = preProject
src\common\Telemetry\ProjectTelemetry.h = src\common\Telemetry\ProjectTelemetry.h
src\common\Telemetry\TelemetryBase.cs = src\common\Telemetry\TelemetryBase.cs
src\common\Telemetry\TraceLoggingDefines.h = src\common\Telemetry\TraceLoggingDefines.h
src\common\Telemetry\TraceBase.h = src\common\Telemetry\TraceBase.h
src\common\Telemetry\TraceLoggingDefines.h = src\common\Telemetry\TraceLoggingDefines.h
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UI", "src\common\Common.UI\Common.UI.csproj", "{C3A17DCA-217B-462C-BB0C-BE086AF80081}"
Expand Down Expand Up @@ -457,7 +457,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithExt", "src\mod
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileLocksmithUI", "src\modules\FileLocksmith\FileLocksmithUI\FileLocksmithUI.csproj", "{E69B044A-2F8A-45AA-AD0B-256C59421807}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLibInterop", "src\modules\FileLocksmith\FileLocksmithLibInterop\FileLocksmithLibInterop.vcxproj", "{C604B37E-9D0E-4484-8778-E8B31B0E1B3A}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.FileLocksmithLib.Interop", "src\modules\FileLocksmith\FileLocksmithLibInterop\FileLocksmithLibInterop.vcxproj", "{C604B37E-9D0E-4484-8778-E8B31B0E1B3A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPOWrapper", "src\common\GPOWrapper\GPOWrapper.vcxproj", "{E599C30B-9DC8-4E5A-BF27-93D4CCEDE788}"
EndProject
Expand Down Expand Up @@ -584,6 +584,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerToys.Settings.DSC.Sche
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.Interop", "src\common\interop\PowerToys.Interop.vcxproj", "{F055103B-F80B-4D0C-BF48-057C55620033}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EtwTrace", "src\common\Telemetry\EtwTrace\EtwTrace.vcxproj", "{8F021B46-362B-485C-BFBA-CCF83E820CBD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Expand Down Expand Up @@ -2602,6 +2604,18 @@ Global
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.Build.0 = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x86.ActiveCfg = Release|x64
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x86.Build.0 = Release|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.Build.0 = Debug|ARM64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.ActiveCfg = Debug|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.Build.0 = Debug|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x86.ActiveCfg = Debug|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x86.Build.0 = Debug|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.ActiveCfg = Release|ARM64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.Build.0 = Release|ARM64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.ActiveCfg = Release|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.Build.0 = Release|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x86.ActiveCfg = Release|x64
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -2818,6 +2832,7 @@ Global
{C0974915-8A1D-4BF0-977B-9587D3807AB7} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{1D6893CB-BC0C-46A8-A76C-9728706CA51A} = {557C4636-D7E1-4838-A504-7D19B725EE95}
{F055103B-F80B-4D0C-BF48-057C55620033} = {5A7818A8-109C-4E1C-850D-1A654E234B0E}
{8F021B46-362B-485C-BFBA-CCF83E820CBD} = {8F62026A-294B-41C6-8839-87463613F216}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
Expand Down
203 changes: 203 additions & 0 deletions src/common/Telemetry/EtwTrace/EtwTrace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//

#pragma once
#include "pch.h"

#include "ETWTrace.h"

#include <wil\stl.h>
#include <wil\win32_helpers.h>

namespace fs = std::filesystem;

namespace
{
inline std::wstring get_root_save_folder_location()
{
PWSTR local_app_path;
winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &local_app_path));
std::wstring result{ local_app_path };
CoTaskMemFree(local_app_path);

result += L"\\Microsoft\\PowerToys";
std::filesystem::path save_path(result);
if (!std::filesystem::exists(save_path))
{
std::filesystem::create_directories(save_path);
}
return result;
}
}

namespace Shared
{
namespace Trace
{
ETWTrace::ETWTrace(const std::wstring& providerGUIDstr)

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

Dstr is not a recognized word. (unrecognized-spelling)
{
GUID id;
if (SUCCEEDED(CLSIDFromString(providerGUIDstr.c_str(), &id)))

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

Dstr is not a recognized word. (unrecognized-spelling)
{
m_providerGUID = id;
}

fs::path outputFolder = get_root_save_folder_location();
m_etwFolder = (outputFolder / c_etwFolderName);
}

ETWTrace::ETWTrace(const GUID& providerGUID) :
m_providerGUID(providerGUID)
{
fs::path outputFolder = get_root_save_folder_location();
m_etwFolder = (outputFolder / c_etwFolderName);
}

ETWTrace::~ETWTrace()
{
Stop();
m_etwFolder.clear();
m_providerGUID = {};
}

void ETWTrace::UpdateState(bool tracing)
{
if (tracing)
{
Start();
}
else
{
Stop();
}
}

void ETWTrace::Flush()
{
if (m_tracing)
{
Control(EVENT_TRACE_CONTROL_FLUSH);
Control(EVENT_TRACE_CONTROL_INCREMENT_FILE);
}
}

void ETWTrace::CreateEtwFolderIfNeeded()
{
if (!std::filesystem::exists(m_etwFolder))
{
std::filesystem::create_directories(m_etwFolder);
}
else if (!std::filesystem::is_directory(m_etwFolder))
{
std::filesystem::remove(m_etwFolder);
std::filesystem::create_directory(m_etwFolder);
}

THROW_HR_IF(E_UNEXPECTED, !std::filesystem::exists(m_etwFolder));
}

void ETWTrace::InitEventTraceProperties()
{
const std::filesystem::path exePath(wil::GetModuleFileNameW<std::wstring>(nullptr));
const auto exeName = exePath.stem().wstring();

auto now = std::chrono::system_clock::now();
auto timeNow = std::chrono::system_clock::to_time_t(now);
std::wstringstream dateTime;
struct tm timeInfo
{
};
errno_t err = localtime_s(&timeInfo, &timeNow);
if (err == 0)
{
dateTime << std::put_time(&timeInfo, L"-%m-%d-%Y__%H_%M_%S");
}

m_sessionName = wil::str_printf<std::wstring>(L"%ws-%d%ws", exeName.c_str(), GetCurrentProcessId(), dateTime.str().c_str());
const ULONG etwSessionNameCharCount = static_cast<ULONG>(m_sessionName.size() + 1);
const ULONG etwSessionNameByteSize = etwSessionNameCharCount * sizeof(m_sessionName[0]);

auto etlFileNameFormattedCounter = m_sessionName + c_etwNewFileFormattedCounter;
std::filesystem::path etlFilePath = m_etwFolder / etlFileNameFormattedCounter;
etlFilePath.replace_extension(c_etwFileNameEnd);
THROW_HR_IF(E_UNEXPECTED, etlFilePath.empty());

const auto etlFilePathStr = etlFilePath.wstring();
// std::string/wstring returns number of characters not including the null terminator, so add +1 for that.
const ULONG etwFilePathCharCount = static_cast<ULONG>(etlFilePathStr.size() + 1);
const ULONG etwFilePathByteSize = etwFilePathCharCount * sizeof(etlFilePathStr[0]);

const ULONG bufferSizeInBytes = sizeof(EVENT_TRACE_PROPERTIES) + etwSessionNameByteSize + etwFilePathByteSize;
auto eventTracePropertiesBuffer = std::make_unique<unsigned char[]>(bufferSizeInBytes);
ZeroMemory(eventTracePropertiesBuffer.get(), bufferSizeInBytes);
auto eventTraceProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES*>(eventTracePropertiesBuffer.get());

eventTraceProperties->Wnode.BufferSize = bufferSizeInBytes;

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

Wnode is not a recognized word. (unrecognized-spelling)
eventTraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

Wnode is not a recognized word. (unrecognized-spelling)

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

WNODE is not a recognized word. (unrecognized-spelling)
eventTraceProperties->Wnode.ClientContext = 1; // QPC clock resolution

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

Wnode is not a recognized word. (unrecognized-spelling)

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

QPC is not a recognized word. (unrecognized-spelling)
eventTraceProperties->Wnode.Guid = m_providerGUID;

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

Wnode is not a recognized word. (unrecognized-spelling)
eventTraceProperties->BufferSize = 4; // 4KB, the minimum size
eventTraceProperties->LogFileMode = EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_PRIVATE_IN_PROC | EVENT_TRACE_FILE_MODE_NEWFILE;

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

NEWFILE is not a recognized word. (unrecognized-spelling)
eventTraceProperties->MaximumFileSize = 1; // 1 MB

// LoggerName is placed at the end of EVENT_TRACE_PROPERTIES structure
eventTraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
wcsncpy_s(reinterpret_cast<LPWSTR>(eventTracePropertiesBuffer.get() + eventTraceProperties->LoggerNameOffset), etwSessionNameCharCount, m_sessionName.c_str(), etwSessionNameCharCount);

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

wcsncpy is not a recognized word. (unrecognized-spelling)

// LogFileName is placed at the end of the Logger Name
eventTraceProperties->LogFileNameOffset = eventTraceProperties->LoggerNameOffset + etwSessionNameByteSize;
wcsncpy_s(reinterpret_cast<LPWSTR>(eventTracePropertiesBuffer.get() + eventTraceProperties->LogFileNameOffset), etwFilePathCharCount, etlFilePathStr.c_str(), etwFilePathCharCount);

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

wcsncpy is not a recognized word. (unrecognized-spelling)

m_eventTracePropertiesBuffer = std::move(eventTracePropertiesBuffer);
}

void ETWTrace::Start()
{
if (m_tracing)
{
return;
}

CreateEtwFolderIfNeeded();
InitEventTraceProperties();

auto eventTraceProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES*>(m_eventTracePropertiesBuffer.get());
THROW_IF_WIN32_ERROR(StartTrace(&m_traceHandle, m_sessionName.c_str(), eventTraceProperties));
Enable(EVENT_CONTROL_CODE_ENABLE_PROVIDER);

m_tracing = true;
}

void ETWTrace::Stop()
{
if (!m_tracing)
{
return;
}

Enable(EVENT_CONTROL_CODE_DISABLE_PROVIDER);

// ControlTrace with EVENT_TRACE_CONTROL_STOP on the trace handle,
// which is equivalent to calling CloseTrace() on the trace handle.
Control(EVENT_TRACE_CONTROL_STOP);

m_traceHandle = INVALID_PROCESSTRACE_HANDLE;

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

PROCESSTRACE is not a recognized word. (unrecognized-spelling)
m_eventTracePropertiesBuffer.reset();
m_tracing = false;
}

void ETWTrace::Control(ULONG traceControlCode)
{
auto eventTraceProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES*>(m_eventTracePropertiesBuffer.get());
const ULONG result = ControlTrace(m_traceHandle, m_sessionName.c_str(), eventTraceProperties, traceControlCode);
THROW_IF_FAILED(HRESULT_FROM_WIN32(result));
}

void ETWTrace::Enable(ULONG eventControlCode)
{
// Control the main provider
THROW_IF_WIN32_ERROR(EnableTraceEx2(m_traceHandle, &m_providerGUID, eventControlCode, TRACE_LEVEL_VERBOSE, 0, 0, 0, nullptr));
}
}
}
45 changes: 45 additions & 0 deletions src/common/Telemetry/EtwTrace/EtwTrace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//

#pragma once
#include "pch.h"

#include <evntrace.h>

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

evntrace is not a recognized word. (unrecognized-spelling)
#include <filesystem>

namespace Shared
{
namespace Trace
{
class ETWTrace
{
public:
ETWTrace(const std::wstring& providerGUID);
ETWTrace(const GUID& providerGUID);
~ETWTrace();

void UpdateState(bool tracing);
void Flush();

private:
void CreateEtwFolderIfNeeded();
void InitEventTraceProperties();
void Start();
void Stop();
void Control(const ULONG traceControlCode);
void Enable(const ULONG eventControlCode);

GUID m_providerGUID{};
std::filesystem::path m_etwFolder;
std::wstring m_sessionName;
TRACEHANDLE m_traceHandle{ INVALID_PROCESSTRACE_HANDLE };

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

TRACEHANDLE is not a recognized word. (unrecognized-spelling)

Check failure

Code scanning / check-spelling

Unrecognized Spelling Error

PROCESSTRACE is not a recognized word. (unrecognized-spelling)
std::unique_ptr<unsigned char[]> m_eventTracePropertiesBuffer;
bool m_tracing{ false };

static constexpr PCWSTR c_etwFolderName = L"etw";
static constexpr PCWSTR c_etwNewFileFormattedCounter = L"-%d";
static constexpr PCWSTR c_etwFileNameEnd = L".etl";
};
}
}
Loading

0 comments on commit 726b012

Please sign in to comment.