1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #pragma once 29 30 #include <string> 31 #include <stdexcept> 32 #if defined _MSC_VER 33 #pragma warning(push,1) 34 #endif 35 #include <objbase.h> 36 #if defined _MSC_VER 37 #pragma warning(pop) 38 #endif 39 40 namespace sal 41 { 42 namespace systools 43 { 44 typedef int HRESULT; 45 46 /* Simple exception class for propagating COM errors */ 47 class ComError : public std::runtime_error 48 { 49 public: 50 ComError(const std::string& message, HRESULT hr) : 51 std::runtime_error(message), 52 hr_(hr) 53 {} 54 55 HRESULT GetHresult() const 56 { 57 return hr_; 58 } 59 60 private: 61 HRESULT hr_; 62 }; 63 64 /* A simple COM smart pointer template */ 65 template <typename T> 66 class COMReference 67 { 68 public: 69 COMReference() : 70 com_ptr_(NULL) 71 { 72 } 73 74 explicit COMReference(T* comptr) : 75 com_ptr_(comptr) 76 { 77 addRef(); 78 } 79 80 /* Explicitly controllable whether AddRef will be called or not */ 81 COMReference(T* comptr, bool bAddRef) : 82 com_ptr_(comptr) 83 { 84 if (bAddRef) 85 addRef(); 86 } 87 88 COMReference(const COMReference<T>& other) : 89 com_ptr_(other.com_ptr_) 90 { 91 addRef(); 92 } 93 94 COMReference<T>& operator=(const COMReference<T>& other) 95 { 96 if (other.com_ptr_) 97 other.com_ptr_->AddRef(); 98 release(); 99 com_ptr_ = other.com_ptr_; 100 return *this; 101 } 102 103 COMReference<T>& operator=(T* comptr) 104 { 105 release(); 106 com_ptr_ = comptr; 107 addRef(); 108 return *this; 109 } 110 111 ~COMReference() 112 { 113 release(); 114 } 115 116 template<typename InterfaceType> 117 COMReference<InterfaceType> QueryInterface(REFIID iid) 118 { 119 COMReference<InterfaceType> ip; 120 HRESULT hr = E_FAIL; 121 if (com_ptr_) 122 hr = com_ptr_->QueryInterface(iid, reinterpret_cast<LPVOID*>(&ip)); 123 124 if (FAILED(hr)) 125 throw ComError("QueryInterface failed: Interface not supported!", hr); 126 127 return ip; 128 } 129 130 T* operator->() const 131 { 132 return com_ptr_; 133 } 134 135 T& operator*() const 136 { 137 return *com_ptr_; 138 } 139 140 /* Necessary for assigning com_ptr_ from functions like 141 CoCreateInstance which require a 'void**' */ 142 T** operator&() 143 { 144 release(); 145 com_ptr_ = NULL; 146 return &com_ptr_; 147 } 148 149 T* get() const 150 { 151 return com_ptr_; 152 } 153 154 COMReference<T>& clear() 155 { 156 release(); 157 com_ptr_ = NULL; 158 return *this; 159 } 160 161 bool is() const 162 { 163 return (com_ptr_ != NULL); 164 } 165 166 private: 167 ULONG addRef() 168 { 169 ULONG cnt = 0; 170 if (com_ptr_) 171 cnt = com_ptr_->AddRef(); 172 return cnt; 173 } 174 175 ULONG release() 176 { 177 ULONG cnt = 0; 178 if (com_ptr_) 179 cnt = com_ptr_->Release(); 180 return cnt; 181 } 182 183 private: 184 T* com_ptr_; 185 }; 186 187 } // systools 188 } // sal 189 190 /* Typedefs for some popular COM interfaces */ 191 typedef sal::systools::COMReference<IDataObject> IDataObjectPtr; 192 typedef sal::systools::COMReference<IStream> IStreamPtr; 193 typedef sal::systools::COMReference<IEnumFORMATETC> IEnumFORMATETCPtr; 194 195