Index: media/midi/midi_manager_winrt.cc |
diff --git a/media/midi/midi_manager_winrt.cc b/media/midi/midi_manager_winrt.cc |
index 11841cbde431cb09c8c6a70dee481c8fe16a081d..ac1dd24d4aedaf3aeaf1a08e4fa11a0a460c598d 100644 |
--- a/media/midi/midi_manager_winrt.cc |
+++ b/media/midi/midi_manager_winrt.cc |
@@ -15,6 +15,7 @@ |
#include <unordered_set> |
#include "base/bind.h" |
+#include "base/lazy_instance.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/threading/thread_checker.h" |
#include "base/threading/thread_task_runner_handle.h" |
@@ -50,17 +51,125 @@ std::ostream& operator<<(std::ostream& os, const PrintHr& phr) { |
return os; |
} |
+class CombaseFunctions { |
+ public: |
+ CombaseFunctions() = default; |
+ |
+ ~CombaseFunctions() { |
+ if (combase_dll_) |
+ ::FreeLibrary(combase_dll_); |
+ } |
+ |
+ bool LoadFunctions() { |
+ combase_dll_ = ::LoadLibrary(L"combase.dll"); |
+ if (!combase_dll_) |
+ return false; |
+ |
+ get_factory_func_ = reinterpret_cast<decltype(&::RoGetActivationFactory)>( |
+ ::GetProcAddress(combase_dll_, "RoGetActivationFactory")); |
+ if (!get_factory_func_) |
+ return false; |
+ |
+ create_string_func_ = reinterpret_cast<decltype(&::WindowsCreateString)>( |
+ ::GetProcAddress(combase_dll_, "WindowsCreateString")); |
+ if (!create_string_func_) |
+ return false; |
+ |
+ delete_string_func_ = reinterpret_cast<decltype(&::WindowsDeleteString)>( |
+ ::GetProcAddress(combase_dll_, "WindowsDeleteString")); |
+ if (!delete_string_func_) |
+ return false; |
+ |
+ get_string_raw_buffer_func_ = |
+ reinterpret_cast<decltype(&::WindowsGetStringRawBuffer)>( |
+ ::GetProcAddress(combase_dll_, "WindowsGetStringRawBuffer")); |
+ if (!get_string_raw_buffer_func_) |
+ return false; |
+ |
+ return true; |
+ } |
+ |
+ HRESULT RoGetActivationFactory(HSTRING class_id, |
+ const IID& iid, |
+ void** out_factory) { |
+ DCHECK(get_factory_func_); |
+ return get_factory_func_(class_id, iid, out_factory); |
+ } |
+ |
+ HRESULT WindowsCreateString(const base::char16* src, |
+ uint32_t len, |
+ HSTRING* out_hstr) { |
+ DCHECK(create_string_func_); |
+ return create_string_func_(src, len, out_hstr); |
+ } |
+ |
+ HRESULT WindowsDeleteString(HSTRING hstr) { |
+ DCHECK(delete_string_func_); |
+ return delete_string_func_(hstr); |
+ } |
+ |
+ const base::char16* WindowsGetStringRawBuffer(HSTRING hstr, |
+ uint32_t* out_len) { |
+ DCHECK(get_string_raw_buffer_func_); |
+ return get_string_raw_buffer_func_(hstr, out_len); |
+ } |
+ |
+ private: |
+ HMODULE combase_dll_ = nullptr; |
+ |
+ decltype(&::RoGetActivationFactory) get_factory_func_ = nullptr; |
+ decltype(&::WindowsCreateString) create_string_func_ = nullptr; |
+ decltype(&::WindowsDeleteString) delete_string_func_ = nullptr; |
+ decltype(&::WindowsGetStringRawBuffer) get_string_raw_buffer_func_ = nullptr; |
+}; |
+ |
+base::LazyInstance<CombaseFunctions> g_combase_functions = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+// Minimalist HSTRING wrapper class to properly maintain HSTRING lifetime. |
Takashi Toyoshima
2016/08/31 10:10:29
Can you use base/scoped_generic.h infra to impleme
Shao-Chuan Lee
2016/09/01 03:06:44
Done.
|
+class HStringWrapper { |
+ public: |
+ HStringWrapper() = default; |
+ ~HStringWrapper() { Release(); } |
+ |
+ HSTRING Get() { return hstring_; } |
+ |
+ HRESULT Set(const base::char16* str) { |
+ Release(); |
+ return g_combase_functions.Get().WindowsCreateString( |
+ str, static_cast<uint32_t>(wcslen(str)), &hstring_); |
+ } |
+ |
+ private: |
+ void Release() { |
+ if (hstring_) |
+ g_combase_functions.Get().WindowsDeleteString(hstring_); |
+ hstring_ = nullptr; |
+ } |
+ |
+ HSTRING hstring_ = nullptr; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HStringWrapper); |
+}; |
+ |
// Factory functions that activate and create WinRT components. The caller takes |
// ownership of the returning ComPtr. |
template <typename InterfaceType, base::char16 const* runtime_class_id> |
ScopedComPtr<InterfaceType> WrlStaticsFactory() { |
ScopedComPtr<InterfaceType> com_ptr; |
- HRESULT hr = GetActivationFactory( |
- WRL::Wrappers::HStringReference(runtime_class_id).Get(), |
- com_ptr.Receive()); |
+ HStringWrapper class_id_hstring; |
+ HRESULT hr = class_id_hstring.Set(runtime_class_id); |
Shao-Chuan Lee
2016/08/31 09:52:13
Here we create new HSTRINGs with WindowsCreateStri
|
+ if (FAILED(hr)) { |
+ VLOG(1) << "WindowsCreateString failed: " << PrintHr(hr); |
+ com_ptr = nullptr; |
+ return com_ptr; |
+ } |
+ |
+ hr = g_combase_functions.Get().RoGetActivationFactory( |
+ class_id_hstring.Get(), __uuidof(InterfaceType), com_ptr.ReceiveVoid()); |
if (FAILED(hr)) { |
- VLOG(1) << "GetActivationFactory failed: " << PrintHr(hr); |
+ VLOG(1) << "RoGetActivationFactory failed: " << PrintHr(hr); |
com_ptr = nullptr; |
} |
@@ -78,7 +187,8 @@ std::string GetStringFromObjectMethod(T* obj) { |
// Note: empty HSTRINGs are represent as nullptr, and instantiating |
// std::string with nullptr (in base::WideToUTF8) is undefined behavior. |
- const base::char16* buffer = WindowsGetStringRawBuffer(result, nullptr); |
+ const base::char16* buffer = |
+ g_combase_functions.Get().WindowsGetStringRawBuffer(result, nullptr); |
if (buffer) |
return base::WideToUTF8(buffer); |
return std::string(); |
@@ -361,7 +471,7 @@ class MidiManagerWinrt::MidiPortManager { |
port_names_[dev_id] = dev_name; |
- WRL::Wrappers::HString dev_id_hstring; |
+ HStringWrapper dev_id_hstring; |
HRESULT hr = dev_id_hstring.Set(base::UTF8ToWide(dev_id).c_str()); |
if (FAILED(hr)) { |
VLOG(1) << "Set failed: " << PrintHr(hr); |
@@ -691,6 +801,13 @@ void MidiManagerWinrt::StartInitialization() { |
return; |
} |
+ if (!g_combase_functions.Get().LoadFunctions()) { |
+ VLOG(1) << "Failed loading functions from Combase.dll: " |
+ << PrintHr(HRESULT_FROM_WIN32(GetLastError())); |
+ CompleteInitialization(Result::INITIALIZATION_ERROR); |
+ return; |
+ } |
+ |
com_thread_.init_com_with_mta(true); |
com_thread_.Start(); |