1 // Copyright 2012 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 #ifndef BASE_WIN_SCOPED_COM_INITIALIZER_H_ 6 #define BASE_WIN_SCOPED_COM_INITIALIZER_H_ 7 8 #include <objbase.h> 9 10 #include <wrl/client.h> 11 12 #include "base/base_export.h" 13 #include "base/threading/thread_checker.h" 14 #include "base/win/com_init_balancer.h" 15 #include "base/win/scoped_windows_thread_environment.h" 16 17 namespace base { 18 namespace win { 19 20 // Initializes COM in the constructor (STA or MTA), and uninitializes COM in the 21 // destructor. 22 // 23 // It is strongly encouraged to block premature uninitialization of the COM 24 // libraries in threads that execute third-party code, as a way to protect 25 // against unbalanced CoInitialize/CoUninitialize pairs. 26 // 27 // WARNING: This should only be used once per thread, ideally scoped to a 28 // similar lifetime as the thread itself. You should not be using this in 29 // random utility functions that make COM calls -- instead ensure these 30 // functions are running on a COM-supporting thread! 31 class BASE_EXPORT ScopedCOMInitializer : public ScopedWindowsThreadEnvironment { 32 public: 33 // Enum value provided to initialize the thread as an MTA instead of STA. 34 enum SelectMTA { kMTA }; 35 36 // Enum values which enumerates uninitialization modes for the COM library. 37 enum class Uninitialization { 38 // Default value. Used in threads where no third-party code is executed. 39 kAllow, 40 41 // Blocks premature uninitialization of the COM libraries before going out 42 // of scope. Used in threads where third-party code is executed. 43 kBlockPremature, 44 }; 45 46 // Constructors for STA initialization. 47 explicit ScopedCOMInitializer( 48 Uninitialization uninitialization = Uninitialization::kAllow); 49 50 // Constructors for MTA initialization. 51 explicit ScopedCOMInitializer( 52 SelectMTA mta, 53 Uninitialization uninitialization = Uninitialization::kAllow); 54 55 ScopedCOMInitializer(const ScopedCOMInitializer&) = delete; 56 ScopedCOMInitializer& operator=(const ScopedCOMInitializer&) = delete; 57 58 ~ScopedCOMInitializer() override; 59 60 // ScopedWindowsThreadEnvironment: 61 bool Succeeded() const override; 62 63 // Used for testing. Returns the COM balancer's apartment thread ref count. 64 DWORD GetCOMBalancerReferenceCountForTesting() const; 65 66 private: 67 void Initialize(COINIT init, Uninitialization uninitialization); 68 69 HRESULT hr_ = S_OK; 70 Microsoft::WRL::ComPtr<internal::ComInitBalancer> com_balancer_; 71 THREAD_CHECKER(thread_checker_); 72 }; 73 74 } // namespace win 75 } // namespace base 76 77 #endif // BASE_WIN_SCOPED_COM_INITIALIZER_H_ 78