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)16ScopedCOMInitializer::ScopedCOMInitializer(Uninitialization uninitialization) { 17 Initialize(COINIT_APARTMENTTHREADED, uninitialization); 18 } 19 ScopedCOMInitializer(SelectMTA mta,Uninitialization uninitialization)20ScopedCOMInitializer::ScopedCOMInitializer(SelectMTA mta, 21 Uninitialization uninitialization) { 22 Initialize(COINIT_MULTITHREADED, uninitialization); 23 } 24 ~ScopedCOMInitializer()25ScopedCOMInitializer::~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() const36bool ScopedCOMInitializer::Succeeded() const { 37 return SUCCEEDED(hr_); 38 } 39 GetCOMBalancerReferenceCountForTesting() const40DWORD ScopedCOMInitializer::GetCOMBalancerReferenceCountForTesting() const { 41 if (com_balancer_) 42 return com_balancer_->GetReferenceCountForTesting(); 43 return 0; 44 } 45 Initialize(COINIT init,Uninitialization uninitialization)46void 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