Remove base::win::RoInitialize and base::win::RoUninitialize
base::win::RoInitialize is banned due to improper use.
BUG=1197722
Change-Id: Ib1cea36a17acaae2af6192a9f4a73aaf9695f97a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2822798
Commit-Queue: Robert Liao <[email protected]>
Reviewed-by: Will Harris <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/master@{#873494}
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 72fef12..d469e67 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1052,12 +1052,14 @@
(
'RoInitialize',
(
- 'Improper use of base::win::RoInitialize() has been implicated in a ',
+ 'Improper use of [base::win]::RoInitialize() has been implicated in a ',
'few COM initialization leaks. Use base::win::ScopedWinrtInitializer ',
'instead. See http://crbug.com/1197722 for more information.'
),
True,
- (),
+ (
+ r'^base[\\/]win[\\/]scoped_winrt_initializer\.cc$'
+ ),
),
)
diff --git a/base/win/core_winrt_util.cc b/base/win/core_winrt_util.cc
index c674406c..74de86f 100644
--- a/base/win/core_winrt_util.cc
+++ b/base/win/core_winrt_util.cc
@@ -19,20 +19,6 @@
return handle ? ::GetProcAddress(handle, function_name) : nullptr;
}
-decltype(&::RoInitialize) GetRoInitializeFunction() {
- static decltype(&::RoInitialize) const function =
- reinterpret_cast<decltype(&::RoInitialize)>(
- LoadComBaseFunction("RoInitialize"));
- return function;
-}
-
-decltype(&::RoUninitialize) GetRoUninitializeFunction() {
- static decltype(&::RoUninitialize) const function =
- reinterpret_cast<decltype(&::RoUninitialize)>(
- LoadComBaseFunction("RoUninitialize"));
- return function;
-}
-
decltype(&::RoActivateInstance) GetRoActivateInstanceFunction() {
static decltype(&::RoActivateInstance) const function =
reinterpret_cast<decltype(&::RoActivateInstance)>(
@@ -54,21 +40,7 @@
bool ResolveCoreWinRTDelayload() {
// TODO(finnur): Add AssertIOAllowed once crbug.com/770193 is fixed.
- return GetRoInitializeFunction() && GetRoUninitializeFunction() &&
- GetRoActivateInstanceFunction() && GetRoGetActivationFactoryFunction();
-}
-
-HRESULT RoInitialize(RO_INIT_TYPE init_type) {
- auto ro_initialize_func = GetRoInitializeFunction();
- if (!ro_initialize_func)
- return E_FAIL;
- return ro_initialize_func(init_type);
-}
-
-void RoUninitialize() {
- auto ro_uninitialize_func = GetRoUninitializeFunction();
- if (ro_uninitialize_func)
- ro_uninitialize_func();
+ return GetRoActivateInstanceFunction() && GetRoGetActivationFactoryFunction();
}
HRESULT RoGetActivationFactory(HSTRING class_id,
diff --git a/base/win/core_winrt_util.h b/base/win/core_winrt_util.h
index 7b821661..a13da7f9 100644
--- a/base/win/core_winrt_util.h
+++ b/base/win/core_winrt_util.h
@@ -27,10 +27,6 @@
// The following stubs are provided for when component build is enabled, in
// order to avoid the propagation of delay-loading CoreWinRT to other modules.
-BASE_EXPORT HRESULT RoInitialize(RO_INIT_TYPE init_type);
-
-BASE_EXPORT void RoUninitialize();
-
BASE_EXPORT HRESULT RoGetActivationFactory(HSTRING class_id,
const IID& iid,
void** out_factory);
diff --git a/base/win/core_winrt_util_unittest.cc b/base/win/core_winrt_util_unittest.cc
index 084c041..b9cb2a4 100644
--- a/base/win/core_winrt_util_unittest.cc
+++ b/base/win/core_winrt_util_unittest.cc
@@ -19,16 +19,5 @@
EXPECT_TRUE(ResolveCoreWinRTDelayload());
}
-TEST(CoreWinrtUtilTest, RoInitializeAndUninitialize) {
- if (GetVersion() < Version::WIN8)
- return;
-
- ASSERT_TRUE(ResolveCoreWinRTDelayload());
- ASSERT_HRESULT_SUCCEEDED(base::win::RoInitialize(RO_INIT_MULTITHREADED));
- AssertComApartmentType(ComApartmentType::MTA);
- base::win::RoUninitialize();
- AssertComApartmentType(ComApartmentType::NONE);
-}
-
} // namespace win
} // namespace base
diff --git a/base/win/scoped_winrt_initializer.cc b/base/win/scoped_winrt_initializer.cc
index c594752..7ec676a 100644
--- a/base/win/scoped_winrt_initializer.cc
+++ b/base/win/scoped_winrt_initializer.cc
@@ -4,7 +4,11 @@
#include "base/win/scoped_winrt_initializer.h"
+#include <roapi.h>
+#include <windows.h>
+
#include "base/check_op.h"
+#include "base/threading/scoped_thread_priority.h"
#include "base/win/com_init_util.h"
#include "base/win/core_winrt_util.h"
#include "base/win/windows_version.h"
@@ -12,8 +16,50 @@
namespace base {
namespace win {
+namespace {
+
+FARPROC LoadComBaseFunction(const char* function_name) {
+ static HMODULE const handle = []() {
+ // Mitigate the issues caused by loading DLLs on a background thread
+ // (http://crbug/973868).
+ SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
+ return ::LoadLibraryEx(L"combase.dll", nullptr,
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
+ }();
+ return handle ? ::GetProcAddress(handle, function_name) : nullptr;
+}
+
+decltype(&::RoInitialize) GetRoInitializeFunction() {
+ static decltype(&::RoInitialize) const function =
+ reinterpret_cast<decltype(&::RoInitialize)>(
+ LoadComBaseFunction("RoInitialize"));
+ return function;
+}
+
+decltype(&::RoUninitialize) GetRoUninitializeFunction() {
+ static decltype(&::RoUninitialize) const function =
+ reinterpret_cast<decltype(&::RoUninitialize)>(
+ LoadComBaseFunction("RoUninitialize"));
+ return function;
+}
+
+HRESULT CallRoInitialize(RO_INIT_TYPE init_type) {
+ auto ro_initialize_func = GetRoInitializeFunction();
+ if (!ro_initialize_func)
+ return E_FAIL;
+ return ro_initialize_func(init_type);
+}
+
+void CallRoUninitialize() {
+ auto ro_uninitialize_func = GetRoUninitializeFunction();
+ if (ro_uninitialize_func)
+ ro_uninitialize_func();
+}
+
+} // namespace
+
ScopedWinrtInitializer::ScopedWinrtInitializer()
- : hr_(base::win::RoInitialize(RO_INIT_MULTITHREADED)) {
+ : hr_(CallRoInitialize(RO_INIT_MULTITHREADED)) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_GE(GetVersion(), Version::WIN8);
#if DCHECK_IS_ON()
@@ -27,7 +73,7 @@
ScopedWinrtInitializer::~ScopedWinrtInitializer() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (SUCCEEDED(hr_))
- base::win::RoUninitialize();
+ CallRoUninitialize();
}
bool ScopedWinrtInitializer::Succeeded() const {