1 |
#ifndef HASHER_H__
|
2 |
#define HASHER_H__
|
3 |
#include <wincrypt.h>
|
4 |
|
5 |
class Hasher
|
6 |
{
|
7 |
public:
|
8 |
Hasher(ALG_ID algId, DWORD provType = PROV_RSA_FULL, LPCTSTR provider = NULL) throw (_com_error)
|
9 |
: m_hProv (NULL)
|
10 |
, m_hHash (NULL)
|
11 |
{
|
12 |
if (!CryptAcquireContext(&m_hProv, NULL, provider, provType, CRYPT_VERIFYCONTEXT))
|
13 |
_com_raise_error(AtlHresultFromLastError());
|
14 |
|
15 |
try
|
16 |
{
|
17 |
if (!CryptCreateHash(m_hProv, algId, 0, 0, &m_hHash))
|
18 |
_com_raise_error(AtlHresultFromLastError());
|
19 |
}
|
20 |
catch(...)
|
21 |
{
|
22 |
if (m_hProv)
|
23 |
CryptReleaseContext(m_hProv, 0);
|
24 |
throw;
|
25 |
}
|
26 |
}
|
27 |
|
28 |
~Hasher()
|
29 |
{
|
30 |
if (m_hHash)
|
31 |
CryptDestroyHash(m_hHash);
|
32 |
|
33 |
if (m_hProv)
|
34 |
CryptReleaseContext(m_hProv, 0);
|
35 |
}
|
36 |
|
37 |
inline void operator() (const BYTE* data, DWORD size) throw (_com_error)
|
38 |
{
|
39 |
if (!CryptHashData(m_hHash, data, size, 0))
|
40 |
_com_raise_error(AtlHresultFromLastError());
|
41 |
}
|
42 |
|
43 |
inline void operator() (const std::string & str) throw (_com_error)
|
44 |
{
|
45 |
operator() (
|
46 |
reinterpret_cast<const BYTE *>(str.data()),
|
47 |
static_cast<DWORD>(str.size())
|
48 |
);
|
49 |
}
|
50 |
|
51 |
DWORD size () throw (_com_error)
|
52 |
{
|
53 |
DWORD dwRetval, dwSizeofRetval = sizeof(dwRetval);
|
54 |
if (!CryptGetHashParam(
|
55 |
m_hHash,
|
56 |
HP_HASHSIZE,
|
57 |
reinterpret_cast<BYTE*>(&dwRetval),
|
58 |
&dwSizeofRetval,
|
59 |
0))
|
60 |
{
|
61 |
_com_raise_error(AtlHresultFromLastError());
|
62 |
}
|
63 |
return dwRetval;
|
64 |
}
|
65 |
|
66 |
inline void finish (__out BYTE* output, __inout DWORD * pdwSize) throw (_com_error)
|
67 |
{
|
68 |
if (!CryptGetHashParam(m_hHash, HP_HASHVAL, output, pdwSize, 0))
|
69 |
_com_raise_error(AtlHresultFromLastError());
|
70 |
}
|
71 |
|
72 |
inline void finish (__out std::string & hex) throw (_com_error)
|
73 |
{
|
74 |
DWORD hashsize = this->size();
|
75 |
BYTE* hashout = new BYTE [hashsize];
|
76 |
|
77 |
if (!hashout)
|
78 |
_com_raise_error(E_OUTOFMEMORY);
|
79 |
|
80 |
try
|
81 |
{
|
82 |
this->finish(hashout, &hashsize);
|
83 |
}
|
84 |
catch (...)
|
85 |
{
|
86 |
delete[] hashout;
|
87 |
throw;
|
88 |
}
|
89 |
|
90 |
hex.resize(hashsize * 2);
|
91 |
buffer2hexstr(hex, hashout, hashsize);
|
92 |
delete[] hashout;
|
93 |
}
|
94 |
|
95 |
private:
|
96 |
HCRYPTPROV m_hProv;
|
97 |
HCRYPTHASH m_hHash;
|
98 |
|
99 |
template<typename String>
|
100 |
static inline void buffer2hexstr(String& outstr, BYTE * buffer, DWORD bufferlen)
|
101 |
{
|
102 |
static const char lookup[] = "0123456789abcdef";
|
103 |
|
104 |
for(DWORD i = 0; i < bufferlen; ++i)
|
105 |
{
|
106 |
outstr[2*i] = lookup[(buffer[i] >> 4) & 0xf];
|
107 |
outstr[2*i+1] = lookup[buffer[i] & 0xf];
|
108 |
}
|
109 |
}
|
110 |
};
|
111 |
|
112 |
#endif // HASHER_H__
|