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