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 {