PKIFCNGUtils.h
Go to the documentation of this file.00001
00010 #if !defined(__PKIFCNGUTILS_H__)
00011 #define __PKIFCNGUTILS_H__
00012
00013 template <typename T> class CleanupFunctor
00014 {
00015 public:
00016 virtual void operator()(T t) const = 0;
00017 };
00018
00019 template <typename T> class HeapFreeFunctor : public CleanupFunctor<T>
00020 {
00021 public:
00022 void operator()(T t) const
00023 {
00024 HeapFree(GetProcessHeap(), 0, t);
00025 }
00026 };
00027
00028 template <typename T> class LocalFreeFunctor : public CleanupFunctor<T>
00029 {
00030 public:
00031 void operator()(T t) const
00032 {
00033 LocalFree(t);
00034 }
00035 };
00036
00037
00038 template <typename T>
00045 class PKIFScopedArray
00046 {
00047 public:
00055 explicit PKIFScopedArray(T* ptr)
00056 :m_ptr(ptr)
00057 {
00058 }
00066 ~PKIFScopedArray()
00067 {
00068 clear();
00069 }
00070
00071 T * get() const
00072 {
00073 return m_ptr;
00074 }
00075
00076 T & operator[](std::ptrdiff_t i) const
00077 {
00078 return m_ptr[i];
00079 }
00080
00088 operator const T *() const
00089 {
00090 return m_ptr;
00091 }
00099 operator T *()
00100 {
00101 return m_ptr;
00102 }
00103
00111 void clear()
00112 {
00113 if(m_ptr) {
00114 delete[] m_ptr;
00115 }
00116 m_ptr = 0;
00117 }
00118
00127 T * assign(T * ptr)
00128 {
00129 T * rv = m_ptr;
00130 m_ptr = ptr;
00131 return rv;
00132 }
00133
00141 void reset(T * ptr)
00142 {
00143 clear();
00144 m_ptr = ptr;
00145 }
00146
00147
00156 T * release()
00157 {
00158 T * rv = m_ptr;
00159 m_ptr = 0;
00160 return rv;
00161 }
00162
00163 private:
00164 T * m_ptr;
00165 };
00166
00167 typedef PKIFScopedArray<char> pkif_char_array;
00168 typedef PKIFScopedArray<unsigned char> pkif_byte_array;
00169
00175 template <typename T> class HandleGuard
00176 {
00177 public:
00185 explicit HandleGuard(T ptr=0)
00186 :m_ptr(ptr)
00187 {
00188 }
00196 virtual ~HandleGuard()
00197 {
00198 }
00199
00200 virtual void clear() = 0;
00201
00202 inline T get() const
00203 {
00204 return m_ptr;
00205 }
00206
00207 inline T operator->() const
00208 {
00209 return m_ptr;
00210 }
00211
00219 inline operator const T() const
00220 {
00221 return m_ptr;
00222 }
00223
00224 inline operator T ()
00225 {
00226 return m_ptr;
00227 }
00228
00229 inline T* operator&() const
00230 {
00231 return const_cast<T*>(&m_ptr);
00232 }
00233
00242 T assign(T ptr)
00243 {
00244 T rv = m_ptr;
00245 m_ptr = ptr;
00246 return rv;
00247 }
00248
00256 void reset(T ptr)
00257 {
00258 clear();
00259 assign(ptr);
00260 }
00261
00270 T release()
00271 {
00272 T rv = m_ptr;
00273 m_ptr = 0;
00274 return rv;
00275 }
00276
00277 protected:
00278 T m_ptr;
00279 };
00280
00285 template <typename T, typename R, R (__stdcall *cleanupFunc)(T)>
00294 class CNGPtr : public HandleGuard<T>
00295 {
00296 public:
00304 explicit CNGPtr(T ptr = 0)
00305 :m_pCleanup(cleanupFunc)
00306 {
00307 m_ptr = ptr;
00308 }
00316 ~CNGPtr()
00317 {
00318 clear();
00319 }
00320
00328 void clear()
00329 {
00330 if(m_ptr && m_pCleanup) {
00331 (*m_pCleanup)(m_ptr);
00332 }
00333 m_ptr = 0;
00334 }
00335
00336 private:
00337
00338 R (__stdcall *m_pCleanup)(T);
00339 };
00340
00341 template <typename T, typename R, typename F ,R (__stdcall *cleanupFunc)(T,F)>
00350 class CNGFlagsPtr : public HandleGuard<T>
00351 {
00352 public:
00360 explicit CNGFlagsPtr(T ptr = 0,F flags = 0)
00361 :m_pCleanup(cleanupFunc),m_flags(flags)
00362 {
00363 m_ptr = ptr;
00364 }
00372 ~CNGFlagsPtr()
00373 {
00374 clear();
00375 }
00376
00384 void clear()
00385 {
00386 if(m_ptr && m_pCleanup) {
00387 (*m_pCleanup)(m_ptr,m_flags);
00388 }
00389 m_ptr = 0;
00390 }
00391
00392 private:
00393 R (__stdcall *m_pCleanup)(T,F);
00394 F m_flags;
00395 };
00396
00397
00398
00399 template <typename T>
00408 class CNGPtrCF : public HandleGuard<T>
00409 {
00410 public:
00418 explicit CNGPtrCF(T ptr =0, CleanupFunctor<T> * cf = new LocalFreeFunctor<T>())
00419 :m_cf(cf)
00420 {
00421 assert(m_cf != 0);
00422 m_ptr = ptr;
00423 }
00431 ~CNGPtrCF()
00432 {
00433 clear();
00434 }
00435
00443 void clear()
00444 {
00445 if(m_ptr) {
00446 (*m_cf)(m_ptr);
00447 }
00448 delete m_cf;
00449 m_ptr = 0;
00450 }
00451
00452 private:
00453 CleanupFunctor<T> * m_cf;
00454 };
00455
00457 #define PKIFCNGPTR_DECLARE(s,f) typedef CNGPtr<s,LONG,f> s##_PKIF
00459 #define PKIFCNGFLAGSPTR_DECLARE(s,f) typedef CNGFlagsPtr<s,LONG,ULONG,f> s##_PKIF
00461 #define PKIFCAPI1PTR_DECLARE(s,f) typedef CNGPtr<s,BOOL,f> s##_PKIF
00463 #define PKIFCAPI1FLAGSPTR_DECLARE(s,f) typedef CNGFlagsPtr<s,BOOL,DWORD,f> s##_PKIF
00465 #define PKIFCNGPTR_DECLARE_CF(s) typedef CNGPtrCF<s> s##_PKIF
00466
00467 PKIFCNGPTR_DECLARE(NCRYPT_PROV_HANDLE,NCryptFreeObject);
00468 PKIFCNGPTR_DECLARE(NCRYPT_KEY_HANDLE,NCryptFreeObject);
00469 PKIFCNGPTR_DECLARE(BCRYPT_KEY_HANDLE,BCryptDestroyKey);
00470 PKIFCNGPTR_DECLARE_CF(PCERT_PUBLIC_KEY_INFO);
00471 PKIFCNGFLAGSPTR_DECLARE(BCRYPT_ALG_HANDLE,BCryptCloseAlgorithmProvider);
00472
00473 PKIFCAPI1FLAGSPTR_DECLARE(HCRYPTPROV,CryptReleaseContext);
00474 PKIFCAPI1PTR_DECLARE(HCRYPTKEY,CryptDestroyKey);
00475 PKIFCAPI1PTR_DECLARE(PCCERT_CONTEXT,CertFreeCertificateContext);
00476
00477 #endif