xref: /aosp_15_r20/external/cronet/base/win/com_init_util.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 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_util.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <windows.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
10*6777b538SAndroid Build Coastguard Worker #include <winternl.h>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace base {
16*6777b538SAndroid Build Coastguard Worker namespace win {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
21*6777b538SAndroid Build Coastguard Worker const char kComNotInitialized[] = "COM is not initialized on this thread.";
22*6777b538SAndroid Build Coastguard Worker #endif  // DCHECK_IS_ON()
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker // Derived from combase.dll.
25*6777b538SAndroid Build Coastguard Worker struct OleTlsData {
26*6777b538SAndroid Build Coastguard Worker   enum ApartmentFlags {
27*6777b538SAndroid Build Coastguard Worker     LOGICAL_THREAD_REGISTERED = 0x2,
28*6777b538SAndroid Build Coastguard Worker     STA = 0x80,
29*6777b538SAndroid Build Coastguard Worker     MTA = 0x140,
30*6777b538SAndroid Build Coastguard Worker   };
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker   uintptr_t thread_base;
33*6777b538SAndroid Build Coastguard Worker   uintptr_t sm_allocator;
34*6777b538SAndroid Build Coastguard Worker   DWORD apartment_id;
35*6777b538SAndroid Build Coastguard Worker   DWORD apartment_flags;
36*6777b538SAndroid Build Coastguard Worker   // There are many more fields than this, but for our purposes, we only care
37*6777b538SAndroid Build Coastguard Worker   // about |apartment_flags|. Correctly declaring the previous types allows this
38*6777b538SAndroid Build Coastguard Worker   // to work between x86 and x64 builds.
39*6777b538SAndroid Build Coastguard Worker };
40*6777b538SAndroid Build Coastguard Worker 
GetOleTlsData()41*6777b538SAndroid Build Coastguard Worker OleTlsData* GetOleTlsData() {
42*6777b538SAndroid Build Coastguard Worker   TEB* teb = NtCurrentTeb();
43*6777b538SAndroid Build Coastguard Worker   return reinterpret_cast<OleTlsData*>(teb->ReservedForOle);
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker }  // namespace
47*6777b538SAndroid Build Coastguard Worker 
GetComApartmentTypeForThread()48*6777b538SAndroid Build Coastguard Worker ComApartmentType GetComApartmentTypeForThread() {
49*6777b538SAndroid Build Coastguard Worker   OleTlsData* ole_tls_data = GetOleTlsData();
50*6777b538SAndroid Build Coastguard Worker   if (!ole_tls_data)
51*6777b538SAndroid Build Coastguard Worker     return ComApartmentType::NONE;
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   if (ole_tls_data->apartment_flags & OleTlsData::ApartmentFlags::STA)
54*6777b538SAndroid Build Coastguard Worker     return ComApartmentType::STA;
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker   if ((ole_tls_data->apartment_flags & OleTlsData::ApartmentFlags::MTA) ==
57*6777b538SAndroid Build Coastguard Worker       OleTlsData::ApartmentFlags::MTA) {
58*6777b538SAndroid Build Coastguard Worker     return ComApartmentType::MTA;
59*6777b538SAndroid Build Coastguard Worker   }
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   return ComApartmentType::NONE;
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
65*6777b538SAndroid Build Coastguard Worker 
AssertComInitialized(const char * message)66*6777b538SAndroid Build Coastguard Worker void AssertComInitialized(const char* message) {
67*6777b538SAndroid Build Coastguard Worker   if (GetComApartmentTypeForThread() != ComApartmentType::NONE)
68*6777b538SAndroid Build Coastguard Worker     return;
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   // COM worker threads don't always set up the apartment, but they do perform
71*6777b538SAndroid Build Coastguard Worker   // some thread registration, so we allow those.
72*6777b538SAndroid Build Coastguard Worker   OleTlsData* ole_tls_data = GetOleTlsData();
73*6777b538SAndroid Build Coastguard Worker   if (ole_tls_data && (ole_tls_data->apartment_flags &
74*6777b538SAndroid Build Coastguard Worker                        OleTlsData::ApartmentFlags::LOGICAL_THREAD_REGISTERED)) {
75*6777b538SAndroid Build Coastguard Worker     return;
76*6777b538SAndroid Build Coastguard Worker   }
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   NOTREACHED() << (message ? message : kComNotInitialized);
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker 
AssertComApartmentType(ComApartmentType apartment_type)81*6777b538SAndroid Build Coastguard Worker void AssertComApartmentType(ComApartmentType apartment_type) {
82*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(apartment_type, GetComApartmentTypeForThread());
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker #endif  // DCHECK_IS_ON()
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker }  // namespace win
88*6777b538SAndroid Build Coastguard Worker }  // namespace base
89