/////////////////////////////////////////////////////////////////////////////////// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>//// See accompanying file COPYING.TXT file for licensing details./////////////////////////////////////////////////////////////////////////////////#define CPPCMS_SOURCE#include <cppcms/urandom.h>#include <cppcms/cppcms_error.h>#ifdef CPPCMS_WIN_NATIVE#include <sstream>#include <booster/thread.h>#ifndef NOMINMAX#define NOMINMAX#endif#include "windows.h"#include "wincrypt.h"namespace cppcms {class urandom_device_impl {public:urandom_device_impl() {if(CryptAcquireContext(&provider_,0,0,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT))return;if(GetLastError() == (DWORD)(NTE_BAD_KEYSET)) {if(CryptAcquireContext(&provider_,0,0,PROV_RSA_FULL,CRYPT_NEWKEYSET))return;}std::ostringstream ss;ss<<"CryptAcquireContext failed with code 0x"<<std::hex<<GetLastError();throw cppcms_error(ss.str());}~urandom_device_impl(){CryptReleaseContext(provider_,0);}void generate(void *ptr,unsigned len){if(CryptGenRandom(provider_,len,static_cast<BYTE *>(ptr)))return;std::ostringstream ss;ss<<"CryptGenRandom failed with code 0x"<<std::hex<<GetLastError();throw cppcms_error(ss.str());}private:HCRYPTPROV provider_;};booster::thread_specific_ptr<urandom_device_impl> urandom_device_impl_ptr;struct urandom_device::_data {};urandom_device::urandom_device(){}urandom_device::~urandom_device(){}void urandom_device::generate(void *ptr,unsigned len){if(!urandom_device_impl_ptr.get())urandom_device_impl_ptr.reset(new urandom_device_impl());urandom_device_impl_ptr->generate(ptr,len);}} // cppcms#else#ifndef CPPCMS_WIN32#include "daemonize.h"#endif#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>namespace cppcms {struct urandom_device::_data {};urandom_device::urandom_device(){}urandom_device::~urandom_device(){}void urandom_device::generate(void *ptr,unsigned len){if(len == 0)return;int n = 0;#ifndef CPPCMS_WIN32if(impl::daemonizer::global_urandom_fd!=-1) {n = read(impl::daemonizer::global_urandom_fd,ptr,len);}else#endif{int fd = open("/dev/urandom",O_RDONLY);if(!fd)throw cppcms_error("Failed to open /dev/urandom");while(len > 0) {n = read(fd,ptr,len);if(n < 0 && errno == EINTR)continue;if(n <= 0)break;ptr = static_cast<char *>(ptr) + n;len -= n;}close(fd);}if(len > 0) {throw cppcms_error("Failed to read /dev/urandom");}}}#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。