OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef BASE_CRYPTO_SCOPED_CAPI_TYPES_H_ | |
6 #define BASE_CRYPTO_SCOPED_CAPI_TYPES_H_ | |
7 #pragma once | |
8 | |
9 #include <windows.h> | |
10 #include <wincrypt.h> | |
11 | |
12 #include <algorithm> | |
13 | |
14 #include "base/logging.h" | |
15 | |
16 namespace base { | |
17 | |
18 // Simple destructor for the Free family of CryptoAPI functions, such as | |
19 // CryptDestroyHash, which take only a single argument to release. | |
20 template <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle)> | |
21 struct CAPIDestroyer { | |
22 void operator()(CAPIHandle handle) const { | |
23 if (handle) { | |
24 BOOL ok = Destroyer(handle); | |
25 DCHECK(ok); | |
26 } | |
27 } | |
28 }; | |
29 | |
30 // Destructor for the Close/Release family of CryptoAPI functions, which take | |
31 // a second DWORD parameter indicating flags to use when closing or releasing. | |
32 // This includes functions like CertCloseStore or CryptReleaseContext. | |
33 template <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle, DWORD), | |
34 DWORD flags> | |
35 struct CAPIDestroyerWithFlags { | |
36 void operator()(CAPIHandle handle) const { | |
37 if (handle) { | |
38 BOOL ok = Destroyer(handle, flags); | |
39 DCHECK(ok); | |
40 } | |
41 } | |
42 }; | |
43 | |
44 // scoped_ptr-like class for the CryptoAPI cryptography and certificate | |
45 // handles. Because these handles are defined as integer types, and not | |
46 // pointers, the existing scoped classes, such as scoped_ptr_malloc, are | |
47 // insufficient. The semantics are the same as scoped_ptr. | |
48 template <class CAPIHandle, typename FreeProc> | |
49 class ScopedCAPIHandle { | |
50 public: | |
51 explicit ScopedCAPIHandle(CAPIHandle handle = NULL) : handle_(handle) {} | |
52 | |
53 ~ScopedCAPIHandle() { | |
54 free_(handle_); | |
55 } | |
56 | |
57 void reset(CAPIHandle handle = NULL) { | |
58 if (handle_ != handle) { | |
59 free_(handle_); | |
60 handle_ = handle; | |
61 } | |
62 } | |
63 | |
64 operator CAPIHandle() const { return handle_; } | |
65 CAPIHandle get() const { return handle_; } | |
66 | |
67 CAPIHandle* receive() { | |
68 CHECK(handle_ == NULL); | |
69 return &handle_; | |
70 } | |
71 | |
72 bool operator==(CAPIHandle handle) const { | |
73 return handle_ == handle; | |
74 } | |
75 | |
76 bool operator!=(CAPIHandle handle) const { | |
77 return handle_ != handle; | |
78 } | |
79 | |
80 void swap(ScopedCAPIHandle& b) { | |
81 CAPIHandle tmp = b.handle_; | |
82 b.handle_ = handle_; | |
83 handle_ = tmp; | |
84 } | |
85 | |
86 CAPIHandle release() { | |
87 CAPIHandle tmp = handle_; | |
88 handle_ = NULL; | |
89 return tmp; | |
90 } | |
91 | |
92 private: | |
93 CAPIHandle handle_; | |
94 static const FreeProc free_; | |
95 | |
96 DISALLOW_COPY_AND_ASSIGN(ScopedCAPIHandle); | |
97 }; | |
98 | |
99 template<class CH, typename FP> | |
100 const FP ScopedCAPIHandle<CH, FP>::free_ = FP(); | |
101 | |
102 template<class CH, typename FP> inline | |
103 bool operator==(CH h, const ScopedCAPIHandle<CH, FP>& b) { | |
104 return h == b.get(); | |
105 } | |
106 | |
107 template<class CH, typename FP> inline | |
108 bool operator!=(CH h, const ScopedCAPIHandle<CH, FP>& b) { | |
109 return h != b.get(); | |
110 } | |
111 | |
112 typedef ScopedCAPIHandle< | |
113 HCRYPTPROV, | |
114 CAPIDestroyerWithFlags<HCRYPTPROV, | |
115 CryptReleaseContext, 0> > ScopedHCRYPTPROV; | |
116 | |
117 typedef ScopedCAPIHandle< | |
118 HCRYPTKEY, CAPIDestroyer<HCRYPTKEY, CryptDestroyKey> > ScopedHCRYPTKEY; | |
119 | |
120 typedef ScopedCAPIHandle< | |
121 HCRYPTHASH, CAPIDestroyer<HCRYPTHASH, CryptDestroyHash> > ScopedHCRYPTHASH; | |
122 | |
123 } // namespace base | |
124 | |
125 #endif // BASE_CRYPTO_SCOPED_CAPI_TYPES_H_ | |
OLD | NEW |