| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_WIN_SCOPED_COMPTR_H_ | 5 #ifndef BASE_WIN_SCOPED_COMPTR_H_ |
| 6 #define BASE_WIN_SCOPED_COMPTR_H_ | 6 #define BASE_WIN_SCOPED_COMPTR_H_ |
| 7 | 7 |
| 8 #include <objbase.h> |
| 8 #include <unknwn.h> | 9 #include <unknwn.h> |
| 9 | 10 |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 | 12 |
| 12 namespace base { | 13 namespace base { |
| 13 namespace win { | 14 namespace win { |
| 14 | 15 |
| 15 // DEPRECATED: Use Microsoft::WRL::ComPtr instead. | 16 // DEPRECATED: Use Microsoft::WRL::ComPtr instead. |
| 16 // A fairly minimalistic smart class for COM interface pointers. | 17 // A fairly minimalistic smart class for COM interface pointers. |
| 17 template <class Interface, const IID* interface_id = &__uuidof(Interface)> | 18 template <class Interface, const IID* interface_id = &__uuidof(Interface)> |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 return reinterpret_cast<void**>(Receive()); | 93 return reinterpret_cast<void**>(Receive()); |
| 93 } | 94 } |
| 94 | 95 |
| 95 template <class Query> | 96 template <class Query> |
| 96 HRESULT QueryInterface(Query** p) { | 97 HRESULT QueryInterface(Query** p) { |
| 97 DCHECK(p); | 98 DCHECK(p); |
| 98 DCHECK(ptr_); | 99 DCHECK(ptr_); |
| 99 // IUnknown already has a template version of QueryInterface | 100 // IUnknown already has a template version of QueryInterface |
| 100 // so the iid parameter is implicit here. The only thing this | 101 // so the iid parameter is implicit here. The only thing this |
| 101 // function adds are the DCHECKs. | 102 // function adds are the DCHECKs. |
| 102 return ptr_->QueryInterface(p); | 103 return ptr_->QueryInterface(IID_PPV_ARGS(p)); |
| 103 } | 104 } |
| 104 | 105 |
| 105 // QI for times when the IID is not associated with the type. | 106 // QI for times when the IID is not associated with the type. |
| 106 HRESULT QueryInterface(const IID& iid, void** obj) { | 107 HRESULT QueryInterface(const IID& iid, void** obj) { |
| 107 DCHECK(obj); | 108 DCHECK(obj); |
| 108 DCHECK(ptr_); | 109 DCHECK(ptr_); |
| 109 return ptr_->QueryInterface(iid, obj); | 110 return ptr_->QueryInterface(iid, obj); |
| 110 } | 111 } |
| 111 | 112 |
| 112 // Queries |other| for the interface this object wraps and returns the | 113 // Queries |other| for the interface this object wraps and returns the |
| 113 // error code from the other->QueryInterface operation. | 114 // error code from the other->QueryInterface operation. |
| 114 HRESULT QueryFrom(IUnknown* object) { | 115 HRESULT QueryFrom(IUnknown* object) { |
| 115 DCHECK(object); | 116 DCHECK(object); |
| 116 return object->QueryInterface(Receive()); | 117 return object->QueryInterface(IID_PPV_ARGS(Receive())); |
| 117 } | 118 } |
| 118 | 119 |
| 119 // Convenience wrapper around CoCreateInstance | 120 // Convenience wrapper around CoCreateInstance |
| 120 HRESULT CreateInstance(const CLSID& clsid, | 121 HRESULT CreateInstance(const CLSID& clsid, |
| 121 IUnknown* outer = nullptr, | 122 IUnknown* outer = nullptr, |
| 122 DWORD context = CLSCTX_ALL) { | 123 DWORD context = CLSCTX_ALL) { |
| 123 DCHECK(!ptr_); | 124 DCHECK(!ptr_); |
| 124 HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id, | 125 HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id, |
| 125 reinterpret_cast<void**>(&ptr_)); | 126 reinterpret_cast<void**>(&ptr_)); |
| 126 return hr; | 127 return hr; |
| 127 } | 128 } |
| 128 | 129 |
| 129 // Checks if the identity of |other| and this object is the same. | 130 // Checks if the identity of |other| and this object is the same. |
| 130 bool IsSameObject(IUnknown* other) { | 131 bool IsSameObject(IUnknown* other) { |
| 131 if (!other && !ptr_) | 132 if (!other && !ptr_) |
| 132 return true; | 133 return true; |
| 133 | 134 |
| 134 if (!other || !ptr_) | 135 if (!other || !ptr_) |
| 135 return false; | 136 return false; |
| 136 | 137 |
| 137 ScopedComPtr<IUnknown> my_identity; | 138 ScopedComPtr<IUnknown> my_identity; |
| 138 QueryInterface(my_identity.Receive()); | 139 QueryInterface(IID_PPV_ARGS(my_identity.Receive())); |
| 139 | 140 |
| 140 ScopedComPtr<IUnknown> other_identity; | 141 ScopedComPtr<IUnknown> other_identity; |
| 141 other->QueryInterface(other_identity.Receive()); | 142 other->QueryInterface(IID_PPV_ARGS(other_identity.Receive())); |
| 142 | 143 |
| 143 return my_identity == other_identity; | 144 return my_identity == other_identity; |
| 144 } | 145 } |
| 145 | 146 |
| 146 // Provides direct access to the interface. | 147 // Provides direct access to the interface. |
| 147 // Here we use a well known trick to make sure we block access to | 148 // Here we use a well known trick to make sure we block access to |
| 148 // IUnknown methods so that something bad like this doesn't happen: | 149 // IUnknown methods so that something bad like this doesn't happen: |
| 149 // ScopedComPtr<IUnknown> p(Foo()); | 150 // ScopedComPtr<IUnknown> p(Foo()); |
| 150 // p->Release(); | 151 // p->Release(); |
| 151 // ... later the destructor runs, which will Release() again. | 152 // ... later the destructor runs, which will Release() again. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 template <typename T> | 251 template <typename T> |
| 251 bool operator!=(std::nullptr_t null, const ScopedComPtr<T>& rhs) { | 252 bool operator!=(std::nullptr_t null, const ScopedComPtr<T>& rhs) { |
| 252 return !operator==(null, rhs); | 253 return !operator==(null, rhs); |
| 253 } | 254 } |
| 254 | 255 |
| 255 template <typename T> | 256 template <typename T> |
| 256 std::ostream& operator<<(std::ostream& out, const ScopedComPtr<T>& p) { | 257 std::ostream& operator<<(std::ostream& out, const ScopedComPtr<T>& p) { |
| 257 return out << p.get(); | 258 return out << p.get(); |
| 258 } | 259 } |
| 259 | 260 |
| 261 // Helper to make IID_PPV_ARGS work with ScopedComPtr. |
| 262 template <typename T> |
| 263 void** IID_PPV_ARGS_Helper(base::win::ScopedComPtr<T>* pp) throw() { |
| 264 return pp->ReceiveVoid(); |
| 265 } |
| 266 |
| 260 } // namespace win | 267 } // namespace win |
| 261 } // namespace base | 268 } // namespace base |
| 262 | 269 |
| 263 #endif // BASE_WIN_SCOPED_COMPTR_H_ | 270 #endif // BASE_WIN_SCOPED_COMPTR_H_ |
| OLD | NEW |