1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #pragma once 25 26 #include <string> 27 #include <stdexcept> 28 #if defined _MSC_VER 29 #pragma warning(push,1) 30 #endif 31 #include <objbase.h> 32 #if defined _MSC_VER 33 #pragma warning(pop) 34 #endif 35 36 namespace sal 37 { 38 namespace systools 39 { 40 typedef int HRESULT; 41 42 /* Simple exception class for propagating COM errors */ 43 class ComError : public std::runtime_error 44 { 45 public: ComError(const std::string & message,HRESULT hr)46 ComError(const std::string& message, HRESULT hr) : 47 std::runtime_error(message), 48 hr_(hr) 49 {} 50 GetHresult() const51 HRESULT GetHresult() const 52 { 53 return hr_; 54 } 55 56 private: 57 HRESULT hr_; 58 }; 59 60 /* A simple COM smart pointer template */ 61 template <typename T> 62 class COMReference 63 { 64 public: COMReference()65 COMReference() : 66 com_ptr_(NULL) 67 { 68 } 69 COMReference(T * comptr)70 explicit COMReference(T* comptr) : 71 com_ptr_(comptr) 72 { 73 addRef(); 74 } 75 76 /* Explicitly controllable whether AddRef will be called or not */ COMReference(T * comptr,bool bAddRef)77 COMReference(T* comptr, bool bAddRef) : 78 com_ptr_(comptr) 79 { 80 if (bAddRef) 81 addRef(); 82 } 83 COMReference(const COMReference<T> & other)84 COMReference(const COMReference<T>& other) : 85 com_ptr_(other.com_ptr_) 86 { 87 addRef(); 88 } 89 operator =(const COMReference<T> & other)90 COMReference<T>& operator=(const COMReference<T>& other) 91 { 92 if (other.com_ptr_) 93 other.com_ptr_->AddRef(); 94 release(); 95 com_ptr_ = other.com_ptr_; 96 return *this; 97 } 98 operator =(T * comptr)99 COMReference<T>& operator=(T* comptr) 100 { 101 release(); 102 com_ptr_ = comptr; 103 addRef(); 104 return *this; 105 } 106 ~COMReference()107 ~COMReference() 108 { 109 release(); 110 } 111 112 template<typename InterfaceType> QueryInterface(REFIID iid)113 COMReference<InterfaceType> QueryInterface(REFIID iid) 114 { 115 COMReference<InterfaceType> ip; 116 HRESULT hr = E_FAIL; 117 if (com_ptr_) 118 hr = com_ptr_->QueryInterface(iid, reinterpret_cast<LPVOID*>(&ip)); 119 120 if (FAILED(hr)) 121 throw ComError("QueryInterface failed: Interface not supported!", hr); 122 123 return ip; 124 } 125 operator ->() const126 T* operator->() const 127 { 128 return com_ptr_; 129 } 130 operator *() const131 T& operator*() const 132 { 133 return *com_ptr_; 134 } 135 136 /* Necessary for assigning com_ptr_ from functions like 137 CoCreateInstance which require a 'void**' */ operator &()138 T** operator&() 139 { 140 release(); 141 com_ptr_ = NULL; 142 return &com_ptr_; 143 } 144 get() const145 T* get() const 146 { 147 return com_ptr_; 148 } 149 clear()150 COMReference<T>& clear() 151 { 152 release(); 153 com_ptr_ = NULL; 154 return *this; 155 } 156 is() const157 bool is() const 158 { 159 return (com_ptr_ != NULL); 160 } 161 162 private: addRef()163 ULONG addRef() 164 { 165 ULONG cnt = 0; 166 if (com_ptr_) 167 cnt = com_ptr_->AddRef(); 168 return cnt; 169 } 170 release()171 ULONG release() 172 { 173 ULONG cnt = 0; 174 if (com_ptr_) 175 cnt = com_ptr_->Release(); 176 return cnt; 177 } 178 179 private: 180 T* com_ptr_; 181 }; 182 183 } // systools 184 } // sal 185 186 /* Typedefs for some popular COM interfaces */ 187 typedef sal::systools::COMReference<IDataObject> IDataObjectPtr; 188 typedef sal::systools::COMReference<IStream> IStreamPtr; 189 typedef sal::systools::COMReference<IEnumFORMATETC> IEnumFORMATETCPtr; 190 191