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 |