• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/win/scoped_com_initializer.h"
6 
7 #include <wrl/implements.h>
8 
9 #include <ostream>
10 
11 #include "base/check_op.h"
12 
13 namespace base {
14 namespace win {
15 
ScopedCOMInitializer(Uninitialization uninitialization)16 ScopedCOMInitializer::ScopedCOMInitializer(Uninitialization uninitialization) {
17   Initialize(COINIT_APARTMENTTHREADED, uninitialization);
18 }
19 
ScopedCOMInitializer(SelectMTA mta,Uninitialization uninitialization)20 ScopedCOMInitializer::ScopedCOMInitializer(SelectMTA mta,
21                                            Uninitialization uninitialization) {
22   Initialize(COINIT_MULTITHREADED, uninitialization);
23 }
24 
~ScopedCOMInitializer()25 ScopedCOMInitializer::~ScopedCOMInitializer() {
26   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
27   if (Succeeded()) {
28     if (com_balancer_) {
29       com_balancer_->Disable();
30       com_balancer_.Reset();
31     }
32     CoUninitialize();
33   }
34 }
35 
Succeeded() const36 bool ScopedCOMInitializer::Succeeded() const {
37   return SUCCEEDED(hr_);
38 }
39 
GetCOMBalancerReferenceCountForTesting() const40 DWORD ScopedCOMInitializer::GetCOMBalancerReferenceCountForTesting() const {
41   if (com_balancer_)
42     return com_balancer_->GetReferenceCountForTesting();
43   return 0;
44 }
45 
Initialize(COINIT init,Uninitialization uninitialization)46 void ScopedCOMInitializer::Initialize(COINIT init,
47                                       Uninitialization uninitialization) {
48   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
49   // COINIT_DISABLE_OLE1DDE is always added based on:
50   // https://docs.microsoft.com/en-us/windows/desktop/learnwin32/initializing-the-com-library
51   if (uninitialization == Uninitialization::kBlockPremature) {
52     com_balancer_ = Microsoft::WRL::Details::Make<internal::ComInitBalancer>(
53         init | COINIT_DISABLE_OLE1DDE);
54   }
55   hr_ = ::CoInitializeEx(nullptr, init | COINIT_DISABLE_OLE1DDE);
56   DCHECK_NE(RPC_E_CHANGED_MODE, hr_) << "Invalid COM thread model change";
57 }
58 
59 }  // namespace win
60 }  // namespace base
61