File: elevated_tracing_service_delegate.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (146 lines) | stat: -rw-r--r-- 5,075 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/windows_services/elevated_tracing_service/elevated_tracing_service_delegate.h"

#include <wrl/client.h>
#include <wrl/implements.h>
#include <wrl/module.h>

#include <utility>

#include "base/command_line.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "chrome/common/win/eventlog_messages.h"
#include "chrome/install_static/install_util.h"
#include "chrome/windows_services/elevated_tracing_service/session_registry.h"
#include "chrome/windows_services/elevated_tracing_service/system_tracing_session.h"
#include "mojo/core/embedder/embedder.h"
#include "services/tracing/public/cpp/trace_startup.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"

namespace elevated_tracing_service {

namespace {

// A class factory for SystemTracingSession.
class SystemTracingSessionClassFactory : public Microsoft::WRL::ClassFactory<> {
 public:
  SystemTracingSessionClassFactory() = default;
  SystemTracingSessionClassFactory(const SystemTracingSessionClassFactory&) =
      delete;
  SystemTracingSessionClassFactory& operator=(
      const SystemTracingSessionClassFactory&) = delete;

  // Sets the task runner to be used for general main-thread processing.
  void set_task_runner(scoped_refptr<base::SequencedTaskRunner> task_runner) {
    task_runner_ = std::move(task_runner);
  }

  // IClassFactory:
  IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter,
                                REFIID riid,
                                void** ppvObject) override {
    // Bump the object count for the duration of this call and reduce it upon
    // exit to ensure that the service terminates if the factory fails to
    // produce an instance and there is no pre-existing instance.
    auto& module =
        Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule();
    module.IncrementObjectCount();
    absl::Cleanup count_decrementer = [&module] {
      module.DecrementObjectCount();
    };

    *ppvObject = nullptr;

    if (pUnkOuter != nullptr) {
      return CLASS_E_NOAGGREGATION;
    }

    Microsoft::WRL::ComPtr<IUnknown> unknown;
    HRESULT hr = Microsoft::WRL::MakeAndInitialize<SystemTracingSession>(
        &unknown, task_runner_);
    return SUCCEEDED(hr) ? unknown.CopyTo(riid, ppvObject) : hr;
  }

 private:
  // The task runner to be used for general main-thread processing.
  scoped_refptr<base::SequencedTaskRunner> task_runner_;
};

}  // namespace

Delegate::Delegate() = default;

Delegate::~Delegate() = default;

uint16_t Delegate::GetLogEventCategory() {
  return TRACING_SERVICE_CATEGORY;
}

uint32_t Delegate::GetLogEventMessageId() {
  return MSG_TRACING_SERVICE_LOG_MESSAGE;
}

base::expected<base::HeapArray<FactoryAndClsid>, HRESULT>
Delegate::CreateClassFactories() {
  unsigned int flags = Microsoft::WRL::ModuleType::OutOfProc;

  auto result = base::HeapArray<FactoryAndClsid>::WithSize(1);
  Microsoft::WRL::ComPtr<IUnknown> unknown;
  HRESULT hr = Microsoft::WRL::Details::CreateClassFactory<
      SystemTracingSessionClassFactory>(&flags, nullptr,
                                        __uuidof(IClassFactory), &unknown);
  if (SUCCEEDED(hr)) {
    hr = unknown.As(&result[0].factory);
    // CreateClassFactory doesn't support passing arguments while constructing
    // the factory, so pass a task runner to be the "main" runner to the factory
    // ex post facto.
    static_cast<SystemTracingSessionClassFactory*>(result[0].factory.Get())
        ->set_task_runner(
            base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock{}}));
  }
  if (FAILED(hr)) {
    return base::unexpected(hr);
  }

  result[0].clsid = base::CommandLine::ForCurrentProcess()->HasSwitch(
                        switches::kSystemTracingClsIdForTestingSwitch)
                        ? kTestSystemTracingSessionClsid
                        : install_static::GetTracingServiceClsid();
  return base::ok(std::move(result));
}

bool Delegate::PreRun() {
  // Initialize mojo and run an IPC thread.
  mojo::core::Init();
  ipc_thread_.StartWithOptions(
      base::Thread::Options(base::MessagePumpType::IO, 0));
  ipc_support_.emplace(ipc_thread_.task_runner(),
                       mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);

  // Run a ThreadPool.
  base::ThreadPoolInstance::CreateAndStartWithDefaultParams(
      "elevated_tracing_service");

  // Initialize tracing in the process.
  tracing::InitTracingPostFeatureList(/*enable_consumer=*/false);

  // Create the global SessionRegistry.
  session_registry_ = base::MakeRefCounted<SessionRegistry>();

  return false;  // This delegate does not implement `Run()`.
}

void Delegate::PostRun() {
  base::ThreadPoolInstance::Get()->Shutdown();

  // Destroy the global SessionRegistry.
  session_registry_.reset();
}

}  // namespace elevated_tracing_service