| OLD | NEW |
| (Empty) |
| 1 // Copyright 2004-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // | |
| 16 // Classes for automatically closing handles. | |
| 17 | |
| 18 #ifndef OMAHA_COMMON_SMART_HANDLE_H_ | |
| 19 #define OMAHA_COMMON_SMART_HANDLE_H_ | |
| 20 | |
| 21 #include <wincrypt.h> | |
| 22 | |
| 23 namespace omaha { | |
| 24 | |
| 25 /** | |
| 26 * Base traits class for handles. | |
| 27 * This base class provides default implementation for InvalidValue and IsValid | |
| 28 * @param T The handle type to be wrapped. | |
| 29 */ | |
| 30 template<class T> | |
| 31 class BaseHandleTraitsT { | |
| 32 public: | |
| 33 // Typedef that is used by this class and derived classes | |
| 34 typedef T HandleType; | |
| 35 | |
| 36 // Returns the invalid handle value | |
| 37 static HandleType InvalidValue() { | |
| 38 return NULL; | |
| 39 } | |
| 40 | |
| 41 // Returns true only if the given handle h is invalid | |
| 42 static bool IsValid(const HandleType& h) { | |
| 43 return h != InvalidValue(); | |
| 44 } | |
| 45 | |
| 46 private: | |
| 47 DISALLOW_EVIL_CONSTRUCTORS(BaseHandleTraitsT); | |
| 48 }; | |
| 49 | |
| 50 /** | |
| 51 * Smart handle class. | |
| 52 * Offers basic HANDLE functionality such as cast, attach/detach and automatic Cl
ose(). | |
| 53 */ | |
| 54 template<class T, class Traits, class AlternateType = T> | |
| 55 class HandleT { | |
| 56 public: | |
| 57 // Default constructor. | |
| 58 HandleT() : h_(Traits::InvalidValue()) { | |
| 59 } | |
| 60 | |
| 61 // Constructor that assumes ownership of the supplied handle | |
| 62 explicit HandleT(T h) : h_(h) { | |
| 63 } | |
| 64 | |
| 65 // Destructor calls @ref Close() | |
| 66 ~HandleT() { | |
| 67 Close(); | |
| 68 } | |
| 69 | |
| 70 // Assumes ownership of the supplied handle, | |
| 71 // potentially closing an already held handle. | |
| 72 void Attach(T h) { | |
| 73 Close(); | |
| 74 h_ = h; | |
| 75 } | |
| 76 | |
| 77 // Transfers ownership to the caller and sets the internal | |
| 78 // state to InvalidValue(). | |
| 79 T Detach() { | |
| 80 T h = h_; | |
| 81 h_ = Traits::InvalidValue(); | |
| 82 return h; | |
| 83 } | |
| 84 | |
| 85 // Handle accessor | |
| 86 T handle() { | |
| 87 return h_; | |
| 88 } | |
| 89 | |
| 90 // An alternate cast for the handle. | |
| 91 // This can be useful for GDI objects that are used | |
| 92 // in functions that e.g. accept both HGDIOBJ and HBITMAP. | |
| 93 AlternateType alt_type() { | |
| 94 return reinterpret_cast<AlternateType>(h_); | |
| 95 } | |
| 96 | |
| 97 // Accesses the contained handle | |
| 98 operator T() { | |
| 99 return h_; | |
| 100 } | |
| 101 | |
| 102 T& receive() { | |
| 103 ASSERT(!IsValid(), (L"Should only be used for out arguments")); | |
| 104 return h_; | |
| 105 } | |
| 106 | |
| 107 // @returns true only if the handle is valid as depicted | |
| 108 // by the traits class. | |
| 109 bool IsValid() { | |
| 110 return Traits::IsValid(h_); | |
| 111 } | |
| 112 | |
| 113 // Closes the handle | |
| 114 void Close() { | |
| 115 if (Traits::IsValid(h_)) { | |
| 116 Traits::Close(h_); | |
| 117 h_ = Traits::InvalidValue(); | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 protected: | |
| 122 T h_; | |
| 123 | |
| 124 private: | |
| 125 DISALLOW_EVIL_CONSTRUCTORS(HandleT); | |
| 126 }; | |
| 127 | |
| 128 | |
| 129 /* | |
| 130 * Traits class for a regular Win32 HANDLE. | |
| 131 */ | |
| 132 class HandleTraitsWin32Handle : public BaseHandleTraitsT<HANDLE> { | |
| 133 public: | |
| 134 // Calls FindClose to close the handle. | |
| 135 static bool Close(HandleType h) { | |
| 136 return (::CloseHandle(h) != false); | |
| 137 } | |
| 138 | |
| 139 // Returns the invalid handle value | |
| 140 static HandleType InvalidValue() { | |
| 141 return NULL; // note that INVALID_HANDLE_VALUE is also an invalid handle | |
| 142 } | |
| 143 | |
| 144 // Returns true only if the given handle h is invalid | |
| 145 static bool IsValid(const HandleType& h) { | |
| 146 return h != InvalidValue() && h != INVALID_HANDLE_VALUE; | |
| 147 } | |
| 148 | |
| 149 private: | |
| 150 DISALLOW_EVIL_CONSTRUCTORS(HandleTraitsWin32Handle); | |
| 151 }; | |
| 152 | |
| 153 /* | |
| 154 * Traits class for FindXXXFile handles. | |
| 155 */ | |
| 156 class HandleTraitsFindHandle : public BaseHandleTraitsT<HANDLE> { | |
| 157 public: | |
| 158 // Calls FindClose to close the handle. | |
| 159 static bool Close(HandleType h) { | |
| 160 return (::FindClose(h) != false); | |
| 161 } | |
| 162 | |
| 163 // Returns the invalid handle value | |
| 164 static HandleType InvalidValue() { | |
| 165 return INVALID_HANDLE_VALUE; | |
| 166 } | |
| 167 | |
| 168 private: | |
| 169 DISALLOW_EVIL_CONSTRUCTORS(HandleTraitsFindHandle); | |
| 170 }; | |
| 171 | |
| 172 /* | |
| 173 * Traits for an HMENU. | |
| 174 */ | |
| 175 class HandleTraitsHMenu : public BaseHandleTraitsT<HMENU> { | |
| 176 public: | |
| 177 // Calls DestroyMenu to destroy the menu. | |
| 178 static bool Close(HandleType h) { | |
| 179 return (::DestroyMenu(h) != FALSE); | |
| 180 } | |
| 181 | |
| 182 private: | |
| 183 DISALLOW_EVIL_CONSTRUCTORS(HandleTraitsHMenu); | |
| 184 }; | |
| 185 | |
| 186 /* | |
| 187 * Traits for an HCRYPTKEY. | |
| 188 */ | |
| 189 class HandleTraitsHCryptKey : public BaseHandleTraitsT<HCRYPTKEY> { | |
| 190 public: | |
| 191 static bool Close(HandleType h) { | |
| 192 return (::CryptDestroyKey(h) != FALSE); | |
| 193 } | |
| 194 | |
| 195 private: | |
| 196 DISALLOW_EVIL_CONSTRUCTORS(HandleTraitsHCryptKey); | |
| 197 }; | |
| 198 | |
| 199 /* | |
| 200 * Traits for an HCRYPTHASH. | |
| 201 */ | |
| 202 class HandleTraitsHCryptHash : public BaseHandleTraitsT<HCRYPTHASH> { | |
| 203 public: | |
| 204 static bool Close(HandleType h) { | |
| 205 return (::CryptDestroyHash(h) != FALSE); | |
| 206 } | |
| 207 | |
| 208 private: | |
| 209 DISALLOW_EVIL_CONSTRUCTORS(HandleTraitsHCryptHash); | |
| 210 }; | |
| 211 | |
| 212 /* | |
| 213 * Traits for LoadLibrary/FreeLibrary. | |
| 214 */ | |
| 215 class HandleTraitsLibrary : public BaseHandleTraitsT<HMODULE> { | |
| 216 public: | |
| 217 static bool Close(HandleType h) { | |
| 218 return (::FreeLibrary(h) != FALSE); | |
| 219 } | |
| 220 | |
| 221 private: | |
| 222 DISALLOW_EVIL_CONSTRUCTORS(HandleTraitsLibrary); | |
| 223 }; | |
| 224 | |
| 225 | |
| 226 /* | |
| 227 * Win32 handle types. Add new ones here as you need them. | |
| 228 * Note that GDI handle types should be kept in common/gdi_smart_ptr.h | |
| 229 * rather than here. | |
| 230 */ | |
| 231 typedef HandleT<HANDLE, HandleTraitsWin32Handle> AutoHandle; | |
| 232 typedef HandleT<HANDLE, HandleTraitsFindHandle> AutoFindHandle; | |
| 233 typedef HandleT<HMENU, HandleTraitsHMenu> AutoHMenu; | |
| 234 typedef HandleT<HCRYPTHASH, HandleTraitsHCryptHash> AutoHCryptHash; | |
| 235 typedef HandleT<HCRYPTKEY, HandleTraitsHCryptKey> AutoHCryptKey; | |
| 236 typedef HandleT<HINSTANCE, HandleTraitsLibrary> AutoLibrary; | |
| 237 | |
| 238 } // namespace omaha | |
| 239 | |
| 240 #endif // OMAHA_COMMON_SMART_HANDLE_H_ | |
| OLD | NEW |