xref: /aosp_15_r20/external/cronet/base/win/com_init_balancer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/win/com_init_balancer.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <objbase.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker namespace base {
12*6777b538SAndroid Build Coastguard Worker namespace win {
13*6777b538SAndroid Build Coastguard Worker namespace internal {
14*6777b538SAndroid Build Coastguard Worker 
ComInitBalancer(DWORD co_init)15*6777b538SAndroid Build Coastguard Worker ComInitBalancer::ComInitBalancer(DWORD co_init) : co_init_(co_init) {
16*6777b538SAndroid Build Coastguard Worker   ULARGE_INTEGER spy_cookie = {};
17*6777b538SAndroid Build Coastguard Worker   HRESULT hr = ::CoRegisterInitializeSpy(this, &spy_cookie);
18*6777b538SAndroid Build Coastguard Worker   if (SUCCEEDED(hr))
19*6777b538SAndroid Build Coastguard Worker     spy_cookie_ = spy_cookie;
20*6777b538SAndroid Build Coastguard Worker }
21*6777b538SAndroid Build Coastguard Worker 
~ComInitBalancer()22*6777b538SAndroid Build Coastguard Worker ComInitBalancer::~ComInitBalancer() {
23*6777b538SAndroid Build Coastguard Worker   DCHECK(!spy_cookie_.has_value());
24*6777b538SAndroid Build Coastguard Worker }
25*6777b538SAndroid Build Coastguard Worker 
Disable()26*6777b538SAndroid Build Coastguard Worker void ComInitBalancer::Disable() {
27*6777b538SAndroid Build Coastguard Worker   if (spy_cookie_.has_value()) {
28*6777b538SAndroid Build Coastguard Worker     ::CoRevokeInitializeSpy(spy_cookie_.value());
29*6777b538SAndroid Build Coastguard Worker     reference_count_ = 0;
30*6777b538SAndroid Build Coastguard Worker     spy_cookie_.reset();
31*6777b538SAndroid Build Coastguard Worker   }
32*6777b538SAndroid Build Coastguard Worker }
33*6777b538SAndroid Build Coastguard Worker 
GetReferenceCountForTesting() const34*6777b538SAndroid Build Coastguard Worker DWORD ComInitBalancer::GetReferenceCountForTesting() const {
35*6777b538SAndroid Build Coastguard Worker   return reference_count_;
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker IFACEMETHODIMP
PreInitialize(DWORD apartment_type,DWORD reference_count)39*6777b538SAndroid Build Coastguard Worker ComInitBalancer::PreInitialize(DWORD apartment_type, DWORD reference_count) {
40*6777b538SAndroid Build Coastguard Worker   return S_OK;
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker IFACEMETHODIMP
PostInitialize(HRESULT result,DWORD apartment_type,DWORD new_reference_count)44*6777b538SAndroid Build Coastguard Worker ComInitBalancer::PostInitialize(HRESULT result,
45*6777b538SAndroid Build Coastguard Worker                                 DWORD apartment_type,
46*6777b538SAndroid Build Coastguard Worker                                 DWORD new_reference_count) {
47*6777b538SAndroid Build Coastguard Worker   reference_count_ = new_reference_count;
48*6777b538SAndroid Build Coastguard Worker   return result;
49*6777b538SAndroid Build Coastguard Worker }
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker IFACEMETHODIMP
PreUninitialize(DWORD reference_count)52*6777b538SAndroid Build Coastguard Worker ComInitBalancer::PreUninitialize(DWORD reference_count) {
53*6777b538SAndroid Build Coastguard Worker   if (reference_count == 1 && spy_cookie_.has_value()) {
54*6777b538SAndroid Build Coastguard Worker     // Increase the reference count to prevent premature and unbalanced
55*6777b538SAndroid Build Coastguard Worker     // uninitalization of the COM library.
56*6777b538SAndroid Build Coastguard Worker     ::CoInitializeEx(nullptr, co_init_);
57*6777b538SAndroid Build Coastguard Worker   }
58*6777b538SAndroid Build Coastguard Worker   return S_OK;
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker IFACEMETHODIMP
PostUninitialize(DWORD new_reference_count)62*6777b538SAndroid Build Coastguard Worker ComInitBalancer::PostUninitialize(DWORD new_reference_count) {
63*6777b538SAndroid Build Coastguard Worker   reference_count_ = new_reference_count;
64*6777b538SAndroid Build Coastguard Worker   return S_OK;
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker }  // namespace internal
68*6777b538SAndroid Build Coastguard Worker }  // namespace win
69*6777b538SAndroid Build Coastguard Worker }  // namespace base
70