mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
HCRYPTPROV is not a HANDLE
Even though it is called "handle" and prefixed with "H", and its value looks like a handle.
This commit is contained in:
parent
61aedb28ef
commit
0eb679f70c
1 changed files with 14 additions and 7 deletions
21
random.c
21
random.c
|
@ -544,11 +544,18 @@ fill_random_bytes_syscall(void *buf, size_t size, int unused)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
STATIC_ASSERT(sizeof_HCRYPTPROV, sizeof(HCRYPTPROV) == sizeof(size_t));
|
||||||
|
|
||||||
|
/* Although HCRYPTPROV is not a HANDLE, it looks like
|
||||||
|
* INVALID_HANDLE_VALUE is not a valid value */
|
||||||
|
static const HCRYPTPROV INVALID_HCRYPTPROV = (HCRYPTPROV)INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
release_crypt(void *p)
|
release_crypt(void *p)
|
||||||
{
|
{
|
||||||
HCRYPTPROV prov = (HCRYPTPROV)ATOMIC_PTR_EXCHANGE(*(HCRYPTPROV *)p, INVALID_HANDLE_VALUE);
|
HCRYPTPROV *ptr = p;
|
||||||
if (prov && prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
|
HCRYPTPROV prov = (HCRYPTPROV)ATOMIC_SIZE_EXCHANGE(*ptr, INVALID_HCRYPTPROV);
|
||||||
|
if (prov && prov != INVALID_HCRYPTPROV) {
|
||||||
CryptReleaseContext(prov, 0);
|
CryptReleaseContext(prov, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,24 +567,24 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
|
||||||
HCRYPTPROV prov = perm_prov, old_prov;
|
HCRYPTPROV prov = perm_prov, old_prov;
|
||||||
if (!prov) {
|
if (!prov) {
|
||||||
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||||
prov = (HCRYPTPROV)INVALID_HANDLE_VALUE;
|
prov = INVALID_HCRYPTPROV;
|
||||||
}
|
}
|
||||||
old_prov = (HCRYPTPROV)ATOMIC_PTR_CAS(perm_prov, 0, prov);
|
old_prov = (HCRYPTPROV)ATOMIC_SIZE_CAS(perm_prov, 0, prov);
|
||||||
if (LIKELY(!old_prov)) { /* no other threads acquired */
|
if (LIKELY(!old_prov)) { /* no other threads acquired */
|
||||||
if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
|
if (prov != INVALID_HCRYPTPROV) {
|
||||||
#undef RUBY_UNTYPED_DATA_WARNING
|
#undef RUBY_UNTYPED_DATA_WARNING
|
||||||
#define RUBY_UNTYPED_DATA_WARNING 0
|
#define RUBY_UNTYPED_DATA_WARNING 0
|
||||||
rb_gc_register_mark_object(Data_Wrap_Struct(0, 0, release_crypt, &perm_prov));
|
rb_gc_register_mark_object(Data_Wrap_Struct(0, 0, release_crypt, &perm_prov));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* another thread acquired */
|
else { /* another thread acquired */
|
||||||
if (prov != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
|
if (prov != INVALID_HCRYPTPROV) {
|
||||||
CryptReleaseContext(prov, 0);
|
CryptReleaseContext(prov, 0);
|
||||||
}
|
}
|
||||||
prov = old_prov;
|
prov = old_prov;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (prov == (HCRYPTPROV)INVALID_HANDLE_VALUE) return -1;
|
if (prov == INVALID_HCRYPTPROV) return -1;
|
||||||
CryptGenRandom(prov, size, seed);
|
CryptGenRandom(prov, size, seed);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue